eCourt-Doc-Edit/web/app/pages/documents/create/[templateId].vue

280 lines
13 KiB
Vue
Raw Normal View History

2026-08-20 06:20:16 +07:00
<script setup lang="ts">
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
/** FR-10 UI — dynamic form สร้างเอกสารจาก field definitions ของ template → generate เป็น v0 + ดาวน์โหลด
* FR-12 — รองรับ re-generate: ?from={documentId} → prefill ค่าล่าสุดของเอกสารนั้นให้แก้ก่อนสร้าง */
import type { DocumentDetail, GenerateDocumentResponse, TemplateDetail } from '~/types/api'
2026-08-20 06:20:16 +07:00
const route = useRoute()
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
const { apiJson } = useApi()
const { openingVersionId, downloadError, fallbackUrl, openNotice, openVersion, resetOpen } = useVersionOpen()
2026-08-20 06:20:16 +07:00
const templateId = computed(() => String(route.params.templateId))
const detail = ref<TemplateDetail | null>(null)
const values = ref<Record<string, string>>({})
const issues = ref<Record<string, string>>({})
/** คำอธิบาย version แบบ commit message (FR-13) — ทางเลือก · re-generate ไม่ prefill เพราะเป็นเอกสารใหม่ */
const message = ref('')
2026-08-20 06:20:16 +07:00
/** เอกสารต้นทางของ re-generate (จาก ?from=) — ใช้ทั้ง prefill และ banner บอกบริบท */
const fromDoc = ref<{ id: string; fileName: string } | null>(null)
const prefill = ref<Record<string, string>>({})
2026-08-20 06:20:16 +07:00
const loading = ref(true)
const loadError = ref<string | null>(null)
const submitting = ref(false)
const submitError = ref<string | null>(null)
const result = ref<GenerateDocumentResponse | null>(null)
const sortedFields = computed(() => [...(detail.value?.fields ?? [])].sort((a, b) => a.sortOrder - b.sortOrder))
useHead({
title: computed(() =>
detail.value
? `สร้างเอกสาร: ${detail.value.name} — e-Court Documents Versioning`
: 'สร้างเอกสาร — e-Court Documents Versioning',
),
})
function blankValues(): Record<string, string> {
return Object.fromEntries((detail.value?.fields ?? []).map((f) => [f.key, '']))
}
2026-08-20 06:20:16 +07:00
async function load() {
loading.value = true
loadError.value = null
try {
detail.value = (await apiJson<TemplateDetail>(`/api/templates/${templateId.value}`))!
const from = typeof route.query.from === 'string' ? route.query.from : null
if (from) {
try {
const src = await apiJson<DocumentDetail>(`/api/documents/${from}`)
if (src?.templateId) {
fromDoc.value = { id: src.id, fileName: src.fileName }
// prefill เฉพาะ key ที่มีใน defs ปัจจุบัน — key ที่หายไปหลัง replace ไฟล์โชว์ไม่ได้ (generate ก็ ignore)
prefill.value = Object.fromEntries(
detail.value.fields.map((f) => {
const value = src.fields.find((s) => s.key === f.key)?.value ?? ''
// field วันที่: input[type=date] รับเฉพาะ yyyy-MM-dd — ค่าจาก sync ของ Word อาจเป็น ISO timestamp เต็ม (FR-14)
return [f.key, resolveEditor(f) === 'date' ? dateInputValue(value) : value]
}),
)
}
} catch {
// ไม่พบเอกสารต้นทาง — ปล่อยให้เป็นฟอร์มว่างตามปกติ
}
}
values.value = { ...blankValues(), ...prefill.value }
2026-08-20 06:20:16 +07:00
} catch (err) {
loadError.value = err instanceof Error ? err.message : 'โหลด template ไม่สำเร็จ'
} finally {
loading.value = false
}
}
/** validate ฝั่ง client (required/type) ก่อนยิง backend — backend ตรวจซ้ำอีกชั้นเสมอ */
async function submit() {
submitError.value = null
downloadError.value = null
issues.value = Object.fromEntries(
validateFieldValues(sortedFields.value, values.value).map((i) => [i.key, i.message]),
)
if (Object.keys(issues.value).length > 0) return
submitting.value = true
try {
result.value = await apiJson<GenerateDocumentResponse>('/api/documents/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ templateId: templateId.value, values: values.value, message: message.value.trim() || null }),
2026-08-20 06:20:16 +07:00
})
window.scrollTo({ top: 0 })
} catch (err) {
submitError.value = err instanceof Error ? err.message : 'สร้างเอกสารไม่สำเร็จ'
} finally {
submitting.value = false
}
}
/** กลับไปกรอกฟอร์มใหม่เพื่อสร้างอีกฉบับจาก template เดิม (ถ้าเป็น re-generate → คืนค่า prefill ไม่ใช่ฟอร์มว่าง) */
2026-08-20 06:20:16 +07:00
function resetForm() {
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
resetOpen()
2026-08-20 06:20:16 +07:00
result.value = null
submitError.value = null
downloadError.value = null
issues.value = {}
values.value = { ...blankValues(), ...prefill.value }
message.value = ''
2026-08-20 06:20:16 +07:00
}
onMounted(load)
</script>
<template>
<AuthGate>
<section class="mx-auto max-w-2xl space-y-6">
2026-08-20 21:34:45 +07:00
<div v-if="loading" class="flex items-center gap-3 py-10 text-sm text-muted">
<span class="spinner" />
2026-08-20 06:20:16 +07:00
กำลังโหลด template…
</div>
<AlertBox v-else-if="loadError" type="error">
{{ loadError }}
<NuxtLink to="/" class="ml-1 font-medium underline">กลับหน้าหลัก</NuxtLink>
</AlertBox>
<template v-else-if="detail">
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
<!-- ผลลัพธ์: สร้างสำเร็จเป็น v0 แล้ว -->
2026-08-20 06:20:16 +07:00
<template v-if="result">
<AlertBox type="success">
สร้างเอกสารสำเร็จ — บันทึกเป็น <strong>version {{ result.versionNumber }}</strong> แล้ว
</AlertBox>
2026-08-20 21:34:45 +07:00
<div class="card p-6">
<h1 class="text-page-title">{{ detail.name }}</h1>
2026-08-20 06:20:16 +07:00
<dl class="mt-4 space-y-2 text-sm">
<div class="flex gap-2">
2026-08-20 21:34:45 +07:00
<dt class="w-32 shrink-0 text-muted">document id</dt>
2026-08-20 06:20:16 +07:00
<dd class="break-all font-mono text-xs leading-6">{{ result.documentId }}</dd>
</div>
<div class="flex gap-2">
2026-08-20 21:34:45 +07:00
<dt class="w-32 shrink-0 text-muted">version</dt>
2026-08-20 06:20:16 +07:00
<dd>{{ result.versionNumber }} (ต้นทางของ version history)</dd>
</div>
</dl>
2026-08-20 21:34:45 +07:00
<div class="mt-6 flex flex-col-reverse gap-2 sm:flex-row sm:flex-wrap">
<NuxtLink to="/" class="btn btn-secondary w-full sm:w-auto">กลับหน้าหลัก</NuxtLink>
<button type="button" class="btn btn-secondary w-full sm:w-auto" @click="resetForm">
สร้างอีกฉบับ
</button>
2026-08-20 06:20:16 +07:00
<button
type="button"
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
:disabled="openingVersionId !== null"
2026-08-20 21:34:45 +07:00
class="btn btn-primary w-full sm:w-auto"
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
@click="openVersion(result.documentId, result.versionId)"
2026-08-20 06:20:16 +07:00
>
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
{{ openingVersionId !== null ? 'กำลังเตรียมไฟล์…' : 'เปิดใน Word' }}
2026-08-20 06:20:16 +07:00
</button>
</div>
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
<AlertBox v-if="fallbackUrl" class="mt-4">
<p v-if="openNotice">{{ openNotice }}</p>
<a :href="fallbackUrl" target="_blank" rel="noopener noreferrer" class="link">ดาวน์โหลด .docx สำรอง</a>
<p class="text-xs text-muted">ลิงก์มีอายุสั้น หากหมดอายุให้กดเปิดใน Word อีกครั้ง</p>
</AlertBox>
2026-08-20 06:20:16 +07:00
<AlertBox v-if="downloadError" type="error" class="mt-4">{{ downloadError }}</AlertBox>
</div>
2026-08-20 21:34:45 +07:00
<div class="panel-info">
<p class="font-medium text-primary">ขั้นต่อไป</p>
<ol class="mt-2 list-decimal space-y-1 pl-5">
2026-08-20 06:20:16 +07:00
<li>เปิดไฟล์ที่ดาวน์โหลดใน Word (Desktop หรือ Online)</li>
<li>
เปิด task pane ของ add-in <strong>e-Court Documents Versioning</strong> — ระบบจะตรวจพบว่าเป็น
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
tracked document และแสดง <strong>version 0</strong> ทันที โดยไม่ต้องกด Start Versioning
2026-08-20 06:20:16 +07:00
</li>
<li>แก้ไขเอกสารต่อแล้วกด <strong>Save &amp; Version</strong> เพื่อบันทึก version ถัดไป</li>
</ol>
</div>
</template>
<!-- ฟอร์มกรอกค่า -->
<form v-else class="space-y-5" @submit.prevent="submit" novalidate>
<div>
2026-08-20 21:34:45 +07:00
<h1 class="text-page-title">{{ detail.name }}</h1>
<p v-if="detail.description" class="mt-1 text-sm text-muted">
2026-08-20 06:20:16 +07:00
{{ detail.description }}
</p>
</div>
<AlertBox v-if="fromDoc">
กำลังสร้างเอกสารใหม่จากค่าปัจจุบันของ <strong class="break-all">{{ fromDoc.fileName }}</strong>
— แก้ค่าได้ก่อนกดสร้าง และเอกสารต้นทางจะไม่ถูกแตะ (ไม่เกิด version ใหม่)
</AlertBox>
<AlertBox v-if="!detail.isActive">
template นี้ถูก deactivate แล้ว — สร้างเอกสารใหม่ไม่ได้ (เอกสารที่สร้างไว้แล้วยังใช้ได้)
</AlertBox>
2026-08-20 06:20:16 +07:00
<div
v-for="f in sortedFields"
:key="f.key"
>
2026-08-20 21:34:45 +07:00
<label :for="`field-${f.key}`" class="label">
2026-08-20 06:20:16 +07:00
{{ f.label }}
2026-08-20 21:34:45 +07:00
<span v-if="f.isRequired" class="text-error-strong">*</span>
<span class="ml-1 font-mono text-xs font-normal text-muted">{{ f.key }}</span>
2026-08-20 06:20:16 +07:00
</label>
<!-- render ตาม editor ของ field (FR-14): textarea สำหรับข้อความยาว · number/date ตาม type -->
<textarea
v-if="resolveEditor(f) === 'textarea'"
:id="`field-${f.key}`"
v-model="values[f.key]"
class="input"
:class="issues[f.key] ? 'border-error' : ''"
rows="4"
/>
<input
v-else-if="resolveEditor(f) === 'number'"
:id="`field-${f.key}`"
v-model="values[f.key]"
type="number"
step="any"
class="input"
:class="issues[f.key] ? 'border-error' : ''"
/>
<input
v-else-if="resolveEditor(f) === 'date'"
:id="`field-${f.key}`"
v-model="values[f.key]"
type="date"
class="input"
:class="issues[f.key] ? 'border-error' : ''"
/>
2026-08-20 06:20:16 +07:00
<input
v-else
2026-08-20 06:20:16 +07:00
:id="`field-${f.key}`"
v-model="values[f.key]"
type="text"
2026-08-20 21:34:45 +07:00
class="input"
:class="issues[f.key] ? 'border-error' : ''"
2026-08-20 06:20:16 +07:00
/>
2026-08-20 21:34:45 +07:00
<p v-if="issues[f.key]" class="mt-1 text-xs text-error-strong">{{ issues[f.key] }}</p>
2026-08-20 06:20:16 +07:00
</div>
<div>
<label for="doc-message" class="label">คำอธิบาย version (ไม่บังคับ)</label>
<textarea
id="doc-message"
v-model="message"
class="input"
rows="2"
maxlength="2048"
placeholder="เช่น ฉบับเสนอลงนามครั้งแรก"
/>
</div>
2026-08-20 21:34:45 +07:00
<div v-if="sortedFields.length === 0" class="empty-state">
2026-08-20 06:20:16 +07:00
template นี้ไม่มี field definitions —
2026-08-20 21:34:45 +07:00
<NuxtLink :to="`/templates/${detail.id}/edit`" class="link">ตรวจสอบที่หน้าจัดการ template</NuxtLink>
2026-08-20 06:20:16 +07:00
</div>
<AlertBox v-if="submitError" type="error">{{ submitError }}</AlertBox>
2026-08-20 21:34:45 +07:00
<div class="flex flex-col-reverse gap-2 pt-2 sm:flex-row sm:justify-end">
<button
type="submit"
:disabled="submitting || sortedFields.length === 0 || !detail.isActive"
class="btn btn-primary w-full sm:w-auto"
>
Phase 11: version PDF (FR-15) - เลข version ใหม่: เว็บ-generate = v0 ฉบับตั้งต้น (ไม่มี PDF), add-in save (Start Versioning + Save & Version) = v1+ มี PDF เสมอ - PDF ผลิตจาก Word จริงผ่าน task pane เท่านั้น (getFileAsync Pdf + runtime guard, manifest ไม่เพิ่ม requirement); capture/upload เป็น best-effort — docx ผ่านแม้ PDF ล้ม + MessageBar เตือนตาม hasPdf - Backend: DocumentVersion.PdfObjectKey (nullable, migration AddVersionPdf) + sibling .pdf ใน bucket docx-versions · multipart part pdf (ผิด type → 400) · /download + /download-link รับ ?format=pdf (ไม่มี → 404) · presigned ฝังชื่อไฟล์ไทย + _vN (RFC 5987) - Web: เปิดไฟล์แทน blob-download — PDF แท็บใหม่, docx ผ่าน ms-word:ofe|u| พร้อม heuristic fallback ลิงก์สำรอง (useVersionOpen, versionDownload) · ปุ่ม "เปิดใน Word" ที่หน้า success ของฟอร์มสร้างเอกสาร - Spec v7 + CONTEXT.md + ADR 0001 + แผน docs/plans/version-pdf.md - Automated QA: backend 68 / add-in 63 / web 55 ผ่าน · manual acceptance ผ่านบน Word for Mac (2026-09-08) รวม fidelity + track changes — ค้างเฉพาะ Windows / Word on the web Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-08 14:01:13 +07:00
{{ submitting ? 'กำลังสร้างเอกสาร…' : 'สร้างเอกสาร (version 0)' }}
2026-08-20 21:34:45 +07:00
</button>
</div>
2026-08-20 06:20:16 +07:00
</form>
</template>
</section>
</AuthGate>
</template>