เพิ่ม editor ต่อ template field — ผู้ดูแลเลือกรูปแบบช่องกรอกในฟอร์มสร้างเอกสารได้: text → textbox/textarea, number/date → control ตาม type (presentation metadata ล้วน — validation ยังยึด Type, ค่า field เป็น string ทั้ง flow, ไม่แตะ generate/sync/add-in) - Backend: TemplateField.Editor (nullable, null = default ของ type) + migration AddTemplateFieldEditor + validate ตาม type ใน PUT templates (ค่าไม่รู้จัก/ไม่เข้ากับ type → 400, normalize-on-write, API คืน resolved เสมอ) - Web: util fieldEditor.ts + editor select หน้าแก้ template (desktop+mobile, ซ่อนเมื่อ type มีทางเดียว) + ฟอร์มสร้างเอกสาร render ตาม editor + แก้ prefill re-generate ของ field date จาก ISO timestamp เต็ม (input[type=date] รับเฉพาะ yyyy-MM-dd เดิมแสดงว่าง) - Docs: spec v6 (FR-14/AC-17) + plan Phase 10 + sub-plan field-editor.md + acceptance-review AC-17 + README/CLAUDE.md - Tests: backend 60/60 (FieldEditorTests ใหม่ 8 กรณี) · web 46/46 + build ผ่าน Co-Authored-By: Claude <noreply@anthropic.com>
43 lines
2.4 KiB
TypeScript
43 lines
2.4 KiB
TypeScript
/**
|
|
* Editor (รูปแบบช่องกรอก) ต่อ template field (FR-14) — pure util ให้ unit test ได้
|
|
* มิเรอร์ allow-list ของ backend (TemplateField.EditorsByType): text เลือก textbox/textarea ได้,
|
|
* number/date มีทางเดียวตาม type — เป็น presentation metadata เท่านั้น (validation ของค่ายังยึด type)
|
|
*/
|
|
|
|
import type { FieldEditor } from '~/types/api'
|
|
|
|
export const EDITORS_BY_TYPE: Record<string, FieldEditor[]> = {
|
|
text: ['textbox', 'textarea'],
|
|
number: ['number'],
|
|
date: ['date'],
|
|
}
|
|
|
|
/** editor เริ่มต้นของ type (ตัวแรกของรายการ) — type ที่ไม่รู้จัก → textbox */
|
|
export function defaultEditor(type: string): FieldEditor {
|
|
return EDITORS_BY_TYPE[type]?.[0] ?? 'textbox'
|
|
}
|
|
|
|
/** ตัวเลือก editor ที่เลือกได้ตาม type — ใช้ซ่อน select เมื่อมีทางเดียว (number/date) */
|
|
export function editorOptions(type: string): FieldEditor[] {
|
|
return EDITORS_BY_TYPE[type] ?? ['textbox']
|
|
}
|
|
|
|
/**
|
|
* หา editor ที่จะใช้ render จริงจาก field — editor ที่ถูกต้องตาม type → ใช้ค่านั้น,
|
|
* ไม่มี/ไม่รู้จัก/ไม่เข้ากับ type → default ของ type (degrade อ่อนโยน ไม่ throw)
|
|
*/
|
|
export function resolveEditor(field: { type: string; editor?: string | null }): FieldEditor {
|
|
const options = EDITORS_BY_TYPE[field.type] ?? ['textbox']
|
|
return options.includes(field.editor as FieldEditor)
|
|
? (field.editor as FieldEditor)
|
|
: options[0]
|
|
}
|
|
|
|
/**
|
|
* ค่าวันที่สำหรับ input[type=date] — รับเฉพาะรูป yyyy-MM-dd เท่านั้น
|
|
* ค่าจาก field sync ของ Word อาจเป็น ISO timestamp เต็ม (backend parse ได้ตาม FR-10) → ตัดเอาส่วนวันที่
|
|
* ค่าอื่นที่ไม่ใช่รูป ISO → คงเดิม ให้ validation ของฟอร์มจัดการต่อ
|
|
*/
|
|
export function dateInputValue(value: string): string {
|
|
return /^\d{4}-\d{2}-\d{2}/.test(value) ? value.slice(0, 10) : value
|
|
}
|