Phase 10: field editor (FR-14)
เพิ่ม 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>
This commit is contained in:
parent
7b20f12ede
commit
9bb4a48c00
23 changed files with 865 additions and 45 deletions
|
|
@ -196,9 +196,18 @@ public class TemplatesController(
|
|||
if (string.IsNullOrWhiteSpace(def.Label))
|
||||
return BadRequest($"label ของ `{def.Key}` ห้ามว่าง");
|
||||
|
||||
// editor (FR-14) — ไม่ส่ง/ว่าง = default ของ type · ค่าที่เท่ากับ default เก็บเป็น null (normalize-on-write)
|
||||
var editor = string.IsNullOrWhiteSpace(def.Editor)
|
||||
? TemplateField.DefaultEditor(def.Type)
|
||||
: def.Editor.Trim();
|
||||
if (!TemplateField.EditorsByType[def.Type].Contains(editor))
|
||||
return BadRequest(
|
||||
$"editor ของ `{def.Key}` ต้องเป็น {string.Join("/", TemplateField.EditorsByType[def.Type])} สำหรับ type {def.Type} (ได้ `{editor}`)");
|
||||
|
||||
var row = template.Fields.First(f => f.Key == def.Key);
|
||||
row.Label = def.Label.Trim();
|
||||
row.Type = def.Type;
|
||||
row.Editor = editor == TemplateField.DefaultEditor(def.Type) ? null : editor;
|
||||
row.IsRequired = def.IsRequired;
|
||||
row.SortOrder = def.SortOrder;
|
||||
}
|
||||
|
|
@ -353,6 +362,7 @@ public class TemplatesController(
|
|||
|
||||
private static List<TemplateFieldDto> FieldDtos(Template template) => template.Fields
|
||||
.OrderBy(f => f.SortOrder)
|
||||
.Select(f => new TemplateFieldDto(f.Id, f.Key, f.Label, f.Type, f.IsRequired, f.SortOrder))
|
||||
.Select(f => new TemplateFieldDto(f.Id, f.Key, f.Label, f.Type,
|
||||
f.Editor ?? TemplateField.DefaultEditor(f.Type), f.IsRequired, f.SortOrder))
|
||||
.ToList();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue