@rytass/bpm-core-react 0.3.7 → 0.4.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 +138 -0
- package/README.md +69 -4
- package/dist/chunks/approval-instance-list-page-BtEc8Cs3.js +278 -0
- package/dist/chunks/approval-instance-list-page-BtEc8Cs3.js.map +1 -0
- package/dist/chunks/approval-instance-list-page-UNIIgUZy.cjs +2 -0
- package/dist/chunks/approval-instance-list-page-UNIIgUZy.cjs.map +1 -0
- package/dist/chunks/auth-provider-D2P-qWmY.cjs +2 -0
- package/dist/chunks/auth-provider-D2P-qWmY.cjs.map +1 -0
- package/dist/chunks/auth-provider-TTO9eNZV.js +83 -0
- package/dist/chunks/auth-provider-TTO9eNZV.js.map +1 -0
- package/dist/chunks/{builder-D950gct_.js → builder-C3E-8OJu.js} +474 -478
- package/dist/chunks/builder-C3E-8OJu.js.map +1 -0
- package/dist/chunks/builder-f-Q_0NUs.cjs +3 -0
- package/dist/chunks/builder-f-Q_0NUs.cjs.map +1 -0
- package/dist/chunks/categories-B6QZKZRt.cjs +2 -0
- package/dist/chunks/categories-B6QZKZRt.cjs.map +1 -0
- package/dist/chunks/categories-DBPoSrsi.js +382 -0
- package/dist/chunks/categories-DBPoSrsi.js.map +1 -0
- package/dist/chunks/chunk-CMqjfN_6.cjs +1 -0
- package/dist/chunks/dashboard-page-CQRBJxze.js +119 -0
- package/dist/chunks/dashboard-page-CQRBJxze.js.map +1 -0
- package/dist/chunks/dashboard-page-DrDChhg1.cjs +2 -0
- package/dist/chunks/dashboard-page-DrDChhg1.cjs.map +1 -0
- package/dist/chunks/delegations-CFXaJrdX.cjs +2 -0
- package/dist/chunks/delegations-CFXaJrdX.cjs.map +1 -0
- package/dist/chunks/delegations-D5pPEWsP.js +641 -0
- package/dist/chunks/delegations-D5pPEWsP.js.map +1 -0
- package/dist/chunks/delegations-DwbYkNUg.cjs +2 -0
- package/dist/chunks/delegations-DwbYkNUg.cjs.map +1 -0
- package/dist/chunks/delegations-FTLaWo1Y.js +568 -0
- package/dist/chunks/delegations-FTLaWo1Y.js.map +1 -0
- package/dist/chunks/detail-B9JkYNHc.cjs +2 -0
- package/dist/chunks/detail-B9JkYNHc.cjs.map +1 -0
- package/dist/chunks/detail-CSxI04gB.js +1518 -0
- package/dist/chunks/detail-CSxI04gB.js.map +1 -0
- package/dist/chunks/format-date-time-XxBzF0F5.cjs +2 -0
- package/dist/chunks/{format-date-time-26_pFvv4.cjs.map → format-date-time-XxBzF0F5.cjs.map} +1 -1
- package/dist/chunks/login-BfmfCclF.cjs +2 -0
- package/dist/chunks/{login-CQ9MfwcC.cjs.map → login-BfmfCclF.cjs.map} +1 -1
- package/dist/chunks/{login-C20yVxbc.js → login-xgI4wLHe.js} +3 -2
- package/dist/chunks/{login-C20yVxbc.js.map → login-xgI4wLHe.js.map} +1 -1
- package/dist/chunks/notifications-BoNa1BXD.js +193 -0
- package/dist/chunks/notifications-BoNa1BXD.js.map +1 -0
- package/dist/chunks/notifications-a-FCxV02.cjs +2 -0
- package/dist/chunks/notifications-a-FCxV02.cjs.map +1 -0
- package/dist/chunks/orgs-BIiqzHvb.cjs +2 -0
- package/dist/chunks/orgs-BIiqzHvb.cjs.map +1 -0
- package/dist/chunks/orgs-Cc18umVt.js +1944 -0
- package/dist/chunks/orgs-Cc18umVt.js.map +1 -0
- package/dist/chunks/router-adapter-BdHZXLS3.js +23 -0
- package/dist/chunks/router-adapter-BdHZXLS3.js.map +1 -0
- package/dist/chunks/router-adapter-BybHrCNP.cjs +2 -0
- package/dist/chunks/router-adapter-BybHrCNP.cjs.map +1 -0
- package/dist/chunks/routes-config-2aKbWq2H.cjs.map +1 -1
- package/dist/chunks/routes-config-dxahImVe.js.map +1 -1
- package/dist/chunks/templates-CL8bPvgn.cjs +2 -0
- package/dist/chunks/templates-CL8bPvgn.cjs.map +1 -0
- package/dist/chunks/templates-DNfDOPGm.js +380 -0
- package/dist/chunks/templates-DNfDOPGm.js.map +1 -0
- package/dist/chunks/users-CUY139DF.js +214 -0
- package/dist/chunks/users-CUY139DF.js.map +1 -0
- package/dist/chunks/users-qghSMtLn.cjs +2 -0
- package/dist/chunks/users-qghSMtLn.cjs.map +1 -0
- package/dist/components/approval-instance-list-page.d.ts +1 -2
- package/dist/components/bpm-notification-bell-button.d.ts +22 -0
- package/dist/components/dashboard-page.d.ts +1 -4
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +206 -97
- package/dist/index.js.map +1 -1
- package/dist/lib/notification-drawer-provider.d.ts +3 -2
- package/dist/lib/notification-unread-provider.d.ts +6 -5
- package/dist/lib/providers.d.ts +3 -2
- package/dist/lib/router-adapter.d.ts +2 -2
- package/dist/lib/routes-config.d.ts +11 -3
- package/dist/lib/use-bpm-logout.d.ts +12 -0
- package/dist/lib/use-bpm-member.d.ts +11 -0
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.js +1 -1
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.js +1 -1
- package/dist/pages/admin/users/index.cjs +1 -1
- package/dist/pages/admin/users/index.js +1 -1
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.js +1 -1
- package/dist/pages/forms/builder/index.cjs +1 -1
- package/dist/pages/forms/builder/index.js +1 -1
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/login/index.cjs +1 -1
- package/dist/pages/login/index.js +1 -1
- package/dist/pages/settings/notifications/index.cjs +1 -1
- package/dist/pages/settings/notifications/index.js +1 -1
- package/dist/pages/templates/categories/index.cjs +1 -1
- package/dist/pages/templates/categories/index.js +1 -1
- package/dist/pages/templates/index.cjs +1 -1
- package/dist/pages/templates/index.js +1 -1
- package/dist/views/admin/delegations/AdminDelegationsView.d.ts +1 -4
- package/dist/views/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +3 -3
- package/dist/views/admin/orgs/AdminOrgsView.d.ts +1 -4
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -1
- package/dist/views/admin/users/AdminUsersView.d.ts +1 -4
- package/dist/views/admin/users/index.cjs +1 -1
- package/dist/views/admin/users/index.js +1 -1
- package/dist/views/cc/CcView.d.ts +1 -3
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.cjs.map +1 -1
- package/dist/views/cc/index.js +2 -3
- package/dist/views/cc/index.js.map +1 -1
- package/dist/views/dashboard/DashboardView.d.ts +1 -3
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.cjs.map +1 -1
- package/dist/views/dashboard/index.js +3 -3
- package/dist/views/dashboard/index.js.map +1 -1
- package/dist/views/delegations/DelegationsView.d.ts +1 -4
- package/dist/views/delegations/index.cjs +1 -1
- package/dist/views/delegations/index.js +1 -1
- package/dist/views/forms/FormsView.d.ts +1 -3
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/index.cjs +1 -1
- package/dist/views/forms/index.cjs.map +1 -1
- package/dist/views/forms/index.js +95 -99
- package/dist/views/forms/index.js.map +1 -1
- package/dist/views/inbox/InboxView.d.ts +1 -3
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.cjs.map +1 -1
- package/dist/views/inbox/index.js +91 -94
- package/dist/views/inbox/index.js.map +1 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.cjs.map +1 -1
- package/dist/views/instances/new/index.js +71 -77
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/login/index.cjs +1 -1
- package/dist/views/login/index.js +1 -1
- package/dist/views/root/RootView.d.ts +1 -3
- package/dist/views/search/SearchView.d.ts +1 -3
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.cjs.map +1 -1
- package/dist/views/search/index.js +2 -3
- package/dist/views/search/index.js.map +1 -1
- package/dist/views/sent/SentView.d.ts +1 -3
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.cjs.map +1 -1
- package/dist/views/sent/index.js +2 -3
- package/dist/views/sent/index.js.map +1 -1
- package/dist/views/settings/index.cjs +1 -1
- package/dist/views/settings/index.js +1 -1
- package/dist/views/settings/notifications/SettingsNotificationsView.d.ts +1 -4
- package/dist/views/settings/notifications/index.cjs +1 -1
- package/dist/views/settings/notifications/index.js +1 -1
- package/dist/views/templates/TemplatesView.d.ts +1 -4
- package/dist/views/templates/categories/TemplateCategoriesView.d.ts +1 -4
- package/dist/views/templates/categories/index.cjs +1 -1
- package/dist/views/templates/categories/index.js +1 -1
- package/dist/views/templates/designer/TemplateDesignerView.d.ts +1 -2
- package/dist/views/templates/designer/index.cjs +7 -7
- package/dist/views/templates/designer/index.cjs.map +1 -1
- package/dist/views/templates/designer/index.js +707 -711
- package/dist/views/templates/designer/index.js.map +1 -1
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.js +2 -2
- package/dist/views/templates/versions/TemplateVersionsView.d.ts +1 -2
- 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 +45 -49
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/app-navigation.css +0 -1
- package/dist/chunks/app-navigation-BSkMsEhy.js +0 -268
- package/dist/chunks/app-navigation-BSkMsEhy.js.map +0 -1
- package/dist/chunks/app-navigation-KnlJCUp1.cjs +0 -2
- package/dist/chunks/app-navigation-KnlJCUp1.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs +0 -2
- package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-CqNdoZqx.js +0 -282
- package/dist/chunks/approval-instance-list-page-CqNdoZqx.js.map +0 -1
- package/dist/chunks/auth-provider-BV8Iiwfb.cjs +0 -2
- package/dist/chunks/auth-provider-BV8Iiwfb.cjs.map +0 -1
- package/dist/chunks/auth-provider-Bnox5gsx.js +0 -98
- package/dist/chunks/auth-provider-Bnox5gsx.js.map +0 -1
- package/dist/chunks/builder-CMlJfQHE.cjs +0 -3
- package/dist/chunks/builder-CMlJfQHE.cjs.map +0 -1
- package/dist/chunks/builder-D950gct_.js.map +0 -1
- package/dist/chunks/categories-5yEM3p3N.cjs +0 -2
- package/dist/chunks/categories-5yEM3p3N.cjs.map +0 -1
- package/dist/chunks/categories-BIpOG451.js +0 -387
- package/dist/chunks/categories-BIpOG451.js.map +0 -1
- package/dist/chunks/dashboard-page-1K_jQXQk.cjs +0 -2
- package/dist/chunks/dashboard-page-1K_jQXQk.cjs.map +0 -1
- package/dist/chunks/dashboard-page-R_T2OEiE.js +0 -122
- package/dist/chunks/dashboard-page-R_T2OEiE.js.map +0 -1
- package/dist/chunks/delegations-B2j-wNEO.js +0 -646
- package/dist/chunks/delegations-B2j-wNEO.js.map +0 -1
- package/dist/chunks/delegations-CsB9ozLu.cjs +0 -2
- package/dist/chunks/delegations-CsB9ozLu.cjs.map +0 -1
- package/dist/chunks/delegations-CvtwTXNP.cjs +0 -2
- package/dist/chunks/delegations-CvtwTXNP.cjs.map +0 -1
- package/dist/chunks/delegations-dKodb0WW.js +0 -573
- package/dist/chunks/delegations-dKodb0WW.js.map +0 -1
- package/dist/chunks/detail-BcGAqJ_R.js +0 -1523
- package/dist/chunks/detail-BcGAqJ_R.js.map +0 -1
- package/dist/chunks/detail-CqjqLd65.cjs +0 -2
- package/dist/chunks/detail-CqjqLd65.cjs.map +0 -1
- package/dist/chunks/format-date-time-26_pFvv4.cjs +0 -2
- package/dist/chunks/login-CQ9MfwcC.cjs +0 -2
- package/dist/chunks/notifications-2swRqDPF.js +0 -198
- package/dist/chunks/notifications-2swRqDPF.js.map +0 -1
- package/dist/chunks/notifications-BaYDebFt.cjs +0 -2
- package/dist/chunks/notifications-BaYDebFt.cjs.map +0 -1
- package/dist/chunks/orgs-CuHxxd_n.js +0 -1949
- package/dist/chunks/orgs-CuHxxd_n.js.map +0 -1
- package/dist/chunks/orgs-YMiVLNvL.cjs +0 -2
- package/dist/chunks/orgs-YMiVLNvL.cjs.map +0 -1
- package/dist/chunks/templates-DTkbSgFY.cjs +0 -2
- package/dist/chunks/templates-DTkbSgFY.cjs.map +0 -1
- package/dist/chunks/templates-DoDWM68t.js +0 -384
- package/dist/chunks/templates-DoDWM68t.js.map +0 -1
- package/dist/chunks/users-3ySyUW4u.cjs +0 -2
- package/dist/chunks/users-3ySyUW4u.cjs.map +0 -1
- package/dist/chunks/users-sMfrSjRQ.js +0 -219
- package/dist/chunks/users-sMfrSjRQ.js.map +0 -1
- package/dist/components/app-navigation.d.ts +0 -41
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder-C3E-8OJu.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 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 {\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 { useBPMRoutes } from '../../../lib/routes-config';\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 routes = useBPMRoutes();\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(routes.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 <>\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 </>\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,IAAuC;CAC3C,YAAY;CACZ,QAAQ;CACR,cAAc;CACd,OAAO;CACP,SAAS;CACT,WAAW;CACX,SAAS;CACT,OAAO;AACT,GAEM,KAA+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,IAAa,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,GAAD;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,EAAsB;EAC9B;EACR,eAAe;EACL;EACG;EACb,UAAU;EACV,OAAM;EACC;EACP,OAAM;CACP,CAAA;AAEL;;;AC8CA,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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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";const e=require("./chunk-CMqjfN_6.cjs"),t=require("./router-adapter-BybHrCNP.cjs"),n=require("./format-date-time-XxBzF0F5.cjs"),r=require("./routes-config-2aKbWq2H.cjs"),i=require("./bpm-form-field-Bc6k4ZEO.cjs"),a=require("./FormRendererView-BwVsH2eX.cjs"),o=require("./form-name-modal-uZCHbtRH.cjs");let s=require("react"),c=require("@mezzanine-ui/react"),l=require("react/jsx-runtime"),u=require("@mezzanine-ui/react/ContentHeader");u=e.t(u,1);let d=require("@mezzanine-ui/icons"),f=require("@rytass/bpm-core-client/form"),p=require("@hello-pangea/dnd"),m=require("next/dynamic");m=e.t(m,1);let h=require("@codemirror/lang-json"),g=require("@codemirror/view");var _={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%`},ee=[(0,h.json)(),g.EditorView.lineWrapping,g.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`}})],v=(0,m.default)(()=>import(`@uiw/react-codemirror`),{loading:()=>(0,l.jsx)(`div`,{style:_,children:`載入 JSON 編輯器`}),ssr:!1});function te({disabled:e,height:t,name:n,onChange:r,placeholder:i,value:a}){return(0,l.jsx)(v,{"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:[...ee],height:t,indentWithTab:!1,onChange:r,placeholder:i,readOnly:e,theme:`light`,value:a,width:`100%`})}var ne=[{description:`單行文字、姓名、編號`,icon:d.AlignLeftIcon,label:`文字`,type:`text`},{description:`多行補充內容`,icon:d.FileIcon,label:`長文字`,type:`textarea`},{description:`金額、數量、分數`,icon:d.CurrencyDollarIcon,label:`數字`,type:`number`},{description:`金額與費用`,icon:d.CurrencyDollarIcon,label:`金額`,type:`money`},{description:`日期或到期日`,icon:d.CalendarIcon,label:`日期`,type:`date`},{description:`日期與時間`,icon:d.CalendarIcon,label:`日期時間`,type:`datetime`},{description:`是 / 否狀態`,icon:d.CheckedIcon,label:`開關`,type:`boolean`},{description:`固定選項擇一`,icon:d.ListIcon,label:`下拉選單`,type:`select`},{description:`固定選項單選`,icon:d.DotGridIcon,label:`單選`,type:`radio`},{description:`固定選項複選`,icon:d.CheckedOutlineIcon,label:`複選`,type:`checkbox`},{description:`附件或佐證資料`,icon:d.FileAttachmentIcon,label:`附件`,type:`file_upload`}],re={alignItems:`start`,display:`flex`,flexWrap:`wrap`,gap:16},ie={flex:`0.55 1 300px`,minWidth:0},ae={flex:`1.45 1 720px`,minWidth:620},y={display:`grid`,gap:12},oe={display:`flex`,flexWrap:`wrap`,gap:6},se={flex:`0 0 auto`,whiteSpace:`nowrap`},ce={display:`grid`,gap:8},le={alignItems:`center`,cursor:`grab`,display:`flex`,gap:12,touchAction:`none`},ue={display:`grid`,flex:`1 1 auto`,gap:2,minWidth:0},de={alignItems:`center`,display:`flex`,flex:`0 0 auto`,gap:4},fe={alignItems:`center`,display:`flex`,gap:6},pe={userSelect:`none`},me={filter:`drop-shadow(0 8px 18px rgba(0, 0, 0, 0.12))`},he={alignItems:`center`,border:`1px dashed var(--mzn-color-border-neutral)`,borderRadius:6,display:`grid`,gap:12,minHeight:240,padding:32,textAlign:`center`},ge={display:`flex`,gap:8,justifyContent:`center`},_e={display:`grid`,gap:14},ve={display:`grid`,columnGap:16,gridTemplateColumns:`repeat(auto-fit, minmax(280px, 1fr))`,rowGap:8},ye={gridColumn:`1 / -1`},be={alignItems:`center`,display:`flex`,gap:8,gridColumn:`1 / -1`,justifyContent:`flex-end`},xe={gridColumn:`1 / -1`},Se={alignItems:`start`,display:`block`,width:`100%`},Ce={...Se,gridColumn:`1 / -1`},we={minWidth:0,width:`100%`},Te={minWidth:`100%`,width:`100%`},Ee={display:`grid`,gap:14},De={alignItems:`start`,display:`block`,width:`100%`},Oe={minWidth:0,width:`100%`},ke={gridColumn:`2 / -1`},Ae={display:`grid`,gap:10,width:`100%`},je={display:`grid`,gap:8,gridTemplateColumns:`repeat(auto-fit, minmax(160px, 1fr))`},Me={display:`inline-flex`},Ne={display:`grid`,gap:16},Pe={display:`grid`,gap:8},Fe={display:`flex`,justifyContent:`flex-end`},Ie={color:`var(--mzn-color-text-error)`,fontSize:`0.72em`,lineHeight:0,marginLeft:2,verticalAlign:`super`};function Le(e){e&&(e.style.width=`100%`)}var b={fields:[],schemaVersion:1},x={layout:[],schemaVersion:1},Re=[{id:`unset`,name:`不預設`},{id:`true`,name:`是`},{id:`false`,name:`否`}],ze=[{id:`true`,name:`是`},{id:`false`,name:`否`}],Be=[{label:`顯示`,name:`fieldVisibleWhen`,supportingText:`符合條件時才顯示這個欄位。`,target:`visibleWhen`},{label:`必填`,name:`fieldRequiredWhen`,supportingText:`符合條件時才要求填寫這個欄位。`,target:`requiredWhen`},{label:`唯讀`,name:`fieldReadonlyWhen`,supportingText:`符合條件時不允許修改這個欄位。`,target:`readonlyWhen`}];function S({formId:e}){let m=t.r(),h=r.r(),g=e,[_,ee]=(0,s.useState)(null),[v,S]=(0,s.useState)(null),[T,D]=(0,s.useState)(b),[k,A]=(0,s.useState)(x),[$e,j]=(0,s.useState)(w(b)),[et,M]=(0,s.useState)(w(x)),[tt,nt]=(0,s.useState)({}),[rt,N]=(0,s.useState)(null),[P,it]=(0,s.useState)(`design`),[F,I]=(0,s.useState)(null),[at,L]=(0,s.useState)(null),[ot,R]=(0,s.useState)(!1),[st,ct]=(0,s.useState)(E(b,x)),[lt,ut]=(0,s.useState)(!0),[dt,ft]=(0,s.useState)(!1),[z,B]=(0,s.useState)(!1);(0,s.useEffect)(()=>{W()},[g]),(0,s.useEffect)(()=>{T.fields.some(e=>e.fieldKey===F)||I(T.fields[0]?.fieldKey??null)},[T.fields,F]),(0,s.useEffect)(()=>{nt(e=>(0,f.buildFormRendererValues)(T.fields,e))},[T.fields]),(0,s.useEffect)(()=>{P!==`advanced`&&(j(w(T)),M(w(k)))},[P,T,k]);let V=(0,s.useMemo)(()=>T.fields.find(e=>e.fieldKey===F)??T.fields[0]??null,[T.fields,F]),pt=(0,s.useMemo)(()=>(_?.versions??[]).map(e=>({key:e.id,publishedAt:n.t(e.publishedAt),status:e.status,updatedAt:n.t(e.updatedAt),version:`v${e.version}`})),[_]),mt=(0,s.useMemo)(()=>[{dataIndex:`version`,key:`version`,title:`版本`,width:120},{key:`status`,render:e=>(0,l.jsx)(Qe,{status:e.status}),title:`狀態`,width:140},{dataIndex:`updatedAt`,key:`updatedAt`,title:`最後更新`,width:180},{dataIndex:`publishedAt`,key:`publishedAt`,title:`發布時間`,width:180}],[]),ht=(0,s.useMemo)(()=>E(T,k),[T,k]),H=ht.schemaJson!==st.schemaJson||ht.uiSchemaJson!==st.uiSchemaJson;(0,s.useEffect)(()=>{function e(e){H&&(e.preventDefault(),e.returnValue=``)}return window.addEventListener(`beforeunload`,e),()=>{window.removeEventListener(`beforeunload`,e)}},[H]);function gt(){H&&!window.confirm(`目前有尚未儲存的表單草稿,確定要離開嗎?`)||m.push(h.forms())}let _t=(0,s.useMemo)(()=>Ye(_?.versions??[],_?.definition.currentVersionId),[_?.definition.currentVersionId,_?.versions]),vt=v??_t??_?.versions[0]??null,U=!H&&vt?.status===`PUBLISHED`,yt=Xe({hasUnsavedChanges:H,latestPublishedVersion:_t,openedContentPublished:U,openedVersion:vt}),bt=z||!H&&U&&!v,xt=H?`保存並發布`:v?`發布草稿`:U?`已發布`:`發布版本`;async function W(){ut(!0),L(null);try{let e=await(0,f.readFormBuilder)(g),t=e.versions.find(e=>e.status===`DRAFT`)??null;ee(e),S(t);let n=t?.schema??e.versions[0]?.schema??b,r=t?.uiSchema??e.versions[0]?.uiSchema??x;D(n),A(r),ct(E(n,r)),j(w(n)),M(w(r)),I(t?.schema.fields[0]?.fieldKey??e.versions[0]?.schema.fields[0]?.fieldKey??null),N(null)}catch(e){L(O(e))}finally{ut(!1)}}async function St(){let e=await(0,f.updateFormDefinitionDraft)((v??await(0,f.forkFormDefinition)(g)).id,T,k);return S(e),e}async function Ct(){B(!0),L(null);try{await St(),await W()}catch(e){L(O(e))}finally{B(!1)}}async function wt(){B(!0),L(null);try{await(0,f.publishFormDefinitionVersion)((await St()).id),await W()}catch(e){L(O(e))}finally{B(!1)}}async function Tt(e){if(!_)throw Error(`尚未載入表單資料`);ft(!0);try{let t=await(0,f.updateFormDefinition)(_.definition.id,e);ee({..._,definition:t}),R(!1)}finally{ft(!1)}}function G(e){let t=(0,f.createFieldDefinition)(e,T.fields.length+1);D({...T,fields:[...T.fields,t]}),A({...k,layout:[...k.layout,{fieldKey:t.fieldKey,width:e===`textarea`||e===`file_upload`?`FULL`:`HALF`}]}),I(t.fieldKey),it(`design`),N(null)}function Et(e){let t=e;t===`advanced`&&P!==`advanced`&&(j(w(T)),M(w(k))),it(t)}function Dt(e){let t=T.fields.filter(t=>t.fieldKey!==e);D({...T,fields:t}),A({...k,layout:k.layout.filter(t=>t.fieldKey!==e)}),I(F===e?t[0]?.fieldKey??null:F),N(null)}function Ot(e){let t=e.destination;t&&e.source.index!==t.index&&(D(n=>({...n,fields:Ze(n.fields,e.source.index,t.index)})),A(n=>({...n,layout:Ze(n.layout,e.source.index,t.index)})),N(null))}function K(e){q(t=>({...t,...e}))}function q(e){if(!V)return;let t=V.fieldKey,n=e(V),r=n.fieldKey;D({...T,fields:T.fields.map(e=>e.fieldKey===t?n:e)}),A({...k,layout:k.layout.map(e=>e.fieldKey===t?{...e,fieldKey:r}:e)}),I(r),N(null)}function J(e){q(t=>We(t)?{...t,...e}:t)}function Y(e){q(t=>(0,f.isNumberFieldDefinition)(t)?{...t,...e}:t)}function kt(e){q(t=>(0,f.isDateFieldDefinition)(t)?{...t,...e}:t)}function X(e){q(t=>(0,f.isSelectFieldDefinition)(t)?{...t,...e}:t)}function At(e){q(t=>t.type===`boolean`?{...t,...e}:t)}function jt(e){q(t=>t.type===`file_upload`?{...t,...e}:t)}function Mt(e){nt(e)}function Nt(e,t){D(n=>({...n,fields:n.fields.map(n=>n.fieldKey===e?{...n,required:t}:n)})),N(null)}function Pt(e){j(e);try{D(JSON.parse(e)),N(null)}catch{N(`Form Schema JSON 格式不正確`)}}function Ft(e){M(e);try{A(JSON.parse(e)),N(null)}catch{N(`UI Schema JSON 格式不正確`)}}return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.PageHeader,{children:(0,l.jsxs)(u.default,{description:yt,onBackClick:gt,title:_?.definition.name??`表單設計器`,children:[(0,l.jsx)(c.Button,{"aria-label":`修改表單名稱`,disabled:dt||!_,icon:d.EditIcon,iconType:`icon-only`,onClick:()=>R(!0),variant:`base-ghost`,children:`修改表單名稱`}),(0,l.jsx)(c.Button,{"aria-label":`儲存草稿`,disabled:z||!H,icon:d.SaveIcon,iconType:`icon-only`,onClick:()=>void Ct(),variant:`base-secondary`,children:`儲存草稿`}),(0,l.jsx)(c.Button,{disabled:bt,icon:d.CheckedIcon,iconType:`leading`,onClick:()=>void wt(),variant:`base-primary`,children:xt})]})}),(0,l.jsx)(c.SectionGroup,{children:(0,l.jsx)(c.Section,{children:(0,l.jsxs)(`div`,{style:Ne,children:[at?(0,l.jsx)(c.Typography,{color:`text-error`,variant:`body`,children:at}):null,(0,l.jsxs)(c.Tab,{activeKey:P,onChange:Et,size:`sub`,children:[(0,l.jsx)(c.TabItem,{children:`設計`},`design`),(0,l.jsx)(c.TabItem,{children:`預覽`},`preview`),(0,l.jsx)(c.TabItem,{children:`版本`},`versions`),(0,l.jsx)(c.TabItem,{children:`進階`},`advanced`)]}),P===`design`?It():null,P===`preview`?tn():null,P===`versions`?nn():null,P===`advanced`?rn():null]})})})]}),(0,l.jsx)(o.t,{confirmText:`儲存`,initialName:_?.definition.name??``,loading:dt,onClose:()=>R(!1),onSubmit:Tt,open:ot,title:`修改表單名稱`})]});function It(){return(0,l.jsxs)(`div`,{style:y,children:[(0,l.jsxs)(`div`,{style:ce,children:[(0,l.jsx)(c.Typography,{component:`h2`,variant:`label-primary`,children:`新增欄位`}),(0,l.jsx)(`div`,{style:oe,children:ne.map(e=>(0,l.jsx)(c.Button,{disabled:z,icon:e.icon,iconType:`leading`,onClick:()=>G(e.type),size:`sub`,style:se,type:`button`,variant:`base-secondary`,children:e.label},e.type))})]}),(0,l.jsxs)(`div`,{style:re,children:[(0,l.jsxs)(`div`,{style:{...y,...ie},children:[(0,l.jsx)(c.Typography,{component:`h2`,variant:`label-primary`,children:`表單畫布`}),T.fields.length>0?(0,l.jsx)(p.DragDropContext,{onDragEnd:Ot,children:(0,l.jsx)(p.Droppable,{droppableId:`form-builder-fields`,children:e=>(0,l.jsxs)(`div`,{...e.droppableProps,ref:e.innerRef,style:y,children:[T.fields.map((e,t)=>(0,l.jsx)(p.Draggable,{draggableId:e.fieldKey,index:t,isDragDisabled:z,children:(t,n)=>$t(e,t,n.isDragging)},e.fieldKey)),e.placeholder]})})}):(0,l.jsxs)(`div`,{style:he,children:[(0,l.jsxs)(`div`,{style:y,children:[(0,l.jsx)(c.Typography,{component:`h3`,variant:`h3`,children:`尚未建立欄位`}),(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`從上方新增第一個欄位,或直接建立常用文字欄位開始設計。`})]}),(0,l.jsxs)(`div`,{style:ge,children:[(0,l.jsx)(c.Button,{disabled:z,onClick:()=>G(`text`),variant:`base-primary`,children:`新增文字欄位`}),(0,l.jsx)(c.Button,{disabled:z,onClick:()=>G(`textarea`),variant:`base-secondary`,children:`新增長文字`})]})]})]}),(0,l.jsxs)(`div`,{style:{...y,...ae},children:[(0,l.jsx)(c.Typography,{component:`h2`,variant:`label-primary`,children:`欄位設定`}),V?Lt(V):(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`請先新增或選取欄位。`})]})]})]})}function Lt(e){return(0,l.jsxs)(`div`,{style:_e,children:[Rt(e),zt(e)]})}function Rt(e){return(0,l.jsxs)(`div`,{style:ve,children:[(0,l.jsx)(`div`,{style:be,children:(0,l.jsx)(c.Badge,{size:`main`,text:Ve(e.type),variant:`text-info`})}),$(`標題`,`fieldLabel`,(0,l.jsx)(c.Input,{onChange:e=>K({label:e.target.value}),placeholder:`例如:申請金額`,value:e.label,variant:`base`}),z),$(`欄位 Key`,`fieldKey`,(0,l.jsx)(c.Input,{onChange:e=>K({fieldKey:e.target.value}),placeholder:`例如:amount`,value:e.fieldKey,variant:`base`}),z),$(`提示文字`,`fieldPlaceholder`,(0,l.jsx)(c.Input,{onChange:e=>K({placeholder:e.target.value||void 0}),placeholder:`例如:請輸入申請金額`,value:e.placeholder??``,variant:`base`}),z),Bt(e)]})}function zt(e){return(0,l.jsx)(c.Accordion,{defaultExpanded:He(e),size:`sub`,title:`進階設定`,children:(0,l.jsxs)(`div`,{style:ve,children:[(0,l.jsx)(c.Typography,{component:`h3`,style:ye,variant:`label-primary`,children:`條件規則`}),(0,l.jsx)(c.Typography,{color:`text-neutral`,style:xe,variant:`body`,children:`只有需要根據其他欄位改變顯示、必填或唯讀狀態時才需要設定。`}),qt(e)]})})}function Bt(e){return We(e)?Vt(e):(0,f.isNumberFieldDefinition)(e)?Ht(e):(0,f.isDateFieldDefinition)(e)?Ut(e):(0,f.isSelectFieldDefinition)(e)?Wt(e):e.type===`boolean`?Gt(e):Kt(e)}function Vt(e){return(0,l.jsxs)(l.Fragment,{children:[$(`預設值`,`fieldDefaultValue`,e.type===`textarea`?Xt({disabled:z,name:`fieldDefaultValue`,onChange:e=>J({defaultValue:e||void 0}),placeholder:`輸入此欄位的預設文字`,rows:3,value:C(e.defaultValue)}):(0,l.jsx)(c.Input,{onChange:e=>J({defaultValue:e.target.value||void 0}),placeholder:`輸入此欄位的預設文字`,value:C(e.defaultValue),variant:`base`}),z),$(`最小長度`,`fieldMinLength`,Q(e.minLength,e=>J({minLength:e}),`例如:2`,{min:0}),z),$(`最大長度`,`fieldMaxLength`,Q(e.maxLength,e=>J({maxLength:e}),`例如:100`,{min:1}),z)]})}function Ht(e){return(0,l.jsxs)(l.Fragment,{children:[$(`預設值`,`fieldDefaultValue`,Q(typeof e.defaultValue==`number`?e.defaultValue:void 0,e=>Y({defaultValue:e}),e.type===`money`?`例如:1000`:`輸入預設數值`,{max:e.maximum,min:e.minimum}),z),$(`最小值`,`fieldMinimum`,Q(e.minimum,e=>Y({minimum:e}),`例如:0`),z),$(`最大值`,`fieldMaximum`,Q(e.maximum,e=>Y({maximum:e}),`例如:999999`),z)]})}function Ut(e){return $(`預設值`,`fieldDefaultValue`,Zt(e,C(e.defaultValue),e=>kt({defaultValue:e})),z)}function Wt(e){let t=Array.isArray(e.defaultValue)?e.defaultValue:[],n=e.options.filter(e=>t.includes(e.value)).map(f.readFieldOptionAsSelectOption);return(0,l.jsxs)(l.Fragment,{children:[$(`預設值`,`fieldDefaultValue`,e.type===`checkbox`?(0,l.jsx)(c.Select,{clearable:!0,mode:`multiple`,onChange:e=>X({defaultValue:e.length?e.map(e=>e.id):void 0}),options:e.options.map(f.readFieldOptionAsSelectOption),placeholder:`選擇一或多個預設選項`,value:n}):(0,l.jsx)(c.Select,{clearable:!0,onChange:e=>X({defaultValue:e?.id||void 0}),options:e.options.map(f.readFieldOptionAsSelectOption),placeholder:`選擇預設選項`,value:typeof e.defaultValue==`string`?(0,f.readSelectOption)(e.options.map(f.readFieldOptionAsSelectOption),e.defaultValue):null}),z),$(`選項`,`fieldOptions`,Qt(e),z,!0)]})}function Gt(e){let t=typeof e.defaultValue==`boolean`?String(e.defaultValue):`unset`;return $(`預設值`,`fieldDefaultValue`,(0,l.jsx)(c.Select,{clearable:!1,onChange:e=>At({defaultValue:e?.id===`true`?!0:e?.id===`false`?!1:void 0}),options:[...Re],placeholder:`選擇預設狀態`,value:(0,f.readSelectOption)(Re,t)}),z)}function Kt(e){return(0,l.jsxs)(l.Fragment,{children:[$(`檔案數`,`fieldMaxFiles`,Q(e.maxFiles,e=>jt({maxFiles:e}),`例如:1`,{min:1}),z),$(`MIME`,`fieldAcceptedMimeTypes`,Xt({disabled:z,name:`fieldAcceptedMimeTypes`,onChange:e=>jt({acceptedMimeTypes:Ge(e)}),placeholder:`每行一個 MIME type,例如:application/pdf`,rows:3,value:Ke(e.acceptedMimeTypes)}),!1)]})}function qt(e){let t=T.fields.filter(t=>t.fieldKey!==e.fieldKey);return t.length?(0,l.jsx)(l.Fragment,{children:Be.map(n=>Jt(e,n,t))}):(0,l.jsx)(c.Typography,{color:`text-neutral`,style:xe,variant:`body`,children:`目前沒有其他欄位可作為條件來源。新增更多欄位後即可設定條件規則。`})}function Jt(e,t,n){let r=e[t.target],i=r?(0,f.parseConditionRule)(r):null,a=n.find(e=>e.fieldKey===i?.fieldKey),o=a??n[0],s=n.map(Ue),u=(0,f.readConditionOperatorOptions)(o),d=i&&u.some(e=>e.id===i.operator)?i.operator:(0,f.readDefaultConditionOperator)(o),p=i?.value??(0,f.readDefaultConditionValue)(o),m=!!r,h=m&&(!i||!a);return $(t.label,t.name,(0,l.jsxs)(`div`,{style:Ae,children:[(0,l.jsx)(c.Toggle,{checked:m,disabled:z,label:m?`已啟用`:`不啟用`,onChange:e=>Z(t.target,e.target.checked?(0,f.buildConditionExpression)(o,(0,f.readDefaultConditionOperator)(o),(0,f.readDefaultConditionValue)(o)):void 0),size:`sub`,supportingText:t.supportingText}),m?h?(0,l.jsx)(c.Typography,{color:`text-warning`,variant:`body`,children:`這個規則不是目前 UI 支援的格式。重新選擇條件後會取代既有規則。`}):(0,l.jsxs)(`div`,{style:je,children:[(0,l.jsx)(c.Select,{clearable:!1,onChange:e=>{let r=n.find(t=>t.fieldKey===e?.id)??o;Z(t.target,(0,f.buildConditionExpression)(r,(0,f.readDefaultConditionOperator)(r),(0,f.readDefaultConditionValue)(r)))},options:s,placeholder:`選擇欄位`,value:(0,f.readSelectOption)(s,o.fieldKey)}),(0,l.jsx)(c.Select,{clearable:!1,onChange:e=>Z(t.target,(0,f.buildConditionExpression)(o,(0,f.readConditionOperatorOption)(e?.id)??d,p)),options:[...u],placeholder:`判斷方式`,value:(0,f.readSelectOption)(u,d)}),Yt(o,p,e=>Z(t.target,(0,f.buildConditionExpression)(o,d,e)))]}):null]}),z,!0)}function Z(e,t){K({[e]:t})}function Yt(e,t,n){if(e.type===`boolean`)return(0,l.jsx)(c.Select,{clearable:!1,onChange:e=>n(e?.id??`true`),options:[...ze],placeholder:`比較值`,value:(0,f.readSelectOption)(ze,t===`false`?`false`:`true`)});if((0,f.isSelectFieldDefinition)(e)){let r=e.options.map(f.readFieldOptionAsSelectOption);return(0,l.jsx)(c.Select,{clearable:!1,onChange:e=>n(e?.id??r[0]?.id??``),options:r,placeholder:`比較值`,value:(0,f.readSelectOption)(r,t)})}return(0,f.isNumberFieldDefinition)(e)?Q((0,f.parseOptionalNumberInput)(t),e=>n(String(e??0)),`比較值`):(0,f.isDateFieldDefinition)(e)?Zt(e,t,e=>n(e??``)):(0,l.jsx)(c.Input,{onChange:e=>n(e.target.value),placeholder:`比較值`,value:t,variant:`base`})}function Xt({disabled:e,name:t,onChange:n,placeholder:r,rows:i,value:a}){return(0,l.jsx)(c.Textarea,{"aria-label":t,disabled:e,onChange:e=>n(e.target.value),placeholder:r,ref:Le,resize:`vertical`,rows:i,style:Te,value:a})}function Q(e,t,n,r={}){return(0,l.jsx)(c.Input,{max:r.max,min:r.min,onChange:e=>t((0,f.clampOptionalNumber)((0,f.parseOptionalNumberInput)(e.target.value),r)),placeholder:n,showSpinner:!0,step:r.step??1,value:typeof e==`number`?String(e):``,variant:`measure`})}function Zt(e,t,n){return e.type===`datetime`?(0,l.jsx)(c.DateTimePicker,{formatDate:`YYYY-MM-DD`,formatTime:`HH:mm`,hideSecond:!0,onChange:e=>n((0,f.formatDateTimePickerValue)(e)),placeholderLeft:`選擇日期`,placeholderRight:`選擇時間`,value:(0,f.readDatePickerValue)(t)}):(0,l.jsx)(c.DatePicker,{format:`YYYY-MM-DD`,onChange:e=>n((0,f.formatDatePickerValue)(e)),placeholder:`選擇日期`,value:(0,f.readDatePickerValue)(t)})}function Qt(e){return(0,l.jsxs)(`div`,{style:Pe,children:[(0,l.jsx)(c.Table,{actions:{render:t=>[{disabled:()=>z||e.options.length<=1,icon:d.TrashIcon,iconType:`icon-only`,name:`移除選項`,onClick:()=>X({options:e.options.filter((e,n)=>n!==t.index)}),variant:`destructive-ghost`}],width:56},columns:[{key:`label`,render:t=>(0,l.jsx)(c.Input,{onChange:n=>X({options:qe(e.options,t.index,{label:n.target.value})}),placeholder:`例如:主管`,size:`sub`,value:t.label,variant:`base`}),title:`Label`},{key:`value`,render:t=>(0,l.jsx)(c.Input,{onChange:n=>X({options:qe(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,l.jsx)(`div`,{style:Fe,children:(0,l.jsx)(c.Button,{disabled:z,icon:d.PlusIcon,iconType:`leading`,onClick:()=>X({options:[...e.options,Je(e.options)]}),variant:`base-secondary`,children:`新增選項`})})]})}function $t(e,t,n){return(0,l.jsx)(`div`,{...t.draggableProps,"data-form-builder-field-key":e.fieldKey,ref:t.innerRef,style:{...pe,...n?me:null,...t.draggableProps.style},children:(0,l.jsx)(c.BaseCard,{children:en(e,t,n)})})}function $(e,t,n,r,a=!1){return(0,l.jsx)(`div`,{style:a?Ce:Se,children:(0,l.jsx)(`div`,{style:we,children:(0,l.jsx)(i.t,{disabled:r,label:e,name:t,children:n})})})}function en(e,t,n){return(0,l.jsxs)(`div`,{...t.dragHandleProps??{},"aria-label":`拖曳排序欄位`,style:le,title:`拖曳排序`,children:[(0,l.jsx)(`span`,{"aria-label":`拖曳排序`,role:`img`,style:Me,title:`拖曳排序`,children:(0,l.jsx)(c.Icon,{icon:d.DotDragVerticalIcon,size:20})}),(0,l.jsxs)(`div`,{style:ue,children:[(0,l.jsxs)(c.Typography,{component:`span`,ellipsis:!0,variant:`label-primary`,children:[e.label,e.required?(0,l.jsx)(`sup`,{"aria-label":`必填`,style:Ie,children:`*`}):null]}),(0,l.jsxs)(c.Typography,{color:`text-neutral`,component:`span`,ellipsis:!0,variant:`caption`,children:[Ve(e.type),` ·`,e.required?` 必填`:` 選填`,` ·`,e.fieldKey]})]}),(0,l.jsxs)(`div`,{style:de,children:[(0,l.jsx)(`div`,{style:fe,children:(0,l.jsx)(c.Toggle,{checked:!!e.required,disabled:z||n,label:`必填`,onChange:t=>Nt(e.fieldKey,t.target.checked)})}),(0,l.jsx)(c.Button,{disabled:n,icon:d.EditIcon,iconType:`icon-only`,onClick:()=>I(e.fieldKey),variant:e.fieldKey===V?.fieldKey?`base-primary`:`base-ghost`,children:`編輯欄位`}),(0,l.jsx)(c.Button,{disabled:z||n,icon:d.TrashIcon,iconType:`icon-only`,onClick:()=>Dt(e.fieldKey),variant:`destructive-ghost`,children:`移除欄位`})]})]})}function tn(){return(0,l.jsxs)(`div`,{style:y,children:[(0,l.jsx)(c.Typography,{component:`h2`,variant:`h3`,children:`填寫預覽`}),(0,l.jsx)(a.t,{onChange:Mt,schema:T,uiSchema:k,value:tt})]})}function nn(){return(0,l.jsxs)(`div`,{style:y,children:[(0,l.jsx)(c.Typography,{component:`h2`,variant:`h3`,children:`版本紀錄`}),(0,l.jsx)(c.Table,{columns:mt,dataSource:pt,loading:lt})]})}function rn(){return(0,l.jsxs)(`div`,{style:y,children:[(0,l.jsx)(c.Typography,{component:`h2`,variant:`h3`,children:`Schema`}),(0,l.jsxs)(`div`,{style:Ee,children:[an(`Form Schema`,`schemaJson`,(0,l.jsx)(te,{disabled:z,height:`360px`,name:`schemaJson`,onChange:Pt,placeholder:`輸入 Form Schema JSON`,value:$e})),an(`UI Schema`,`uiSchemaJson`,(0,l.jsx)(te,{disabled:z,height:`240px`,name:`uiSchemaJson`,onChange:Ft,placeholder:`輸入 UI Schema JSON`,value:et})),rt?(0,l.jsx)(c.Typography,{color:`text-error`,style:ke,variant:`body`,children:rt}):null]})]})}function an(e,t,n){return(0,l.jsx)(`div`,{style:De,children:(0,l.jsx)(`div`,{style:Oe,children:(0,l.jsx)(i.t,{disabled:z,label:e,name:t,children:n})})})}}function Ve(e){return ne.find(t=>t.type===e)?.label??e}function He(e){return!!(e.visibleWhen||e.requiredWhen||e.readonlyWhen)}function Ue(e){return{id:e.fieldKey,name:e.label}}function We(e){return e.type===`text`||e.type===`textarea`}function C(e){return typeof e==`string`?e:``}function Ge(e){let t=e.split(/[\n,]/u).map(e=>e.trim()).filter(Boolean);return t.length?t:void 0}function Ke(e){return e?.join(`
|
|
2
|
+
`)??``}function w(e){return JSON.stringify(e,null,2)}function qe(e,t,n){return e.map((e,r)=>r===t?{...e,...n}:e)}function Je(e){let t=e.length+1;return{label:`選項 ${t}`,value:T(e,t)}}function T(e,t){let n=`option_${t}`;return e.some(e=>e.value===n)?T(e,t+1):n}function E(e,t){return{schemaJson:w(e),uiSchemaJson:w(t)}}function Ye(e,t){return(t?e.find(e=>e.id===t):null)??e.find(e=>e.status===`PUBLISHED`)??null}function Xe({hasUnsavedChanges:e,latestPublishedVersion:t,openedContentPublished:r,openedVersion:i}){return`${e?`有未儲存修改`:`沒有未儲存修改`} · ${D({hasUnsavedChanges:e,openedContentPublished:r,openedVersion:i})} · ${t?`目前發布 v${t.version}:${n.t(t.publishedAt)}`:`目前沒有已發布版本`}`}function D({hasUnsavedChanges:e,openedContentPublished:t,openedVersion:n}){return e?n?`修改尚未發布,來源 v${n.version}`:`修改尚未發布`:t&&n?`當前內容已發布 v${n.version}`:n?`當前內容尚未發布 v${n.version}`:`當前內容尚未發布`}function Ze(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)]}function Qe({status:e}){return e===`PUBLISHED`?(0,l.jsx)(c.Badge,{size:`sub`,text:`已發布`,variant:`dot-success`}):e===`ARCHIVED`?(0,l.jsx)(c.Badge,{size:`sub`,text:`已封存`,variant:`dot-inactive`}):(0,l.jsx)(c.Badge,{size:`sub`,text:`草稿`,variant:`dot-warning`})}function O(e){return e instanceof Error?e.message:`發生未知錯誤`}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return S}});
|
|
3
|
+
//# sourceMappingURL=builder-f-Q_0NUs.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder-f-Q_0NUs.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,\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 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 {\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 { useBPMRoutes } from '../../../lib/routes-config';\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 routes = useBPMRoutes();\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(routes.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 <>\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 </>\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":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";require('../categories.css');const e=require("./chunk-CMqjfN_6.cjs"),t=require("./format-date-time-XxBzF0F5.cjs"),n=require("./bpm-form-field-Bc6k4ZEO.cjs");let r=require("react"),i=require("@mezzanine-ui/react"),a=require("react/jsx-runtime"),o=require("@mezzanine-ui/react/ContentHeader");o=e.t(o,1);let s=require("@mezzanine-ui/core/form"),c=require("@mezzanine-ui/icons"),l=require("@rytass/bpm-core-client/template");var u={templateFilterArea:`bpm_templateFilterArea_nUL-R`,templateModalFields:`bpm_templateModalFields_hUxWp`},d=[10,20,50],f=[{key:`ALL`,label:`全部`},{key:`ACTIVE`,label:`啟用`},{key:`INACTIVE`,label:`停用`}];function p(){let[e,n]=(0,r.useState)([]),[p,y]=(0,r.useState)(1),[b,x]=(0,r.useState)(10),[S,C]=(0,r.useState)(`ALL`),[w,T]=(0,r.useState)(0),[E,D]=(0,r.useState)(null),[O,k]=(0,r.useState)(null),[A,j]=(0,r.useState)(!0),[M,N]=(0,r.useState)(null),[P,F]=(0,r.useState)(!1),[I,L]=(0,r.useState)(``),R=(0,r.useCallback)(async()=>{j(!0),k(null);try{let e=await(0,l.listApprovalTemplateCategoriesPage)({page:p,pageSize:b,searchText:I,status:_(S)});n(e.categories),T(e.totalCount)}catch(e){k(v(e))}finally{j(!1)}},[p,b,S,I]);(0,r.useEffect)(()=>{R()},[R]);let z=(0,r.useMemo)(()=>e.map(e=>({...e,key:e.id,updatedAtLabel:t.t(e.updatedAt)})),[e]),B=(0,r.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`分類名稱`,width:180},{key:`status`,render:e=>(0,a.jsx)(h,{isActive:e.isActive}),title:`狀態`,width:120},{dataIndex:`sortOrder`,key:`sortOrder`,title:`排序`,width:100},{key:`description`,render:e=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.description||`無`}),title:`說明`,width:260},{dataIndex:`updatedAtLabel`,key:`updatedAtLabel`,title:`更新時間`,width:220}],[]);async function V(e){F(!0),k(null);try{M?.type===`EDIT`&&M.record?await(0,l.updateApprovalTemplateCategory)({...e,id:M.record.id}):await(0,l.createApprovalTemplateCategory)(e),N(null),await R()}catch(e){throw k(v(e)),e}finally{F(!1)}}async function H(e){F(!0),k(null);try{await(0,l.updateApprovalTemplateCategory)({description:e.description,id:e.id,isActive:!e.isActive,name:e.name,sortOrder:e.sortOrder}),await R()}catch(e){k(v(e))}finally{F(!1)}}async function U(){if(E){F(!0),k(null);try{await(0,l.deleteApprovalTemplateCategory)(E.id),D(null),await R()}catch(e){k(v(e))}finally{F(!1)}}}let W=(0,r.useMemo)(()=>({render:e=>[{name:`編輯`,onClick:()=>N({record:e,type:`EDIT`})},{name:e.isActive?`停用`:`啟用`,onClick:()=>void H(e),variant:e.isActive?`destructive-secondary`:`base-secondary`},{name:`刪除`,onClick:()=>D({id:e.id,name:e.name}),variant:`destructive-secondary`}],variant:`base-secondary`,width:192}),[R]);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.PageHeader,{children:(0,a.jsx)(o.default,{description:`維護簽核模板分類,供模板建立、篩選與列表標示使用。`,title:`簽核模板分類`,children:(0,a.jsx)(i.Button,{icon:c.PlusIcon,iconType:`leading`,onClick:()=>N({record:null,type:`CREATE`}),variant:`base-primary`,children:`建立分類`})})}),(0,a.jsx)(i.SectionGroup,{children:(0,a.jsxs)(i.Section,{filterArea:(0,a.jsx)(i.FilterArea,{className:u.templateFilterArea,size:`sub`,children:(0,a.jsx)(i.FilterLine,{children:(0,a.jsx)(i.Filter,{span:3,children:(0,a.jsx)(i.FormField,{fullWidth:!0,layout:s.FormFieldLayout.VERTICAL,name:`categorySearchText`,children:(0,a.jsx)(i.Input,{fullWidth:!0,onChange:e=>{L(e.target.value),y(1)},placeholder:`關鍵字:搜尋分類名稱或說明`,size:`sub`,value:I,variant:`base`})})})})}),tab:(0,a.jsx)(i.Tab,{activeKey:S,onChange:e=>{C(g(e)),y(1)},children:f.map(e=>(0,a.jsx)(i.TabItem,{children:e.label},e.key))}),children:[O?(0,a.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:O}):null,(0,a.jsx)(i.Table,{actions:W,columns:B,dataSource:z,fullWidth:!0,loading:A||P,pagination:{current:p,onChange:e=>{y(e)},onChangePageSize:e=>{y(1),x(e)},pageSize:b,pageSizeLabel:`每頁筆數`,pageSizeOptions:d,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:w}})]})})]}),(0,a.jsx)(m,{loading:P,modal:M,onClose:()=>N(null),onSubmit:V}),(0,a.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{variant:`destructive-primary`},confirmText:`刪除`,loading:P,modalStatusType:`error`,modalType:`standard`,onCancel:()=>D(null),onClose:()=>D(null),onConfirm:()=>void U(),open:!!E,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`若分類已被模板使用,系統會改為停用分類並保留既有模板關聯。`,title:`刪除分類`,children:(0,a.jsxs)(i.Typography,{color:`text-neutral`,variant:`body`,children:[`確定要刪除「`,E?.name??``,`」嗎?`]})})]})}function m({loading:e,modal:t,onClose:o,onSubmit:s}){let[c,l]=(0,r.useState)(``),[d,f]=(0,r.useState)(null),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)(`0`);(0,r.useEffect)(()=>{t&&(l(t.record?.description??``),f(null),m(t.record?.name??``),g(String(t.record?.sortOrder??0)))},[t]);async function _(){let e=p.trim(),n=Number(h);if(!e){f(`請輸入分類名稱`);return}if(!Number.isInteger(n)){f(`排序必須是整數`);return}try{await s({description:c.trim()||null,isActive:t?.record?.isActive??!0,name:e,sortOrder:n})}catch(e){f(v(e))}}return(0,a.jsxs)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!p.trim()},confirmText:t?.type===`EDIT`?`儲存`:`建立`,loading:e,modalType:`standard`,onCancel:o,onClose:o,onConfirm:()=>void _(),open:!!t,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:t?.type===`EDIT`?`編輯分類`:`建立分類`,children:[(0,a.jsxs)(`div`,{className:u.templateModalFields,children:[(0,a.jsx)(n.t,{label:`分類名稱`,name:`categoryName`,required:!0,children:(0,a.jsx)(i.Input,{autoFocus:!0,fullWidth:!0,onChange:e=>{m(e.target.value),f(null)},placeholder:`例如:行政管理`,value:p,variant:`base`})}),(0,a.jsx)(n.t,{label:`排序`,name:`categorySortOrder`,children:(0,a.jsx)(i.Input,{fullWidth:!0,onChange:e=>{g(e.target.value),f(null)},placeholder:`0`,value:h,variant:`base`})}),(0,a.jsx)(n.t,{label:`說明`,name:`categoryDescription`,children:(0,a.jsx)(i.Textarea,{onChange:e=>{l(e.target.value),f(null)},placeholder:`補充分類用途`,value:c})})]}),d?(0,a.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:d}):null]})}function h({isActive:e}){return e?(0,a.jsx)(i.Badge,{size:`sub`,text:`啟用`,variant:`dot-success`}):(0,a.jsx)(i.Badge,{size:`sub`,text:`停用`,variant:`dot-inactive`})}function g(e){return e===`ACTIVE`||e===`INACTIVE`?e:`ALL`}function _(e){return e}function v(e){return e instanceof Error?e.message:`發生未知錯誤`}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return p}});
|
|
2
|
+
//# sourceMappingURL=categories-B6QZKZRt.cjs.map
|