@rytass/bpm-core-react 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/dist/chunks/FormBuilderView-B_KGPjlp.cjs +3 -0
- package/dist/chunks/FormBuilderView-B_KGPjlp.cjs.map +1 -0
- package/dist/chunks/FormBuilderView-D8DrQOXD.js +1090 -0
- package/dist/chunks/FormBuilderView-D8DrQOXD.js.map +1 -0
- package/dist/chunks/{approval-instance-list-page-C5ZKPHdA.cjs → approval-instance-list-page-BMUKxzcz.cjs} +2 -2
- package/dist/chunks/{approval-instance-list-page-C5ZKPHdA.cjs.map → approval-instance-list-page-BMUKxzcz.cjs.map} +1 -1
- package/dist/chunks/{approval-instance-list-page-BF2r5D2-.js → approval-instance-list-page-YZcGGDD8.js} +2 -2
- package/dist/chunks/{approval-instance-list-page-BF2r5D2-.js.map → approval-instance-list-page-YZcGGDD8.js.map} +1 -1
- package/dist/chunks/compose-PMrmi-LE.js +451 -0
- package/dist/chunks/compose-PMrmi-LE.js.map +1 -0
- package/dist/chunks/compose-ziVbRYdo.cjs +2 -0
- package/dist/chunks/compose-ziVbRYdo.cjs.map +1 -0
- package/dist/chunks/{dashboard-page-Ib8srCMy.js → dashboard-page-DJ9vOPga.js} +2 -2
- package/dist/chunks/{dashboard-page-Ib8srCMy.js.map → dashboard-page-DJ9vOPga.js.map} +1 -1
- package/dist/chunks/{dashboard-page-CddG1MnK.cjs → dashboard-page-DwHQY6Ki.cjs} +2 -2
- package/dist/chunks/{dashboard-page-CddG1MnK.cjs.map → dashboard-page-DwHQY6Ki.cjs.map} +1 -1
- package/dist/chunks/designer-DCn6_v4b.cjs +65 -0
- package/dist/chunks/designer-DCn6_v4b.cjs.map +1 -0
- package/dist/chunks/designer-mOMxJ0Py.js +2576 -0
- package/dist/chunks/designer-mOMxJ0Py.js.map +1 -0
- package/dist/chunks/detail-Bml-vXHX.js +1622 -0
- package/dist/chunks/detail-Bml-vXHX.js.map +1 -0
- package/dist/chunks/detail-CWeCrmtC.cjs +2 -0
- package/dist/chunks/detail-CWeCrmtC.cjs.map +1 -0
- package/dist/chunks/{routes-config-dxahImVe.js → routes-config-RBYQtUd0.js} +2 -3
- package/dist/chunks/routes-config-RBYQtUd0.js.map +1 -0
- package/dist/chunks/routes-config-fDVHmvXi.cjs +2 -0
- package/dist/chunks/routes-config-fDVHmvXi.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +268 -128
- package/dist/index.js.map +1 -1
- package/dist/lib/routes-config.d.ts +6 -4
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.js +1 -1
- package/dist/next/workflow-chat-route.cjs +19 -0
- package/dist/next/workflow-chat-route.cjs.map +1 -0
- package/dist/next/workflow-chat-route.d.ts +17 -0
- package/dist/next/workflow-chat-route.js +31 -0
- package/dist/next/workflow-chat-route.js.map +1 -0
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/templates/compose/index.cjs +2 -0
- package/dist/pages/templates/compose/index.cjs.map +1 -0
- package/dist/pages/templates/compose/index.d.ts +13 -0
- package/dist/pages/templates/compose/index.js +14 -0
- package/dist/pages/templates/compose/index.js.map +1 -0
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.cjs.map +1 -1
- package/dist/pages/templates/designer/index.js +7 -2
- package/dist/pages/templates/designer/index.js.map +1 -1
- package/dist/pages/templates/index.cjs +1 -1
- package/dist/pages/templates/index.cjs.map +1 -1
- package/dist/pages/templates/index.js +3 -3
- package/dist/pages/templates/index.js.map +1 -1
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.js +1 -1
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.js +1 -1
- package/dist/views/forms/builder/FormBuilderView.d.ts +13 -4
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/builder/json-code-editor.d.ts +1 -1
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.js +1 -1
- package/dist/views/instances/detail/InstanceDetailView.d.ts +11 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.d.ts +5 -0
- package/dist/views/instances/detail/index.js +2 -2
- package/dist/views/instances/detail/sections/InstanceAttachmentsSection.d.ts +15 -0
- package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +33 -0
- package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +29 -0
- package/dist/views/instances/detail/sections/InstanceSignaturesSection.d.ts +14 -0
- package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +44 -0
- package/dist/views/instances/detail/sections/container-helpers.d.ts +8 -0
- package/dist/views/instances/detail/sections/shared.d.ts +103 -0
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.js +1 -1
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.js +1 -1
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.js +1 -1
- package/dist/views/templates/TemplatesView.d.ts +5 -0
- package/dist/views/templates/compose/TemplateComposeWizardView.d.ts +8 -0
- package/dist/views/templates/compose/index.cjs +1 -0
- package/dist/views/templates/compose/index.d.ts +2 -0
- package/dist/views/templates/compose/index.js +2 -0
- package/dist/views/templates/compose/steps/ComposeFormStep.d.ts +15 -0
- package/dist/views/templates/compose/steps/ComposeReviewStep.d.ts +12 -0
- package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +11 -0
- package/dist/views/templates/compose/use-template-compose-wizard.d.ts +46 -0
- package/dist/views/templates/designer/TemplateDesignerView.d.ts +60 -2
- package/dist/views/templates/designer/chrome-workflow-chat.d.ts +12 -0
- package/dist/views/templates/designer/index.cjs +1 -51
- package/dist/views/templates/designer/index.js +2 -2272
- package/dist/views/templates/designer/use-workflow-chat.d.ts +21 -0
- package/dist/views/templates/designer/use-workflow-designer-controller.d.ts +41 -0
- package/dist/views/templates/designer/workflow-chat-drawer.d.ts +16 -0
- package/dist/views/templates/index.cjs +2 -1
- package/dist/views/templates/index.cjs.map +1 -0
- package/dist/views/templates/index.js +265 -4
- package/dist/views/templates/index.js.map +1 -0
- package/dist/views/templates/versions/index.cjs +1 -1
- package/dist/views/templates/versions/index.cjs.map +1 -1
- package/dist/views/templates/versions/index.js +38 -42
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +22 -19
- package/dist/chunks/builder-BLVnnpnP.js +0 -1300
- package/dist/chunks/builder-BLVnnpnP.js.map +0 -1
- package/dist/chunks/builder-DVE9zIKH.cjs +0 -3
- package/dist/chunks/builder-DVE9zIKH.cjs.map +0 -1
- package/dist/chunks/detail-Dcr5mM8g.cjs +0 -2
- package/dist/chunks/detail-Dcr5mM8g.cjs.map +0 -1
- package/dist/chunks/detail-u9DdLhDW.js +0 -1518
- package/dist/chunks/detail-u9DdLhDW.js.map +0 -1
- package/dist/chunks/form-name-modal-C3OEvkCV.js +0 -64
- package/dist/chunks/form-name-modal-C3OEvkCV.js.map +0 -1
- package/dist/chunks/form-name-modal-uZCHbtRH.cjs +0 -2
- package/dist/chunks/form-name-modal-uZCHbtRH.cjs.map +0 -1
- package/dist/chunks/routes-config-2aKbWq2H.cjs +0 -2
- package/dist/chunks/routes-config-2aKbWq2H.cjs.map +0 -1
- package/dist/chunks/routes-config-dxahImVe.js.map +0 -1
- package/dist/chunks/templates-D44FSB46.js +0 -380
- package/dist/chunks/templates-D44FSB46.js.map +0 -1
- package/dist/chunks/templates-w96t83N-.cjs +0 -2
- package/dist/chunks/templates-w96t83N-.cjs.map +0 -1
- package/dist/pages/forms/builder/index.cjs +0 -2
- package/dist/pages/forms/builder/index.cjs.map +0 -1
- package/dist/pages/forms/builder/index.d.ts +0 -21
- package/dist/pages/forms/builder/index.js +0 -15
- package/dist/pages/forms/builder/index.js.map +0 -1
- package/dist/pages/forms/index.cjs +0 -2
- package/dist/pages/forms/index.cjs.map +0 -1
- package/dist/pages/forms/index.d.ts +0 -17
- package/dist/pages/forms/index.js +0 -14
- package/dist/pages/forms/index.js.map +0 -1
- package/dist/views/forms/FormsView.d.ts +0 -2
- package/dist/views/forms/form-name-modal.d.ts +0 -12
- package/dist/views/forms/index.cjs +0 -2
- package/dist/views/forms/index.cjs.map +0 -1
- package/dist/views/forms/index.d.ts +0 -2
- package/dist/views/forms/index.js +0 -186
- package/dist/views/forms/index.js.map +0 -1
- package/dist/views/templates/designer/index.cjs.map +0 -1
- package/dist/views/templates/designer/index.js.map +0 -1
- package/dist/views/templates/template-name-modal.d.ts +0 -22
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,67 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
Releases are managed by [`nx release`](https://nx.dev/recipes/nx-release) with
|
|
9
9
|
Conventional Commits — see `nx.json` for the release config.
|
|
10
10
|
|
|
11
|
+
## 0.5.0 — 2026-06-04
|
|
12
|
+
|
|
13
|
+
Covers all changes since 0.4.1, including the undocumented internal
|
|
14
|
+
0.4.2–0.4.4 version bumps.
|
|
15
|
+
|
|
16
|
+
### Breaking
|
|
17
|
+
|
|
18
|
+
- **The standalone forms area is removed.** Forms are now designed only
|
|
19
|
+
inside the template compose wizard and the designer's form drawer.
|
|
20
|
+
Removed surfaces:
|
|
21
|
+
- `FormsView` and the `./views/forms` subpath (the
|
|
22
|
+
`./views/forms/builder` and `./views/forms/renderer` subpaths
|
|
23
|
+
remain).
|
|
24
|
+
- The `./pages/forms` and `./pages/forms/builder` Next.js page shims
|
|
25
|
+
(`/forms`, `/forms/[id]/builder`). Hosts must delete the
|
|
26
|
+
corresponding `app/forms/**` re-export files.
|
|
27
|
+
- `BPMRoutes.forms()` and `BPMRoutes.formBuilder(formId)` — hosts
|
|
28
|
+
providing a custom `BPMRoutes` map must drop these members.
|
|
29
|
+
- **`FormBuilderView` is now a pure controlled panel.** The `formId`
|
|
30
|
+
and `embedded` props are removed; the component no longer loads from
|
|
31
|
+
or saves to the server. Use `value` / `onChange` only — server
|
|
32
|
+
persistence happens through the compose wizard or
|
|
33
|
+
`composeApprovalTemplateWithForm`.
|
|
34
|
+
- **`TemplateNameModal` is removed.** Template creation goes through
|
|
35
|
+
the compose wizard; the name-and-category modal flow no longer
|
|
36
|
+
exists. `TemplateCategoryOption` now lives in `TemplatesView`.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- **Template compose wizard** (`./views/templates/compose`,
|
|
41
|
+
`./pages/templates/compose`, route `/templates/compose`):
|
|
42
|
+
`TemplateComposeWizardView` designs a form and an approval flow
|
|
43
|
+
together — the form step embeds the builder, the review step can
|
|
44
|
+
dry-run the flow — and publishes both atomically.
|
|
45
|
+
- **Designer upgrades** (`TemplateDesignerView`): embedded mode for
|
|
46
|
+
wizard reuse, an in-page form edit drawer, a dry-run button
|
|
47
|
+
(`showDryRun` prop / `BPM_TEMPLATE_DRY_RUN_ENABLED` env on the page
|
|
48
|
+
shim), and one-click save-and-publish — the publish button forks and
|
|
49
|
+
saves the draft as needed instead of requiring a separate save-draft
|
|
50
|
+
step first.
|
|
51
|
+
- **Instance detail sections.** `InstanceDetailView` is split into
|
|
52
|
+
individually exported `InstanceFormSection` /
|
|
53
|
+
`InstanceAttachmentsSection` / `InstanceTasksSection` /
|
|
54
|
+
`InstanceSignaturesSection` / `InstanceHistorySection`, toggleable
|
|
55
|
+
via `showForm` / `showAttachments` / `showTasks` / `showSignatures` /
|
|
56
|
+
`showHistory` props.
|
|
57
|
+
- **Notification drawer resolution states.** Resolved task
|
|
58
|
+
notifications render their outcome instead of offering stale
|
|
59
|
+
approve / reject actions.
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- `TemplatesView`: the create entry routes to the compose wizard (one
|
|
64
|
+
primary 建立模板 button); the modal-based create flow is removed.
|
|
65
|
+
|
|
66
|
+
### Why a minor
|
|
67
|
+
|
|
68
|
+
Removes the standalone forms surfaces and `FormBuilderView`'s
|
|
69
|
+
server-backed mode — breaking under 0.x SemVer conventions
|
|
70
|
+
(0.4.x → 0.5.0).
|
|
71
|
+
|
|
11
72
|
## 0.4.1 — 2026-05-28
|
|
12
73
|
|
|
13
74
|
### Fixed
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";const e=require("./chunk-CMqjfN_6.cjs"),t=require("./bpm-form-field-Bc6k4ZEO.cjs"),n=require("./FormRendererView-BwVsH2eX.cjs");let r=require("react"),i=require("@mezzanine-ui/react"),a=require("react/jsx-runtime"),o=require("@mezzanine-ui/icons"),s=require("@rytass/bpm-core-client/form"),c=require("@hello-pangea/dnd"),l=require("next/dynamic");l=e.t(l,1);let u=require("@codemirror/lang-json"),d=require("@codemirror/view");var f={alignItems:`center`,border:`1px solid var(--mzn-color-border-neutral)`,borderRadius:4,color:`var(--mzn-color-text-neutral)`,display:`flex`,minHeight:160,padding:12,width:`100%`},p=[(0,u.json)(),d.EditorView.lineWrapping,d.EditorView.theme({"&":{border:`1px solid var(--mzn-color-border-neutral)`,borderRadius:`4px`,fontSize:`13px`,width:`100%`},"&.cm-focused":{outline:`1px solid var(--mzn-color-border-primary)`},".cm-content":{fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace`,minHeight:`100%`},".cm-editor":{width:`100%`},".cm-gutters":{borderRight:`1px solid var(--mzn-color-border-neutral)`},".cm-scroller":{fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace`}})],m=(0,l.default)(()=>import(`@uiw/react-codemirror`),{loading:()=>(0,a.jsx)(`div`,{style:f,children:`載入 JSON 編輯器`}),ssr:!1});function h({disabled:e=!1,height:t,name:n,onChange:r,placeholder:i,value:o}){return(0,a.jsx)(m,{"aria-label":n,basicSetup:{autocompletion:!0,bracketMatching:!0,closeBrackets:!0,defaultKeymap:!0,foldGutter:!0,highlightActiveLine:!0,highlightSelectionMatches:!0,lineNumbers:!0,syntaxHighlighting:!0},editable:!e,extensions:[...p],height:t,indentWithTab:!1,onChange:r,placeholder:i,readOnly:e,theme:`light`,value:o,width:`100%`})}var g=[{description:`單行文字、姓名、編號`,icon:o.AlignLeftIcon,label:`文字`,type:`text`},{description:`多行補充內容`,icon:o.FileIcon,label:`長文字`,type:`textarea`},{description:`金額、數量、分數`,icon:o.CurrencyDollarIcon,label:`數字`,type:`number`},{description:`金額與費用`,icon:o.CurrencyDollarIcon,label:`金額`,type:`money`},{description:`日期或到期日`,icon:o.CalendarIcon,label:`日期`,type:`date`},{description:`日期與時間`,icon:o.CalendarIcon,label:`日期時間`,type:`datetime`},{description:`是 / 否狀態`,icon:o.CheckedIcon,label:`開關`,type:`boolean`},{description:`固定選項擇一`,icon:o.ListIcon,label:`下拉選單`,type:`select`},{description:`固定選項單選`,icon:o.DotGridIcon,label:`單選`,type:`radio`},{description:`固定選項複選`,icon:o.CheckedOutlineIcon,label:`複選`,type:`checkbox`},{description:`附件或佐證資料`,icon:o.FileAttachmentIcon,label:`附件`,type:`file_upload`}],ee={alignItems:`start`,display:`flex`,flexWrap:`wrap`,gap:16},te={flex:`0.55 1 300px`,minWidth:0},ne={flex:`1.45 1 720px`,minWidth:620},_={display:`grid`,gap:12},re={display:`flex`,flexWrap:`wrap`,gap:6},ie={flex:`0 0 auto`,whiteSpace:`nowrap`},ae={display:`grid`,gap:8},oe={alignItems:`center`,cursor:`grab`,display:`flex`,gap:12,touchAction:`none`},se={display:`grid`,flex:`1 1 auto`,gap:2,minWidth:0},ce={alignItems:`center`,display:`flex`,flex:`0 0 auto`,gap:4},le={alignItems:`center`,display:`flex`,gap:6},ue={cursor:`pointer`,userSelect:`none`},de={filter:`drop-shadow(0 8px 18px rgba(0, 0, 0, 0.12))`},fe={backgroundColor:`color-mix(in srgb, var(--mzn-color-primary) 8%, var(--mzn-color-bg-surface))`,boxShadow:`inset 0 0 0 1px var(--mzn-color-border-primary)`},pe={alignItems:`center`,border:`1px dashed var(--mzn-color-border-neutral)`,borderRadius:6,display:`grid`,gap:12,minHeight:240,padding:32,textAlign:`center`},me={display:`flex`,gap:8,justifyContent:`center`},he={display:`grid`,gap:14},v={display:`grid`,columnGap:16,gridTemplateColumns:`repeat(auto-fit, minmax(280px, 1fr))`,rowGap:8},ge={gridColumn:`1 / -1`},_e={alignItems:`center`,display:`flex`,gap:8,gridColumn:`1 / -1`,justifyContent:`flex-end`},y={gridColumn:`1 / -1`},b={alignItems:`start`,display:`block`,width:`100%`},ve={...b,gridColumn:`1 / -1`},ye={minWidth:0,width:`100%`},be={minWidth:`100%`,width:`100%`},xe={display:`grid`,gap:14},Se={alignItems:`start`,display:`block`,width:`100%`},Ce={minWidth:0,width:`100%`},we={gridColumn:`2 / -1`},Te={display:`grid`,gap:10,width:`100%`},Ee={display:`grid`,gap:8,gridTemplateColumns:`repeat(auto-fit, minmax(160px, 1fr))`},De={display:`inline-flex`},Oe={display:`grid`,gap:16},ke={display:`grid`,gap:8},Ae={display:`flex`,justifyContent:`flex-end`},je={color:`var(--mzn-color-text-error)`,fontSize:`0.72em`,lineHeight:0,marginLeft:2,verticalAlign:`super`};function Me(e){e&&(e.style.width=`100%`)}var Ne={fields:[],schemaVersion:1},Pe={layout:[],schemaVersion:1},x=[{id:`unset`,name:`不預設`},{id:`true`,name:`是`},{id:`false`,name:`否`}],S=[{id:`true`,name:`是`},{id:`false`,name:`否`}],Fe=[{label:`顯示`,name:`fieldVisibleWhen`,supportingText:`符合條件時才顯示這個欄位。`,target:`visibleWhen`},{label:`必填`,name:`fieldRequiredWhen`,supportingText:`符合條件時才要求填寫這個欄位。`,target:`requiredWhen`},{label:`唯讀`,name:`fieldReadonlyWhen`,supportingText:`符合條件時不允許修改這個欄位。`,target:`readonlyWhen`}];function C({onChange:e,value:l}){let u=l?.schema??Ne,d=l?.uiSchema??Pe,[f,p]=(0,r.useState)(u),[m,C]=(0,r.useState)(d),[k,j]=(0,r.useState)(D(u)),[Ve,M]=(0,r.useState)(D(d)),[He,N]=(0,r.useState)({}),[P,F]=(0,r.useState)(null),[I,L]=(0,r.useState)(`design`),[R,z]=(0,r.useState)(null);(0,r.useEffect)(()=>{f.fields.some(e=>e.fieldKey===R)||z(f.fields[0]?.fieldKey??null)},[f.fields,R]),(0,r.useEffect)(()=>{N(e=>(0,s.buildFormRendererValues)(f.fields,e))},[f.fields]),(0,r.useEffect)(()=>{I!==`advanced`&&(j(D(f)),M(D(m)))},[I,f,m]);let B=(0,r.useMemo)(()=>f.fields.find(e=>e.fieldKey===R)??f.fields[0]??null,[f.fields,R]);(0,r.useEffect)(()=>{e?.({schema:f,uiSchema:m})},[f,m]);function V(e){let t=(0,s.createFieldDefinition)(e,f.fields.length+1);p({...f,fields:[...f.fields,t]}),C({...m,layout:[...m.layout,{fieldKey:t.fieldKey,width:e===`textarea`||e===`file_upload`?`FULL`:`HALF`}]}),z(t.fieldKey),L(`design`),F(null)}function Ue(e){let t=e;t===`advanced`&&I!==`advanced`&&(j(D(f)),M(D(m))),L(t)}function We(e){let t=f.fields.filter(t=>t.fieldKey!==e);p({...f,fields:t}),C({...m,layout:m.layout.filter(t=>t.fieldKey!==e)}),z(R===e?t[0]?.fieldKey??null:R),F(null)}function Ge(e){let t=e.destination;t&&e.source.index!==t.index&&(p(n=>({...n,fields:A(n.fields,e.source.index,t.index)})),C(n=>({...n,layout:A(n.layout,e.source.index,t.index)})),F(null))}function H(e){U(t=>({...t,...e}))}function U(e){if(!B)return;let t=B.fieldKey,n=e(B),r=n.fieldKey;p({...f,fields:f.fields.map(e=>e.fieldKey===t?n:e)}),C({...m,layout:m.layout.map(e=>e.fieldKey===t?{...e,fieldKey:r}:e)}),z(r),F(null)}function W(e){U(t=>T(t)?{...t,...e}:t)}function G(e){U(t=>(0,s.isNumberFieldDefinition)(t)?{...t,...e}:t)}function Ke(e){U(t=>(0,s.isDateFieldDefinition)(t)?{...t,...e}:t)}function K(e){U(t=>(0,s.isSelectFieldDefinition)(t)?{...t,...e}:t)}function qe(e){U(t=>t.type===`boolean`?{...t,...e}:t)}function q(e){U(t=>t.type===`file_upload`?{...t,...e}:t)}function Je(e){N(e)}function Ye(e,t){p(n=>({...n,fields:n.fields.map(n=>n.fieldKey===e?{...n,required:t}:n)})),F(null)}function Xe(e){j(e);try{p(JSON.parse(e)),F(null)}catch{F(`Form Schema JSON 格式不正確`)}}function Ze(e){M(e);try{C(JSON.parse(e)),F(null)}catch{F(`UI Schema JSON 格式不正確`)}}return(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(i.SectionGroup,{children:(0,a.jsx)(i.Section,{children:(0,a.jsxs)(`div`,{style:Oe,children:[(0,a.jsxs)(i.Tab,{activeKey:I,onChange:Ue,size:`sub`,children:[(0,a.jsx)(i.TabItem,{children:`設計`},`design`),(0,a.jsx)(i.TabItem,{children:`預覽`},`preview`),(0,a.jsx)(i.TabItem,{children:`進階`},`advanced`)]}),I===`design`?Qe():null,I===`preview`?ht():null,I===`advanced`?gt():null]})})})})});function Qe(){return(0,a.jsxs)(`div`,{style:_,children:[(0,a.jsxs)(`div`,{style:ae,children:[(0,a.jsx)(i.Typography,{component:`h2`,variant:`label-primary`,children:`新增欄位`}),(0,a.jsx)(`div`,{style:re,children:g.map(e=>(0,a.jsx)(i.Button,{icon:e.icon,iconType:`leading`,onClick:()=>V(e.type),size:`sub`,style:ie,type:`button`,variant:`base-secondary`,children:e.label},e.type))})]}),(0,a.jsxs)(`div`,{style:ee,children:[(0,a.jsxs)(`div`,{style:{..._,...te},children:[(0,a.jsx)(i.Typography,{component:`h2`,variant:`label-primary`,children:`表單畫布`}),f.fields.length>0?(0,a.jsx)(c.DragDropContext,{onDragEnd:Ge,children:(0,a.jsx)(c.Droppable,{droppableId:`form-builder-fields`,children:e=>(0,a.jsxs)(`div`,{...e.droppableProps,ref:e.innerRef,style:_,children:[f.fields.map((e,t)=>(0,a.jsx)(c.Draggable,{draggableId:e.fieldKey,index:t,children:(t,n)=>pt(e,t,n.isDragging)},e.fieldKey)),e.placeholder]})})}):(0,a.jsxs)(`div`,{style:pe,children:[(0,a.jsxs)(`div`,{style:_,children:[(0,a.jsx)(i.Typography,{component:`h3`,variant:`h3`,children:`尚未建立欄位`}),(0,a.jsx)(i.Typography,{color:`text-neutral`,variant:`body`,children:`從上方新增第一個欄位,或直接建立常用文字欄位開始設計。`})]}),(0,a.jsxs)(`div`,{style:me,children:[(0,a.jsx)(i.Button,{onClick:()=>V(`text`),variant:`base-primary`,children:`新增文字欄位`}),(0,a.jsx)(i.Button,{onClick:()=>V(`textarea`),variant:`base-secondary`,children:`新增長文字`})]})]})]}),(0,a.jsxs)(`div`,{style:{..._,...ne},children:[(0,a.jsx)(i.Typography,{component:`h2`,variant:`label-primary`,children:`欄位設定`}),B?$e(B):(0,a.jsx)(i.Typography,{color:`text-neutral`,variant:`body`,children:`請先新增或選取欄位。`})]})]})]})}function $e(e){return(0,a.jsxs)(`div`,{style:he,children:[et(e),tt(e)]})}function et(e){return(0,a.jsxs)(`div`,{style:v,children:[(0,a.jsx)(`div`,{style:_e,children:(0,a.jsx)(i.Badge,{size:`main`,text:w(e.type),variant:`text-info`})}),Q(`標題`,`fieldLabel`,(0,a.jsx)(i.Input,{onChange:e=>H({label:e.target.value}),placeholder:`例如:申請金額`,value:e.label,variant:`base`})),Q(`欄位 Key`,`fieldKey`,(0,a.jsx)(i.Input,{onChange:e=>H({fieldKey:e.target.value}),placeholder:`例如:amount`,value:e.fieldKey,variant:`base`})),Q(`提示文字`,`fieldPlaceholder`,(0,a.jsx)(i.Input,{onChange:e=>H({placeholder:e.target.value||void 0}),placeholder:`例如:請輸入申請金額`,value:e.placeholder??``,variant:`base`})),nt(e)]})}function tt(e){return(0,a.jsx)(i.Accordion,{defaultExpanded:Ie(e),size:`sub`,title:`進階設定`,children:(0,a.jsxs)(`div`,{style:v,children:[(0,a.jsx)(i.Typography,{component:`h3`,style:ge,variant:`label-primary`,children:`條件規則`}),(0,a.jsx)(i.Typography,{color:`text-neutral`,style:y,variant:`body`,children:`只有需要根據其他欄位改變顯示、必填或唯讀狀態時才需要設定。`}),lt(e)]})})}function nt(e){return T(e)?rt(e):(0,s.isNumberFieldDefinition)(e)?it(e):(0,s.isDateFieldDefinition)(e)?at(e):(0,s.isSelectFieldDefinition)(e)?ot(e):e.type===`boolean`?st(e):ct(e)}function rt(e){return(0,a.jsxs)(a.Fragment,{children:[Q(`預設值`,`fieldDefaultValue`,e.type===`textarea`?Y({name:`fieldDefaultValue`,onChange:e=>W({defaultValue:e||void 0}),placeholder:`輸入此欄位的預設文字`,rows:3,value:E(e.defaultValue)}):(0,a.jsx)(i.Input,{onChange:e=>W({defaultValue:e.target.value||void 0}),placeholder:`輸入此欄位的預設文字`,value:E(e.defaultValue),variant:`base`})),Q(`最小長度`,`fieldMinLength`,X(e.minLength,e=>W({minLength:e}),`例如:2`,{min:0})),Q(`最大長度`,`fieldMaxLength`,X(e.maxLength,e=>W({maxLength:e}),`例如:100`,{min:1}))]})}function it(e){return(0,a.jsxs)(a.Fragment,{children:[Q(`預設值`,`fieldDefaultValue`,X(typeof e.defaultValue==`number`?e.defaultValue:void 0,e=>G({defaultValue:e}),e.type===`money`?`例如:1000`:`輸入預設數值`,{max:e.maximum,min:e.minimum})),Q(`最小值`,`fieldMinimum`,X(e.minimum,e=>G({minimum:e}),`例如:0`)),Q(`最大值`,`fieldMaximum`,X(e.maximum,e=>G({maximum:e}),`例如:999999`))]})}function at(e){return Q(`預設值`,`fieldDefaultValue`,Z(e,E(e.defaultValue),e=>Ke({defaultValue:e})))}function ot(e){let t=Array.isArray(e.defaultValue)?e.defaultValue:[],n=e.options.filter(e=>t.includes(e.value)).map(s.readFieldOptionAsSelectOption);return(0,a.jsxs)(a.Fragment,{children:[Q(`預設值`,`fieldDefaultValue`,e.type===`checkbox`?(0,a.jsx)(i.Select,{clearable:!0,mode:`multiple`,onChange:e=>K({defaultValue:e.length?e.map(e=>e.id):void 0}),options:e.options.map(s.readFieldOptionAsSelectOption),placeholder:`選擇一或多個預設選項`,value:n}):(0,a.jsx)(i.Select,{clearable:!0,onChange:e=>K({defaultValue:e?.id||void 0}),options:e.options.map(s.readFieldOptionAsSelectOption),placeholder:`選擇預設選項`,value:typeof e.defaultValue==`string`?(0,s.readSelectOption)(e.options.map(s.readFieldOptionAsSelectOption),e.defaultValue):null})),Q(`選項`,`fieldOptions`,ft(e),!0)]})}function st(e){let t=typeof e.defaultValue==`boolean`?String(e.defaultValue):`unset`;return Q(`預設值`,`fieldDefaultValue`,(0,a.jsx)(i.Select,{clearable:!1,onChange:e=>qe({defaultValue:e?.id===`true`?!0:e?.id===`false`?!1:void 0}),options:[...x],placeholder:`選擇預設狀態`,value:(0,s.readSelectOption)(x,t)}))}function ct(e){return(0,a.jsxs)(a.Fragment,{children:[Q(`檔案數`,`fieldMaxFiles`,X(e.maxFiles,e=>q({maxFiles:e}),`例如:1`,{min:1})),Q(`MIME`,`fieldAcceptedMimeTypes`,Y({name:`fieldAcceptedMimeTypes`,onChange:e=>q({acceptedMimeTypes:Re(e)}),placeholder:`每行一個 MIME type,例如:application/pdf`,rows:3,value:ze(e.acceptedMimeTypes)}),!1)]})}function lt(e){let t=f.fields.filter(t=>t.fieldKey!==e.fieldKey);return t.length?(0,a.jsx)(a.Fragment,{children:Fe.map(n=>ut(e,n,t))}):(0,a.jsx)(i.Typography,{color:`text-neutral`,style:y,variant:`body`,children:`目前沒有其他欄位可作為條件來源。新增更多欄位後即可設定條件規則。`})}function ut(e,t,n){let r=e[t.target],o=r?(0,s.parseConditionRule)(r):null,c=n.find(e=>e.fieldKey===o?.fieldKey),l=c??n[0],u=n.map(Le),d=(0,s.readConditionOperatorOptions)(l),f=o&&d.some(e=>e.id===o.operator)?o.operator:(0,s.readDefaultConditionOperator)(l),p=o?.value??(0,s.readDefaultConditionValue)(l),m=!!r,h=m&&(!o||!c);return Q(t.label,t.name,(0,a.jsxs)(`div`,{style:Te,children:[(0,a.jsx)(i.Toggle,{checked:m,label:m?`已啟用`:`不啟用`,onChange:e=>J(t.target,e.target.checked?(0,s.buildConditionExpression)(l,(0,s.readDefaultConditionOperator)(l),(0,s.readDefaultConditionValue)(l)):void 0),size:`sub`,supportingText:t.supportingText}),m?h?(0,a.jsx)(i.Typography,{color:`text-warning`,variant:`body`,children:`這個規則不是目前 UI 支援的格式。重新選擇條件後會取代既有規則。`}):(0,a.jsxs)(`div`,{style:Ee,children:[(0,a.jsx)(i.Select,{clearable:!1,onChange:e=>{let r=n.find(t=>t.fieldKey===e?.id)??l;J(t.target,(0,s.buildConditionExpression)(r,(0,s.readDefaultConditionOperator)(r),(0,s.readDefaultConditionValue)(r)))},options:u,placeholder:`選擇欄位`,value:(0,s.readSelectOption)(u,l.fieldKey)}),(0,a.jsx)(i.Select,{clearable:!1,onChange:e=>J(t.target,(0,s.buildConditionExpression)(l,(0,s.readConditionOperatorOption)(e?.id)??f,p)),options:[...d],placeholder:`判斷方式`,value:(0,s.readSelectOption)(d,f)}),dt(l,p,e=>J(t.target,(0,s.buildConditionExpression)(l,f,e)))]}):null]}),!0)}function J(e,t){H({[e]:t})}function dt(e,t,n){if(e.type===`boolean`)return(0,a.jsx)(i.Select,{clearable:!1,onChange:e=>n(e?.id??`true`),options:[...S],placeholder:`比較值`,value:(0,s.readSelectOption)(S,t===`false`?`false`:`true`)});if((0,s.isSelectFieldDefinition)(e)){let r=e.options.map(s.readFieldOptionAsSelectOption);return(0,a.jsx)(i.Select,{clearable:!1,onChange:e=>n(e?.id??r[0]?.id??``),options:r,placeholder:`比較值`,value:(0,s.readSelectOption)(r,t)})}return(0,s.isNumberFieldDefinition)(e)?X((0,s.parseOptionalNumberInput)(t),e=>n(String(e??0)),`比較值`):(0,s.isDateFieldDefinition)(e)?Z(e,t,e=>n(e??``)):(0,a.jsx)(i.Input,{onChange:e=>n(e.target.value),placeholder:`比較值`,value:t,variant:`base`})}function Y({name:e,onChange:t,placeholder:n,rows:r,value:o}){return(0,a.jsx)(i.Textarea,{"aria-label":e,onChange:e=>t(e.target.value),placeholder:n,ref:Me,resize:`vertical`,rows:r,style:be,value:o})}function X(e,t,n,r={}){return(0,a.jsx)(i.Input,{max:r.max,min:r.min,onChange:e=>t((0,s.clampOptionalNumber)((0,s.parseOptionalNumberInput)(e.target.value),r)),placeholder:n,showSpinner:!0,step:r.step??1,value:typeof e==`number`?String(e):``,variant:`measure`})}function Z(e,t,n){return e.type===`datetime`?(0,a.jsx)(i.DateTimePicker,{formatDate:`YYYY-MM-DD`,formatTime:`HH:mm`,hideSecond:!0,onChange:e=>n((0,s.formatDateTimePickerValue)(e)),placeholderLeft:`選擇日期`,placeholderRight:`選擇時間`,value:(0,s.readDatePickerValue)(t)}):(0,a.jsx)(i.DatePicker,{format:`YYYY-MM-DD`,onChange:e=>n((0,s.formatDatePickerValue)(e)),placeholder:`選擇日期`,value:(0,s.readDatePickerValue)(t)})}function ft(e){return(0,a.jsxs)(`div`,{style:ke,children:[(0,a.jsx)(i.Table,{actions:{render:t=>[{disabled:()=>e.options.length<=1,icon:o.TrashIcon,iconType:`icon-only`,name:`移除選項`,onClick:()=>K({options:e.options.filter((e,n)=>n!==t.index)}),variant:`destructive-ghost`}],width:56},columns:[{key:`label`,render:t=>(0,a.jsx)(i.Input,{onChange:n=>K({options:O(e.options,t.index,{label:n.target.value})}),placeholder:`例如:主管`,size:`sub`,value:t.label,variant:`base`}),title:`Label`},{key:`value`,render:t=>(0,a.jsx)(i.Input,{onChange:n=>K({options:O(e.options,t.index,{value:n.target.value})}),placeholder:`例如:manager`,size:`sub`,value:t.value,variant:`base`}),title:`Value`}],dataSource:e.options.map((t,n)=>({index:n,key:`${e.fieldKey}-${n}`,label:t.label,value:t.value})),showHeader:!0,size:`sub`}),(0,a.jsx)(`div`,{style:Ae,children:(0,a.jsx)(i.Button,{icon:o.PlusIcon,iconType:`leading`,onClick:()=>K({options:[...e.options,Be(e.options)]}),variant:`base-secondary`,children:`新增選項`})})]})}function pt(e,t,n){return(0,a.jsx)(`div`,{...t.draggableProps,"data-form-builder-field-key":e.fieldKey,ref:t.innerRef,style:{...ue,...n?de:null,...t.draggableProps.style},children:(0,a.jsx)(i.BaseCard,{style:e.fieldKey===B?.fieldKey?fe:void 0,children:mt(e,t,n)})})}function Q(e,n,r,i=!1){return(0,a.jsx)(`div`,{style:i?ve:b,children:(0,a.jsx)(`div`,{style:ye,children:(0,a.jsx)(t.t,{label:e,name:n,children:r})})})}function mt(e,t,n){return(0,a.jsxs)(`div`,{...t.dragHandleProps??{},"aria-label":`選取或拖曳排序欄位`,onClick:()=>z(e.fieldKey),style:oe,title:`點擊選取,拖曳排序`,children:[(0,a.jsx)(`span`,{"aria-label":`拖曳排序`,role:`img`,style:De,title:`拖曳排序`,children:(0,a.jsx)(i.Icon,{icon:o.DotDragVerticalIcon,size:20})}),(0,a.jsxs)(`div`,{style:se,children:[(0,a.jsxs)(i.Typography,{component:`span`,ellipsis:!0,variant:`label-primary`,children:[e.label,e.required?(0,a.jsx)(`sup`,{"aria-label":`必填`,style:je,children:`*`}):null]}),(0,a.jsxs)(i.Typography,{color:`text-neutral`,component:`span`,ellipsis:!0,variant:`caption`,children:[w(e.type),` ·`,e.required?` 必填`:` 選填`,` ·`,e.fieldKey]})]}),(0,a.jsxs)(`div`,{onClick:e=>e.stopPropagation(),style:ce,children:[(0,a.jsx)(`div`,{style:le,children:(0,a.jsx)(i.Toggle,{checked:!!e.required,disabled:n,label:`必填`,onChange:t=>Ye(e.fieldKey,t.target.checked)})}),(0,a.jsx)(i.Button,{disabled:n,icon:o.TrashIcon,iconType:`icon-only`,onClick:()=>We(e.fieldKey),variant:`destructive-ghost`,children:`移除欄位`})]})]})}function ht(){return(0,a.jsxs)(`div`,{style:_,children:[(0,a.jsx)(i.Typography,{component:`h2`,variant:`h3`,children:`填寫預覽`}),(0,a.jsx)(n.t,{onChange:Je,schema:f,uiSchema:m,value:He})]})}function gt(){return(0,a.jsxs)(`div`,{style:_,children:[(0,a.jsx)(i.Typography,{component:`h2`,variant:`h3`,children:`Schema`}),(0,a.jsxs)(`div`,{style:xe,children:[$(`Form Schema`,`schemaJson`,(0,a.jsx)(h,{height:`360px`,name:`schemaJson`,onChange:Xe,placeholder:`輸入 Form Schema JSON`,value:k})),$(`UI Schema`,`uiSchemaJson`,(0,a.jsx)(h,{height:`240px`,name:`uiSchemaJson`,onChange:Ze,placeholder:`輸入 UI Schema JSON`,value:Ve})),P?(0,a.jsx)(i.Typography,{color:`text-error`,style:we,variant:`body`,children:P}):null]})]})}function $(e,n,r){return(0,a.jsx)(`div`,{style:Se,children:(0,a.jsx)(`div`,{style:Ce,children:(0,a.jsx)(t.t,{label:e,name:n,children:r})})})}}function w(e){return g.find(t=>t.type===e)?.label??e}function Ie(e){return!!(e.visibleWhen||e.requiredWhen||e.readonlyWhen)}function Le(e){return{id:e.fieldKey,name:e.label}}function T(e){return e.type===`text`||e.type===`textarea`}function E(e){return typeof e==`string`?e:``}function Re(e){let t=e.split(/[\n,]/u).map(e=>e.trim()).filter(Boolean);return t.length?t:void 0}function ze(e){return e?.join(`
|
|
2
|
+
`)??``}function D(e){return JSON.stringify(e,null,2)}function O(e,t,n){return e.map((e,r)=>r===t?{...e,...n}:e)}function Be(e){let t=e.length+1;return{label:`選項 ${t}`,value:k(e,t)}}function k(e,t){let n=`option_${t}`;return e.some(e=>e.value===n)?k(e,t+1):n}function A(e,t,n){let r=e[t];if(!r||t===n)return[...e];let i=e.filter((e,n)=>n!==t);return[...i.slice(0,n),r,...i.slice(n)]}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return C}});
|
|
3
|
+
//# sourceMappingURL=FormBuilderView-B_KGPjlp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormBuilderView-B_KGPjlp.cjs","names":[],"sources":["../../src/views/forms/builder/json-code-editor.tsx","../../src/views/forms/builder/FormBuilderView.tsx"],"sourcesContent":["'use client';\n\nimport { CSSProperties, ReactElement } from 'react';\nimport dynamic from 'next/dynamic';\nimport { json } from '@codemirror/lang-json';\nimport { EditorView } from '@codemirror/view';\nimport type { Extension, ReactCodeMirrorProps } from '@uiw/react-codemirror';\n\nconst EDITOR_FALLBACK_STYLE: CSSProperties = {\n alignItems: 'center',\n border: '1px solid var(--mzn-color-border-neutral)',\n borderRadius: 4,\n color: 'var(--mzn-color-text-neutral)',\n display: 'flex',\n minHeight: 160,\n padding: 12,\n width: '100%',\n};\n\nconst JSON_EDITOR_EXTENSIONS: readonly Extension[] = [\n json(),\n EditorView.lineWrapping,\n EditorView.theme({\n '&': {\n border: '1px solid var(--mzn-color-border-neutral)',\n borderRadius: '4px',\n fontSize: '13px',\n width: '100%',\n },\n '&.cm-focused': {\n outline: '1px solid var(--mzn-color-border-primary)',\n },\n '.cm-content': {\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace',\n minHeight: '100%',\n },\n '.cm-editor': {\n width: '100%',\n },\n '.cm-gutters': {\n borderRight: '1px solid var(--mzn-color-border-neutral)',\n },\n '.cm-scroller': {\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace',\n },\n }),\n];\n\nconst CodeMirror = dynamic<ReactCodeMirrorProps>(\n () => import('@uiw/react-codemirror'),\n {\n loading: (): ReactElement => (\n <div style={EDITOR_FALLBACK_STYLE}>載入 JSON 編輯器</div>\n ),\n ssr: false,\n },\n);\n\ninterface JsonCodeEditorProps {\n readonly disabled?: boolean;\n readonly height: string;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly value: string;\n}\n\nexport function JsonCodeEditor({\n disabled = false,\n height,\n name,\n onChange,\n placeholder,\n value,\n}: JsonCodeEditorProps): ReactElement {\n return (\n <CodeMirror\n aria-label={name}\n basicSetup={{\n autocompletion: true,\n bracketMatching: true,\n closeBrackets: true,\n defaultKeymap: true,\n foldGutter: true,\n highlightActiveLine: true,\n highlightSelectionMatches: true,\n lineNumbers: true,\n syntaxHighlighting: true,\n }}\n editable={!disabled}\n extensions={[...JSON_EDITOR_EXTENSIONS]}\n height={height}\n indentWithTab={false}\n onChange={onChange}\n placeholder={placeholder}\n readOnly={disabled}\n theme=\"light\"\n value={value}\n width=\"100%\"\n />\n );\n}\n","'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n Key,\n MouseEvent,\n ReactElement,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n DragDropContext,\n Draggable,\n DraggableProvided,\n Droppable,\n DropResult,\n} from '@hello-pangea/dnd';\nimport {\n Accordion,\n BaseCard,\n Badge,\n Button,\n DatePicker,\n DateTimePicker,\n Icon,\n Input,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport {\n AlignLeftIcon,\n CalendarIcon,\n CheckedIcon,\n CheckedOutlineIcon,\n CurrencyDollarIcon,\n DotDragVerticalIcon,\n DotGridIcon,\n FileAttachmentIcon,\n FileIcon,\n ListIcon,\n PlusIcon,\n TrashIcon,\n} from '@mezzanine-ui/icons';\nimport type { IconDefinition } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n BooleanFieldDefinition,\n DateFieldDefinition,\n FileUploadFieldDefinition,\n FormDefinitionSchema,\n FormFieldDefinition,\n FormFieldOption,\n FormUiSchema,\n NumberFieldDefinition,\n SelectFieldDefinition,\n TextFieldDefinition,\n} from '@rytass/bpm-core-shared/form';\nimport { createFieldDefinition } from '@rytass/bpm-core-client/form';\nimport {\n buildConditionExpression,\n buildFormRendererValues,\n clampOptionalNumber,\n formatDatePickerValue,\n formatDateTimePickerValue,\n FormRendererValues,\n isDateFieldDefinition,\n isNumberFieldDefinition,\n isSelectFieldDefinition,\n parseConditionRule,\n parseOptionalNumberInput,\n readConditionOperatorOption,\n readConditionOperatorOptions,\n readDatePickerValue,\n readDefaultConditionOperator,\n readDefaultConditionValue,\n readFieldOptionAsSelectOption,\n readSelectOption,\n} from '@rytass/bpm-core-client/form';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { FormRenderer } from '../renderer/FormRendererView';\nimport { JsonCodeEditor } from './json-code-editor';\n\ntype FieldType = FormFieldDefinition['type'];\ntype BuilderTabKey = 'design' | 'preview' | 'advanced';\ntype FieldOptionRow = Readonly<\n Record<string, unknown> & {\n index: number;\n key: string;\n label: string;\n value: string;\n }\n>;\n\ntype FieldTypeOption = Readonly<{\n description: string;\n icon: IconDefinition;\n label: string;\n type: FieldType;\n}>;\n\ntype ConditionRuleTarget = 'readonlyWhen' | 'requiredWhen' | 'visibleWhen';\n\ntype ConditionRuleConfig = Readonly<{\n label: string;\n name: string;\n supportingText: string;\n target: ConditionRuleTarget;\n}>;\n\nconst FIELD_TYPE_OPTIONS: readonly FieldTypeOption[] = [\n {\n description: '單行文字、姓名、編號',\n icon: AlignLeftIcon,\n label: '文字',\n type: 'text',\n },\n {\n description: '多行補充內容',\n icon: FileIcon,\n label: '長文字',\n type: 'textarea',\n },\n {\n description: '金額、數量、分數',\n icon: CurrencyDollarIcon,\n label: '數字',\n type: 'number',\n },\n {\n description: '金額與費用',\n icon: CurrencyDollarIcon,\n label: '金額',\n type: 'money',\n },\n {\n description: '日期或到期日',\n icon: CalendarIcon,\n label: '日期',\n type: 'date',\n },\n {\n description: '日期與時間',\n icon: CalendarIcon,\n label: '日期時間',\n type: 'datetime',\n },\n {\n description: '是 / 否狀態',\n icon: CheckedIcon,\n label: '開關',\n type: 'boolean',\n },\n {\n description: '固定選項擇一',\n icon: ListIcon,\n label: '下拉選單',\n type: 'select',\n },\n {\n description: '固定選項單選',\n icon: DotGridIcon,\n label: '單選',\n type: 'radio',\n },\n {\n description: '固定選項複選',\n icon: CheckedOutlineIcon,\n label: '複選',\n type: 'checkbox',\n },\n {\n description: '附件或佐證資料',\n icon: FileAttachmentIcon,\n label: '附件',\n type: 'file_upload',\n },\n];\n\nconst WORKSPACE_GRID_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'flex',\n flexWrap: 'wrap',\n gap: 16,\n};\n\nconst CANVAS_COLUMN_STYLE: CSSProperties = {\n flex: '0.55 1 300px',\n minWidth: 0,\n};\n\nconst SETTINGS_COLUMN_STYLE: CSSProperties = {\n flex: '1.45 1 720px',\n minWidth: 620,\n};\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 12,\n};\n\nconst FIELD_LIBRARY_STYLE: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 6,\n};\n\nconst FIELD_LIBRARY_BUTTON_STYLE: CSSProperties = {\n flex: '0 0 auto',\n whiteSpace: 'nowrap',\n};\n\nconst FIELD_LIBRARY_HEADER_STYLE: CSSProperties = {\n display: 'grid',\n gap: 8,\n};\n\nconst FIELD_BLOCK_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n cursor: 'grab',\n display: 'flex',\n gap: 12,\n touchAction: 'none',\n};\n\nconst FIELD_BLOCK_TEXT_STYLE: CSSProperties = {\n display: 'grid',\n flex: '1 1 auto',\n gap: 2,\n minWidth: 0,\n};\n\nconst FIELD_BLOCK_ACTIONS_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'flex',\n flex: '0 0 auto',\n gap: 4,\n};\n\nconst FIELD_BLOCK_REQUIRED_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'flex',\n gap: 6,\n};\n\nconst FIELD_BLOCK_STYLE: CSSProperties = {\n cursor: 'pointer',\n userSelect: 'none',\n};\n\nconst FIELD_BLOCK_DRAGGING_STYLE: CSSProperties = {\n filter: 'drop-shadow(0 8px 18px rgba(0, 0, 0, 0.12))',\n};\n\n// Selected field: tint the whole card with a light brand fill over the surface\n// so the active row is obvious without relying on the (removed) edit button.\nconst FIELD_BLOCK_SELECTED_CARD_STYLE: CSSProperties = {\n backgroundColor:\n 'color-mix(in srgb, var(--mzn-color-primary) 8%, var(--mzn-color-bg-surface))',\n boxShadow: 'inset 0 0 0 1px var(--mzn-color-border-primary)',\n};\n\nconst EMPTY_CANVAS_STYLE: CSSProperties = {\n alignItems: 'center',\n border: '1px dashed var(--mzn-color-border-neutral)',\n borderRadius: 6,\n display: 'grid',\n gap: 12,\n minHeight: 240,\n padding: 32,\n textAlign: 'center',\n};\n\nconst EMPTY_CANVAS_ACTIONS_STYLE: CSSProperties = {\n display: 'flex',\n gap: 8,\n justifyContent: 'center',\n};\n\nconst FIELD_SETTINGS_FORM_STYLE: CSSProperties = {\n display: 'grid',\n gap: 14,\n};\n\nconst FIELD_SETTINGS_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n columnGap: 16,\n gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',\n rowGap: 8,\n};\n\nconst FIELD_SETTINGS_SECTION_TITLE_STYLE: CSSProperties = {\n gridColumn: '1 / -1',\n};\n\nconst FIELD_SETTINGS_BADGE_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'flex',\n gap: 8,\n gridColumn: '1 / -1',\n justifyContent: 'flex-end',\n};\n\nconst FIELD_SETTINGS_HINT_STYLE: CSSProperties = {\n gridColumn: '1 / -1',\n};\n\nconst FIELD_SETTINGS_ROW_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'block',\n width: '100%',\n};\n\nconst FIELD_SETTINGS_ROW_WIDE_STYLE: CSSProperties = {\n ...FIELD_SETTINGS_ROW_STYLE,\n gridColumn: '1 / -1',\n};\n\nconst FIELD_SETTINGS_VALUE_STYLE: CSSProperties = {\n minWidth: 0,\n width: '100%',\n};\n\nconst FIELD_SETTINGS_TEXTAREA_STYLE: CSSProperties = {\n minWidth: '100%',\n width: '100%',\n};\n\nconst ADVANCED_SCHEMA_FORM_STYLE: CSSProperties = {\n display: 'grid',\n gap: 14,\n};\n\nconst ADVANCED_SCHEMA_ROW_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'block',\n width: '100%',\n};\n\nconst ADVANCED_SCHEMA_VALUE_STYLE: CSSProperties = {\n minWidth: 0,\n width: '100%',\n};\n\nconst ADVANCED_SCHEMA_MESSAGE_STYLE: CSSProperties = {\n gridColumn: '2 / -1',\n};\n\nconst CONDITION_RULE_CONTROL_STYLE: CSSProperties = {\n display: 'grid',\n gap: 10,\n width: '100%',\n};\n\nconst CONDITION_RULE_GRID_STYLE: CSSProperties = {\n display: 'grid',\n gap: 8,\n gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))',\n};\n\nconst DRAG_HANDLE_STYLE: CSSProperties = {\n display: 'inline-flex',\n};\n\nconst WORKBENCH_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\nconst COMPACT_STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 8,\n};\n\nconst OPTION_ACTIONS_STYLE: CSSProperties = {\n display: 'flex',\n justifyContent: 'flex-end',\n};\n\nconst REQUIRED_ASTERISK_STYLE: CSSProperties = {\n color: 'var(--mzn-color-text-error)',\n fontSize: '0.72em',\n lineHeight: 0,\n marginLeft: 2,\n verticalAlign: 'super',\n};\n\nfunction applyFullWidthTextareaHost(element: HTMLDivElement | null): void {\n if (!element) {\n return;\n }\n\n element.style.width = '100%';\n}\n\nconst EMPTY_SCHEMA: FormDefinitionSchema = {\n fields: [],\n schemaVersion: 1,\n};\n\nconst EMPTY_UI_SCHEMA: FormUiSchema = {\n layout: [],\n schemaVersion: 1,\n};\n\nconst BOOLEAN_DEFAULT_OPTIONS: readonly {\n readonly id: string;\n readonly name: string;\n}[] = [\n { id: 'unset', name: '不預設' },\n { id: 'true', name: '是' },\n { id: 'false', name: '否' },\n];\n\nconst BOOLEAN_CONDITION_VALUE_OPTIONS: readonly {\n readonly id: string;\n readonly name: string;\n}[] = [\n { id: 'true', name: '是' },\n { id: 'false', name: '否' },\n];\n\nconst CONDITION_RULE_CONFIGS: readonly ConditionRuleConfig[] = [\n {\n label: '顯示',\n name: 'fieldVisibleWhen',\n supportingText: '符合條件時才顯示這個欄位。',\n target: 'visibleWhen',\n },\n {\n label: '必填',\n name: 'fieldRequiredWhen',\n supportingText: '符合條件時才要求填寫這個欄位。',\n target: 'requiredWhen',\n },\n {\n label: '唯讀',\n name: 'fieldReadonlyWhen',\n supportingText: '符合條件時不允許修改這個欄位。',\n target: 'readonlyWhen',\n },\n];\n\nexport interface FormBuilderViewProps {\n /**\n * Initial (or controlled) schema value.\n * If omitted, the builder starts with empty schema / uiSchema.\n */\n readonly value?: {\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n };\n\n /** Called whenever the schema or uiSchema changes. */\n readonly onChange?: (next: {\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n }) => void;\n}\n\nexport function FormBuilderView({\n onChange,\n value,\n}: FormBuilderViewProps): ReactElement {\n const initialSchema = value?.schema ?? EMPTY_SCHEMA;\n const initialUiSchema = value?.uiSchema ?? EMPTY_UI_SCHEMA;\n const [schema, setSchema] = useState<FormDefinitionSchema>(initialSchema);\n const [uiSchema, setUiSchema] = useState<FormUiSchema>(initialUiSchema);\n const [schemaJsonText, setSchemaJsonText] = useState(\n stringifyJson(initialSchema),\n );\n const [uiSchemaJsonText, setUiSchemaJsonText] = useState(\n stringifyJson(initialUiSchema),\n );\n const [previewValues, setPreviewValues] = useState<FormRendererValues>({});\n const [advancedSchemaMessage, setAdvancedSchemaMessage] = useState<\n string | null\n >(null);\n const [activeTab, setActiveTab] = useState<BuilderTabKey>('design');\n const [selectedFieldKey, setSelectedFieldKey] = useState<string | null>(null);\n useEffect((): void => {\n const hasSelectedField = schema.fields.some(\n (field) => field.fieldKey === selectedFieldKey,\n );\n\n if (hasSelectedField) {\n return;\n }\n\n setSelectedFieldKey(schema.fields[0]?.fieldKey ?? null);\n }, [schema.fields, selectedFieldKey]);\n\n useEffect((): void => {\n setPreviewValues((currentValues) =>\n buildFormRendererValues(schema.fields, currentValues),\n );\n }, [schema.fields]);\n\n useEffect((): void => {\n if (activeTab === 'advanced') {\n return;\n }\n\n setSchemaJsonText(stringifyJson(schema));\n setUiSchemaJsonText(stringifyJson(uiSchema));\n }, [activeTab, schema, uiSchema]);\n\n const selectedField = useMemo(\n (): FormFieldDefinition | null =>\n schema.fields.find((field) => field.fieldKey === selectedFieldKey) ??\n schema.fields[0] ??\n null,\n [schema.fields, selectedFieldKey],\n );\n useEffect((): void => {\n onChange?.({ schema, uiSchema });\n }, [schema, uiSchema]);\n\n function handleAddField(type: FieldType): void {\n const nextIndex = schema.fields.length + 1;\n const field = createFieldDefinition(type, nextIndex);\n\n setSchema({\n ...schema,\n fields: [...schema.fields, field],\n });\n setUiSchema({\n ...uiSchema,\n layout: [\n ...uiSchema.layout,\n {\n fieldKey: field.fieldKey,\n width:\n type === 'textarea' || type === 'file_upload' ? 'FULL' : 'HALF',\n },\n ],\n });\n setSelectedFieldKey(field.fieldKey);\n setActiveTab('design');\n setAdvancedSchemaMessage(null);\n }\n\n function handleTabChange(activeKey: Key): void {\n const nextTab = activeKey as BuilderTabKey;\n\n if (nextTab === 'advanced' && activeTab !== 'advanced') {\n setSchemaJsonText(stringifyJson(schema));\n setUiSchemaJsonText(stringifyJson(uiSchema));\n }\n\n setActiveTab(nextTab);\n }\n\n function handleRemoveField(fieldKey: string): void {\n const remainingFields = schema.fields.filter(\n (field) => field.fieldKey !== fieldKey,\n );\n\n setSchema({\n ...schema,\n fields: remainingFields,\n });\n setUiSchema({\n ...uiSchema,\n layout: uiSchema.layout.filter((item) => item.fieldKey !== fieldKey),\n });\n setSelectedFieldKey(\n selectedFieldKey === fieldKey\n ? (remainingFields[0]?.fieldKey ?? null)\n : selectedFieldKey,\n );\n setAdvancedSchemaMessage(null);\n }\n\n function handleFieldDragEnd(result: DropResult): void {\n const destination = result.destination;\n\n if (!destination) {\n return;\n }\n\n if (result.source.index === destination.index) {\n return;\n }\n\n setSchema((currentSchema) => ({\n ...currentSchema,\n fields: moveItemByIndex(\n currentSchema.fields,\n result.source.index,\n destination.index,\n ),\n }));\n setUiSchema((currentUiSchema) => ({\n ...currentUiSchema,\n layout: moveItemByIndex(\n currentUiSchema.layout,\n result.source.index,\n destination.index,\n ),\n }));\n setAdvancedSchemaMessage(null);\n }\n\n function updateSelectedField(\n patch: Partial<\n Pick<\n FormFieldDefinition,\n | 'defaultValue'\n | 'fieldKey'\n | 'label'\n | 'placeholder'\n | 'readonlyWhen'\n | 'required'\n | 'requiredWhen'\n | 'visibleWhen'\n >\n >,\n ): void {\n updateSelectedFieldWith(\n (field) => ({ ...field, ...patch }) as FormFieldDefinition,\n );\n }\n\n function updateSelectedFieldWith(\n updater: (field: FormFieldDefinition) => FormFieldDefinition,\n ): void {\n if (!selectedField) {\n return;\n }\n\n const previousFieldKey = selectedField.fieldKey;\n const nextField = updater(selectedField);\n const nextFieldKey = nextField.fieldKey;\n\n setSchema({\n ...schema,\n fields: schema.fields.map(\n (field): FormFieldDefinition =>\n field.fieldKey === previousFieldKey ? nextField : field,\n ),\n });\n setUiSchema({\n ...uiSchema,\n layout: uiSchema.layout.map((item) =>\n item.fieldKey === previousFieldKey\n ? { ...item, fieldKey: nextFieldKey }\n : item,\n ),\n });\n setSelectedFieldKey(nextFieldKey);\n setAdvancedSchemaMessage(null);\n }\n\n function updateSelectedTextField(\n patch: Partial<\n Pick<TextFieldDefinition, 'defaultValue' | 'maxLength' | 'minLength'>\n >,\n ): void {\n updateSelectedFieldWith((field) =>\n isTextFieldDefinition(field) ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedNumberField(\n patch: Partial<\n Pick<NumberFieldDefinition, 'defaultValue' | 'maximum' | 'minimum'>\n >,\n ): void {\n updateSelectedFieldWith((field) =>\n isNumberFieldDefinition(field) ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedDateField(\n patch: Partial<Pick<DateFieldDefinition, 'defaultValue'>>,\n ): void {\n updateSelectedFieldWith((field) =>\n isDateFieldDefinition(field) ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedSelectField(\n patch: Partial<Pick<SelectFieldDefinition, 'defaultValue' | 'options'>>,\n ): void {\n updateSelectedFieldWith((field) =>\n isSelectFieldDefinition(field) ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedBooleanField(\n patch: Partial<Pick<BooleanFieldDefinition, 'defaultValue'>>,\n ): void {\n updateSelectedFieldWith((field) =>\n field.type === 'boolean' ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedFileUploadField(\n patch: Partial<\n Pick<\n FileUploadFieldDefinition,\n 'acceptedMimeTypes' | 'defaultValue' | 'maxFiles'\n >\n >,\n ): void {\n updateSelectedFieldWith((field) =>\n field.type === 'file_upload' ? { ...field, ...patch } : field,\n );\n }\n\n function updatePreviewValues(values: FormRendererValues): void {\n setPreviewValues(values);\n }\n\n function updateFieldRequired(fieldKey: string, required: boolean): void {\n setSchema((currentSchema) => ({\n ...currentSchema,\n fields: currentSchema.fields.map(\n (field): FormFieldDefinition =>\n field.fieldKey === fieldKey\n ? ({ ...field, required } as FormFieldDefinition)\n : field,\n ),\n }));\n setAdvancedSchemaMessage(null);\n }\n\n function updateSchemaJson(value: string): void {\n setSchemaJsonText(value);\n\n try {\n setSchema(JSON.parse(value) as FormDefinitionSchema);\n setAdvancedSchemaMessage(null);\n } catch {\n setAdvancedSchemaMessage('Form Schema JSON 格式不正確');\n }\n }\n\n function updateUiSchemaJson(value: string): void {\n setUiSchemaJsonText(value);\n\n try {\n setUiSchema(JSON.parse(value) as FormUiSchema);\n setAdvancedSchemaMessage(null);\n } catch {\n setAdvancedSchemaMessage('UI Schema JSON 格式不正確');\n }\n }\n\n return (\n <>\n <>\n <SectionGroup>\n <Section>\n <div style={WORKBENCH_STYLE}>\n <Tab\n activeKey={activeTab}\n onChange={handleTabChange}\n size=\"sub\"\n >\n <TabItem key=\"design\">設計</TabItem>\n <TabItem key=\"preview\">預覽</TabItem>\n <TabItem key=\"advanced\">進階</TabItem>\n </Tab>\n\n {activeTab === 'design' ? renderDesignTab() : null}\n {activeTab === 'preview' ? renderPreviewTab() : null}\n {activeTab === 'advanced' ? renderAdvancedTab() : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n\n </>\n );\n\n function renderDesignTab(): ReactElement {\n return (\n <div style={STACK_STYLE}>\n <div style={FIELD_LIBRARY_HEADER_STYLE}>\n <Typography component=\"h2\" variant=\"label-primary\">\n 新增欄位\n </Typography>\n <div style={FIELD_LIBRARY_STYLE}>\n {FIELD_TYPE_OPTIONS.map((option) => (\n <Button\n icon={option.icon}\n iconType=\"leading\"\n key={option.type}\n onClick={(): void => handleAddField(option.type)}\n size=\"sub\"\n style={FIELD_LIBRARY_BUTTON_STYLE}\n type=\"button\"\n variant=\"base-secondary\"\n >\n {option.label}\n </Button>\n ))}\n </div>\n </div>\n\n <div style={WORKSPACE_GRID_STYLE}>\n <div style={{ ...STACK_STYLE, ...CANVAS_COLUMN_STYLE }}>\n <Typography component=\"h2\" variant=\"label-primary\">\n 表單畫布\n </Typography>\n {schema.fields.length > 0 ? (\n <DragDropContext onDragEnd={handleFieldDragEnd}>\n <Droppable droppableId=\"form-builder-fields\">\n {(droppableProvided): ReactElement => (\n <div\n {...droppableProvided.droppableProps}\n ref={droppableProvided.innerRef}\n style={STACK_STYLE}\n >\n {schema.fields.map((field, index) => (\n <Draggable\n draggableId={field.fieldKey}\n index={index}\n key={field.fieldKey}\n >\n {(draggableProvided, snapshot): ReactElement =>\n renderFieldBlock(\n field,\n draggableProvided,\n snapshot.isDragging,\n )\n }\n </Draggable>\n ))}\n {droppableProvided.placeholder}\n </div>\n )}\n </Droppable>\n </DragDropContext>\n ) : (\n <div style={EMPTY_CANVAS_STYLE}>\n <div style={STACK_STYLE}>\n <Typography component=\"h3\" variant=\"h3\">\n 尚未建立欄位\n </Typography>\n <Typography color=\"text-neutral\" variant=\"body\">\n 從上方新增第一個欄位,或直接建立常用文字欄位開始設計。\n </Typography>\n </div>\n <div style={EMPTY_CANVAS_ACTIONS_STYLE}>\n <Button\n onClick={(): void => handleAddField('text')}\n variant=\"base-primary\"\n >\n 新增文字欄位\n </Button>\n <Button\n onClick={(): void => handleAddField('textarea')}\n variant=\"base-secondary\"\n >\n 新增長文字\n </Button>\n </div>\n </div>\n )}\n </div>\n\n <div style={{ ...STACK_STYLE, ...SETTINGS_COLUMN_STYLE }}>\n <Typography component=\"h2\" variant=\"label-primary\">\n 欄位設定\n </Typography>\n {selectedField ? (\n renderFieldSettings(selectedField)\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 請先新增或選取欄位。\n </Typography>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n function renderFieldSettings(field: FormFieldDefinition): ReactElement {\n return (\n <div style={FIELD_SETTINGS_FORM_STYLE}>\n {renderMainFieldSettings(field)}\n {renderAdvancedFieldSettings(field)}\n </div>\n );\n }\n\n function renderMainFieldSettings(field: FormFieldDefinition): ReactElement {\n return (\n <div style={FIELD_SETTINGS_SECTION_STYLE}>\n <div style={FIELD_SETTINGS_BADGE_ROW_STYLE}>\n <Badge\n size=\"main\"\n text={readFieldTypeLabel(field.type)}\n variant=\"text-info\"\n />\n </div>\n {renderSettingsFormRow(\n '標題',\n 'fieldLabel',\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedField({ label: event.target.value })\n }\n placeholder=\"例如:申請金額\"\n value={field.label}\n variant=\"base\"\n />,\n )}\n {renderSettingsFormRow(\n '欄位 Key',\n 'fieldKey',\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedField({ fieldKey: event.target.value })\n }\n placeholder=\"例如:amount\"\n value={field.fieldKey}\n variant=\"base\"\n />,\n )}\n {renderSettingsFormRow(\n '提示文字',\n 'fieldPlaceholder',\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedField({\n placeholder: event.target.value || undefined,\n })\n }\n placeholder=\"例如:請輸入申請金額\"\n value={field.placeholder ?? ''}\n variant=\"base\"\n />,\n )}\n {renderTypeSpecificSettings(field)}\n </div>\n );\n }\n\n function renderAdvancedFieldSettings(\n field: FormFieldDefinition,\n ): ReactElement {\n return (\n <Accordion\n defaultExpanded={hasConditionRules(field)}\n size=\"sub\"\n title=\"進階設定\"\n >\n <div style={FIELD_SETTINGS_SECTION_STYLE}>\n <Typography\n component=\"h3\"\n style={FIELD_SETTINGS_SECTION_TITLE_STYLE}\n variant=\"label-primary\"\n >\n 條件規則\n </Typography>\n <Typography\n color=\"text-neutral\"\n style={FIELD_SETTINGS_HINT_STYLE}\n variant=\"body\"\n >\n 只有需要根據其他欄位改變顯示、必填或唯讀狀態時才需要設定。\n </Typography>\n {renderConditionSettings(field)}\n </div>\n </Accordion>\n );\n }\n\n function renderTypeSpecificSettings(\n field: FormFieldDefinition,\n ): ReactElement {\n if (isTextFieldDefinition(field)) {\n return renderTextFieldSettings(field);\n }\n\n if (isNumberFieldDefinition(field)) {\n return renderNumberFieldSettings(field);\n }\n\n if (isDateFieldDefinition(field)) {\n return renderDateFieldSettings(field);\n }\n\n if (isSelectFieldDefinition(field)) {\n return renderSelectFieldSettings(field);\n }\n\n if (field.type === 'boolean') {\n return renderBooleanFieldSettings(field);\n }\n\n return renderFileUploadFieldSettings(field);\n }\n\n function renderTextFieldSettings(field: TextFieldDefinition): ReactElement {\n return (\n <>\n {renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n field.type === 'textarea' ? (\n renderSettingsTextarea({\n name: 'fieldDefaultValue',\n onChange: (value): void =>\n updateSelectedTextField({ defaultValue: value || undefined }),\n placeholder: '輸入此欄位的預設文字',\n rows: 3,\n value: readStringDefaultValue(field.defaultValue),\n })\n ) : (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedTextField({\n defaultValue: event.target.value || undefined,\n })\n }\n placeholder=\"輸入此欄位的預設文字\"\n value={readStringDefaultValue(field.defaultValue)}\n variant=\"base\"\n />\n ),\n )}\n {renderSettingsFormRow(\n '最小長度',\n 'fieldMinLength',\n renderNumberInput(\n field.minLength,\n (value): void => updateSelectedTextField({ minLength: value }),\n '例如:2',\n { min: 0 },\n ),\n )}\n {renderSettingsFormRow(\n '最大長度',\n 'fieldMaxLength',\n renderNumberInput(\n field.maxLength,\n (value): void => updateSelectedTextField({ maxLength: value }),\n '例如:100',\n { min: 1 },\n ),\n )}\n </>\n );\n }\n\n function renderNumberFieldSettings(\n field: NumberFieldDefinition,\n ): ReactElement {\n return (\n <>\n {renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n renderNumberInput(\n typeof field.defaultValue === 'number'\n ? field.defaultValue\n : undefined,\n (value): void => updateSelectedNumberField({ defaultValue: value }),\n field.type === 'money' ? '例如:1000' : '輸入預設數值',\n { max: field.maximum, min: field.minimum },\n ),\n )}\n {renderSettingsFormRow(\n '最小值',\n 'fieldMinimum',\n renderNumberInput(\n field.minimum,\n (value): void => updateSelectedNumberField({ minimum: value }),\n '例如:0',\n ),\n )}\n {renderSettingsFormRow(\n '最大值',\n 'fieldMaximum',\n renderNumberInput(\n field.maximum,\n (value): void => updateSelectedNumberField({ maximum: value }),\n '例如:999999',\n ),\n )}\n </>\n );\n }\n\n function renderDateFieldSettings(field: DateFieldDefinition): ReactElement {\n return renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n renderDateValuePicker(\n field,\n readStringDefaultValue(field.defaultValue),\n (value): void => updateSelectedDateField({ defaultValue: value }),\n ),\n );\n }\n\n function renderSelectFieldSettings(\n field: SelectFieldDefinition,\n ): ReactElement {\n const defaultValues = Array.isArray(field.defaultValue)\n ? field.defaultValue\n : [];\n const selectedValues = field.options\n .filter((option) => defaultValues.includes(option.value))\n .map(readFieldOptionAsSelectOption);\n\n return (\n <>\n {renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n field.type === 'checkbox' ? (\n <Select\n clearable\n mode=\"multiple\"\n onChange={(options): void =>\n updateSelectedSelectField({\n defaultValue: options.length\n ? options.map((option) => option.id)\n : undefined,\n })\n }\n options={field.options.map(readFieldOptionAsSelectOption)}\n placeholder=\"選擇一或多個預設選項\"\n value={selectedValues}\n />\n ) : (\n <Select\n clearable\n onChange={(option): void =>\n updateSelectedSelectField({\n defaultValue: option?.id || undefined,\n })\n }\n options={field.options.map(readFieldOptionAsSelectOption)}\n placeholder=\"選擇預設選項\"\n value={\n typeof field.defaultValue === 'string'\n ? readSelectOption(\n field.options.map(readFieldOptionAsSelectOption),\n field.defaultValue,\n )\n : null\n }\n />\n ),\n )}\n {renderSettingsFormRow(\n '選項',\n 'fieldOptions',\n renderFieldOptionsTable(field),\n true,\n )}\n </>\n );\n }\n\n function renderBooleanFieldSettings(\n field: BooleanFieldDefinition,\n ): ReactElement {\n const defaultValue =\n typeof field.defaultValue === 'boolean'\n ? String(field.defaultValue)\n : 'unset';\n\n return renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n <Select\n clearable={false}\n onChange={(option): void =>\n updateSelectedBooleanField({\n defaultValue:\n option?.id === 'true'\n ? true\n : option?.id === 'false'\n ? false\n : undefined,\n })\n }\n options={[...BOOLEAN_DEFAULT_OPTIONS]}\n placeholder=\"選擇預設狀態\"\n value={readSelectOption(BOOLEAN_DEFAULT_OPTIONS, defaultValue)}\n />,\n );\n }\n\n function renderFileUploadFieldSettings(\n field: FileUploadFieldDefinition,\n ): ReactElement {\n return (\n <>\n {renderSettingsFormRow(\n '檔案數',\n 'fieldMaxFiles',\n renderNumberInput(\n field.maxFiles,\n (value): void => updateSelectedFileUploadField({ maxFiles: value }),\n '例如:1',\n { min: 1 },\n ),\n )}\n {renderSettingsFormRow(\n 'MIME',\n 'fieldAcceptedMimeTypes',\n renderSettingsTextarea({\n name: 'fieldAcceptedMimeTypes',\n onChange: (value): void =>\n updateSelectedFileUploadField({\n acceptedMimeTypes: parseStringList(value),\n }),\n placeholder: '每行一個 MIME type,例如:application/pdf',\n rows: 3,\n value: readStringListInput(field.acceptedMimeTypes),\n }),\n false,\n )}\n </>\n );\n }\n\n function renderConditionSettings(field: FormFieldDefinition): ReactElement {\n const conditionFieldOptions = schema.fields.filter(\n (schemaField) => schemaField.fieldKey !== field.fieldKey,\n );\n\n if (!conditionFieldOptions.length) {\n return (\n <Typography\n color=\"text-neutral\"\n style={FIELD_SETTINGS_HINT_STYLE}\n variant=\"body\"\n >\n 目前沒有其他欄位可作為條件來源。新增更多欄位後即可設定條件規則。\n </Typography>\n );\n }\n\n return (\n <>\n {CONDITION_RULE_CONFIGS.map((config) =>\n renderConditionRule(field, config, conditionFieldOptions),\n )}\n </>\n );\n }\n\n function renderConditionRule(\n field: FormFieldDefinition,\n config: ConditionRuleConfig,\n conditionFieldOptions: readonly FormFieldDefinition[],\n ): ReactElement {\n const expression = field[config.target];\n const parsedRule = expression ? parseConditionRule(expression) : null;\n const parsedConditionField = conditionFieldOptions.find(\n (conditionField) => conditionField.fieldKey === parsedRule?.fieldKey,\n );\n const selectedConditionField =\n parsedConditionField ?? conditionFieldOptions[0];\n const conditionFieldSelectOptions = conditionFieldOptions.map(\n readFieldAsConditionSelectOption,\n );\n const conditionOperatorOptions = readConditionOperatorOptions(\n selectedConditionField,\n );\n const selectedOperator =\n parsedRule &&\n conditionOperatorOptions.some(\n (option) => option.id === parsedRule.operator,\n )\n ? parsedRule.operator\n : readDefaultConditionOperator(selectedConditionField);\n const selectedValue =\n parsedRule?.value ?? readDefaultConditionValue(selectedConditionField);\n const enabled = Boolean(expression);\n const unsupportedRule = enabled && (!parsedRule || !parsedConditionField);\n\n return renderSettingsFormRow(\n config.label,\n config.name,\n <div style={CONDITION_RULE_CONTROL_STYLE}>\n <Toggle\n checked={enabled}\n label={enabled ? '已啟用' : '不啟用'}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedConditionRule(\n config.target,\n event.target.checked\n ? buildConditionExpression(\n selectedConditionField,\n readDefaultConditionOperator(selectedConditionField),\n readDefaultConditionValue(selectedConditionField),\n )\n : undefined,\n )\n }\n size=\"sub\"\n supportingText={config.supportingText}\n />\n {enabled ? (\n unsupportedRule ? (\n <Typography color=\"text-warning\" variant=\"body\">\n 這個規則不是目前 UI 支援的格式。重新選擇條件後會取代既有規則。\n </Typography>\n ) : (\n <div style={CONDITION_RULE_GRID_STYLE}>\n <Select\n clearable={false}\n onChange={(option): void => {\n const nextField =\n conditionFieldOptions.find(\n (conditionField) =>\n conditionField.fieldKey === option?.id,\n ) ?? selectedConditionField;\n\n updateSelectedConditionRule(\n config.target,\n buildConditionExpression(\n nextField,\n readDefaultConditionOperator(nextField),\n readDefaultConditionValue(nextField),\n ),\n );\n }}\n options={conditionFieldSelectOptions}\n placeholder=\"選擇欄位\"\n value={readSelectOption(\n conditionFieldSelectOptions,\n selectedConditionField.fieldKey,\n )}\n />\n <Select\n clearable={false}\n onChange={(option): void =>\n updateSelectedConditionRule(\n config.target,\n buildConditionExpression(\n selectedConditionField,\n readConditionOperatorOption(option?.id) ??\n selectedOperator,\n selectedValue,\n ),\n )\n }\n options={[...conditionOperatorOptions]}\n placeholder=\"判斷方式\"\n value={readSelectOption(\n conditionOperatorOptions,\n selectedOperator,\n )}\n />\n {renderConditionValueControl(\n selectedConditionField,\n selectedValue,\n (nextValue): void =>\n updateSelectedConditionRule(\n config.target,\n buildConditionExpression(\n selectedConditionField,\n selectedOperator,\n nextValue,\n ),\n ),\n )}\n </div>\n )\n ) : null}\n </div>,\n true,\n );\n }\n\n function updateSelectedConditionRule(\n target: ConditionRuleTarget,\n expression: string | undefined,\n ): void {\n updateSelectedField({ [target]: expression });\n }\n\n function renderConditionValueControl(\n conditionField: FormFieldDefinition,\n value: string,\n onChange: (value: string) => void,\n ): ReactElement {\n if (conditionField.type === 'boolean') {\n return (\n <Select\n clearable={false}\n onChange={(option): void => onChange(option?.id ?? 'true')}\n options={[...BOOLEAN_CONDITION_VALUE_OPTIONS]}\n placeholder=\"比較值\"\n value={readSelectOption(\n BOOLEAN_CONDITION_VALUE_OPTIONS,\n value === 'false' ? 'false' : 'true',\n )}\n />\n );\n }\n\n if (isSelectFieldDefinition(conditionField)) {\n const options = conditionField.options.map(readFieldOptionAsSelectOption);\n\n return (\n <Select\n clearable={false}\n onChange={(option): void =>\n onChange(option?.id ?? options[0]?.id ?? '')\n }\n options={options}\n placeholder=\"比較值\"\n value={readSelectOption(options, value)}\n />\n );\n }\n\n if (isNumberFieldDefinition(conditionField)) {\n return renderNumberInput(\n parseOptionalNumberInput(value),\n (nextValue): void => onChange(String(nextValue ?? 0)),\n '比較值',\n );\n }\n\n if (isDateFieldDefinition(conditionField)) {\n return renderDateValuePicker(conditionField, value, (nextValue): void =>\n onChange(nextValue ?? ''),\n );\n }\n\n return (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(event.target.value)\n }\n placeholder=\"比較值\"\n value={value}\n variant=\"base\"\n />\n );\n }\n\n function renderSettingsTextarea({\n name,\n onChange,\n placeholder,\n rows,\n value,\n }: {\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly rows: number;\n readonly value: string;\n }): ReactElement {\n return (\n <Textarea\n aria-label={name}\n onChange={(event: ChangeEvent<HTMLTextAreaElement>): void =>\n onChange(event.target.value)\n }\n placeholder={placeholder}\n ref={applyFullWidthTextareaHost}\n resize=\"vertical\"\n rows={rows}\n style={FIELD_SETTINGS_TEXTAREA_STYLE}\n value={value}\n />\n );\n }\n\n function renderNumberInput(\n value: number | undefined,\n onChange: (value: number | undefined) => void,\n placeholder: string,\n options: {\n readonly max?: number;\n readonly min?: number;\n readonly step?: number;\n } = {},\n ): ReactElement {\n return (\n <Input\n max={options.max}\n min={options.min}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(\n clampOptionalNumber(\n parseOptionalNumberInput(event.target.value),\n options,\n ),\n )\n }\n placeholder={placeholder}\n showSpinner\n step={options.step ?? 1}\n value={typeof value === 'number' ? String(value) : ''}\n variant=\"measure\"\n />\n );\n }\n\n function renderDateValuePicker(\n field: DateFieldDefinition,\n value: string,\n onChange: (value: string | undefined) => void,\n ): ReactElement {\n if (field.type === 'datetime') {\n return (\n <DateTimePicker\n formatDate=\"YYYY-MM-DD\"\n formatTime=\"HH:mm\"\n hideSecond\n onChange={(nextValue): void =>\n onChange(formatDateTimePickerValue(nextValue))\n }\n placeholderLeft=\"選擇日期\"\n placeholderRight=\"選擇時間\"\n value={readDatePickerValue(value)}\n />\n );\n }\n\n return (\n <DatePicker\n format=\"YYYY-MM-DD\"\n onChange={(nextValue): void =>\n onChange(formatDatePickerValue(nextValue))\n }\n placeholder=\"選擇日期\"\n value={readDatePickerValue(value)}\n />\n );\n }\n\n function renderFieldOptionsTable(field: SelectFieldDefinition): ReactElement {\n const optionRows: FieldOptionRow[] = field.options.map((option, index) => ({\n index,\n key: `${field.fieldKey}-${index}`,\n label: option.label,\n value: option.value,\n }));\n const optionColumns: TableColumn<FieldOptionRow>[] = [\n {\n key: 'label',\n render: (row): ReactElement => (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedSelectField({\n options: updateFieldOption(field.options, row.index, {\n label: event.target.value,\n }),\n })\n }\n placeholder=\"例如:主管\"\n size=\"sub\"\n value={row.label}\n variant=\"base\"\n />\n ),\n title: 'Label',\n },\n {\n key: 'value',\n render: (row): ReactElement => (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedSelectField({\n options: updateFieldOption(field.options, row.index, {\n value: event.target.value,\n }),\n })\n }\n placeholder=\"例如:manager\"\n size=\"sub\"\n value={row.value}\n variant=\"base\"\n />\n ),\n title: 'Value',\n },\n ];\n const optionActions: TableActions<FieldOptionRow> = {\n render: (row): ReturnType<TableActions<FieldOptionRow>['render']> => [\n {\n disabled: (): boolean => field.options.length <= 1,\n icon: TrashIcon,\n iconType: 'icon-only',\n name: '移除選項',\n onClick: (): void =>\n updateSelectedSelectField({\n options: field.options.filter((_, index) => index !== row.index),\n }),\n variant: 'destructive-ghost',\n },\n ],\n width: 56,\n };\n\n return (\n <div style={COMPACT_STACK_STYLE}>\n <Table\n actions={optionActions}\n columns={optionColumns}\n dataSource={optionRows}\n showHeader\n size=\"sub\"\n />\n <div style={OPTION_ACTIONS_STYLE}>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n updateSelectedSelectField({\n options: [\n ...field.options,\n createNextFieldOption(field.options),\n ],\n })\n }\n variant=\"base-secondary\"\n >\n 新增選項\n </Button>\n </div>\n </div>\n );\n }\n\n function renderFieldBlock(\n field: FormFieldDefinition,\n draggableProvided: DraggableProvided,\n isDragging: boolean,\n ): ReactElement {\n return (\n <div\n {...draggableProvided.draggableProps}\n data-form-builder-field-key={field.fieldKey}\n ref={draggableProvided.innerRef}\n style={{\n ...FIELD_BLOCK_STYLE,\n ...(isDragging ? FIELD_BLOCK_DRAGGING_STYLE : null),\n ...draggableProvided.draggableProps.style,\n }}\n >\n <BaseCard\n style={\n field.fieldKey === selectedField?.fieldKey\n ? FIELD_BLOCK_SELECTED_CARD_STYLE\n : undefined\n }\n >\n {renderFieldBlockContent(field, draggableProvided, isDragging)}\n </BaseCard>\n </div>\n );\n }\n\n function renderSettingsFormRow(\n label: string,\n name: string,\n control: ReactElement,\n wide = false,\n ): ReactElement {\n return (\n <div\n style={wide ? FIELD_SETTINGS_ROW_WIDE_STYLE : FIELD_SETTINGS_ROW_STYLE}\n >\n <div style={FIELD_SETTINGS_VALUE_STYLE}>\n <BPMFormField label={label} name={name}>\n {control}\n </BPMFormField>\n </div>\n </div>\n );\n }\n\n function renderFieldBlockContent(\n field: FormFieldDefinition,\n draggableProvided: DraggableProvided,\n isDragging: boolean,\n ): ReactElement {\n return (\n <div\n {...(draggableProvided.dragHandleProps ?? {})}\n aria-label=\"選取或拖曳排序欄位\"\n onClick={(): void => setSelectedFieldKey(field.fieldKey)}\n style={FIELD_BLOCK_ROW_STYLE}\n title=\"點擊選取,拖曳排序\"\n >\n <span\n aria-label=\"拖曳排序\"\n role=\"img\"\n style={DRAG_HANDLE_STYLE}\n title=\"拖曳排序\"\n >\n <Icon icon={DotDragVerticalIcon} size={20} />\n </span>\n <div style={FIELD_BLOCK_TEXT_STYLE}>\n <Typography component=\"span\" ellipsis variant=\"label-primary\">\n {field.label}\n {field.required ? (\n <sup aria-label=\"必填\" style={REQUIRED_ASTERISK_STYLE}>\n *\n </sup>\n ) : null}\n </Typography>\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n variant=\"caption\"\n >\n {readFieldTypeLabel(field.type)} ·\n {field.required ? ' 必填' : ' 選填'} ·{field.fieldKey}\n </Typography>\n </div>\n <div\n onClick={(event: MouseEvent<HTMLDivElement>): void =>\n event.stopPropagation()\n }\n style={FIELD_BLOCK_ACTIONS_STYLE}\n >\n <div style={FIELD_BLOCK_REQUIRED_STYLE}>\n <Toggle\n checked={Boolean(field.required)}\n disabled={isDragging}\n label=\"必填\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateFieldRequired(field.fieldKey, event.target.checked)\n }\n />\n </div>\n <Button\n disabled={isDragging}\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void => handleRemoveField(field.fieldKey)}\n variant=\"destructive-ghost\"\n >\n 移除欄位\n </Button>\n </div>\n </div>\n );\n }\n\n function renderPreviewTab(): ReactElement {\n return (\n <div style={STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 填寫預覽\n </Typography>\n <FormRenderer\n onChange={updatePreviewValues}\n schema={schema}\n uiSchema={uiSchema}\n value={previewValues}\n />\n </div>\n );\n }\n\n function renderAdvancedTab(): ReactElement {\n return (\n <div style={STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n Schema\n </Typography>\n <div style={ADVANCED_SCHEMA_FORM_STYLE}>\n {renderAdvancedSchemaRow(\n 'Form Schema',\n 'schemaJson',\n <JsonCodeEditor\n height=\"360px\"\n name=\"schemaJson\"\n onChange={updateSchemaJson}\n placeholder=\"輸入 Form Schema JSON\"\n value={schemaJsonText}\n />,\n )}\n {renderAdvancedSchemaRow(\n 'UI Schema',\n 'uiSchemaJson',\n <JsonCodeEditor\n height=\"240px\"\n name=\"uiSchemaJson\"\n onChange={updateUiSchemaJson}\n placeholder=\"輸入 UI Schema JSON\"\n value={uiSchemaJsonText}\n />,\n )}\n {advancedSchemaMessage ? (\n <Typography\n color=\"text-error\"\n style={ADVANCED_SCHEMA_MESSAGE_STYLE}\n variant=\"body\"\n >\n {advancedSchemaMessage}\n </Typography>\n ) : null}\n </div>\n </div>\n );\n }\n\n function renderAdvancedSchemaRow(\n label: string,\n name: string,\n control: ReactElement,\n ): ReactElement {\n return (\n <div style={ADVANCED_SCHEMA_ROW_STYLE}>\n <div style={ADVANCED_SCHEMA_VALUE_STYLE}>\n <BPMFormField label={label} name={name}>\n {control}\n </BPMFormField>\n </div>\n </div>\n );\n }\n}\n\nfunction readFieldTypeLabel(type: FieldType): string {\n return (\n FIELD_TYPE_OPTIONS.find((option) => option.type === type)?.label ?? type\n );\n}\n\nfunction hasConditionRules(field: FormFieldDefinition): boolean {\n return Boolean(field.visibleWhen || field.requiredWhen || field.readonlyWhen);\n}\n\nfunction readFieldAsConditionSelectOption(field: FormFieldDefinition): {\n readonly id: string;\n readonly name: string;\n} {\n return {\n id: field.fieldKey,\n name: field.label,\n };\n}\n\nfunction isTextFieldDefinition(\n field: FormFieldDefinition,\n): field is TextFieldDefinition {\n return field.type === 'text' || field.type === 'textarea';\n}\n\nfunction readStringDefaultValue(\n value: FormFieldDefinition['defaultValue'],\n): string {\n return typeof value === 'string' ? value : '';\n}\n\nfunction parseStringList(value: string): readonly string[] | undefined {\n const values = value\n .split(/[\\n,]/u)\n .map((item) => item.trim())\n .filter(Boolean);\n\n return values.length ? values : undefined;\n}\n\nfunction readStringListInput(value: readonly string[] | undefined): string {\n return value?.join('\\n') ?? '';\n}\n\nfunction stringifyJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\nfunction updateFieldOption(\n options: readonly FormFieldOption[],\n targetIndex: number,\n patch: Partial<FormFieldOption>,\n): readonly FormFieldOption[] {\n return options.map((option, index) =>\n index === targetIndex ? { ...option, ...patch } : option,\n );\n}\n\nfunction createNextFieldOption(\n options: readonly FormFieldOption[],\n): FormFieldOption {\n const nextIndex = options.length + 1;\n\n return {\n label: `選項 ${nextIndex}`,\n value: readNextOptionValue(options, nextIndex),\n };\n}\n\nfunction readNextOptionValue(\n options: readonly FormFieldOption[],\n index: number,\n): string {\n const value = `option_${index}`;\n\n return options.some((option) => option.value === value)\n ? readNextOptionValue(options, index + 1)\n : value;\n}\n\nfunction moveItemByIndex<TItem>(\n items: readonly TItem[],\n sourceIndex: number,\n destinationIndex: number,\n): TItem[] {\n const sourceItem = items[sourceIndex];\n\n if (!sourceItem || sourceIndex === destinationIndex) {\n return [...items];\n }\n\n const remainingItems = items.filter((_, index) => index !== sourceIndex);\n\n return [\n ...remainingItems.slice(0, destinationIndex),\n sourceItem,\n ...remainingItems.slice(destinationIndex),\n ];\n}\n\n"],"mappings":"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"}
|