@rytass/bpm-core-react 0.3.0 → 0.3.2

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.
Files changed (184) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/README.md +13 -1
  3. package/dist/chunks/app-navigation-BSkMsEhy.js +268 -0
  4. package/dist/chunks/app-navigation-BSkMsEhy.js.map +1 -0
  5. package/dist/chunks/app-navigation-KnlJCUp1.cjs +2 -0
  6. package/dist/chunks/app-navigation-KnlJCUp1.cjs.map +1 -0
  7. package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs +2 -0
  8. package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs.map +1 -0
  9. package/dist/chunks/{approval-instance-list-page-BgE4vQw8.js → approval-instance-list-page-CqNdoZqx.js} +103 -99
  10. package/dist/chunks/approval-instance-list-page-CqNdoZqx.js.map +1 -0
  11. package/dist/chunks/builder-CMlJfQHE.cjs +3 -0
  12. package/dist/chunks/builder-CMlJfQHE.cjs.map +1 -0
  13. package/dist/chunks/{builder-Du_0apkh.js → builder-D950gct_.js} +436 -432
  14. package/dist/chunks/builder-D950gct_.js.map +1 -0
  15. package/dist/chunks/categories-5yEM3p3N.cjs +2 -0
  16. package/dist/chunks/categories-5yEM3p3N.cjs.map +1 -0
  17. package/dist/chunks/categories-BIpOG451.js +387 -0
  18. package/dist/chunks/categories-BIpOG451.js.map +1 -0
  19. package/dist/chunks/dashboard-page-1K_jQXQk.cjs +2 -0
  20. package/dist/chunks/dashboard-page-1K_jQXQk.cjs.map +1 -0
  21. package/dist/chunks/dashboard-page-R_T2OEiE.js +122 -0
  22. package/dist/chunks/dashboard-page-R_T2OEiE.js.map +1 -0
  23. package/dist/chunks/delegations-B2j-wNEO.js +646 -0
  24. package/dist/chunks/delegations-B2j-wNEO.js.map +1 -0
  25. package/dist/chunks/delegations-CsB9ozLu.cjs +2 -0
  26. package/dist/chunks/delegations-CsB9ozLu.cjs.map +1 -0
  27. package/dist/chunks/delegations-CvtwTXNP.cjs +2 -0
  28. package/dist/chunks/delegations-CvtwTXNP.cjs.map +1 -0
  29. package/dist/chunks/delegations-dKodb0WW.js +573 -0
  30. package/dist/chunks/delegations-dKodb0WW.js.map +1 -0
  31. package/dist/chunks/detail-BcGAqJ_R.js +1523 -0
  32. package/dist/chunks/detail-BcGAqJ_R.js.map +1 -0
  33. package/dist/chunks/detail-CqjqLd65.cjs +2 -0
  34. package/dist/chunks/detail-CqjqLd65.cjs.map +1 -0
  35. package/dist/chunks/{format-date-time-hKLVMxq4.cjs → format-date-time-26_pFvv4.cjs} +2 -2
  36. package/dist/chunks/{format-date-time-hKLVMxq4.cjs.map → format-date-time-26_pFvv4.cjs.map} +1 -1
  37. package/dist/chunks/notifications-2swRqDPF.js +198 -0
  38. package/dist/chunks/notifications-2swRqDPF.js.map +1 -0
  39. package/dist/chunks/notifications-BaYDebFt.cjs +2 -0
  40. package/dist/chunks/notifications-BaYDebFt.cjs.map +1 -0
  41. package/dist/chunks/{orgs-c29y74w2.js → orgs-CuHxxd_n.js} +665 -661
  42. package/dist/chunks/orgs-CuHxxd_n.js.map +1 -0
  43. package/dist/chunks/orgs-YMiVLNvL.cjs +2 -0
  44. package/dist/chunks/orgs-YMiVLNvL.cjs.map +1 -0
  45. package/dist/chunks/routes-config-2aKbWq2H.cjs +2 -0
  46. package/dist/chunks/routes-config-2aKbWq2H.cjs.map +1 -0
  47. package/dist/chunks/routes-config-dxahImVe.js +43 -0
  48. package/dist/chunks/routes-config-dxahImVe.js.map +1 -0
  49. package/dist/chunks/templates-DTkbSgFY.cjs +2 -0
  50. package/dist/chunks/templates-DTkbSgFY.cjs.map +1 -0
  51. package/dist/chunks/{templates-Dn9QHFSy.js → templates-DoDWM68t.js} +136 -132
  52. package/dist/chunks/templates-DoDWM68t.js.map +1 -0
  53. package/dist/chunks/users-3ySyUW4u.cjs +2 -0
  54. package/dist/chunks/users-3ySyUW4u.cjs.map +1 -0
  55. package/dist/chunks/users-sMfrSjRQ.js +219 -0
  56. package/dist/chunks/users-sMfrSjRQ.js.map +1 -0
  57. package/dist/components/app-navigation.d.ts +17 -10
  58. package/dist/index.cjs +1 -1
  59. package/dist/index.cjs.map +1 -1
  60. package/dist/index.d.ts +1 -0
  61. package/dist/index.js +101 -99
  62. package/dist/index.js.map +1 -1
  63. package/dist/lib/notification-drawer-provider.d.ts +1 -1
  64. package/dist/lib/notification-unread-provider.d.ts +1 -1
  65. package/dist/lib/providers.d.ts +1 -1
  66. package/dist/lib/routes-config.d.ts +96 -0
  67. package/dist/next/index.cjs +1 -1
  68. package/dist/next/index.cjs.map +1 -1
  69. package/dist/next/index.d.ts +1 -0
  70. package/dist/next/index.js +22 -21
  71. package/dist/next/index.js.map +1 -1
  72. package/dist/pages/admin/delegations/index.cjs +1 -1
  73. package/dist/pages/admin/delegations/index.js +1 -1
  74. package/dist/pages/admin/orgs/index.cjs +1 -1
  75. package/dist/pages/admin/orgs/index.js +1 -1
  76. package/dist/pages/admin/users/index.cjs +1 -1
  77. package/dist/pages/admin/users/index.js +1 -1
  78. package/dist/pages/delegations/index.cjs +1 -1
  79. package/dist/pages/delegations/index.js +1 -1
  80. package/dist/pages/forms/builder/index.cjs +1 -1
  81. package/dist/pages/forms/builder/index.js +1 -1
  82. package/dist/pages/instances/detail/index.cjs +1 -1
  83. package/dist/pages/instances/detail/index.js +1 -1
  84. package/dist/pages/settings/notifications/index.cjs +1 -1
  85. package/dist/pages/settings/notifications/index.js +1 -1
  86. package/dist/pages/templates/categories/index.cjs +1 -1
  87. package/dist/pages/templates/categories/index.js +1 -1
  88. package/dist/pages/templates/index.cjs +1 -1
  89. package/dist/pages/templates/index.js +1 -1
  90. package/dist/views/admin/delegations/index.cjs +1 -1
  91. package/dist/views/admin/delegations/index.js +1 -1
  92. package/dist/views/admin/index.cjs +1 -1
  93. package/dist/views/admin/index.js +3 -3
  94. package/dist/views/admin/orgs/index.cjs +1 -1
  95. package/dist/views/admin/orgs/index.js +1 -1
  96. package/dist/views/admin/users/index.cjs +1 -1
  97. package/dist/views/admin/users/index.js +1 -1
  98. package/dist/views/cc/index.cjs +1 -1
  99. package/dist/views/cc/index.js +1 -1
  100. package/dist/views/dashboard/index.cjs +1 -1
  101. package/dist/views/dashboard/index.js +1 -1
  102. package/dist/views/delegations/index.cjs +1 -1
  103. package/dist/views/delegations/index.js +1 -1
  104. package/dist/views/forms/builder/index.cjs +1 -1
  105. package/dist/views/forms/builder/index.js +1 -1
  106. package/dist/views/forms/index.cjs +1 -1
  107. package/dist/views/forms/index.cjs.map +1 -1
  108. package/dist/views/forms/index.js +84 -80
  109. package/dist/views/forms/index.js.map +1 -1
  110. package/dist/views/inbox/index.cjs +1 -1
  111. package/dist/views/inbox/index.cjs.map +1 -1
  112. package/dist/views/inbox/index.js +83 -79
  113. package/dist/views/inbox/index.js.map +1 -1
  114. package/dist/views/instances/detail/index.cjs +1 -1
  115. package/dist/views/instances/detail/index.js +1 -1
  116. package/dist/views/instances/new/index.cjs +1 -1
  117. package/dist/views/instances/new/index.cjs.map +1 -1
  118. package/dist/views/instances/new/index.js +107 -100
  119. package/dist/views/instances/new/index.js.map +1 -1
  120. package/dist/views/search/index.cjs +1 -1
  121. package/dist/views/search/index.js +1 -1
  122. package/dist/views/sent/index.cjs +1 -1
  123. package/dist/views/sent/index.js +1 -1
  124. package/dist/views/settings/index.cjs +1 -1
  125. package/dist/views/settings/index.js +1 -1
  126. package/dist/views/settings/notifications/index.cjs +1 -1
  127. package/dist/views/settings/notifications/index.js +1 -1
  128. package/dist/views/templates/categories/index.cjs +1 -1
  129. package/dist/views/templates/categories/index.js +1 -1
  130. package/dist/views/templates/designer/index.cjs +6 -6
  131. package/dist/views/templates/designer/index.cjs.map +1 -1
  132. package/dist/views/templates/designer/index.js +758 -754
  133. package/dist/views/templates/designer/index.js.map +1 -1
  134. package/dist/views/templates/index.cjs +1 -1
  135. package/dist/views/templates/index.js +2 -2
  136. package/dist/views/templates/versions/index.cjs +1 -1
  137. package/dist/views/templates/versions/index.cjs.map +1 -1
  138. package/dist/views/templates/versions/index.js +47 -43
  139. package/dist/views/templates/versions/index.js.map +1 -1
  140. package/package.json +3 -3
  141. package/dist/chunks/app-navigation-BRRFCkxZ.cjs +0 -2
  142. package/dist/chunks/app-navigation-BRRFCkxZ.cjs.map +0 -1
  143. package/dist/chunks/app-navigation-rxhpHCch.js +0 -262
  144. package/dist/chunks/app-navigation-rxhpHCch.js.map +0 -1
  145. package/dist/chunks/approval-instance-list-page-2vUWc5-c.cjs +0 -2
  146. package/dist/chunks/approval-instance-list-page-2vUWc5-c.cjs.map +0 -1
  147. package/dist/chunks/approval-instance-list-page-BgE4vQw8.js.map +0 -1
  148. package/dist/chunks/builder-B8X-m6C5.cjs +0 -3
  149. package/dist/chunks/builder-B8X-m6C5.cjs.map +0 -1
  150. package/dist/chunks/builder-Du_0apkh.js.map +0 -1
  151. package/dist/chunks/categories-DG4k7S8V.js +0 -383
  152. package/dist/chunks/categories-DG4k7S8V.js.map +0 -1
  153. package/dist/chunks/categories-DshBQG33.cjs +0 -2
  154. package/dist/chunks/categories-DshBQG33.cjs.map +0 -1
  155. package/dist/chunks/dashboard-page-CTBwpu_D.js +0 -114
  156. package/dist/chunks/dashboard-page-CTBwpu_D.js.map +0 -1
  157. package/dist/chunks/dashboard-page-DcDiWQp2.cjs +0 -2
  158. package/dist/chunks/dashboard-page-DcDiWQp2.cjs.map +0 -1
  159. package/dist/chunks/delegations-BAZQbElH.js +0 -642
  160. package/dist/chunks/delegations-BAZQbElH.js.map +0 -1
  161. package/dist/chunks/delegations-DzrckrPp.js +0 -569
  162. package/dist/chunks/delegations-DzrckrPp.js.map +0 -1
  163. package/dist/chunks/delegations-Z8hTajLj.cjs +0 -2
  164. package/dist/chunks/delegations-Z8hTajLj.cjs.map +0 -1
  165. package/dist/chunks/delegations-hb9JoVZe.cjs +0 -2
  166. package/dist/chunks/delegations-hb9JoVZe.cjs.map +0 -1
  167. package/dist/chunks/detail-DilI0PPe.js +0 -1519
  168. package/dist/chunks/detail-DilI0PPe.js.map +0 -1
  169. package/dist/chunks/detail-DuRg3Y7b.cjs +0 -2
  170. package/dist/chunks/detail-DuRg3Y7b.cjs.map +0 -1
  171. package/dist/chunks/notifications-B2Lk3grg.js +0 -194
  172. package/dist/chunks/notifications-B2Lk3grg.js.map +0 -1
  173. package/dist/chunks/notifications-C8ADhnxF.cjs +0 -2
  174. package/dist/chunks/notifications-C8ADhnxF.cjs.map +0 -1
  175. package/dist/chunks/orgs-CGv3VNDR.cjs +0 -2
  176. package/dist/chunks/orgs-CGv3VNDR.cjs.map +0 -1
  177. package/dist/chunks/orgs-c29y74w2.js.map +0 -1
  178. package/dist/chunks/templates-Cd0WFheA.cjs +0 -2
  179. package/dist/chunks/templates-Cd0WFheA.cjs.map +0 -1
  180. package/dist/chunks/templates-Dn9QHFSy.js.map +0 -1
  181. package/dist/chunks/users-B-trMu0E.cjs +0 -2
  182. package/dist/chunks/users-B-trMu0E.cjs.map +0 -1
  183. package/dist/chunks/users-itVXXRj7.js +0 -215
  184. package/dist/chunks/users-itVXXRj7.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"builder-Du_0apkh.js","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,\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 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 Layout,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport {\n AlignLeftIcon,\n CalendarIcon,\n CheckedOutlineIcon,\n CheckedIcon,\n CurrencyDollarIcon,\n DotDragVerticalIcon,\n DotGridIcon,\n EditIcon,\n FileAttachmentIcon,\n FileIcon,\n ListIcon,\n PlusIcon,\n SaveIcon,\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 { formatDateTime } from '../../../lib/format-date-time';\nimport { AppNavigation } from '../../../components/app-navigation';\nimport {\n createFieldDefinition,\n FormBuilderRecord,\n FormDefinitionVersionRecord,\n forkFormDefinition,\n publishFormDefinitionVersion,\n readFormBuilder,\n updateFormDefinition,\n updateFormDefinitionDraft,\n} 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 { useRouterAdapter } from '../../../lib/router-adapter';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { FormRenderer } from '../renderer/FormRendererView';\nimport { FormNameModal } from '../form-name-modal';\nimport { JsonCodeEditor } from './json-code-editor';\n\ntype FieldType = FormFieldDefinition['type'];\ntype BuilderTabKey = 'design' | 'preview' | 'versions' | 'advanced';\ntype FieldOptionRow = Readonly<\n Record<string, unknown> & {\n index: number;\n key: string;\n label: string;\n value: string;\n }\n>;\n\ntype VersionRow = Readonly<\n Record<string, unknown> & {\n key: string;\n publishedAt: string;\n status: FormDefinitionVersionRecord['status'];\n updatedAt: string;\n version: string;\n }\n>;\n\ntype BuilderSnapshot = Readonly<{\n schemaJson: string;\n uiSchemaJson: string;\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 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\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 * The id of the form definition being edited. Routed via the host's\n * dynamic segment (e.g. `[id]` in Next.js).\n */\n readonly formId: string;\n}\n\nexport function FormBuilderView({ formId }: FormBuilderViewProps): ReactElement {\n const router = useRouterAdapter();\n const formDefinitionId = formId;\n const [record, setRecord] = useState<FormBuilderRecord | null>(null);\n const [draft, setDraft] = useState<FormDefinitionVersionRecord | null>(null);\n const [schema, setSchema] = useState<FormDefinitionSchema>(EMPTY_SCHEMA);\n const [uiSchema, setUiSchema] = useState<FormUiSchema>(EMPTY_UI_SCHEMA);\n const [schemaJsonText, setSchemaJsonText] = useState(\n stringifyJson(EMPTY_SCHEMA),\n );\n const [uiSchemaJsonText, setUiSchemaJsonText] = useState(\n stringifyJson(EMPTY_UI_SCHEMA),\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 const [error, setError] = useState<string | null>(null);\n const [renameModalOpen, setRenameModalOpen] = useState(false);\n const [loadedSnapshot, setLoadedSnapshot] = useState<BuilderSnapshot>(\n readBuilderSnapshot(EMPTY_SCHEMA, EMPTY_UI_SCHEMA),\n );\n const [loading, setLoading] = useState(true);\n const [renaming, setRenaming] = useState(false);\n const [saving, setSaving] = useState(false);\n\n useEffect((): void => {\n void refreshBuilder();\n }, [formDefinitionId]);\n\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 const versionRows = useMemo(\n (): VersionRow[] =>\n (record?.versions ?? []).map((version) => ({\n key: version.id,\n publishedAt: formatDateTime(version.publishedAt),\n status: version.status,\n updatedAt: formatDateTime(version.updatedAt),\n version: `v${version.version}`,\n })),\n [record],\n );\n const versionColumns = useMemo(\n (): TableColumn<VersionRow>[] => [\n { dataIndex: 'version', key: 'version', title: '版本', width: 120 },\n {\n key: 'status',\n render: (record: VersionRow): ReactElement => (\n <FormVersionStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 140,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '最後更新',\n width: 180,\n },\n {\n dataIndex: 'publishedAt',\n key: 'publishedAt',\n title: '發布時間',\n width: 180,\n },\n ],\n [],\n );\n const currentSnapshot = useMemo(\n (): BuilderSnapshot => readBuilderSnapshot(schema, uiSchema),\n [schema, uiSchema],\n );\n const hasUnsavedChanges =\n currentSnapshot.schemaJson !== loadedSnapshot.schemaJson ||\n currentSnapshot.uiSchemaJson !== loadedSnapshot.uiSchemaJson;\n\n useEffect((): (() => void) => {\n function handleBeforeUnload(event: BeforeUnloadEvent): void {\n if (!hasUnsavedChanges) {\n return;\n }\n\n event.preventDefault();\n event.returnValue = '';\n }\n\n window.addEventListener('beforeunload', handleBeforeUnload);\n\n return (): void => {\n window.removeEventListener('beforeunload', handleBeforeUnload);\n };\n }, [hasUnsavedChanges]);\n\n function handleBackToForms(): void {\n if (\n hasUnsavedChanges &&\n !window.confirm('目前有尚未儲存的表單草稿,確定要離開嗎?')\n ) {\n return;\n }\n\n router.push('/forms');\n }\n const latestPublishedVersion = useMemo(\n (): FormDefinitionVersionRecord | null =>\n readPublishedVersion(\n record?.versions ?? [],\n record?.definition.currentVersionId,\n ),\n [record?.definition.currentVersionId, record?.versions],\n );\n const openedVersion =\n draft ?? latestPublishedVersion ?? record?.versions[0] ?? null;\n const openedContentPublished =\n !hasUnsavedChanges && openedVersion?.status === 'PUBLISHED';\n const headerDescription = readHeaderDescription({\n hasUnsavedChanges,\n latestPublishedVersion,\n openedContentPublished,\n openedVersion,\n });\n const publishDisabled =\n saving || (!hasUnsavedChanges && openedContentPublished && !draft);\n const publishButtonText = hasUnsavedChanges\n ? '保存並發布'\n : draft\n ? '發布草稿'\n : openedContentPublished\n ? '已發布'\n : '發布版本';\n\n async function refreshBuilder(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n const nextRecord = await readFormBuilder(formDefinitionId);\n const nextDraft =\n nextRecord.versions.find((version) => version.status === 'DRAFT') ??\n null;\n\n setRecord(nextRecord);\n setDraft(nextDraft);\n const nextSchema =\n nextDraft?.schema ?? nextRecord.versions[0]?.schema ?? EMPTY_SCHEMA;\n const nextUiSchema =\n nextDraft?.uiSchema ??\n nextRecord.versions[0]?.uiSchema ??\n EMPTY_UI_SCHEMA;\n\n setSchema(nextSchema);\n setUiSchema(nextUiSchema);\n setLoadedSnapshot(readBuilderSnapshot(nextSchema, nextUiSchema));\n setSchemaJsonText(stringifyJson(nextSchema));\n setUiSchemaJsonText(stringifyJson(nextUiSchema));\n setSelectedFieldKey(\n nextDraft?.schema.fields[0]?.fieldKey ??\n nextRecord.versions[0]?.schema.fields[0]?.fieldKey ??\n null,\n );\n setAdvancedSchemaMessage(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function saveCurrentDraft(): Promise<FormDefinitionVersionRecord> {\n const targetDraft = draft ?? (await forkFormDefinition(formDefinitionId));\n const nextDraft = await updateFormDefinitionDraft(\n targetDraft.id,\n schema,\n uiSchema,\n );\n\n setDraft(nextDraft);\n\n return nextDraft;\n }\n\n async function handleSaveDraft(): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await saveCurrentDraft();\n await refreshBuilder();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n async function handlePublish(): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n const savedDraft = await saveCurrentDraft();\n await publishFormDefinitionVersion(savedDraft.id);\n await refreshBuilder();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n async function handleRenameForm(name: string): Promise<void> {\n if (!record) {\n throw new Error('尚未載入表單資料');\n }\n\n setRenaming(true);\n\n try {\n const updatedDefinition = await updateFormDefinition(\n record.definition.id,\n name,\n );\n\n setRecord({\n ...record,\n definition: updatedDefinition,\n });\n setRenameModalOpen(false);\n } finally {\n setRenaming(false);\n }\n }\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 <Layout>\n <AppNavigation activeHref=\"/forms\" />\n\n <Layout.Main>\n <PageHeader>\n <ContentHeader\n description={headerDescription}\n onBackClick={handleBackToForms}\n title={record?.definition.name ?? '表單設計器'}\n >\n <Button\n aria-label=\"修改表單名稱\"\n disabled={renaming || !record}\n icon={EditIcon}\n iconType=\"icon-only\"\n onClick={(): void => setRenameModalOpen(true)}\n variant=\"base-ghost\"\n >\n 修改表單名稱\n </Button>\n <Button\n aria-label=\"儲存草稿\"\n disabled={saving || !hasUnsavedChanges}\n icon={SaveIcon}\n iconType=\"icon-only\"\n onClick={(): void => void handleSaveDraft()}\n variant=\"base-secondary\"\n >\n 儲存草稿\n </Button>\n <Button\n disabled={publishDisabled}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={(): void => void handlePublish()}\n variant=\"base-primary\"\n >\n {publishButtonText}\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={WORKBENCH_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\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=\"versions\">版本</TabItem>\n <TabItem key=\"advanced\">進階</TabItem>\n </Tab>\n\n {activeTab === 'design' ? renderDesignTab() : null}\n {activeTab === 'preview' ? renderPreviewTab() : null}\n {activeTab === 'versions' ? renderVersionsTab() : null}\n {activeTab === 'advanced' ? renderAdvancedTab() : null}\n </div>\n </Section>\n </SectionGroup>\n </Layout.Main>\n </Layout>\n\n <FormNameModal\n confirmText=\"儲存\"\n initialName={record?.definition.name ?? ''}\n loading={renaming}\n onClose={(): void => setRenameModalOpen(false)}\n onSubmit={handleRenameForm}\n open={renameModalOpen}\n title=\"修改表單名稱\"\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 disabled={saving}\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 isDragDisabled={saving}\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 disabled={saving}\n onClick={(): void => handleAddField('text')}\n variant=\"base-primary\"\n >\n 新增文字欄位\n </Button>\n <Button\n disabled={saving}\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 saving,\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 saving,\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 saving,\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 disabled: saving,\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 saving,\n )}\n {renderSettingsFormRow(\n '最小長度',\n 'fieldMinLength',\n renderNumberInput(\n field.minLength,\n (value): void => updateSelectedTextField({ minLength: value }),\n '例如:2',\n { min: 0 },\n ),\n saving,\n )}\n {renderSettingsFormRow(\n '最大長度',\n 'fieldMaxLength',\n renderNumberInput(\n field.maxLength,\n (value): void => updateSelectedTextField({ maxLength: value }),\n '例如:100',\n { min: 1 },\n ),\n saving,\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 saving,\n )}\n {renderSettingsFormRow(\n '最小值',\n 'fieldMinimum',\n renderNumberInput(\n field.minimum,\n (value): void => updateSelectedNumberField({ minimum: value }),\n '例如:0',\n ),\n saving,\n )}\n {renderSettingsFormRow(\n '最大值',\n 'fieldMaximum',\n renderNumberInput(\n field.maximum,\n (value): void => updateSelectedNumberField({ maximum: value }),\n '例如:999999',\n ),\n saving,\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 saving,\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 saving,\n )}\n {renderSettingsFormRow(\n '選項',\n 'fieldOptions',\n renderFieldOptionsTable(field),\n saving,\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 saving,\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 saving,\n )}\n {renderSettingsFormRow(\n 'MIME',\n 'fieldAcceptedMimeTypes',\n renderSettingsTextarea({\n disabled: saving,\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 disabled={saving}\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 saving,\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 disabled,\n name,\n onChange,\n placeholder,\n rows,\n value,\n }: {\n readonly disabled: boolean;\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 disabled={disabled}\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 => saving || 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 disabled={saving}\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 {renderFieldBlockContent(field, draggableProvided, isDragging)}\n </BaseCard>\n </div>\n );\n }\n\n function renderSettingsFormRow(\n label: string,\n name: string,\n control: ReactElement,\n disabled: boolean,\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 disabled={disabled} 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 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 style={FIELD_BLOCK_ACTIONS_STYLE}>\n <div style={FIELD_BLOCK_REQUIRED_STYLE}>\n <Toggle\n checked={Boolean(field.required)}\n disabled={saving || 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={EditIcon}\n iconType=\"icon-only\"\n onClick={(): void => setSelectedFieldKey(field.fieldKey)}\n variant={\n field.fieldKey === selectedField?.fieldKey\n ? 'base-primary'\n : 'base-ghost'\n }\n >\n 編輯欄位\n </Button>\n <Button\n disabled={saving || 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 renderVersionsTab(): ReactElement {\n return (\n <div style={STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 版本紀錄\n </Typography>\n <Table\n columns={versionColumns}\n dataSource={versionRows}\n loading={loading}\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 disabled={saving}\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 disabled={saving}\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 disabled={saving} 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 readBuilderSnapshot(\n schema: FormDefinitionSchema,\n uiSchema: FormUiSchema,\n): BuilderSnapshot {\n return {\n schemaJson: stringifyJson(schema),\n uiSchemaJson: stringifyJson(uiSchema),\n };\n}\n\nfunction readPublishedVersion(\n versions: readonly FormDefinitionVersionRecord[],\n currentVersionId: string | null | undefined,\n): FormDefinitionVersionRecord | null {\n return (\n (currentVersionId\n ? versions.find((version) => version.id === currentVersionId)\n : null) ??\n versions.find((version) => version.status === 'PUBLISHED') ??\n null\n );\n}\n\nfunction readHeaderDescription({\n hasUnsavedChanges,\n latestPublishedVersion,\n openedContentPublished,\n openedVersion,\n}: {\n readonly hasUnsavedChanges: boolean;\n readonly latestPublishedVersion: FormDefinitionVersionRecord | null;\n readonly openedContentPublished: boolean;\n readonly openedVersion: FormDefinitionVersionRecord | null;\n}): string {\n const editState = hasUnsavedChanges ? '有未儲存修改' : '沒有未儲存修改';\n const openedState = readOpenedVersionState({\n hasUnsavedChanges,\n openedContentPublished,\n openedVersion,\n });\n const publishedState = latestPublishedVersion\n ? `目前發布 v${latestPublishedVersion.version}:${formatDateTime(\n latestPublishedVersion.publishedAt,\n )}`\n : '目前沒有已發布版本';\n\n return `${editState} · ${openedState} · ${publishedState}`;\n}\n\nfunction readOpenedVersionState({\n hasUnsavedChanges,\n openedContentPublished,\n openedVersion,\n}: {\n readonly hasUnsavedChanges: boolean;\n readonly openedContentPublished: boolean;\n readonly openedVersion: FormDefinitionVersionRecord | null;\n}): string {\n if (hasUnsavedChanges) {\n return openedVersion\n ? `修改尚未發布,來源 v${openedVersion.version}`\n : '修改尚未發布';\n }\n\n if (openedContentPublished && openedVersion) {\n return `當前內容已發布 v${openedVersion.version}`;\n }\n\n if (openedVersion) {\n return `當前內容尚未發布 v${openedVersion.version}`;\n }\n\n return '當前內容尚未發布';\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\nfunction FormVersionStatusBadge({\n status,\n}: {\n readonly status: FormDefinitionVersionRecord['status'];\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n if (status === 'ARCHIVED') {\n return <Badge size=\"sub\" text=\"已封存\" variant=\"dot-inactive\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-warning\" />;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAQA,IAAM,KAAuC;CAC3C,YAAY;CACZ,QAAQ;CACR,cAAc;CACd,OAAO;CACP,SAAS;CACT,WAAW;CACX,SAAS;CACT,OAAO;AACT,GAEM,IAA+C;CACnD,EAAK;CACL,EAAW;CACX,EAAW,MAAM;EACf,KAAK;GACH,QAAQ;GACR,cAAc;GACd,UAAU;GACV,OAAO;EACT;EACA,gBAAgB,EACd,SAAS,4CACX;EACA,eAAe;GACb,YACE;GACF,WAAW;EACb;EACA,cAAc,EACZ,OAAO,OACT;EACA,eAAe,EACb,aAAa,4CACf;EACA,gBAAgB,EACd,YACE,wFACJ;CACF,CAAC;AACH,GAEM,KAAa,QACX,OAAO,0BACb;CACE,eACE,kBAAC,OAAD;EAAK,OAAO;YAAuB;CAAgB,CAAA;CAErD,KAAK;AACP,CACF;AAWA,SAAgB,GAAe,EAC7B,aACA,WACA,SACA,aACA,gBACA,YACoC;CACpC,OACE,kBAAC,IAAD;EACE,cAAY;EACZ,YAAY;GACV,gBAAgB;GAChB,iBAAiB;GACjB,eAAe;GACf,eAAe;GACf,YAAY;GACZ,qBAAqB;GACrB,2BAA2B;GAC3B,aAAa;GACb,oBAAoB;EACtB;EACA,UAAU,CAAC;EACX,YAAY,CAAC,GAAG,CAAsB;EAC9B;EACR,eAAe;EACL;EACG;EACb,UAAU;EACV,OAAM;EACC;EACP,OAAM;CACP,CAAA;AAEL;;;AC+CA,IAAM,KAAiD;CACrD;EACE,aAAa;EACb,MAAM;EACN,OAAO;EACP,MAAM;CACR;CACA;EACE,aAAa;EACb,MAAM;EACN,OAAO;EACP,MAAM;CACR;CACA;EACE,aAAa;EACb,MAAM;EACN,OAAO;EACP,MAAM;CACR;CACA;EACE,aAAa;EACb,MAAM;EACN,OAAO;EACP,MAAM;CACR;CACA;EACE,aAAa;EACb,MAAM;EACN,OAAO;EACP,MAAM;CACR;CACA;EACE,aAAa;EACb,MAAM;EACN,OAAO;EACP,MAAM;CACR;CACA;EACE,aAAa;EACb,MAAM;EACN,OAAO;EACP,MAAM;CACR;CACA;EACE,aAAa;EACb,MAAM;EACN,OAA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"}
@@ -1,383 +0,0 @@
1
- "use client";
2
- import { t as e } from "./format-date-time-CB-LxzqT.js";
3
- import { t } from "./app-navigation-rxhpHCch.js";
4
- import { t as n } from "./bpm-form-field-Cao0rMol.js";
5
- import { useCallback as r, useEffect as i, useMemo as a, useState as o } from "react";
6
- import { Badge as s, Button as c, Filter as l, FilterArea as u, FilterLine as d, FormField as f, Input as p, Layout as m, Modal as h, PageHeader as g, Section as _, SectionGroup as ee, Tab as te, TabItem as ne, Table as re, Textarea as v, Typography as y } from "@mezzanine-ui/react";
7
- import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
8
- import { PlusIcon as C } from "@mezzanine-ui/icons";
9
- import w from "@mezzanine-ui/react/ContentHeader";
10
- import { FormFieldLayout as T } from "@mezzanine-ui/core/form";
11
- import { createApprovalTemplateCategory as E, deleteApprovalTemplateCategory as D, listApprovalTemplateCategoriesPage as O, updateApprovalTemplateCategory as k } from "@rytass/bpm-core-client/template";
12
- import '../categories.css';var A = {
13
- templateFilterArea: "bpm_templateFilterArea_nUL-R",
14
- templateModalFields: "bpm_templateModalFields_hUxWp"
15
- }, j = [
16
- 10,
17
- 20,
18
- 50
19
- ], M = [
20
- {
21
- key: "ALL",
22
- label: "全部"
23
- },
24
- {
25
- key: "ACTIVE",
26
- label: "啟用"
27
- },
28
- {
29
- key: "INACTIVE",
30
- label: "停用"
31
- }
32
- ];
33
- function N({ activeHref: n = "/templates/categories" } = {}) {
34
- let [s, v] = o([]), [N, I] = o(1), [L, R] = o(10), [z, B] = o("ALL"), [V, H] = o(0), [U, W] = o(null), [G, K] = o(null), [se, q] = o(!0), [J, Y] = o(null), [X, Z] = o(!1), [Q, ce] = o(""), $ = r(async () => {
35
- q(!0), K(null);
36
- try {
37
- let e = await O({
38
- page: N,
39
- pageSize: L,
40
- searchText: Q,
41
- status: P(z)
42
- });
43
- v(e.categories), H(e.totalCount);
44
- } catch (e) {
45
- K(F(e));
46
- } finally {
47
- q(!1);
48
- }
49
- }, [
50
- N,
51
- L,
52
- z,
53
- Q
54
- ]);
55
- i(() => {
56
- $();
57
- }, [$]);
58
- let le = a(() => s.map((t) => ({
59
- ...t,
60
- key: t.id,
61
- updatedAtLabel: e(t.updatedAt)
62
- })), [s]), ue = a(() => [
63
- {
64
- dataIndex: "name",
65
- key: "name",
66
- title: "分類名稱",
67
- width: 180
68
- },
69
- {
70
- key: "status",
71
- render: (e) => /* @__PURE__ */ x(ae, { isActive: e.isActive }),
72
- title: "狀態",
73
- width: 120
74
- },
75
- {
76
- dataIndex: "sortOrder",
77
- key: "sortOrder",
78
- title: "排序",
79
- width: 100
80
- },
81
- {
82
- key: "description",
83
- render: (e) => /* @__PURE__ */ x(y, {
84
- component: "span",
85
- variant: "body",
86
- children: e.description || "無"
87
- }),
88
- title: "說明",
89
- width: 260
90
- },
91
- {
92
- dataIndex: "updatedAtLabel",
93
- key: "updatedAtLabel",
94
- title: "更新時間",
95
- width: 220
96
- }
97
- ], []);
98
- async function de(e) {
99
- Z(!0), K(null);
100
- try {
101
- J?.type === "EDIT" && J.record ? await k({
102
- ...e,
103
- id: J.record.id
104
- }) : await E(e), Y(null), await $();
105
- } catch (e) {
106
- throw K(F(e)), e;
107
- } finally {
108
- Z(!1);
109
- }
110
- }
111
- async function fe(e) {
112
- Z(!0), K(null);
113
- try {
114
- await k({
115
- description: e.description,
116
- id: e.id,
117
- isActive: !e.isActive,
118
- name: e.name,
119
- sortOrder: e.sortOrder
120
- }), await $();
121
- } catch (e) {
122
- K(F(e));
123
- } finally {
124
- Z(!1);
125
- }
126
- }
127
- async function pe() {
128
- if (U) {
129
- Z(!0), K(null);
130
- try {
131
- await D(U.id), W(null), await $();
132
- } catch (e) {
133
- K(F(e));
134
- } finally {
135
- Z(!1);
136
- }
137
- }
138
- }
139
- let me = a(() => ({
140
- render: (e) => [
141
- {
142
- name: "編輯",
143
- onClick: () => Y({
144
- record: e,
145
- type: "EDIT"
146
- })
147
- },
148
- {
149
- name: e.isActive ? "停用" : "啟用",
150
- onClick: () => void fe(e),
151
- variant: e.isActive ? "destructive-secondary" : "base-secondary"
152
- },
153
- {
154
- name: "刪除",
155
- onClick: () => W({
156
- id: e.id,
157
- name: e.name
158
- }),
159
- variant: "destructive-secondary"
160
- }
161
- ],
162
- variant: "base-secondary",
163
- width: 192
164
- }), [$]);
165
- return /* @__PURE__ */ S(b, { children: [
166
- /* @__PURE__ */ S(m, { children: [/* @__PURE__ */ x(t, { activeHref: n }), /* @__PURE__ */ S(m.Main, { children: [/* @__PURE__ */ x(g, { children: /* @__PURE__ */ x(w, {
167
- description: "維護簽核模板分類,供模板建立、篩選與列表標示使用。",
168
- title: "簽核模板分類",
169
- children: /* @__PURE__ */ x(c, {
170
- icon: C,
171
- iconType: "leading",
172
- onClick: () => Y({
173
- record: null,
174
- type: "CREATE"
175
- }),
176
- variant: "base-primary",
177
- children: "建立分類"
178
- })
179
- }) }), /* @__PURE__ */ x(ee, { children: /* @__PURE__ */ S(_, {
180
- filterArea: /* @__PURE__ */ x(u, {
181
- className: A.templateFilterArea,
182
- size: "sub",
183
- children: /* @__PURE__ */ x(d, { children: /* @__PURE__ */ x(l, {
184
- span: 3,
185
- children: /* @__PURE__ */ x(f, {
186
- fullWidth: !0,
187
- layout: T.VERTICAL,
188
- name: "categorySearchText",
189
- children: /* @__PURE__ */ x(p, {
190
- fullWidth: !0,
191
- onChange: (e) => {
192
- ce(e.target.value), I(1);
193
- },
194
- placeholder: "關鍵字:搜尋分類名稱或說明",
195
- size: "sub",
196
- value: Q,
197
- variant: "base"
198
- })
199
- })
200
- }) })
201
- }),
202
- tab: /* @__PURE__ */ x(te, {
203
- activeKey: z,
204
- onChange: (e) => {
205
- B(oe(e)), I(1);
206
- },
207
- children: M.map((e) => /* @__PURE__ */ x(ne, { children: e.label }, e.key))
208
- }),
209
- children: [G ? /* @__PURE__ */ x(y, {
210
- color: "text-error",
211
- variant: "body",
212
- children: G
213
- }) : null, /* @__PURE__ */ x(re, {
214
- actions: me,
215
- columns: ue,
216
- dataSource: le,
217
- fullWidth: !0,
218
- loading: se || X,
219
- pagination: {
220
- current: N,
221
- onChange: (e) => {
222
- I(e);
223
- },
224
- onChangePageSize: (e) => {
225
- I(1), R(e);
226
- },
227
- pageSize: L,
228
- pageSizeLabel: "每頁筆數",
229
- pageSizeOptions: j,
230
- renderResultSummary: (e, t, n) => `顯示 ${e}-${t} 筆,共 ${n} 筆`,
231
- showPageSizeOptions: !0,
232
- total: V
233
- }
234
- })]
235
- }) })] })] }),
236
- /* @__PURE__ */ x(ie, {
237
- loading: X,
238
- modal: J,
239
- onClose: () => Y(null),
240
- onSubmit: de
241
- }),
242
- /* @__PURE__ */ x(h, {
243
- cancelText: "取消",
244
- confirmButtonProps: { variant: "destructive-primary" },
245
- confirmText: "刪除",
246
- loading: X,
247
- modalStatusType: "error",
248
- modalType: "standard",
249
- onCancel: () => W(null),
250
- onClose: () => W(null),
251
- onConfirm: () => void pe(),
252
- open: !!U,
253
- showModalFooter: !0,
254
- showModalHeader: !0,
255
- size: "regular",
256
- supportingText: "若分類已被模板使用,系統會改為停用分類並保留既有模板關聯。",
257
- title: "刪除分類",
258
- children: /* @__PURE__ */ S(y, {
259
- color: "text-neutral",
260
- variant: "body",
261
- children: [
262
- "確定要刪除「",
263
- U?.name ?? "",
264
- "」嗎?"
265
- ]
266
- })
267
- })
268
- ] });
269
- }
270
- function ie({ loading: e, modal: t, onClose: r, onSubmit: a }) {
271
- let [s, c] = o(""), [l, u] = o(null), [d, f] = o(""), [m, g] = o("0");
272
- i(() => {
273
- t && (c(t.record?.description ?? ""), u(null), f(t.record?.name ?? ""), g(String(t.record?.sortOrder ?? 0)));
274
- }, [t]);
275
- async function _() {
276
- let e = d.trim(), n = Number(m);
277
- if (!e) {
278
- u("請輸入分類名稱");
279
- return;
280
- }
281
- if (!Number.isInteger(n)) {
282
- u("排序必須是整數");
283
- return;
284
- }
285
- try {
286
- await a({
287
- description: s.trim() || null,
288
- isActive: t?.record?.isActive ?? !0,
289
- name: e,
290
- sortOrder: n
291
- });
292
- } catch (e) {
293
- u(F(e));
294
- }
295
- }
296
- return /* @__PURE__ */ S(h, {
297
- cancelText: "取消",
298
- confirmButtonProps: { disabled: !d.trim() },
299
- confirmText: t?.type === "EDIT" ? "儲存" : "建立",
300
- loading: e,
301
- modalType: "standard",
302
- onCancel: r,
303
- onClose: r,
304
- onConfirm: () => void _(),
305
- open: !!t,
306
- showModalFooter: !0,
307
- showModalHeader: !0,
308
- size: "regular",
309
- title: t?.type === "EDIT" ? "編輯分類" : "建立分類",
310
- children: [/* @__PURE__ */ S("div", {
311
- className: A.templateModalFields,
312
- children: [
313
- /* @__PURE__ */ x(n, {
314
- label: "分類名稱",
315
- name: "categoryName",
316
- required: !0,
317
- children: /* @__PURE__ */ x(p, {
318
- autoFocus: !0,
319
- fullWidth: !0,
320
- onChange: (e) => {
321
- f(e.target.value), u(null);
322
- },
323
- placeholder: "例如:行政管理",
324
- value: d,
325
- variant: "base"
326
- })
327
- }),
328
- /* @__PURE__ */ x(n, {
329
- label: "排序",
330
- name: "categorySortOrder",
331
- children: /* @__PURE__ */ x(p, {
332
- fullWidth: !0,
333
- onChange: (e) => {
334
- g(e.target.value), u(null);
335
- },
336
- placeholder: "0",
337
- value: m,
338
- variant: "base"
339
- })
340
- }),
341
- /* @__PURE__ */ x(n, {
342
- label: "說明",
343
- name: "categoryDescription",
344
- children: /* @__PURE__ */ x(v, {
345
- onChange: (e) => {
346
- c(e.target.value), u(null);
347
- },
348
- placeholder: "補充分類用途",
349
- value: s
350
- })
351
- })
352
- ]
353
- }), l ? /* @__PURE__ */ x(y, {
354
- color: "text-error",
355
- variant: "body",
356
- children: l
357
- }) : null]
358
- });
359
- }
360
- function ae({ isActive: e }) {
361
- return e ? /* @__PURE__ */ x(s, {
362
- size: "sub",
363
- text: "啟用",
364
- variant: "dot-success"
365
- }) : /* @__PURE__ */ x(s, {
366
- size: "sub",
367
- text: "停用",
368
- variant: "dot-inactive"
369
- });
370
- }
371
- function oe(e) {
372
- return e === "ACTIVE" || e === "INACTIVE" ? e : "ALL";
373
- }
374
- function P(e) {
375
- return e;
376
- }
377
- function F(e) {
378
- return e instanceof Error ? e.message : "發生未知錯誤";
379
- }
380
- //#endregion
381
- export { A as n, N as t };
382
-
383
- //# sourceMappingURL=categories-DG4k7S8V.js.map