@rytass/bpm-core-react 0.4.1 → 0.6.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 +85 -0
- package/README.md +21 -0
- package/dist/chunks/FormBuilderView-B_KGPjlp.cjs +3 -0
- package/dist/chunks/FormBuilderView-B_KGPjlp.cjs.map +1 -0
- package/dist/chunks/FormBuilderView-D8DrQOXD.js +1090 -0
- package/dist/chunks/FormBuilderView-D8DrQOXD.js.map +1 -0
- package/dist/chunks/{approval-instance-list-page-C5ZKPHdA.cjs → approval-instance-list-page-BMUKxzcz.cjs} +2 -2
- package/dist/chunks/{approval-instance-list-page-C5ZKPHdA.cjs.map → approval-instance-list-page-BMUKxzcz.cjs.map} +1 -1
- package/dist/chunks/{approval-instance-list-page-BF2r5D2-.js → approval-instance-list-page-YZcGGDD8.js} +2 -2
- package/dist/chunks/{approval-instance-list-page-BF2r5D2-.js.map → approval-instance-list-page-YZcGGDD8.js.map} +1 -1
- package/dist/chunks/compose-PMrmi-LE.js +451 -0
- package/dist/chunks/compose-PMrmi-LE.js.map +1 -0
- package/dist/chunks/compose-ziVbRYdo.cjs +2 -0
- package/dist/chunks/compose-ziVbRYdo.cjs.map +1 -0
- package/dist/chunks/{dashboard-page-Ib8srCMy.js → dashboard-page-DJ9vOPga.js} +2 -2
- package/dist/chunks/{dashboard-page-Ib8srCMy.js.map → dashboard-page-DJ9vOPga.js.map} +1 -1
- package/dist/chunks/{dashboard-page-CddG1MnK.cjs → dashboard-page-DwHQY6Ki.cjs} +2 -2
- package/dist/chunks/{dashboard-page-CddG1MnK.cjs.map → dashboard-page-DwHQY6Ki.cjs.map} +1 -1
- package/dist/chunks/designer-DCn6_v4b.cjs +65 -0
- package/dist/chunks/designer-DCn6_v4b.cjs.map +1 -0
- package/dist/chunks/designer-mOMxJ0Py.js +2576 -0
- package/dist/chunks/designer-mOMxJ0Py.js.map +1 -0
- package/dist/chunks/detail-Cci9tnoC.cjs +2 -0
- package/dist/chunks/detail-Cci9tnoC.cjs.map +1 -0
- package/dist/chunks/detail-kyolfdBu.js +1957 -0
- package/dist/chunks/detail-kyolfdBu.js.map +1 -0
- package/dist/chunks/{routes-config-dxahImVe.js → routes-config-RBYQtUd0.js} +2 -3
- package/dist/chunks/routes-config-RBYQtUd0.js.map +1 -0
- package/dist/chunks/routes-config-fDVHmvXi.cjs +2 -0
- package/dist/chunks/routes-config-fDVHmvXi.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +268 -128
- package/dist/index.js.map +1 -1
- package/dist/lib/routes-config.d.ts +6 -4
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.js +1 -1
- package/dist/next/workflow-chat-route.cjs +19 -0
- package/dist/next/workflow-chat-route.cjs.map +1 -0
- package/dist/next/workflow-chat-route.d.ts +17 -0
- package/dist/next/workflow-chat-route.js +31 -0
- package/dist/next/workflow-chat-route.js.map +1 -0
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/templates/compose/index.cjs +2 -0
- package/dist/pages/templates/compose/index.cjs.map +1 -0
- package/dist/pages/templates/compose/index.d.ts +13 -0
- package/dist/pages/templates/compose/index.js +14 -0
- package/dist/pages/templates/compose/index.js.map +1 -0
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.cjs.map +1 -1
- package/dist/pages/templates/designer/index.js +7 -2
- package/dist/pages/templates/designer/index.js.map +1 -1
- package/dist/pages/templates/index.cjs +1 -1
- package/dist/pages/templates/index.cjs.map +1 -1
- package/dist/pages/templates/index.js +3 -3
- package/dist/pages/templates/index.js.map +1 -1
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.js +1 -1
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.js +1 -1
- package/dist/views/forms/builder/FormBuilderView.d.ts +13 -4
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/builder/json-code-editor.d.ts +1 -1
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.js +1 -1
- package/dist/views/instances/detail/InstanceDetailView.d.ts +11 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.d.ts +5 -0
- package/dist/views/instances/detail/index.js +2 -2
- package/dist/views/instances/detail/sections/InstanceAttachmentsSection.d.ts +15 -0
- package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +33 -0
- package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +29 -0
- package/dist/views/instances/detail/sections/InstanceSignaturesSection.d.ts +14 -0
- package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +51 -0
- package/dist/views/instances/detail/sections/container-helpers.d.ts +9 -0
- package/dist/views/instances/detail/sections/shared.d.ts +103 -0
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.js +1 -1
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.js +1 -1
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.js +1 -1
- package/dist/views/templates/TemplatesView.d.ts +5 -0
- package/dist/views/templates/compose/TemplateComposeWizardView.d.ts +8 -0
- package/dist/views/templates/compose/index.cjs +1 -0
- package/dist/views/templates/compose/index.d.ts +2 -0
- package/dist/views/templates/compose/index.js +2 -0
- package/dist/views/templates/compose/steps/ComposeFormStep.d.ts +15 -0
- package/dist/views/templates/compose/steps/ComposeReviewStep.d.ts +12 -0
- package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +11 -0
- package/dist/views/templates/compose/use-template-compose-wizard.d.ts +46 -0
- package/dist/views/templates/designer/TemplateDesignerView.d.ts +60 -2
- package/dist/views/templates/designer/chrome-workflow-chat.d.ts +12 -0
- package/dist/views/templates/designer/index.cjs +1 -51
- package/dist/views/templates/designer/index.js +2 -2272
- package/dist/views/templates/designer/use-workflow-chat.d.ts +21 -0
- package/dist/views/templates/designer/use-workflow-designer-controller.d.ts +41 -0
- package/dist/views/templates/designer/workflow-chat-drawer.d.ts +16 -0
- package/dist/views/templates/index.cjs +2 -1
- package/dist/views/templates/index.cjs.map +1 -0
- package/dist/views/templates/index.js +265 -4
- package/dist/views/templates/index.js.map +1 -0
- package/dist/views/templates/versions/index.cjs +1 -1
- package/dist/views/templates/versions/index.cjs.map +1 -1
- package/dist/views/templates/versions/index.js +38 -42
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +22 -19
- package/dist/chunks/builder-BLVnnpnP.js +0 -1300
- package/dist/chunks/builder-BLVnnpnP.js.map +0 -1
- package/dist/chunks/builder-DVE9zIKH.cjs +0 -3
- package/dist/chunks/builder-DVE9zIKH.cjs.map +0 -1
- package/dist/chunks/detail-Dcr5mM8g.cjs +0 -2
- package/dist/chunks/detail-Dcr5mM8g.cjs.map +0 -1
- package/dist/chunks/detail-u9DdLhDW.js +0 -1518
- package/dist/chunks/detail-u9DdLhDW.js.map +0 -1
- package/dist/chunks/form-name-modal-C3OEvkCV.js +0 -64
- package/dist/chunks/form-name-modal-C3OEvkCV.js.map +0 -1
- package/dist/chunks/form-name-modal-uZCHbtRH.cjs +0 -2
- package/dist/chunks/form-name-modal-uZCHbtRH.cjs.map +0 -1
- package/dist/chunks/routes-config-2aKbWq2H.cjs +0 -2
- package/dist/chunks/routes-config-2aKbWq2H.cjs.map +0 -1
- package/dist/chunks/routes-config-dxahImVe.js.map +0 -1
- package/dist/chunks/templates-D44FSB46.js +0 -380
- package/dist/chunks/templates-D44FSB46.js.map +0 -1
- package/dist/chunks/templates-w96t83N-.cjs +0 -2
- package/dist/chunks/templates-w96t83N-.cjs.map +0 -1
- package/dist/pages/forms/builder/index.cjs +0 -2
- package/dist/pages/forms/builder/index.cjs.map +0 -1
- package/dist/pages/forms/builder/index.d.ts +0 -21
- package/dist/pages/forms/builder/index.js +0 -15
- package/dist/pages/forms/builder/index.js.map +0 -1
- package/dist/pages/forms/index.cjs +0 -2
- package/dist/pages/forms/index.cjs.map +0 -1
- package/dist/pages/forms/index.d.ts +0 -17
- package/dist/pages/forms/index.js +0 -14
- package/dist/pages/forms/index.js.map +0 -1
- package/dist/views/forms/FormsView.d.ts +0 -2
- package/dist/views/forms/form-name-modal.d.ts +0 -12
- package/dist/views/forms/index.cjs +0 -2
- package/dist/views/forms/index.cjs.map +0 -1
- package/dist/views/forms/index.d.ts +0 -2
- package/dist/views/forms/index.js +0 -186
- package/dist/views/forms/index.js.map +0 -1
- package/dist/views/templates/designer/index.cjs.map +0 -1
- package/dist/views/templates/designer/index.js.map +0 -1
- package/dist/views/templates/template-name-modal.d.ts +0 -22
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/views/templates/designer/TemplateDesignerView.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n MouseEvent as ReactMouseEvent,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport {\n Background,\n ControlButton,\n Controls,\n Edge,\n Handle,\n MiniMap,\n Node,\n NodeProps,\n NodeTypes,\n Panel,\n Position,\n ReactFlow,\n applyNodeChanges,\n Connection,\n ConnectionMode,\n getViewportForBounds,\n type Handle as FlowHandle,\n type Viewport,\n} from '@xyflow/react';\nimport * as dagre from 'dagre';\nimport {\n AutoComplete,\n Button,\n Icon,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport {\n CheckedIcon,\n DotGridIcon,\n EyeIcon,\n FilterIcon,\n MailIcon,\n SaveIcon,\n TrashIcon,\n UserIcon,\n type IconDefinition,\n} from '@mezzanine-ui/icons';\nimport {\n FormDefinitionSchema,\n FormFieldDefinition,\n FormFieldOption,\n} from '@rytass/bpm-core-shared/form';\nimport {\n ApproverResolver,\n ApproverResolverFallback,\n ServiceAction,\n WorkflowDefinition,\n WorkflowEdge,\n WorkflowEdgeConditionOperator,\n WorkflowEdgeData,\n WorkflowNode,\n WorkflowNodeTriggerMode,\n ReturnResubmitStrategy,\n} from '@rytass/bpm-core-shared/workflow';\nimport {\n OrgUnitOption,\n OrgUnitPicker,\n PositionOption,\n PositionPicker,\n readOrgUnitOption,\n readPositionOption,\n} from '../../../components/admin-pickers';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport {\n OrgUnitRecord,\n MembershipRecord,\n PositionRecord,\n readOrganizationDashboard,\n} from '@rytass/bpm-core-client/organization';\nimport {\n ApprovalTemplateVersionRecord,\n WorkflowDryRunResultRecord,\n dryRunApprovalWorkflow,\n forkApprovalTemplate,\n MemberProfileRecord,\n publishApprovalTemplateVersion,\n PublishedFormVersionOption,\n readTemplateDesigner,\n resolveMemberOptions,\n searchMemberOptions,\n searchPublishedFormVersionOptions,\n TemplateDesignerRecord,\n updateApprovalTemplateDraft,\n} from '@rytass/bpm-core-client/template';\n\ntype FlowNodeData = Readonly<{\n approverLines: readonly string[] | null;\n approverSummary: string | null;\n hasInput: boolean;\n hasOutput: boolean;\n initiatorPolicySummary: string | null;\n label: string;\n nodeKind: WorkflowNode['type'];\n}>;\ntype FlowNode = Node<FlowNodeData, WorkflowNode['type']>;\ntype FlowNodeHandle = Omit<FlowHandle, 'nodeId'>;\ntype FlowEdgeData = Readonly<WorkflowEdgeData>;\ntype FlowEdge = Edge<FlowEdgeData>;\ntype NodePaletteType = 'exclusiveGateway' | 'serviceTask' | 'userTask';\ntype FormVersionSelectOption = Readonly<{\n id: string;\n name: string;\n schema: FormDefinitionSchema;\n}>;\ntype ConditionFieldOption = Readonly<{\n fieldType: FormFieldDefinition['type'];\n id: string;\n name: string;\n}>;\ntype ConditionOperatorOption = Readonly<{\n id: WorkflowEdgeConditionOperator;\n name: string;\n}>;\ntype ConditionValueOption = Readonly<{\n id: string;\n name: string;\n}>;\ntype MemberSelectOption = Readonly<{\n displayName: string;\n email: string;\n id: string;\n memberId: string;\n name: string;\n}>;\ntype InitiatorPolicyMode =\n | 'ALL'\n | 'CUSTOM'\n | 'NONE'\n | 'ORG_UNIT'\n | 'ORG_UNIT_POSITION';\ntype InitiatorPolicyDraft = Readonly<{\n includeDescendants?: boolean;\n mode: InitiatorPolicyMode;\n orgUnitId?: string;\n positionId?: string;\n value: string;\n}>;\ntype InitiatorPolicyModeOption = Readonly<{\n id: InitiatorPolicyMode;\n name: string;\n}>;\ntype ReturnResubmitStrategyOption = Readonly<{\n id: ReturnResubmitStrategy;\n name: string;\n}>;\ntype ApproverResolverMode = Extract<\n ApproverResolver['type'],\n | 'DIRECT'\n | 'ORG_MANAGER'\n | 'ORG_UNIT_MANAGER'\n | 'ORG_UNIT_MEMBER'\n | 'ORG_UNIT_POSITION'\n | 'POSITION'\n>;\ntype ApproverResolverModeOption = Readonly<{\n id: ApproverResolverMode;\n name: string;\n}>;\ntype ManagerLevelOption = Readonly<{\n id: string;\n name: string;\n value: number;\n}>;\ntype ApproverFallbackMode = 'DIRECT' | 'NONE';\ntype ApproverFallbackModeOption = Readonly<{\n id: ApproverFallbackMode;\n name: string;\n}>;\ntype WorkflowConnectionCandidate = Readonly<{\n source?: string | null;\n sourceHandle?: string | null;\n target?: string | null;\n targetHandle?: string | null;\n}>;\n\nconst WORKSPACE_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\nconst TWO_COLUMN_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'grid',\n gap: 16,\n gridTemplateColumns: 'minmax(0, 1fr) 420px',\n};\n\nconst FLOW_CANVAS_STYLE: CSSProperties = {\n border: '1px solid var(--mzn-color-border-neutral)',\n borderRadius: 6,\n height: 620,\n minWidth: 0,\n overflow: 'hidden',\n};\n\nconst SELECTION_DELETE_CONTROL_BUTTON_STYLE: CSSProperties = {\n alignItems: 'center',\n boxSizing: 'border-box',\n color: 'var(--mzn-color-text-error)',\n display: 'flex',\n height: 26,\n justifyContent: 'center',\n lineHeight: 0,\n padding: 0,\n width: 26,\n};\n\nconst SELECTION_DELETE_CONTROL_ICON_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'flex',\n height: '100%',\n justifyContent: 'center',\n width: '100%',\n};\n\nconst SIDE_PANEL_CLASS_NAME = 'workflow-designer-side-panel';\nconst SIDE_PANEL_FORM_LABEL_WIDTH = 96;\nconst SIDE_PANEL_GLOBAL_STYLE = `\n.${SIDE_PANEL_CLASS_NAME} .mzn-form-field--stretch .mzn-form-field__label-area,\n.${SIDE_PANEL_CLASS_NAME} .mzn-form-field--horizontal .mzn-form-field__label-area {\n flex: 0 0 ${SIDE_PANEL_FORM_LABEL_WIDTH}px;\n width: ${SIDE_PANEL_FORM_LABEL_WIDTH}px;\n}\n\n.${SIDE_PANEL_CLASS_NAME} .mzn-form-field--stretch .mzn-form-field__data-entry,\n.${SIDE_PANEL_CLASS_NAME} .mzn-form-field--horizontal .mzn-form-field__data-entry {\n min-width: 0;\n}\n`;\n\nconst CONDITION_EDGE_COLOR = '#2563eb';\nconst DEFAULT_EDGE_COLOR = '#64748b';\nconst INCOMPLETE_CONDITION_EDGE_COLOR = 'var(--mzn-color-text-error, #dc2626)';\nconst SELECTED_EDGE_GLOW_FILTER =\n 'drop-shadow(0 0 3px rgba(0, 87, 255, 0.85)) drop-shadow(0 0 9px rgba(0, 87, 255, 0.36))';\nconst FLOW_CANVAS_GLOBAL_STYLE = `\n.workflow-selection-delete-control.react-flow__controls-button {\n align-items: center !important;\n display: flex !important;\n height: 26px !important;\n justify-content: center !important;\n padding: 0 !important;\n width: 26px !important;\n}\n\n.workflow-selection-delete-control .mzn-icon {\n align-items: center;\n display: flex;\n justify-content: center;\n}\n\n.workflow-selection-delete-control .mzn-icon svg {\n height: 16px !important;\n max-height: none !important;\n max-width: none !important;\n width: 16px !important;\n}\n\n.workflow-edge--selected .react-flow__edge-path,\n.react-flow__edge-path.workflow-edge--selected {\n filter: ${SELECTED_EDGE_GLOW_FILTER};\n opacity: 1 !important;\n stroke: ${DEFAULT_EDGE_COLOR} !important;\n stroke-opacity: 1 !important;\n stroke-width: 1.5px !important;\n}\n\n.workflow-edge--selected {\n --xy-edge-stroke: ${DEFAULT_EDGE_COLOR};\n --xy-edge-stroke-selected: ${DEFAULT_EDGE_COLOR};\n --xy-edge-stroke-width: 1.5px;\n}\n\n`;\n\nconst PANEL_STYLE: CSSProperties = {\n display: 'grid',\n gap: 12,\n};\n\nconst FORM_STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 12,\n};\n\nconst DRY_RUN_RESULT_STYLE: CSSProperties = {\n border: '1px solid var(--mzn-color-border-neutral)',\n borderRadius: 6,\n display: 'grid',\n gap: 8,\n maxHeight: 360,\n overflow: 'auto',\n padding: 12,\n};\n\nconst DRY_RUN_STEP_STYLE: CSSProperties = {\n borderBottom: '1px solid var(--mzn-color-border-neutral)',\n display: 'grid',\n gap: 4,\n padding: '0 0 8px',\n};\n\nconst BUTTON_ROW_STYLE: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 8,\n};\n\nconst TOOL_GROUP_STYLE: CSSProperties = {\n display: 'grid',\n gap: 8,\n};\n\nconst NODE_STYLE: CSSProperties = {\n alignContent: 'center',\n background: 'var(--mzn-color-bg-surface)',\n border: '1px solid var(--mzn-color-border-neutral)',\n borderRadius: 6,\n boxShadow: '0 8px 20px rgba(15, 23, 42, 0.08)',\n boxSizing: 'border-box',\n display: 'grid',\n gap: 4,\n height: '100%',\n minWidth: 132,\n overflow: 'visible',\n padding: '10px 12px',\n textAlign: 'center',\n width: '100%',\n};\nconst SELECTED_NODE_BOX_SHADOW =\n '0 8px 20px rgba(15, 23, 42, 0.08), 0 0 0 1px var(--mzn-color-primary, #0057ff), 0 0 10px rgba(0, 87, 255, 0.3)';\nconst FLOW_NODE_INITIAL_HEIGHT = 64;\nconst FLOW_NODE_INITIAL_WIDTH = 160;\nconst FLOW_NODE_ADDITIONAL_LINE_HEIGHT = 20;\nconst GATEWAY_NODE_INITIAL_HEIGHT = 64;\nconst GATEWAY_NODE_INITIAL_WIDTH = 180;\n\nconst GATEWAY_NODE_STYLE: CSSProperties = {\n ...NODE_STYLE,\n display: 'grid',\n gap: 8,\n padding: '10px 12px',\n};\n\nconst EXCLUSIVE_GATEWAY_NODE_STYLE: CSSProperties = {\n ...GATEWAY_NODE_STYLE,\n background: '#eff6ff',\n border: '1px solid #2563eb',\n};\n\nconst PARALLEL_GATEWAY_NODE_STYLE: CSSProperties = {\n ...GATEWAY_NODE_STYLE,\n background: '#f0fdfa',\n border: '1px solid #0f766e',\n};\n\nconst USER_TASK_NODE_STYLE: CSSProperties = {\n ...NODE_STYLE,\n background: '#ffffff',\n};\n\nconst START_NODE_STYLE: CSSProperties = {\n ...NODE_STYLE,\n background: '#ecfdf3',\n border: '1px solid #2f855a',\n};\n\nconst END_NODE_STYLE: CSSProperties = {\n ...NODE_STYLE,\n background: '#fff4ed',\n border: '1px solid #c2410c',\n};\n\nconst NODE_TEXT_STYLE: CSSProperties = {\n display: 'block',\n maxWidth: '100%',\n minWidth: 0,\n};\n\nconst NODE_PRIMARY_LABELS_STYLE: CSSProperties = {\n display: 'grid',\n gap: 2,\n minWidth: 0,\n};\n\nconst WORKFLOW_INPUT_HANDLE_ID = 'input';\nconst WORKFLOW_OUTPUT_HANDLE_ID = 'output';\n\nconst NODE_TYPE_LABELS: Readonly<Record<WorkflowNode['type'], string>> = {\n endEvent: '結束',\n exclusiveGateway: '條件分流',\n parallelGateway: '並行處理',\n serviceTask: '系統',\n startEvent: '開始',\n userTask: '簽核',\n};\n\nconst ACTION_NODE_PALETTE: readonly {\n readonly icon: IconDefinition;\n readonly label: string;\n readonly type: Extract<NodePaletteType, 'serviceTask' | 'userTask'>;\n}[] = [\n { icon: UserIcon, label: '簽核節點', type: 'userTask' },\n { icon: MailIcon, label: '知會節點', type: 'serviceTask' },\n];\nconst FLOW_CONTROL_PALETTE: readonly {\n readonly icon: IconDefinition;\n readonly label: string;\n readonly type: Extract<NodePaletteType, 'exclusiveGateway'>;\n}[] = [{ icon: FilterIcon, label: '條件分流', type: 'exclusiveGateway' }];\nconst NODE_TRIGGER_MODE_OPTIONS: readonly {\n readonly id: WorkflowNodeTriggerMode;\n readonly name: string;\n}[] = [\n { id: 'AND', name: '全部前置完成' },\n { id: 'OR', name: '任一前置完成' },\n];\nconst RETURN_RESUBMIT_STRATEGY_OPTIONS: readonly ReturnResubmitStrategyOption[] =\n [\n { id: 'RESTART', name: '重新送出後從開始重跑' },\n { id: 'FROM_RETURN_POINT', name: '重新送出後回到退回節點' },\n ];\nconst APPROVER_RESOLVER_MODE_OPTIONS: readonly ApproverResolverModeOption[] = [\n { id: 'DIRECT', name: '指定會員' },\n { id: 'ORG_MANAGER', name: '發起人主管' },\n { id: 'ORG_UNIT_MANAGER', name: '指定組織主管' },\n { id: 'ORG_UNIT_MEMBER', name: '組織任一人' },\n { id: 'ORG_UNIT_POSITION', name: '組織特定職位' },\n { id: 'POSITION', name: '指定職位' },\n];\nconst MANAGER_LEVEL_OPTIONS: readonly ManagerLevelOption[] = [\n { id: '1', name: '直屬主管', value: 1 },\n { id: '2', name: '第二層主管', value: 2 },\n { id: '3', name: '第三層主管', value: 3 },\n];\nconst APPROVER_FALLBACK_MODE_OPTIONS: readonly ApproverFallbackModeOption[] = [\n { id: 'NONE', name: '停止流程並提示' },\n { id: 'DIRECT', name: '固定改派' },\n];\nconst CONDITION_OPERATOR_OPTIONS: readonly ConditionOperatorOption[] = [\n { id: 'EQUALS', name: '等於' },\n { id: 'NOT_EQUALS', name: '不等於' },\n { id: 'GREATER_THAN', name: '大於' },\n { id: 'GREATER_THAN_OR_EQUALS', name: '大於等於' },\n { id: 'LESS_THAN', name: '小於' },\n { id: 'LESS_THAN_OR_EQUALS', name: '小於等於' },\n { id: 'IS_FILLED', name: '已填寫' },\n { id: 'IS_EMPTY', name: '未填寫' },\n];\nconst CONDITION_OPERATORS_REQUIRING_VALUE: readonly WorkflowEdgeConditionOperator[] =\n [\n 'EQUALS',\n 'GREATER_THAN',\n 'GREATER_THAN_OR_EQUALS',\n 'LESS_THAN',\n 'LESS_THAN_OR_EQUALS',\n 'NOT_EQUALS',\n ];\nconst INITIATOR_POLICY_MODE_OPTIONS: readonly InitiatorPolicyModeOption[] = [\n { id: 'NONE', name: '未設定' },\n { id: 'ALL', name: '所有人' },\n { id: 'ORG_UNIT', name: '指定組織' },\n { id: 'ORG_UNIT_POSITION', name: '指定組織職位' },\n];\nconst INITIATOR_POLICY_CUSTOM_OPTION: InitiatorPolicyModeOption = {\n id: 'CUSTOM',\n name: '既有自訂規則',\n};\nconst DRY_RUN_MEMBER_ID = 'member-001';\n\nconst nodeTypes: NodeTypes = {\n endEvent: WorkflowNodeCard,\n exclusiveGateway: WorkflowNodeCard,\n parallelGateway: WorkflowNodeCard,\n serviceTask: WorkflowNodeCard,\n startEvent: WorkflowNodeCard,\n userTask: WorkflowNodeCard,\n};\n\nexport interface TemplateDesignerViewProps {\n readonly templateId: string;\n}\n\nexport function TemplateDesignerView({\n templateId,\n}: TemplateDesignerViewProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [record, setRecord] = useState<TemplateDesignerRecord | null>(null);\n const [draft, setDraft] = useState<ApprovalTemplateVersionRecord | null>(\n null,\n );\n const [workflowDefinition, setWorkflowDefinition] =\n useState<WorkflowDefinition>(readFallbackWorkflowDefinition());\n const [loadedDesignerSnapshot, setLoadedDesignerSnapshot] = useState('');\n const [formDefinitionVersionId, setFormDefinitionVersionId] = useState<\n string | null\n >(null);\n const [initiatorPolicyCel, setInitiatorPolicyCel] = useState<string | null>(\n null,\n );\n const [initiatorPolicyModeDraft, setInitiatorPolicyModeDraft] =\n useState<Exclude<InitiatorPolicyMode, 'CUSTOM'> | null>(null);\n const [initiatorPolicyDraftOverride, setInitiatorPolicyDraftOverride] =\n useState<InitiatorPolicyDraft | null>(null);\n const [selectedNodeId, setSelectedNodeId] = useState<string | null>('start');\n const [selectedEdgeIds, setSelectedEdgeIds] = useState<readonly string[]>([]);\n const [editingEdgeId, setEditingEdgeId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [formVersionLoading, setFormVersionLoading] = useState(false);\n const [formVersionOptions, setFormVersionOptions] = useState<\n readonly FormVersionSelectOption[]\n >([]);\n const currentDesignerSnapshot = useMemo(\n (): string =>\n JSON.stringify({\n formDefinitionVersionId,\n initiatorPolicyCel,\n workflowDefinition,\n }),\n [formDefinitionVersionId, initiatorPolicyCel, workflowDefinition],\n );\n const hasUnsavedChanges =\n Boolean(loadedDesignerSnapshot) &&\n currentDesignerSnapshot !== loadedDesignerSnapshot;\n const [memberLoading, setMemberLoading] = useState(false);\n const [memberOptions, setMemberOptions] = useState<\n readonly MemberSelectOption[]\n >([]);\n const [orgUnits, setOrgUnits] = useState<readonly OrgUnitRecord[]>([]);\n const [positions, setPositions] = useState<readonly PositionRecord[]>([]);\n const [memberships, setMemberships] = useState<readonly MembershipRecord[]>(\n [],\n );\n const [dryRunModalOpen, setDryRunModalOpen] = useState(false);\n const [dryRunRunning, setDryRunRunning] = useState(false);\n const [dryRunFormDataJson, setDryRunFormDataJson] = useState('{}');\n const [dryRunResult, setDryRunResult] =\n useState<WorkflowDryRunResultRecord | null>(null);\n const [dryRunError, setDryRunError] = useState<string | null>(null);\n const [flowViewport, setFlowViewport] = useState<Viewport | undefined>(\n undefined,\n );\n const flowCanvasRef = useRef<HTMLDivElement | null>(null);\n\n useEffect((): void => {\n void refreshDesigner();\n }, [templateId]);\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 useEffect((): void => {\n void resolveWorkflowMemberOptions(workflowDefinition);\n }, [workflowDefinition, memberOptions]);\n\n useEffect((): void => {\n setWorkflowDefinition((currentDefinition) =>\n normalizeDesignerWorkflowDefinition(currentDefinition),\n );\n }, [workflowDefinition.edges, workflowDefinition.nodes]);\n\n function handleBackToTemplates(): void {\n if (\n hasUnsavedChanges &&\n !window.confirm('目前有尚未儲存的流程草稿,確定要離開嗎?')\n ) {\n return;\n }\n\n router.push(routes.templates());\n }\n\n const selectedNode = useMemo(\n (): WorkflowNode | null =>\n workflowDefinition.nodes.find((node) => node.id === selectedNodeId) ??\n null,\n [selectedNodeId, workflowDefinition.nodes],\n );\n const selectedNodeCanDelete = selectedNode\n ? isWorkflowNodeRemovable(selectedNode)\n : false;\n const hasDeletableSelection =\n selectedEdgeIds.length > 0 || selectedNodeCanDelete;\n const removeSelectedWorkflowElements = useCallback((): void => {\n const selectedNodeIdToRemove =\n selectedNode && isWorkflowNodeRemovable(selectedNode)\n ? selectedNode.id\n : null;\n\n setWorkflowDefinition((currentDefinition) => ({\n ...currentDefinition,\n edges: currentDefinition.edges.filter(\n (edge) =>\n !selectedEdgeIds.includes(edge.id) &&\n edge.source !== selectedNodeIdToRemove &&\n edge.target !== selectedNodeIdToRemove,\n ),\n nodes: selectedNodeIdToRemove\n ? currentDefinition.nodes.filter(\n (node) => node.id !== selectedNodeIdToRemove,\n )\n : currentDefinition.nodes,\n }));\n setSelectedEdgeIds([]);\n setEditingEdgeId(null);\n\n if (selectedNodeIdToRemove) {\n setSelectedNodeId('start');\n }\n }, [selectedEdgeIds, selectedNode]);\n\n useEffect((): (() => void) | undefined => {\n if (!hasDeletableSelection) {\n return undefined;\n }\n\n function handleDeleteSelectedElements(event: KeyboardEvent): void {\n if (event.key !== 'Delete' && event.key !== 'Backspace') {\n return;\n }\n\n if (isEditableKeyboardTarget(event.target)) {\n return;\n }\n\n event.preventDefault();\n removeSelectedWorkflowElements();\n }\n\n window.addEventListener('keydown', handleDeleteSelectedElements);\n\n return (): void => {\n window.removeEventListener('keydown', handleDeleteSelectedElements);\n };\n }, [hasDeletableSelection, removeSelectedWorkflowElements]);\n\n const editingEdge = useMemo(\n (): WorkflowEdge | null =>\n workflowDefinition.edges.find((edge) => edge.id === editingEdgeId) ??\n null,\n [editingEdgeId, workflowDefinition.edges],\n );\n const selectedEdge = useMemo(\n (): WorkflowEdge | null =>\n selectedEdgeIds.length === 1\n ? (workflowDefinition.edges.find(\n (edge) => edge.id === selectedEdgeIds[0],\n ) ?? null)\n : null,\n [selectedEdgeIds, workflowDefinition.edges],\n );\n const selectedEdges = useMemo(\n (): readonly WorkflowEdge[] =>\n selectedEdgeIds\n .map(\n (edgeId) =>\n workflowDefinition.edges.find((edge) => edge.id === edgeId) ?? null,\n )\n .filter((edge): edge is WorkflowEdge => Boolean(edge)),\n [selectedEdgeIds, workflowDefinition.edges],\n );\n const initiatorPolicyDraft = useMemo(\n (): InitiatorPolicyDraft =>\n initiatorPolicyDraftOverride ??\n readInitiatorPolicyUiDraft(initiatorPolicyCel, initiatorPolicyModeDraft),\n [\n initiatorPolicyCel,\n initiatorPolicyDraftOverride,\n initiatorPolicyModeDraft,\n ],\n );\n const flowNodes = useMemo(\n (): FlowNode[] =>\n workflowDefinition.nodes.map((node) =>\n readFlowNode(\n node,\n memberOptions,\n orgUnits,\n positions,\n node.id === selectedNodeId,\n initiatorPolicyDraft,\n ),\n ),\n [\n initiatorPolicyDraft,\n memberOptions,\n orgUnits,\n positions,\n selectedNodeId,\n workflowDefinition.nodes,\n ],\n );\n const flowEdges = useMemo(\n (): FlowEdge[] =>\n workflowDefinition.edges.map((edge) =>\n readFlowEdge(\n edge,\n workflowDefinition.nodes,\n selectedEdgeIds.includes(edge.id),\n ),\n ),\n [selectedEdgeIds, workflowDefinition.edges, workflowDefinition.nodes],\n );\n\n const selectedFormVersionOption = useMemo(\n (): FormVersionSelectOption | null =>\n readSelectOption(formVersionOptions, formDefinitionVersionId) ??\n readSelectOption(\n readFormVersionSelectOptions(record?.formVersions ?? []),\n formDefinitionVersionId,\n ),\n [formDefinitionVersionId, formVersionOptions, record?.formVersions],\n );\n const visibleFormVersionOptions = useMemo(\n (): readonly FormVersionSelectOption[] =>\n mergeSelectedOption(formVersionOptions, selectedFormVersionOption),\n [formVersionOptions, selectedFormVersionOption],\n );\n const workflowIssue = useMemo(\n (): string | null => readWorkflowDefinitionIssue(workflowDefinition),\n [workflowDefinition],\n );\n const formVersionBindingLocked = useMemo(\n (): boolean => hasConfiguredConditionEdges(workflowDefinition),\n [workflowDefinition],\n );\n const initiatorPolicyIssue = useMemo(\n (): string | null => readInitiatorPolicyIssue(initiatorPolicyDraft),\n [initiatorPolicyDraft],\n );\n\n async function refreshDesigner(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n const [nextRecord, organizationDashboard] = await Promise.all([\n readTemplateDesigner(templateId),\n readOrganizationDashboard(),\n ]);\n const nextDraft =\n nextRecord.versions.find((version) => version.status === 'DRAFT') ??\n null;\n const sourceVersion = nextDraft ?? nextRecord.versions[0] ?? null;\n\n setRecord(nextRecord);\n setDraft(nextDraft);\n setOrgUnits(organizationDashboard.orgUnits);\n setPositions(organizationDashboard.positions);\n setMemberships(organizationDashboard.memberships);\n setFormVersionOptions(\n readFormVersionSelectOptions(nextRecord.formVersions),\n );\n const nextWorkflowDefinition =\n sourceVersion?.workflowDefinition ?? readFallbackWorkflowDefinition();\n const nextFormDefinitionVersionId =\n sourceVersion?.formDefinitionVersionId ??\n nextRecord.formVersions[0]?.id ??\n null;\n const nextInitiatorPolicyCel = sourceVersion?.initiatorPolicyCel ?? null;\n\n setWorkflowDefinition(nextWorkflowDefinition);\n setFormDefinitionVersionId(nextFormDefinitionVersionId);\n setInitiatorPolicyCel(nextInitiatorPolicyCel);\n setLoadedDesignerSnapshot(\n JSON.stringify({\n formDefinitionVersionId: nextFormDefinitionVersionId,\n initiatorPolicyCel: nextInitiatorPolicyCel,\n workflowDefinition: nextWorkflowDefinition,\n }),\n );\n setInitiatorPolicyModeDraft(\n sourceVersion &&\n !nextRecord.template.currentVersionId &&\n !sourceVersion.initiatorPolicyCel &&\n isEmptyDesignerWorkflowDefinition(sourceVersion.workflowDefinition)\n ? 'NONE'\n : null,\n );\n setInitiatorPolicyDraftOverride(null);\n setSelectedNodeId(\n sourceVersion?.workflowDefinition.nodes[0]?.id ?? 'start',\n );\n setSelectedEdgeIds([]);\n setEditingEdgeId(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSearchFormVersions(searchText: string): Promise<void> {\n setFormVersionLoading(true);\n setError(null);\n\n try {\n const options = await searchPublishedFormVersionOptions(searchText);\n setFormVersionOptions(\n mergeSelectedOption(\n readFormVersionSelectOptions(options),\n selectedFormVersionOption,\n ),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setFormVersionLoading(false);\n }\n }\n\n async function handleSearchMembers(searchText: string): Promise<void> {\n setMemberLoading(true);\n setError(null);\n\n try {\n const options = await searchMemberOptions(searchText);\n setMemberOptions((currentOptions) =>\n mergeMemberOptions(currentOptions, readMemberSelectOptions(options)),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setMemberLoading(false);\n }\n }\n\n async function resolveWorkflowMemberOptions(\n definition: WorkflowDefinition,\n ): Promise<void> {\n const memberIds = readWorkflowDirectMemberIds(definition);\n const missingMemberIds = memberIds.filter(\n (memberId) =>\n !memberOptions.some((option) => option.memberId === memberId),\n );\n\n if (missingMemberIds.length === 0) {\n return;\n }\n\n try {\n const options = await resolveMemberOptions(missingMemberIds);\n setMemberOptions((currentOptions) =>\n mergeMemberOptions(currentOptions, readMemberSelectOptions(options)),\n );\n } catch {\n setMemberOptions((currentOptions) =>\n mergeMemberOptions(\n currentOptions,\n missingMemberIds.map(readFallbackMemberSelectOption),\n ),\n );\n }\n }\n\n async function handleSaveDraft(): Promise<ApprovalTemplateVersionRecord> {\n setSaving(true);\n setError(null);\n\n try {\n const validationIssue = readWorkflowDefinitionIssue(workflowDefinition);\n const policyIssue = readInitiatorPolicyIssue(initiatorPolicyDraft);\n\n if (validationIssue || policyIssue) {\n const issue = validationIssue ?? policyIssue ?? '流程設定未完成';\n\n setError(issue);\n throw new Error(issue);\n }\n\n const targetDraft = draft ?? (await forkApprovalTemplate(templateId));\n const nextDraft = await updateApprovalTemplateDraft({\n formDefinitionVersionId,\n initiatorPolicyCel,\n versionId: targetDraft.id,\n workflowDefinition,\n });\n\n setDraft(nextDraft);\n await refreshDesigner();\n\n return nextDraft;\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n throw 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 handleSaveDraft();\n await publishApprovalTemplateVersion(savedDraft.id);\n await refreshDesigner();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n function openDryRunModal(): void {\n setDryRunFormDataJson(\n JSON.stringify(\n readDryRunSampleFormData(selectedFormVersionOption),\n null,\n 2,\n ),\n );\n setDryRunResult(null);\n setDryRunError(null);\n setDryRunModalOpen(true);\n }\n\n function closeDryRunModal(): void {\n if (dryRunRunning) {\n return;\n }\n\n setDryRunModalOpen(false);\n }\n\n async function handleDryRun(): Promise<void> {\n setDryRunRunning(true);\n setDryRunError(null);\n setDryRunResult(null);\n\n try {\n const formData = parseDryRunFormData(dryRunFormDataJson);\n const result = await dryRunApprovalWorkflow({\n formData,\n initiatorMemberId: DRY_RUN_MEMBER_ID,\n initiatorMetadataSnapshot: readDryRunInitiatorMetadataSnapshot(\n DRY_RUN_MEMBER_ID,\n memberships,\n ),\n workflowDefinition,\n });\n\n setDryRunResult(result);\n } catch (requestError: unknown) {\n setDryRunError(readErrorMessage(requestError));\n } finally {\n setDryRunRunning(false);\n }\n }\n\n function handleNodeChanges(\n changes: Parameters<typeof applyNodeChanges>[0],\n ): void {\n const nextFlowNodes = applyNodeChanges(changes, flowNodes);\n\n setWorkflowDefinition((currentDefinition) => ({\n ...currentDefinition,\n nodes: currentDefinition.nodes.map((node) => {\n const flowNode = nextFlowNodes.find(\n (candidate) => candidate.id === node.id,\n );\n\n return flowNode ? { ...node, position: flowNode.position } : node;\n }),\n }));\n }\n\n function handleConnect(connection: Connection): void {\n if (!isWorkflowConnectionValid(connection, workflowDefinition.nodes)) {\n return;\n }\n\n const shouldOpenConditionSettings = workflowDefinition.nodes.some(\n (node) =>\n node.id === connection.source && node.type === 'exclusiveGateway',\n );\n const nextEdge = createWorkflowEdge(\n connection.source,\n connection.target,\n {},\n );\n\n setWorkflowDefinition((currentDefinition) => ({\n ...currentDefinition,\n edges: [...currentDefinition.edges, nextEdge],\n }));\n setSelectedNodeId(null);\n setSelectedEdgeIds([nextEdge.id]);\n setEditingEdgeId(shouldOpenConditionSettings ? nextEdge.id : null);\n }\n\n function handleEdgeClick(event: ReactMouseEvent, edge: FlowEdge): void {\n event.stopPropagation();\n\n setSelectedEdgeIds((currentEdgeIds) =>\n event.shiftKey || event.metaKey || event.ctrlKey\n ? toggleSelectedEdgeId(currentEdgeIds, edge.id)\n : [edge.id],\n );\n setSelectedNodeId(null);\n }\n\n function closeEdgeSettingsModal(): void {\n setEditingEdgeId(null);\n }\n\n function addWorkflowNode(type: NodePaletteType): void {\n const nodeIndex = readNextWorkflowNodeIndex(workflowDefinition.nodes, type);\n const node = createWorkflowNode(type, nodeIndex);\n const inserted = insertWorkflowNodeIntoDefinition({\n definition: workflowDefinition,\n node,\n selectedEdgeId: selectedEdgeIds.length === 1 ? selectedEdgeIds[0] : null,\n selectedNodeId,\n });\n const nextDefinition = layoutWorkflowDefinition(inserted.definition);\n const nextViewport = readWorkflowViewport(\n nextDefinition,\n flowCanvasRef.current,\n );\n\n setWorkflowDefinition(nextDefinition);\n setSelectedNodeId(inserted.selectedNodeId);\n setSelectedEdgeIds(inserted.selectedEdgeIds);\n setEditingEdgeId(inserted.editingEdgeId);\n\n if (nextViewport) {\n setFlowViewport(nextViewport);\n }\n }\n\n function updateSelectedNodeLabel(label: string): void {\n if (!selectedNode) {\n return;\n }\n\n updateNode(selectedNode.id, (node) => renameWorkflowNode(node, label));\n }\n\n function updateUserTaskResolver(approverResolver: ApproverResolver): void {\n if (!selectedNode || selectedNode.type !== 'userTask') {\n return;\n }\n\n updateNode(selectedNode.id, (node) =>\n node.type === 'userTask'\n ? {\n ...node,\n data: {\n ...node.data,\n approverResolver,\n decisionPolicy: { type: 'SINGLE' },\n },\n }\n : node,\n );\n }\n\n function updateUserTaskReturnResubmitStrategy(\n resubmitStrategy: ReturnResubmitStrategy,\n ): void {\n if (!selectedNode || selectedNode.type !== 'userTask') {\n return;\n }\n\n updateNode(selectedNode.id, (node) =>\n node.type === 'userTask'\n ? {\n ...node,\n data: {\n ...node.data,\n returnBehavior: {\n ...node.data.returnBehavior,\n resubmitStrategy,\n },\n },\n }\n : node,\n );\n }\n\n function updateServiceAction(action: ServiceAction): void {\n if (!selectedNode || selectedNode.type !== 'serviceTask') {\n return;\n }\n\n updateNode(selectedNode.id, (node) =>\n node.type === 'serviceTask'\n ? {\n ...node,\n data: {\n ...node.data,\n action,\n },\n }\n : node,\n );\n }\n\n function updateInitiatorPolicyDraft(\n draft: InitiatorPolicyDraft,\n ): void {\n setInitiatorPolicyDraftOverride(\n draft.mode === 'ALL' || draft.mode === 'CUSTOM' ? null : draft,\n );\n setInitiatorPolicyModeDraft(\n draft.mode === 'ALL' || draft.mode === 'CUSTOM' ? null : draft.mode,\n );\n setInitiatorPolicyCel(readInitiatorPolicyCel(draft, orgUnits));\n }\n\n function updateSelectedNodeTriggerMode(\n triggerMode: WorkflowNodeTriggerMode,\n ): void {\n if (!selectedNode || selectedNode.type === 'startEvent') {\n return;\n }\n\n updateNode(selectedNode.id, (node) =>\n applyWorkflowNodeTriggerMode(node, triggerMode),\n );\n }\n\n function updateNode(\n nodeId: string,\n updater: (node: WorkflowNode) => WorkflowNode,\n ): void {\n setWorkflowDefinition((currentDefinition) => ({\n ...currentDefinition,\n nodes: currentDefinition.nodes.map((node) =>\n node.id === nodeId ? updater(node) : node,\n ),\n }));\n }\n\n function updateWorkflowEdge(\n edgeId: string,\n updater: (edge: WorkflowEdge) => WorkflowEdge,\n ): void {\n setWorkflowDefinition((currentDefinition) => ({\n ...currentDefinition,\n edges: currentDefinition.edges.map((edge) =>\n edge.id === edgeId ? updater(edge) : edge,\n ),\n }));\n }\n\n function updateSelectedEdgeDefault(edgeId: string, checked: boolean): void {\n setWorkflowDefinition((currentDefinition) => {\n const targetEdge = currentDefinition.edges.find(\n (edge) => edge.id === edgeId,\n );\n\n if (!targetEdge) {\n return currentDefinition;\n }\n\n return {\n ...currentDefinition,\n edges: currentDefinition.edges.map((edge) => {\n if (\n checked &&\n edge.source === targetEdge.source &&\n edge.id !== targetEdge.id &&\n isExclusiveGatewaySourceEdge(edge, currentDefinition.nodes)\n ) {\n return {\n ...edge,\n data: {\n ...edge.data,\n isDefault: false,\n },\n };\n }\n\n return edge.id === targetEdge.id\n ? {\n ...edge,\n data: {\n ...edge.data,\n isDefault: checked,\n },\n }\n : edge;\n }),\n };\n });\n }\n\n function updateSelectedEdgeConditionState({\n edgeId,\n fieldKey,\n operator,\n value,\n }: {\n readonly edgeId: string;\n readonly fieldKey?: string | null;\n readonly operator?: WorkflowEdgeConditionOperator | null;\n readonly value?: string | null;\n }): void {\n const schema = selectedFormVersionOption?.schema ?? null;\n\n updateWorkflowEdge(edgeId, (currentEdge) => {\n const nextFieldKey =\n fieldKey ?? currentEdge.data.conditionFieldKey ?? null;\n const field = readConditionField(schema, nextFieldKey);\n const nextOperator = readNextConditionOperator(\n field,\n operator ?? currentEdge.data.conditionOperator ?? null,\n );\n const nextValue = readNextConditionValue(\n field,\n nextOperator,\n value ?? currentEdge.data.conditionValue ?? null,\n );\n const nextLabel = readConditionLabel(field, nextOperator, nextValue);\n\n return {\n ...currentEdge,\n data: {\n ...currentEdge.data,\n condition: readConditionExpression(field, nextOperator, nextValue),\n conditionFieldKey: field?.fieldKey,\n conditionOperator: nextOperator,\n conditionValue: nextValue,\n isDefault: false,\n label: nextLabel,\n },\n };\n });\n }\n\n function applyAutoLayout(): void {\n const nextDefinition = layoutWorkflowDefinition(workflowDefinition);\n const nextViewport = readWorkflowViewport(\n nextDefinition,\n flowCanvasRef.current,\n );\n\n setWorkflowDefinition(nextDefinition);\n\n if (nextViewport) {\n setFlowViewport(nextViewport);\n }\n }\n\n return (\n <>\n <style>{SIDE_PANEL_GLOBAL_STYLE}</style>\n <PageHeader>\n <ContentHeader\n description={`${draft ? `草稿 v${draft.version}` : '尚未建立草稿'} ·${\n record?.template.currentVersionId ? ' 已發布版本' : ' 尚未發布'\n }`}\n onBackClick={handleBackToTemplates}\n title={record?.template.name ?? '流程設計器'}\n >\n <Button\n aria-label=\"儲存草稿\"\n disabled={\n saving ||\n Boolean(workflowIssue) ||\n Boolean(initiatorPolicyIssue)\n }\n icon={SaveIcon}\n iconType=\"icon-only\"\n onClick={(): void => void handleSaveDraft()}\n variant=\"base-secondary\"\n >\n 儲存草稿\n </Button>\n <Button\n disabled={\n loading ||\n Boolean(workflowIssue) ||\n Boolean(initiatorPolicyIssue)\n }\n icon={EyeIcon}\n iconType=\"leading\"\n onClick={openDryRunModal}\n variant=\"base-secondary\"\n >\n 試跑流程\n </Button>\n <Button\n disabled={\n saving ||\n !draft ||\n Boolean(workflowIssue) ||\n Boolean(initiatorPolicyIssue)\n }\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={(): void => void handlePublish()}\n variant=\"base-primary\"\n >\n 發布版本\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={WORKSPACE_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {workflowIssue ? (\n <Typography color=\"text-error\" variant=\"body\">\n {workflowIssue}\n </Typography>\n ) : null}\n {initiatorPolicyIssue ? (\n <Typography color=\"text-error\" variant=\"body\">\n {initiatorPolicyIssue}\n </Typography>\n ) : null}\n <div style={FORM_STACK_STYLE}>\n <BPMFormField\n hintText={\n formVersionBindingLocked\n ? '已設定條件分流條件。請先移除所有條件,才能更換綁定表單版本。'\n : undefined\n }\n label=\"綁定表單版本\"\n name=\"formDefinitionVersionId\"\n required\n >\n <AutoComplete\n asyncData\n disabled={loading || formVersionBindingLocked}\n disabledOptionsFilter\n emptyText=\"沒有符合的已發布表單版本\"\n isForceClearable={\n Boolean(formDefinitionVersionId) &&\n !formVersionBindingLocked\n }\n loading={formVersionLoading}\n loadingText=\"搜尋表單版本中...\"\n mode=\"single\"\n onChange={(option): void => {\n if (!formVersionBindingLocked) {\n setFormDefinitionVersionId(option?.id ?? null);\n }\n }}\n onClear={(): void => {\n if (!formVersionBindingLocked) {\n setFormDefinitionVersionId(null);\n }\n }}\n onSearch={handleSearchFormVersions}\n onVisibilityChange={(open): void => {\n if (open && !formVersionBindingLocked) {\n void handleSearchFormVersions('');\n }\n }}\n options={[...visibleFormVersionOptions]}\n placeholder=\"選擇已發布表單版本\"\n searchDebounceTime={300}\n value={selectedFormVersionOption}\n />\n </BPMFormField>\n </div>\n <div style={TWO_COLUMN_STYLE}>\n <div ref={flowCanvasRef} style={FLOW_CANVAS_STYLE}>\n <ReactFlow\n connectionMode={ConnectionMode.Strict}\n edges={flowEdges}\n fitView\n isValidConnection={(connection): boolean =>\n isWorkflowConnectionValid(\n connection,\n workflowDefinition.nodes,\n )\n }\n nodeTypes={nodeTypes}\n nodes={flowNodes}\n deleteKeyCode={null}\n multiSelectionKeyCode={['Shift', 'Meta', 'Control']}\n onConnect={handleConnect}\n onEdgeClick={handleEdgeClick}\n onNodeClick={(_, node): void => {\n setSelectedNodeId(node.id);\n setSelectedEdgeIds([]);\n }}\n onNodesChange={handleNodeChanges}\n onPaneClick={(): void => {\n setSelectedNodeId(null);\n setSelectedEdgeIds([]);\n }}\n onViewportChange={setFlowViewport}\n viewport={flowViewport}\n >\n <Background />\n <style>{FLOW_CANVAS_GLOBAL_STYLE}</style>\n <Controls>\n {hasDeletableSelection ? (\n <ControlButton\n aria-label=\"刪除選取項目\"\n className=\"workflow-selection-delete-control\"\n onClick={removeSelectedWorkflowElements}\n style={SELECTION_DELETE_CONTROL_BUTTON_STYLE}\n title=\"刪除選取項目\"\n >\n <span style={SELECTION_DELETE_CONTROL_ICON_STYLE}>\n <Icon color=\"error\" icon={TrashIcon} size={16} />\n </span>\n </ControlButton>\n ) : null}\n </Controls>\n <AutoLayoutPanel onApplyAutoLayout={applyAutoLayout} />\n <MiniMap />\n </ReactFlow>\n </div>\n <div className={SIDE_PANEL_CLASS_NAME} style={PANEL_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 流程工具\n </Typography>\n <div style={TOOL_GROUP_STYLE}>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 動作節點\n </Typography>\n <div style={BUTTON_ROW_STYLE}>\n {ACTION_NODE_PALETTE.map((item) => (\n <Button\n icon={item.icon}\n iconType=\"leading\"\n key={item.type}\n onClick={(): void => addWorkflowNode(item.type)}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n {item.label}\n </Button>\n ))}\n </div>\n </div>\n <div style={TOOL_GROUP_STYLE}>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 流程控制\n </Typography>\n <div style={BUTTON_ROW_STYLE}>\n {FLOW_CONTROL_PALETTE.map((item) => (\n <Button\n icon={item.icon}\n iconType=\"leading\"\n key={item.type}\n onClick={(): void => addWorkflowNode(item.type)}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n {item.label}\n </Button>\n ))}\n </div>\n </div>\n {selectedEdges.length > 1\n ? renderSelectedEdgesPanel(selectedEdges)\n : null}\n {selectedEdges.length === 1 && selectedEdge\n ? renderEdgePanel(selectedEdge)\n : null}\n {selectedEdges.length === 0 && selectedNode\n ? renderNodePanel(selectedNode)\n : null}\n </div>\n </div>\n </div>\n </Section>\n </SectionGroup>\n {renderEdgeSettingsModal(editingEdge)}\n {renderDryRunModal()}\n </>\n );\n\n function renderDryRunModal(): ReactElement {\n return (\n <Modal\n cancelText=\"關閉\"\n confirmText=\"執行試跑\"\n loading={dryRunRunning}\n modalType=\"standard\"\n onCancel={closeDryRunModal}\n onClose={closeDryRunModal}\n onConfirm={(): void => void handleDryRun()}\n open={dryRunModalOpen}\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText={`使用 ${DRY_RUN_MEMBER_ID} 與範例表單資料模擬目前畫布流程,不會建立案件。`}\n title=\"試跑流程\"\n >\n <div style={FORM_STACK_STYLE}>\n <BPMFormField\n label=\"表單資料 JSON\"\n name=\"dryRunFormDataJson\"\n required\n >\n <Textarea\n onChange={(event: ChangeEvent<HTMLTextAreaElement>): void =>\n setDryRunFormDataJson(event.target.value)\n }\n resize=\"vertical\"\n rows={8}\n value={dryRunFormDataJson}\n />\n </BPMFormField>\n {dryRunError ? (\n <Typography color=\"text-error\" variant=\"body\">\n {dryRunError}\n </Typography>\n ) : null}\n {dryRunResult ? (\n <div style={DRY_RUN_RESULT_STYLE}>\n <Typography\n color={dryRunResult.valid ? 'text-success' : 'text-error'}\n variant=\"label-primary-highlight\"\n >\n {dryRunResult.valid ? '試跑通過' : '試跑失敗'}\n </Typography>\n {dryRunResult.errors.map((resultError) => (\n <Typography color=\"text-error\" key={resultError} variant=\"body\">\n {resultError}\n </Typography>\n ))}\n {dryRunResult.steps.map((step) => (\n <div key={step.id} style={DRY_RUN_STEP_STYLE}>\n <Typography variant=\"label-primary-highlight\">\n {step.nodeLabel} · {readDryRunStatusLabel(step.status)}\n </Typography>\n <Typography color=\"text-neutral\" variant=\"caption\">\n {readWorkflowNodeTypeLabel(step.nodeType)}\n {step.assigneeMemberId\n ? ` · 處理者:${step.assigneeMemberId}`\n : ''}\n {step.edgeLabel ? ` · 來源線段:${step.edgeLabel}` : ''}\n </Typography>\n {step.edgeReason ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n {step.edgeReason}\n </Typography>\n ) : null}\n {step.entryCondition ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 進入條件:\n {step.entryConditionMatched ? '符合' : '不符合'} ·{' '}\n {step.entryCondition}\n </Typography>\n ) : null}\n <Typography color=\"text-neutral\" variant=\"body\">\n {step.message}\n </Typography>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n </Modal>\n );\n }\n\n function renderNodePanel(node: WorkflowNode): ReactElement {\n return (\n <div style={FORM_STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 節點屬性\n </Typography>\n <Typography color=\"text-neutral\" variant=\"body\">\n {NODE_TYPE_LABELS[node.type]} · {node.id}\n </Typography>\n <BPMFormField label=\"顯示名稱\" name=\"nodeLabel\" required>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedNodeLabel(event.target.value)\n }\n value={node.data.label}\n variant=\"base\"\n />\n </BPMFormField>\n {node.type === 'startEvent' ? renderStartEventPanel() : null}\n {node.type !== 'startEvent' ? renderNodeTriggerModePanel(node) : null}\n {node.type === 'userTask' ? renderUserTaskPanel(node) : null}\n {node.type === 'serviceTask' ? renderServiceTaskPanel(node) : null}\n </div>\n );\n }\n\n function renderStartEventPanel(): ReactElement {\n const policyModeOptions =\n initiatorPolicyDraft.mode === 'CUSTOM'\n ? [...INITIATOR_POLICY_MODE_OPTIONS, INITIATOR_POLICY_CUSTOM_OPTION]\n : [...INITIATOR_POLICY_MODE_OPTIONS];\n const selectedInitiatorOrgUnit =\n initiatorPolicyDraft.mode === 'ORG_UNIT' ||\n initiatorPolicyDraft.mode === 'ORG_UNIT_POSITION'\n ? readSelectedOrgUnitOption(\n orgUnits,\n initiatorPolicyDraft.orgUnitId ?? '',\n )\n : null;\n const selectedInitiatorPosition =\n initiatorPolicyDraft.mode === 'ORG_UNIT_POSITION'\n ? readSelectedPositionOption(\n positions,\n initiatorPolicyDraft.positionId ?? '',\n )\n : null;\n const initiatorScopedPositions =\n initiatorPolicyDraft.mode === 'ORG_UNIT_POSITION'\n ? readOrgScopedPositions({\n includeDescendants: Boolean(\n initiatorPolicyDraft.includeDescendants,\n ),\n memberships,\n orgUnitId: initiatorPolicyDraft.orgUnitId ?? '',\n orgUnits,\n positions,\n })\n : [];\n\n return (\n <>\n <BPMFormField\n hintText={\n initiatorPolicyDraft.mode === 'CUSTOM'\n ? '這是舊版表達式規則;切換成標準選項後會改由 UI 管理。'\n : undefined\n }\n label=\"發起權限\"\n name=\"initiatorPolicyMode\"\n required\n >\n <Select\n clearable={false}\n onChange={(option): void => {\n if (option?.id === 'CUSTOM') {\n setInitiatorPolicyModeDraft(null);\n setInitiatorPolicyDraftOverride(null);\n\n return;\n }\n\n const mode = readInitiatorPolicyMode(option?.id ?? null);\n const draft = readDefaultInitiatorPolicyDraft(mode);\n\n setInitiatorPolicyModeDraft(mode === 'ALL' ? null : mode);\n setInitiatorPolicyDraftOverride(mode === 'ALL' ? null : draft);\n setInitiatorPolicyCel(\n readInitiatorPolicyCel(draft, orgUnits),\n );\n }}\n options={policyModeOptions}\n placeholder=\"選擇誰可以發起\"\n value={readSelectOption(\n policyModeOptions,\n initiatorPolicyDraft.mode,\n )}\n />\n </BPMFormField>\n {initiatorPolicyDraft.mode === 'ORG_UNIT' ||\n initiatorPolicyDraft.mode === 'ORG_UNIT_POSITION' ? (\n <BPMFormField label=\"組織\" name=\"initiatorOrgUnitId\" required>\n <OrgUnitPicker\n name=\"initiatorOrgUnitId\"\n onChange={(option): void =>\n updateInitiatorPolicyDraft({\n ...initiatorPolicyDraft,\n orgUnitId: option?.id ?? '',\n positionId: '',\n value: option?.id ?? '',\n })\n }\n orgUnits={orgUnits}\n placeholder=\"選擇組織\"\n value={selectedInitiatorOrgUnit}\n />\n </BPMFormField>\n ) : null}\n {initiatorPolicyDraft.mode === 'ORG_UNIT' ||\n initiatorPolicyDraft.mode === 'ORG_UNIT_POSITION' ? (\n <BPMFormField label=\"包含下層\" name=\"initiatorIncludeDescendants\">\n <Toggle\n checked={Boolean(initiatorPolicyDraft.includeDescendants)}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateInitiatorPolicyDraft({\n ...initiatorPolicyDraft,\n includeDescendants: event.target.checked,\n ...(initiatorPolicyDraft.mode === 'ORG_UNIT_POSITION'\n ? { positionId: '' }\n : {}),\n })\n }\n />\n </BPMFormField>\n ) : null}\n {initiatorPolicyDraft.mode === 'ORG_UNIT_POSITION' ? (\n <BPMFormField label=\"職位\" name=\"initiatorPositionId\" required>\n <PositionPicker\n disabled={!initiatorPolicyDraft.orgUnitId?.trim()}\n name=\"initiatorPositionId\"\n onChange={(option): void =>\n updateInitiatorPolicyDraft({\n ...initiatorPolicyDraft,\n positionId: option?.id ?? '',\n })\n }\n placeholder={\n initiatorPolicyDraft.orgUnitId?.trim()\n ? '選擇職位'\n : '請先選擇組織'\n }\n positions={initiatorScopedPositions}\n value={selectedInitiatorPosition}\n />\n </BPMFormField>\n ) : null}\n </>\n );\n }\n\n function renderNodeTriggerModePanel(\n node: Exclude<WorkflowNode, { type: 'startEvent' }>,\n ): ReactElement {\n const incomingEdgeCount = workflowDefinition.edges.filter(\n (edge) => edge.target === node.id,\n ).length;\n const triggerModeLocked = incomingEdgeCount < 2;\n const triggerMode = triggerModeLocked\n ? 'AND'\n : (node.data.triggerMode ?? 'AND');\n\n return (\n <BPMFormField\n hintText={\n triggerModeLocked\n ? '需要至少兩條前置連線,才可切換為任一前置完成。'\n : incomingEdgeCount > 1\n ? `${incomingEdgeCount} 條前置連線會依此規則觸發。`\n : '只有一條前置連線時,兩種設定效果相同。'\n }\n label=\"前置條件\"\n name=\"triggerMode\"\n required\n >\n <Select\n clearable={false}\n onChange={(option): void =>\n triggerModeLocked\n ? undefined\n : updateSelectedNodeTriggerMode(\n readWorkflowNodeTriggerMode(option?.id ?? null),\n )\n }\n options={[...NODE_TRIGGER_MODE_OPTIONS]}\n readOnly={triggerModeLocked}\n value={readSelectOption(NODE_TRIGGER_MODE_OPTIONS, triggerMode)}\n />\n </BPMFormField>\n );\n }\n\n function renderUserTaskPanel(\n node: Extract<WorkflowNode, { type: 'userTask' }>,\n ): ReactElement {\n const resolver = node.data.approverResolver;\n const resolverMode = readApproverResolverMode(resolver.type);\n const selectedMember =\n resolver.type === 'DIRECT'\n ? readPrimaryMemberOption(resolver.memberIds, memberOptions)\n : null;\n const selectedOrgUnit =\n resolver.type === 'ORG_UNIT_MANAGER' ||\n resolver.type === 'ORG_UNIT_MEMBER' ||\n resolver.type === 'ORG_UNIT_POSITION'\n ? readSelectedOrgUnitOption(orgUnits, resolver.orgUnitId)\n : null;\n const selectedPosition =\n resolver.type === 'POSITION' || resolver.type === 'ORG_UNIT_POSITION'\n ? readSelectedPositionOption(positions, resolver.positionId)\n : null;\n const orgScopedPositions =\n resolver.type === 'ORG_UNIT_POSITION'\n ? readOrgScopedPositions({\n includeDescendants: Boolean(resolver.includeDescendants),\n memberships,\n orgUnitId: resolver.orgUnitId,\n orgUnits,\n positions,\n })\n : [];\n const selectedManagerLevel =\n resolver.type === 'ORG_MANAGER'\n ? readManagerLevelOption(resolver.levelsUp)\n : MANAGER_LEVEL_OPTIONS[0];\n const fallback =\n resolver.type === 'ORG_MANAGER' || resolver.type === 'ORG_UNIT_MANAGER'\n ? (resolver.fallback ?? { type: 'NONE' as const })\n : { type: 'NONE' as const };\n const fallbackMember =\n fallback.type === 'DIRECT'\n ? readMemberSelectOption(memberOptions, fallback.memberId)\n : null;\n const resubmitStrategy =\n node.data.returnBehavior.resubmitStrategy ?? 'RESTART';\n\n return (\n <>\n <BPMFormField label=\"簽核來源\" name=\"approverResolverType\" required>\n <Select\n clearable={false}\n onChange={(option): void =>\n updateUserTaskResolver(\n readDefaultApproverResolver(option?.id ?? null),\n )\n }\n options={[...APPROVER_RESOLVER_MODE_OPTIONS]}\n value={readSelectOption(\n APPROVER_RESOLVER_MODE_OPTIONS,\n resolverMode,\n )}\n />\n </BPMFormField>\n {resolver.type === 'DIRECT' ? (\n <BPMFormField label=\"簽核者\" name=\"memberId\" required>\n <AutoComplete\n asyncData\n disabledOptionsFilter\n emptyText=\"沒有符合的成員\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'workflow-approver-search',\n spellCheck: false,\n }}\n loading={memberLoading}\n loadingText=\"搜尋成員中...\"\n mode=\"single\"\n onChange={(option): void =>\n updateUserTaskResolver({\n memberIds: option?.id ? [option.id] : [],\n type: 'DIRECT',\n })\n }\n onSearch={handleSearchMembers}\n onVisibilityChange={(open): void => {\n if (open) {\n void handleSearchMembers('');\n }\n }}\n options={[...memberOptions]}\n placeholder=\"搜尋姓名或信箱\"\n searchDebounceTime={300}\n value={selectedMember}\n />\n </BPMFormField>\n ) : null}\n {resolver.type === 'ORG_MANAGER' ? (\n <BPMFormField\n hintText=\"依發起人的有效會員歸屬與主管解析規則決定簽核人。\"\n label=\"主管層級\"\n name=\"managerLevelsUp\"\n required\n >\n <Select\n clearable={false}\n onChange={(option): void =>\n updateUserTaskResolver({\n baseFromInitiator: true,\n levelsUp: readManagerLevelOptionById(option?.id ?? null)\n .value,\n type: 'ORG_MANAGER',\n })\n }\n options={[...MANAGER_LEVEL_OPTIONS]}\n value={selectedManagerLevel}\n />\n </BPMFormField>\n ) : null}\n {resolver.type === 'ORG_UNIT_MANAGER' ||\n resolver.type === 'ORG_UNIT_MEMBER' ||\n resolver.type === 'ORG_UNIT_POSITION' ? (\n <BPMFormField\n hintText={\n resolver.type === 'ORG_UNIT_MANAGER'\n ? '依指定組織或其上層的主管解析規則決定簽核人。'\n : '依指定組織目前有效會員歸屬建立候選簽核人。'\n }\n label=\"組織\"\n name=\"orgUnitId\"\n required\n >\n <OrgUnitPicker\n name=\"orgUnitId\"\n onChange={(option): void =>\n updateUserTaskResolver(\n resolver.type === 'ORG_UNIT_MEMBER'\n ? {\n includeDescendants: resolver.includeDescendants,\n orgUnitId: option?.id ?? '',\n type: 'ORG_UNIT_MEMBER',\n }\n : resolver.type === 'ORG_UNIT_POSITION'\n ? {\n includeDescendants: resolver.includeDescendants,\n orgUnitId: option?.id ?? '',\n positionId: '',\n type: 'ORG_UNIT_POSITION',\n }\n : {\n fallback: resolver.fallback,\n orgUnitId: option?.id ?? '',\n type: 'ORG_UNIT_MANAGER',\n },\n )\n }\n orgUnits={orgUnits}\n placeholder=\"選擇組織\"\n value={selectedOrgUnit}\n />\n </BPMFormField>\n ) : null}\n {resolver.type === 'ORG_MANAGER' ||\n resolver.type === 'ORG_UNIT_MANAGER' ? (\n <>\n <BPMFormField\n hintText=\"預設會停止流程並提示;若設定固定人,找不到主管時會改派給該會員。\"\n label=\"無主管時\"\n name=\"approverFallbackMode\"\n required\n >\n <Select\n clearable={false}\n onChange={(option): void =>\n updateUserTaskResolver(\n updateApproverResolverFallback(\n resolver,\n readApproverFallbackMode(option?.id ?? null) === 'DIRECT'\n ? { memberId: '', type: 'DIRECT' }\n : { type: 'NONE' },\n ),\n )\n }\n options={[...APPROVER_FALLBACK_MODE_OPTIONS]}\n value={readSelectOption(\n APPROVER_FALLBACK_MODE_OPTIONS,\n fallback.type,\n )}\n />\n </BPMFormField>\n {fallback.type === 'DIRECT' ? (\n <>\n <BPMFormField\n label=\"改派人員\"\n name=\"approverFallbackMemberId\"\n required\n >\n <AutoComplete\n asyncData\n disabledOptionsFilter\n emptyText=\"沒有符合的成員\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'workflow-approver-fallback-search',\n spellCheck: false,\n }}\n loading={memberLoading}\n loadingText=\"搜尋成員中...\"\n mode=\"single\"\n onChange={(option): void =>\n updateUserTaskResolver(\n updateApproverResolverFallback(resolver, {\n allowInitiatorSelfApproval:\n fallback.allowInitiatorSelfApproval,\n memberId: option?.id ?? '',\n type: 'DIRECT',\n }),\n )\n }\n onSearch={handleSearchMembers}\n onVisibilityChange={(open): void => {\n if (open) {\n void handleSearchMembers('');\n }\n }}\n options={[...memberOptions]}\n placeholder=\"搜尋姓名或信箱\"\n searchDebounceTime={300}\n value={fallbackMember}\n />\n </BPMFormField>\n <BPMFormField\n hintText=\"預設禁止申請人簽自己的案件;只有此流程允許自簽時才開啟。\"\n label=\"允許自簽\"\n name=\"allowInitiatorSelfApproval\"\n >\n <Toggle\n checked={Boolean(fallback.allowInitiatorSelfApproval)}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateUserTaskResolver(\n updateApproverResolverFallback(resolver, {\n allowInitiatorSelfApproval: event.target.checked,\n memberId: fallback.memberId,\n type: 'DIRECT',\n }),\n )\n }\n />\n </BPMFormField>\n </>\n ) : null}\n </>\n ) : null}\n {resolver.type === 'ORG_UNIT_MEMBER' ||\n resolver.type === 'ORG_UNIT_POSITION' ? (\n <BPMFormField label=\"包含下層\" name=\"includeDescendants\">\n <Toggle\n checked={Boolean(resolver.includeDescendants)}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateUserTaskResolver({\n ...resolver,\n includeDescendants: event.target.checked,\n ...(resolver.type === 'ORG_UNIT_POSITION'\n ? { positionId: '' }\n : {}),\n })\n }\n />\n </BPMFormField>\n ) : null}\n {resolver.type === 'POSITION' ? (\n <BPMFormField\n hintText=\"指派給目前有效歸屬中擁有此職位的會員;主要歸屬優先。\"\n label=\"職位\"\n name=\"positionId\"\n required\n >\n <PositionPicker\n name=\"positionId\"\n onChange={(option): void =>\n updateUserTaskResolver({\n positionId: option?.id ?? '',\n type: 'POSITION',\n })\n }\n placeholder=\"選擇職位\"\n positions={positions}\n value={selectedPosition}\n />\n </BPMFormField>\n ) : null}\n {resolver.type === 'ORG_UNIT_POSITION' ? (\n <BPMFormField\n hintText=\"只納入指定組織範圍內擁有此職位的有效會員。\"\n label=\"職位\"\n name=\"orgUnitPositionId\"\n required\n >\n <PositionPicker\n disabled={!resolver.orgUnitId.trim()}\n name=\"orgUnitPositionId\"\n onChange={(option): void =>\n updateUserTaskResolver({\n includeDescendants: resolver.includeDescendants,\n orgUnitId: resolver.orgUnitId,\n positionId: option?.id ?? '',\n type: 'ORG_UNIT_POSITION',\n })\n }\n placeholder={\n resolver.orgUnitId.trim() ? '選擇職位' : '請先選擇組織'\n }\n positions={orgScopedPositions}\n value={selectedPosition}\n />\n </BPMFormField>\n ) : null}\n {node.data.returnBehavior.allowReturn ? (\n <BPMFormField\n hintText=\"退回發起人後,重新送出時要從流程開始重跑,或直接回到退回的簽核節點。\"\n label=\"重送策略\"\n name=\"returnResubmitStrategy\"\n required\n >\n <Select\n clearable={false}\n onChange={(option): void =>\n updateUserTaskReturnResubmitStrategy(\n readReturnResubmitStrategy(option?.id ?? null),\n )\n }\n options={[...RETURN_RESUBMIT_STRATEGY_OPTIONS]}\n value={readSelectOption(\n RETURN_RESUBMIT_STRATEGY_OPTIONS,\n resubmitStrategy,\n )}\n />\n </BPMFormField>\n ) : null}\n </>\n );\n }\n\n function renderServiceTaskPanel(\n node: Extract<WorkflowNode, { type: 'serviceTask' }>,\n ): ReactElement {\n const selectedMembers = readServiceTaskMemberIds(node.data.action).map(\n (memberId) => readMemberSelectOption(memberOptions, memberId),\n );\n\n return (\n <BPMFormField label=\"知會對象\" name=\"notifyMemberIds\" required>\n <AutoComplete\n asyncData\n disabledOptionsFilter\n emptyText=\"沒有符合的成員\"\n loading={memberLoading}\n loadingText=\"搜尋成員中...\"\n mode=\"multiple\"\n onChange={(options): void =>\n updateServiceAction({\n channels: ['IN_APP'],\n recipients: {\n memberIds: options.map((option) => option.id),\n type: 'DIRECT',\n },\n type: 'NOTIFY',\n })\n }\n onSearch={handleSearchMembers}\n onVisibilityChange={(open): void => {\n if (open) {\n void handleSearchMembers('');\n }\n }}\n options={[...memberOptions]}\n overflowStrategy=\"wrap\"\n placeholder=\"搜尋姓名或信箱\"\n searchDebounceTime={300}\n value={[...selectedMembers]}\n />\n </BPMFormField>\n );\n }\n\n function renderSelectedEdgesPanel(\n edges: readonly WorkflowEdge[],\n ): ReactElement {\n return (\n <div style={FORM_STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 已選取線段\n </Typography>\n <Typography color=\"text-neutral\" variant=\"body\">\n 已選取 {edges.length} 條線段,可使用 Delete 或控制面板刪除。\n </Typography>\n </div>\n );\n }\n\n function renderEdgePanel(edge: WorkflowEdge): ReactElement {\n const isConditionPath = isExclusiveGatewaySourceEdge(\n edge,\n workflowDefinition.nodes,\n );\n\n return (\n <div style={FORM_STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n {isConditionPath ? '條件設定' : '線段屬性'}\n </Typography>\n <Typography color=\"text-neutral\" variant=\"body\">\n {edge.source} → {edge.target}\n </Typography>\n {isConditionPath ? (\n renderConditionEdgeSettingsForm(edge)\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 這條線會直接把流程送到下一個節點。\n </Typography>\n )}\n </div>\n );\n }\n\n function renderEdgeSettingsModal(\n edge: WorkflowEdge | null,\n ): ReactElement | null {\n if (!edge) {\n return null;\n }\n\n const isConditionPath = isExclusiveGatewaySourceEdge(\n edge,\n workflowDefinition.nodes,\n );\n\n if (!isConditionPath) {\n return null;\n }\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !edge.data.isDefault && !edge.data.condition,\n }}\n confirmText=\"完成\"\n modalType=\"standard\"\n onCancel={closeEdgeSettingsModal}\n onClose={closeEdgeSettingsModal}\n onConfirm={closeEdgeSettingsModal}\n open={Boolean(editingEdgeId)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"條件分流的輸出連線需要指定條件,條件會直接顯示在線上。\"\n title=\"條件設定\"\n >\n {renderConditionEdgeSettingsForm(edge)}\n </Modal>\n );\n }\n\n function renderConditionEdgeSettingsForm(edge: WorkflowEdge): ReactElement {\n const pathLabelPreview = readEdgeCanvasLabel(\n edge,\n workflowDefinition.nodes,\n );\n const conditionFieldOptions = readConditionFieldOptions(\n selectedFormVersionOption?.schema ?? null,\n );\n const selectedConditionField = readConditionField(\n selectedFormVersionOption?.schema ?? null,\n edge.data.conditionFieldKey ?? null,\n );\n const conditionOperatorOptions = readConditionOperatorOptions(\n selectedConditionField,\n );\n const conditionValueOptions = readConditionValueOptions(\n selectedConditionField,\n );\n const selectedConditionOperator = readSelectOption(\n conditionOperatorOptions,\n edge.data.conditionOperator ?? null,\n );\n const pathLabelIsIncomplete = !edge.data.isDefault && !edge.data.condition;\n\n return (\n <div style={FORM_STACK_STYLE}>\n <Typography color=\"text-neutral\" variant=\"body\">\n 畫布上的這條線目前會顯示「\n <span\n style={{\n color: pathLabelIsIncomplete\n ? INCOMPLETE_CONDITION_EDGE_COLOR\n : undefined,\n }}\n >\n {pathLabelPreview ?? '請設定條件'}\n </span>\n 」。\n </Typography>\n <Toggle\n checked={Boolean(edge.data.isDefault)}\n label=\"其他情況走這條\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedEdgeDefault(edge.id, event.target.checked)\n }\n />\n {edge.data.isDefault ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 其他條件都不符合時,流程會走這條線。\n </Typography>\n ) : (\n <>\n {!selectedFormVersionOption ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 請先綁定表單版本,才能選擇條件欄位。\n </Typography>\n ) : null}\n <BPMFormField label=\"條件欄位\" name=\"edgeConditionField\" required>\n <Select\n clearable={false}\n onChange={(option): void =>\n updateSelectedEdgeConditionState({\n edgeId: edge.id,\n fieldKey: option?.id ?? null,\n operator: null,\n value: null,\n })\n }\n options={[...conditionFieldOptions]}\n placeholder=\"選擇條件欄位\"\n value={readSelectOption(\n conditionFieldOptions,\n edge.data.conditionFieldKey ?? null,\n )}\n />\n </BPMFormField>\n <BPMFormField\n label=\"條件判斷\"\n name=\"edgeConditionOperator\"\n required\n >\n <Select\n clearable={false}\n onChange={(option): void =>\n updateSelectedEdgeConditionState({\n edgeId: edge.id,\n operator: readConditionOperator(option?.id ?? null),\n value: null,\n })\n }\n options={[...conditionOperatorOptions]}\n placeholder=\"選擇判斷方式\"\n value={selectedConditionOperator}\n />\n </BPMFormField>\n {selectedConditionOperator &&\n shouldConditionOperatorUseValue(selectedConditionOperator.id) ? (\n <BPMFormField label=\"條件值\" name=\"edgeConditionValue\" required>\n {conditionValueOptions.length > 0 ? (\n <Select\n clearable={false}\n onChange={(option): void =>\n updateSelectedEdgeConditionState({\n edgeId: edge.id,\n value: option?.id ?? null,\n })\n }\n options={[...conditionValueOptions]}\n placeholder=\"選擇條件值\"\n value={readSelectOption(\n conditionValueOptions,\n edge.data.conditionValue ?? null,\n )}\n />\n ) : (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedEdgeConditionState({\n edgeId: edge.id,\n value: event.target.value,\n })\n }\n placeholder=\"輸入要比對的值\"\n value={edge.data.conditionValue ?? ''}\n variant=\"base\"\n />\n )}\n </BPMFormField>\n ) : null}\n </>\n )}\n </div>\n );\n }\n}\n\nfunction AutoLayoutPanel({\n onApplyAutoLayout,\n}: {\n readonly onApplyAutoLayout: () => void;\n}): ReactElement {\n function handleAutoLayout(): void {\n onApplyAutoLayout();\n }\n\n return (\n <Panel position=\"top-right\">\n <Button\n icon={DotGridIcon}\n iconType=\"leading\"\n onClick={handleAutoLayout}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 自動排版\n </Button>\n </Panel>\n );\n}\n\nfunction WorkflowNodeCard({\n data,\n selected,\n type,\n}: NodeProps<FlowNode>): ReactElement {\n const primaryLabels = data.approverLines ?? [\n data.approverSummary ?? data.label,\n ];\n const secondaryLabel = readWorkflowNodeSecondaryLabel(data);\n const nodeStyle = readWorkflowNodeCardStyle(type, selected);\n\n return (\n <div style={nodeStyle}>\n {renderWorkflowNodeHandles(data)}\n <div style={NODE_PRIMARY_LABELS_STYLE}>\n {primaryLabels.map((primaryLabel, index) => (\n <Typography\n component=\"span\"\n ellipsis\n key={`${primaryLabel}_${index}`}\n style={NODE_TEXT_STYLE}\n title={primaryLabel}\n variant=\"label-primary\"\n >\n {primaryLabel}\n </Typography>\n ))}\n </div>\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n style={NODE_TEXT_STYLE}\n title={secondaryLabel}\n variant=\"caption\"\n >\n {secondaryLabel}\n </Typography>\n </div>\n );\n}\n\nfunction readWorkflowNodeSecondaryLabel(data: FlowNodeData): string {\n if (data.nodeKind === 'startEvent') {\n return data.initiatorPolicySummary ?? '所有人';\n }\n\n if (data.approverSummary || data.approverLines) {\n return data.label;\n }\n\n if (data.nodeKind === 'exclusiveGateway') {\n return '條件在線上';\n }\n\n if (data.nodeKind === 'parallelGateway') {\n return '多條路徑同時進行';\n }\n\n return NODE_TYPE_LABELS[data.nodeKind];\n}\n\nfunction readWorkflowNodeCardStyle(\n type: WorkflowNode['type'],\n selected: boolean,\n): CSSProperties {\n const baseStyle = readWorkflowNodeBaseCardStyle(type);\n\n return selected\n ? {\n ...baseStyle,\n border: '1px solid var(--mzn-color-primary, #0057ff)',\n boxShadow: SELECTED_NODE_BOX_SHADOW,\n }\n : baseStyle;\n}\n\nfunction readWorkflowNodeBaseCardStyle(\n type: WorkflowNode['type'],\n): CSSProperties {\n if (type === 'exclusiveGateway') {\n return EXCLUSIVE_GATEWAY_NODE_STYLE;\n }\n\n if (type === 'parallelGateway') {\n return PARALLEL_GATEWAY_NODE_STYLE;\n }\n\n if (type === 'startEvent') {\n return START_NODE_STYLE;\n }\n\n if (type === 'endEvent') {\n return END_NODE_STYLE;\n }\n\n if (type === 'userTask') {\n return USER_TASK_NODE_STYLE;\n }\n\n return NODE_STYLE;\n}\n\nfunction renderWorkflowNodeHandles(\n data: FlowNodeData,\n): ReactElement | readonly ReactElement[] | null {\n if (!data.hasInput && data.hasOutput) {\n return (\n <Handle\n id={WORKFLOW_OUTPUT_HANDLE_ID}\n position={Position.Right}\n type=\"source\"\n />\n );\n }\n\n if (data.hasInput && !data.hasOutput) {\n return (\n <Handle\n id={WORKFLOW_INPUT_HANDLE_ID}\n position={Position.Left}\n type=\"target\"\n />\n );\n }\n\n if (!data.hasInput && !data.hasOutput) {\n return null;\n }\n\n return [\n <Handle\n id={WORKFLOW_INPUT_HANDLE_ID}\n key=\"target\"\n position={Position.Left}\n type=\"target\"\n />,\n <Handle\n id={WORKFLOW_OUTPUT_HANDLE_ID}\n key=\"source\"\n position={Position.Right}\n type=\"source\"\n />,\n ];\n}\n\nfunction readFlowNode(\n node: WorkflowNode,\n memberOptions: readonly MemberSelectOption[],\n orgUnits: readonly OrgUnitRecord[],\n positions: readonly PositionRecord[],\n selected: boolean,\n initiatorPolicyDraft: InitiatorPolicyDraft,\n): FlowNode {\n const dimensions = readWorkflowNodeDimensions(node);\n\n return {\n data: {\n approverLines: readNodeApproverLines(node, memberOptions),\n approverSummary: readNodeApproverSummary(\n node,\n memberOptions,\n orgUnits,\n positions,\n ),\n hasInput: isWorkflowNodeInputConnectable(node),\n hasOutput: isWorkflowNodeOutputConnectable(node),\n initiatorPolicySummary:\n node.type === 'startEvent'\n ? readInitiatorPolicySummary(\n initiatorPolicyDraft,\n orgUnits,\n positions,\n )\n : null,\n label: node.data.label,\n nodeKind: node.type,\n },\n height: dimensions.height,\n handles: readFlowNodeHandles(node),\n id: node.id,\n initialHeight: dimensions.height,\n initialWidth: dimensions.width,\n position: node.position,\n selected,\n sourcePosition: Position.Right,\n targetPosition: Position.Left,\n type: node.type,\n width: dimensions.width,\n };\n}\n\nfunction readWorkflowNodeDimensions(\n node: WorkflowNode,\n): Readonly<{ height: number; width: number }> {\n if (node.type === 'exclusiveGateway' || node.type === 'parallelGateway') {\n return {\n height: GATEWAY_NODE_INITIAL_HEIGHT,\n width: GATEWAY_NODE_INITIAL_WIDTH,\n };\n }\n\n if (node.type === 'serviceTask') {\n const memberCount = Math.max(\n 1,\n readServiceTaskMemberIds(node.data.action).length,\n );\n\n return {\n height:\n FLOW_NODE_INITIAL_HEIGHT +\n (memberCount - 1) * FLOW_NODE_ADDITIONAL_LINE_HEIGHT,\n width: FLOW_NODE_INITIAL_WIDTH,\n };\n }\n\n return {\n height: FLOW_NODE_INITIAL_HEIGHT,\n width: FLOW_NODE_INITIAL_WIDTH,\n };\n}\n\nfunction readFlowNodeHandles(node: WorkflowNode): FlowNodeHandle[] {\n const dimensions = readWorkflowNodeDimensions(node);\n\n return [\n ...(isWorkflowNodeInputConnectable(node)\n ? [readTargetFlowNodeHandle(dimensions)]\n : []),\n ...(isWorkflowNodeOutputConnectable(node)\n ? [readSourceFlowNodeHandle(dimensions)]\n : []),\n ];\n}\n\nfunction readTargetFlowNodeHandle({\n height,\n}: Readonly<{ height: number; width: number }>): FlowNodeHandle {\n const handleSize = 9;\n const centeredHandleY = height / 2 - handleSize / 2;\n\n return {\n height: handleSize,\n id: WORKFLOW_INPUT_HANDLE_ID,\n position: Position.Left,\n type: 'target',\n width: handleSize,\n x: -handleSize / 2,\n y: centeredHandleY,\n };\n}\n\nfunction readSourceFlowNodeHandle({\n height,\n width,\n}: Readonly<{ height: number; width: number }>): FlowNodeHandle {\n const handleSize = 9;\n const centeredHandleY = height / 2 - handleSize / 2;\n\n return {\n height: handleSize,\n id: WORKFLOW_OUTPUT_HANDLE_ID,\n position: Position.Right,\n type: 'source',\n width: handleSize,\n x: width - handleSize / 2,\n y: centeredHandleY,\n };\n}\n\nfunction readFlowEdge(\n edge: WorkflowEdge,\n nodes: readonly WorkflowNode[],\n selected: boolean,\n): FlowEdge {\n const label = readEdgeCanvasLabel(edge, nodes);\n const isConditionEdge = isExclusiveGatewaySourceEdge(edge, nodes);\n const isIncompleteConditionEdge =\n isConditionEdge && !edge.data.isDefault && !edge.data.condition;\n const labelColor = isIncompleteConditionEdge\n ? INCOMPLETE_CONDITION_EDGE_COLOR\n : isConditionEdge\n ? CONDITION_EDGE_COLOR\n : '#475569';\n const labelBackgroundColor = isIncompleteConditionEdge\n ? '#fef2f2'\n : isConditionEdge\n ? '#eff6ff'\n : '#ffffff';\n const labelBorderColor = isIncompleteConditionEdge\n ? INCOMPLETE_CONDITION_EDGE_COLOR\n : isConditionEdge\n ? CONDITION_EDGE_COLOR\n : DEFAULT_EDGE_COLOR;\n\n return {\n className: selected ? 'workflow-edge--selected' : undefined,\n data: edge.data,\n id: edge.id,\n label,\n labelBgBorderRadius: 6,\n labelBgPadding: [8, 4],\n labelBgStyle: {\n fill: labelBackgroundColor,\n stroke: labelBorderColor,\n strokeWidth: 1,\n },\n labelShowBg: Boolean(label),\n labelStyle: {\n fill: labelColor,\n fontSize: 12,\n fontWeight: 600,\n },\n selected,\n source: edge.source,\n sourceHandle: edge.sourceHandle,\n style: {\n filter: selected ? SELECTED_EDGE_GLOW_FILTER : undefined,\n opacity: 1,\n stroke: DEFAULT_EDGE_COLOR,\n strokeOpacity: 1,\n strokeWidth: 1.5,\n },\n target: edge.target,\n targetHandle: edge.targetHandle,\n type: edge.type ?? 'smoothstep',\n };\n}\n\nfunction renameWorkflowNode(node: WorkflowNode, label: string): WorkflowNode {\n if (node.type === 'startEvent') {\n return { ...node, data: { ...node.data, label } };\n }\n\n if (node.type === 'endEvent') {\n return { ...node, data: { ...node.data, label } };\n }\n\n if (node.type === 'userTask') {\n return { ...node, data: { ...node.data, label } };\n }\n\n if (node.type === 'serviceTask') {\n return { ...node, data: { ...node.data, label } };\n }\n\n if (node.type === 'exclusiveGateway') {\n return { ...node, data: { ...node.data, label } };\n }\n\n return { ...node, data: { ...node.data, label } };\n}\n\nfunction applyWorkflowNodeTriggerMode(\n node: WorkflowNode,\n triggerMode: WorkflowNodeTriggerMode,\n): WorkflowNode {\n if (node.type === 'startEvent') {\n return node;\n }\n\n if (node.type === 'endEvent') {\n return { ...node, data: { ...node.data, triggerMode } };\n }\n\n if (node.type === 'userTask') {\n return { ...node, data: { ...node.data, triggerMode } };\n }\n\n if (node.type === 'serviceTask') {\n return { ...node, data: { ...node.data, triggerMode } };\n }\n\n if (node.type === 'exclusiveGateway') {\n return { ...node, data: { ...node.data, triggerMode } };\n }\n\n return { ...node, data: { ...node.data, triggerMode } };\n}\n\nfunction normalizeDesignerWorkflowDefinition(\n definition: WorkflowDefinition,\n): WorkflowDefinition {\n return normalizeSingleIncomingTriggerModes(\n removeAsyncNotifyOutgoingEdges(definition),\n );\n}\n\nfunction removeAsyncNotifyOutgoingEdges(\n definition: WorkflowDefinition,\n): WorkflowDefinition {\n const asyncNotifyNodeIds = new Set(\n definition.nodes\n .filter((node) => isAsyncNotifyServiceTask(node))\n .map((node) => node.id),\n );\n const edges = definition.edges.filter(\n (edge) => !asyncNotifyNodeIds.has(edge.source),\n );\n\n return edges.length === definition.edges.length\n ? definition\n : { ...definition, edges };\n}\n\nfunction normalizeSingleIncomingTriggerModes(\n definition: WorkflowDefinition,\n): WorkflowDefinition {\n const incomingEdgeCounts = definition.edges.reduce<Record<string, number>>(\n (counts, edge) => ({\n ...counts,\n [edge.target]: (counts[edge.target] ?? 0) + 1,\n }),\n {},\n );\n const nodes = definition.nodes.map((node) => {\n if (node.type === 'startEvent') {\n return node;\n }\n\n const incomingEdgeCount = incomingEdgeCounts[node.id] ?? 0;\n\n return incomingEdgeCount < 2 && node.data.triggerMode !== 'AND'\n ? applyWorkflowNodeTriggerMode(node, 'AND')\n : node;\n });\n const hasNodeChanges = nodes.some(\n (node, index) => node !== definition.nodes[index],\n );\n\n return hasNodeChanges ? { ...definition, nodes } : definition;\n}\n\nfunction createWorkflowNode(\n type: NodePaletteType,\n index: number,\n): WorkflowNode {\n const id = `${type}_${index}`;\n const base = {\n id,\n position: { x: 260 + index * 48, y: 120 + index * 42 },\n };\n\n if (type === 'userTask') {\n return {\n ...base,\n data: {\n allowAddSigner: false,\n allowReject: true,\n allowTransfer: true,\n approverResolver: { memberIds: ['member-001'], type: 'DIRECT' },\n decisionPolicy: { type: 'SINGLE' },\n label: `簽核節點 ${index}`,\n returnBehavior: {\n allowReturn: true,\n allowedTargets: 'INITIATOR',\n resubmitStrategy: 'RESTART',\n },\n triggerMode: 'AND',\n },\n type,\n };\n }\n\n if (type === 'serviceTask') {\n return {\n ...base,\n data: {\n action: {\n channels: ['IN_APP'],\n recipients: { memberIds: ['member-001'], type: 'DIRECT' },\n type: 'NOTIFY',\n },\n label: `知會節點 ${index}`,\n triggerMode: 'AND',\n },\n type,\n };\n }\n\n return {\n ...base,\n data: {\n direction: 'split',\n label: `條件分流 ${index}`,\n triggerMode: 'AND',\n },\n type,\n };\n}\n\nfunction readNextWorkflowNodeIndex(\n nodes: readonly WorkflowNode[],\n type: NodePaletteType,\n): number {\n const usedIndexes = new Set(\n nodes\n .filter((node) => node.type === type)\n .map((node) => Number(node.id.replace(`${type}_`, '')))\n .filter((index) => Number.isInteger(index) && index > 0),\n );\n\n return (\n Array.from({ length: nodes.length + 1 }, (_, index) => index + 1).find(\n (index) => !usedIndexes.has(index),\n ) ?? nodes.length + 1\n );\n}\n\nfunction insertWorkflowNodeIntoDefinition({\n definition,\n node,\n selectedEdgeId,\n selectedNodeId,\n}: {\n readonly definition: WorkflowDefinition;\n readonly node: WorkflowNode;\n readonly selectedEdgeId: string | null;\n readonly selectedNodeId: string | null;\n}): Readonly<{\n definition: WorkflowDefinition;\n editingEdgeId: string | null;\n selectedEdgeIds: readonly string[];\n selectedNodeId: string | null;\n}> {\n const selectedEdge = selectedEdgeId\n ? (definition.edges.find((edge) => edge.id === selectedEdgeId) ?? null)\n : null;\n const selectedNode = selectedNodeId\n ? (definition.nodes.find((candidate) => candidate.id === selectedNodeId) ??\n null)\n : null;\n\n if (selectedEdge) {\n return insertWorkflowNodeAtEdge(definition, node, selectedEdge);\n }\n\n if (selectedNode) {\n return insertWorkflowNodeAfterNode(definition, node, selectedNode);\n }\n\n return {\n definition: { ...definition, nodes: [...definition.nodes, node] },\n editingEdgeId: null,\n selectedEdgeIds: [],\n selectedNodeId: node.id,\n };\n}\n\nfunction insertWorkflowNodeAtEdge(\n definition: WorkflowDefinition,\n node: WorkflowNode,\n edge: WorkflowEdge,\n): Readonly<{\n definition: WorkflowDefinition;\n editingEdgeId: string | null;\n selectedEdgeIds: readonly string[];\n selectedNodeId: string | null;\n}> {\n if (!isWorkflowNodeInputConnectable(node)) {\n return {\n definition,\n editingEdgeId: null,\n selectedEdgeIds: [edge.id],\n selectedNodeId: null,\n };\n }\n\n if (!isWorkflowNodeOutputConnectable(node)) {\n const incomingEdge = createWorkflowEdge(edge.source, node.id, {});\n\n return {\n definition: {\n ...definition,\n edges: [...definition.edges, incomingEdge],\n nodes: [...definition.nodes, node],\n },\n editingEdgeId: null,\n selectedEdgeIds: [],\n selectedNodeId: node.id,\n };\n }\n\n const incomingEdge = createWorkflowEdge(edge.source, node.id, edge.data);\n const outgoingEdge = createWorkflowEdge(\n node.id,\n edge.target,\n readInsertedOutgoingEdgeData(node, edge),\n );\n const shouldEditOutgoingEdge = isExclusiveGatewaySourceEdge(outgoingEdge, [\n ...definition.nodes,\n node,\n ]);\n\n return {\n definition: {\n ...definition,\n edges: definition.edges.flatMap((currentEdge) =>\n currentEdge.id === edge.id\n ? [incomingEdge, outgoingEdge]\n : [currentEdge],\n ),\n nodes: [...definition.nodes, node],\n },\n editingEdgeId: shouldEditOutgoingEdge ? outgoingEdge.id : null,\n selectedEdgeIds: shouldEditOutgoingEdge ? [outgoingEdge.id] : [],\n selectedNodeId: shouldEditOutgoingEdge ? null : node.id,\n };\n}\n\nfunction insertWorkflowNodeAfterNode(\n definition: WorkflowDefinition,\n node: WorkflowNode,\n sourceNode: WorkflowNode,\n): Readonly<{\n definition: WorkflowDefinition;\n editingEdgeId: string | null;\n selectedEdgeIds: readonly string[];\n selectedNodeId: string | null;\n}> {\n if (!isWorkflowNodeOutputConnectable(sourceNode)) {\n return {\n definition: { ...definition, nodes: [...definition.nodes, node] },\n editingEdgeId: null,\n selectedEdgeIds: [],\n selectedNodeId: node.id,\n };\n }\n\n const firstOutgoingEdge =\n definition.edges.find((edge) => edge.source === sourceNode.id) ?? null;\n\n if (firstOutgoingEdge && isWorkflowNodeOutputConnectable(node)) {\n return insertWorkflowNodeAtEdge(definition, node, firstOutgoingEdge);\n }\n\n const endNode = definition.nodes.find(\n (candidate) => candidate.type === 'endEvent',\n );\n\n if (\n endNode &&\n sourceNode.id !== endNode.id &&\n isWorkflowNodeOutputConnectable(node)\n ) {\n const incomingEdge = createWorkflowEdge(sourceNode.id, node.id, {});\n const outgoingEdge = createWorkflowEdge(\n node.id,\n endNode.id,\n readInsertedOutgoingEdgeData(node, incomingEdge),\n );\n const shouldEditOutgoingEdge = isExclusiveGatewaySourceEdge(outgoingEdge, [\n ...definition.nodes,\n node,\n ]);\n\n return {\n definition: {\n ...definition,\n edges: [...definition.edges, incomingEdge, outgoingEdge],\n nodes: [...definition.nodes, node],\n },\n editingEdgeId: shouldEditOutgoingEdge ? outgoingEdge.id : null,\n selectedEdgeIds: shouldEditOutgoingEdge ? [outgoingEdge.id] : [],\n selectedNodeId: shouldEditOutgoingEdge ? null : node.id,\n };\n }\n\n const incomingEdge = createWorkflowEdge(sourceNode.id, node.id, {});\n\n return {\n definition: {\n ...definition,\n edges: [...definition.edges, incomingEdge],\n nodes: [...definition.nodes, node],\n },\n editingEdgeId: null,\n selectedEdgeIds: [],\n selectedNodeId: node.id,\n };\n}\n\nfunction createWorkflowEdge(\n source: string,\n target: string,\n data: WorkflowEdgeData,\n): WorkflowEdge {\n return {\n data,\n id: `edge_${source}_${target}_${Date.now()}_${Math.random()\n .toString(36)\n .slice(2, 8)}`,\n source,\n sourceHandle: WORKFLOW_OUTPUT_HANDLE_ID,\n target,\n targetHandle: WORKFLOW_INPUT_HANDLE_ID,\n type: 'smoothstep',\n };\n}\n\nfunction readInsertedOutgoingEdgeData(\n node: WorkflowNode,\n _replacedEdge: WorkflowEdge,\n): WorkflowEdgeData {\n if (node.type === 'exclusiveGateway') {\n return { isDefault: true, label: '其他情況' };\n }\n\n return {};\n}\n\nfunction readFallbackWorkflowDefinition(): WorkflowDefinition {\n return {\n edges: [],\n meta: { schemaVersion: 1 },\n nodes: [\n {\n data: { label: '開始' },\n id: 'start',\n position: { x: 80, y: 160 },\n type: 'startEvent',\n },\n {\n data: { endState: 'APPROVED', label: '完成', triggerMode: 'AND' },\n id: 'end',\n position: { x: 560, y: 160 },\n type: 'endEvent',\n },\n ],\n };\n}\n\nfunction isEmptyDesignerWorkflowDefinition(\n definition: WorkflowDefinition,\n): boolean {\n return (\n definition.edges.length === 0 &&\n definition.nodes.length === 2 &&\n definition.nodes.some((node) => node.type === 'startEvent') &&\n definition.nodes.some((node) => node.type === 'endEvent')\n );\n}\n\nfunction layoutWorkflowDefinition(\n definition: WorkflowDefinition,\n): WorkflowDefinition {\n const graph = new dagre.graphlib.Graph();\n graph.setDefaultEdgeLabel(() => ({}));\n graph.setGraph({ rankdir: 'LR', ranksep: 120 });\n definition.nodes.forEach((node): void => {\n graph.setNode(node.id, readWorkflowNodeDimensions(node));\n });\n definition.edges.forEach((edge): void => {\n graph.setEdge(edge.source, edge.target);\n });\n dagre.layout(graph);\n\n return {\n ...definition,\n nodes: definition.nodes.map((node) => {\n const positionedNode = graph.node(node.id) as\n | { readonly x: number; readonly y: number }\n | undefined;\n\n return positionedNode\n ? {\n ...node,\n position: {\n x: positionedNode.x - readWorkflowNodeDimensions(node).width / 2,\n y: positionedNode.y - readWorkflowNodeDimensions(node).height / 2,\n },\n }\n : node;\n }),\n };\n}\n\nfunction readSelectOption<TOption extends { readonly id: string }>(\n options: readonly TOption[],\n id: string | null,\n): TOption | null {\n return id ? (options.find((option) => option.id === id) ?? null) : null;\n}\n\nfunction readWorkflowNodeTriggerMode(\n value: string | null,\n): WorkflowNodeTriggerMode {\n return value === 'OR' ? 'OR' : 'AND';\n}\n\nfunction readReturnResubmitStrategy(\n value: string | null,\n): ReturnResubmitStrategy {\n return value === 'FROM_RETURN_POINT' ? 'FROM_RETURN_POINT' : 'RESTART';\n}\n\nfunction readApproverResolverMode(value: string): ApproverResolverMode {\n return value === 'ORG_MANAGER' ||\n value === 'ORG_UNIT_MANAGER' ||\n value === 'ORG_UNIT_MEMBER' ||\n value === 'ORG_UNIT_POSITION' ||\n value === 'POSITION'\n ? value\n : 'DIRECT';\n}\n\nfunction readDefaultApproverResolver(value: string | null): ApproverResolver {\n const mode = readApproverResolverMode(value ?? 'DIRECT');\n\n if (mode === 'ORG_MANAGER') {\n return { baseFromInitiator: true, levelsUp: 1, type: 'ORG_MANAGER' };\n }\n\n if (mode === 'ORG_UNIT_MANAGER') {\n return { orgUnitId: '', type: 'ORG_UNIT_MANAGER' };\n }\n\n if (mode === 'ORG_UNIT_MEMBER') {\n return {\n includeDescendants: false,\n orgUnitId: '',\n type: 'ORG_UNIT_MEMBER',\n };\n }\n\n if (mode === 'ORG_UNIT_POSITION') {\n return {\n includeDescendants: false,\n orgUnitId: '',\n positionId: '',\n type: 'ORG_UNIT_POSITION',\n };\n }\n\n if (mode === 'POSITION') {\n return { positionId: '', type: 'POSITION' };\n }\n\n return { memberIds: [], type: 'DIRECT' };\n}\n\nfunction readApproverFallbackMode(value: string | null): ApproverFallbackMode {\n return value === 'DIRECT' ? 'DIRECT' : 'NONE';\n}\n\nfunction updateApproverResolverFallback(\n resolver: ApproverResolver,\n fallback: ApproverResolverFallback,\n): ApproverResolver {\n if (resolver.type === 'ORG_MANAGER') {\n return { ...resolver, fallback };\n }\n\n if (resolver.type === 'ORG_UNIT_MANAGER') {\n return { ...resolver, fallback };\n }\n\n return resolver;\n}\n\nfunction readManagerLevelOption(levelsUp: number): ManagerLevelOption {\n return (\n MANAGER_LEVEL_OPTIONS.find((option) => option.value === levelsUp) ??\n MANAGER_LEVEL_OPTIONS[0]\n );\n}\n\nfunction readManagerLevelOptionById(id: string | null): ManagerLevelOption {\n return (\n MANAGER_LEVEL_OPTIONS.find((option) => option.id === id) ??\n MANAGER_LEVEL_OPTIONS[0]\n );\n}\n\nfunction readInitiatorPolicyMode(\n value: string | null,\n): Exclude<InitiatorPolicyMode, 'CUSTOM'> {\n if (\n value === 'ORG_UNIT' ||\n value === 'ORG_UNIT_POSITION' ||\n value === 'NONE'\n ) {\n return value;\n }\n\n return 'ALL';\n}\n\nfunction readInitiatorPolicyDraft(\n initiatorPolicyCel: string | null,\n): InitiatorPolicyDraft {\n const expression = initiatorPolicyCel?.trim();\n\n if (!expression) {\n return { mode: 'ALL', value: '' };\n }\n\n const orgUnitIds = readCelStringListOperands(\n expression,\n /\"([^\"]+)\" in subject\\.orgUnitIds/gu,\n );\n const positionIds = readCelStringListOperands(\n expression,\n /\"([^\"]+)\" in subject\\.positionIds/gu,\n );\n\n if (orgUnitIds.length > 0 && positionIds.length > 0) {\n return {\n includeDescendants: orgUnitIds.length > 1,\n mode: 'ORG_UNIT_POSITION',\n orgUnitId: orgUnitIds[0],\n positionId: positionIds[0],\n value: orgUnitIds[0] ?? '',\n };\n }\n\n if (orgUnitIds.length > 0) {\n return {\n includeDescendants: orgUnitIds.length > 1,\n mode: 'ORG_UNIT',\n orgUnitId: orgUnitIds[0],\n value: orgUnitIds[0] ?? '',\n };\n }\n\n return { mode: 'CUSTOM', value: expression };\n}\n\nfunction readInitiatorPolicyUiDraft(\n initiatorPolicyCel: string | null,\n modeDraft: Exclude<InitiatorPolicyMode, 'CUSTOM'> | null,\n): InitiatorPolicyDraft {\n const persistedDraft = readInitiatorPolicyDraft(initiatorPolicyCel);\n\n if (!modeDraft || modeDraft === 'ALL' || modeDraft === 'NONE') {\n return modeDraft === 'ALL' || modeDraft === 'NONE'\n ? { mode: modeDraft, value: '' }\n : persistedDraft;\n }\n\n return persistedDraft.mode === modeDraft\n ? persistedDraft\n : readDefaultInitiatorPolicyDraft(modeDraft);\n}\n\nfunction readInitiatorPolicyIssue(\n policyDraft: InitiatorPolicyDraft,\n): string | null {\n if (policyDraft.mode === 'NONE') {\n return '發起權限需要選擇誰可以發起。';\n }\n\n if (\n (policyDraft.mode === 'ORG_UNIT' ||\n policyDraft.mode === 'ORG_UNIT_POSITION') &&\n !policyDraft.orgUnitId?.trim()\n ) {\n return '指定組織發起時,需要選擇組織。';\n }\n\n if (\n policyDraft.mode === 'ORG_UNIT_POSITION' &&\n !policyDraft.positionId?.trim()\n ) {\n return '指定組織職位發起時,需要選擇職位。';\n }\n\n return null;\n}\n\nfunction readCelStringListOperands(\n expression: string,\n pattern: RegExp,\n): readonly string[] {\n return [...expression.matchAll(pattern)]\n .map((match) => match[1])\n .filter((value): value is string => Boolean(value));\n}\n\nfunction readInitiatorPolicyCel(\n draft: InitiatorPolicyDraft,\n orgUnits: readonly OrgUnitRecord[],\n): string | null {\n if (draft.mode === 'ALL' || draft.mode === 'NONE') {\n return null;\n }\n\n const orgUnitId = draft.orgUnitId?.trim() ?? '';\n\n if (!orgUnitId) {\n return null;\n }\n\n const orgUnitIds = readOrgUnitScopeIds(\n orgUnits,\n orgUnitId,\n Boolean(draft.includeDescendants),\n );\n const orgUnitExpression = orgUnitIds\n .map((id) => `${JSON.stringify(id)} in subject.orgUnitIds`)\n .join(' || ');\n\n if (draft.mode === 'ORG_UNIT') {\n return orgUnitExpression ? `(${orgUnitExpression})` : null;\n }\n\n const positionId = draft.positionId?.trim() ?? '';\n\n if (!positionId) {\n return null;\n }\n\n return orgUnitExpression\n ? `(${orgUnitExpression}) && ${JSON.stringify(positionId)} in subject.positionIds`\n : null;\n}\n\nfunction readInitiatorPolicySummary(\n policyDraft: InitiatorPolicyDraft,\n orgUnits: readonly OrgUnitRecord[],\n positions: readonly PositionRecord[],\n): string {\n if (policyDraft.mode === 'NONE') {\n return '未設定';\n }\n\n if (policyDraft.mode === 'ORG_UNIT') {\n return policyDraft.orgUnitId\n ? `組織:${readOrgUnitDisplayName(orgUnits, policyDraft.orgUnitId)}`\n : '指定組織';\n }\n\n if (policyDraft.mode === 'ORG_UNIT_POSITION') {\n return policyDraft.orgUnitId && policyDraft.positionId\n ? `組織職位:${readOrgUnitDisplayName(\n orgUnits,\n policyDraft.orgUnitId,\n )} / ${readPositionDisplayName(positions, policyDraft.positionId)}`\n : '指定組織職位';\n }\n\n if (policyDraft.mode === 'CUSTOM') {\n return '既有自訂規則';\n }\n\n return '所有人';\n}\n\nfunction readDefaultInitiatorPolicyDraft(\n mode: Exclude<InitiatorPolicyMode, 'CUSTOM'>,\n): InitiatorPolicyDraft {\n return {\n includeDescendants: true,\n mode,\n orgUnitId: '',\n positionId: '',\n value: '',\n };\n}\n\nfunction isWorkflowConnectionValid(\n connection: WorkflowConnectionCandidate,\n nodes: readonly WorkflowNode[],\n): boolean {\n const sourceNode = connection.source\n ? (nodes.find((node) => node.id === connection.source) ?? null)\n : null;\n const targetNode = connection.target\n ? (nodes.find((node) => node.id === connection.target) ?? null)\n : null;\n\n return (\n Boolean(sourceNode) &&\n Boolean(targetNode) &&\n connection.source !== connection.target &&\n connection.sourceHandle === WORKFLOW_OUTPUT_HANDLE_ID &&\n connection.targetHandle === WORKFLOW_INPUT_HANDLE_ID &&\n Boolean(sourceNode && isWorkflowNodeOutputConnectable(sourceNode)) &&\n Boolean(targetNode && isWorkflowNodeInputConnectable(targetNode))\n );\n}\n\nfunction toggleSelectedEdgeId(\n edgeIds: readonly string[],\n edgeId: string,\n): readonly string[] {\n return edgeIds.includes(edgeId)\n ? edgeIds.filter((currentEdgeId) => currentEdgeId !== edgeId)\n : [...edgeIds, edgeId];\n}\n\nfunction isWorkflowNodeRemovable(node: WorkflowNode): boolean {\n return node.type !== 'startEvent' && node.type !== 'endEvent';\n}\n\nfunction isWorkflowNodeInputConnectable(node: WorkflowNode): boolean {\n return node.type !== 'startEvent';\n}\n\nfunction isWorkflowNodeOutputConnectable(node: WorkflowNode): boolean {\n return node.type !== 'endEvent' && !isAsyncNotifyServiceTask(node);\n}\n\nfunction isAsyncNotifyServiceTask(node: WorkflowNode): boolean {\n return node.type === 'serviceTask' && node.data.action.type === 'NOTIFY';\n}\n\nfunction isEditableKeyboardTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) {\n return false;\n }\n\n return (\n target.isContentEditable ||\n target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'SELECT' ||\n Boolean(target.closest('[contenteditable=\"true\"]'))\n );\n}\n\nfunction readFormVersionSelectOptions(\n options: readonly PublishedFormVersionOption[],\n): readonly FormVersionSelectOption[] {\n return options.map((option) => ({\n id: option.id,\n name: `${option.formName} | v${option.version}`,\n schema: option.schema,\n }));\n}\n\nfunction readDryRunSampleFormData(\n option: FormVersionSelectOption | null,\n): Readonly<Record<string, unknown>> {\n return (option?.schema.fields ?? []).reduce<\n Readonly<Record<string, unknown>>\n >(\n (formData, field) => ({\n ...formData,\n [field.fieldKey]: readDryRunSampleFieldValue(field),\n }),\n {},\n );\n}\n\nfunction readDryRunSampleFieldValue(field: FormFieldDefinition): unknown {\n if (field.type === 'number') {\n return 1000;\n }\n\n if (field.type === 'boolean') {\n return true;\n }\n\n if (field.type === 'select') {\n return field.options[0]?.value ?? '';\n }\n\n if (field.type === 'checkbox') {\n return field.options[0] ? [field.options[0].value] : [];\n }\n\n if (field.type === 'date') {\n return '2026-05-08';\n }\n\n if (field.type === 'datetime') {\n return '2026-05-08T09:00:00+08:00';\n }\n\n return field.placeholder ?? field.label;\n}\n\nfunction parseDryRunFormData(value: string): Readonly<Record<string, unknown>> {\n const parsedValue = JSON.parse(value) as unknown;\n\n if (!isRecord(parsedValue)) {\n throw new Error('表單資料 JSON 必須是物件。');\n }\n\n return parsedValue;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readDryRunStatusLabel(status: string): string {\n if (status === 'COMPLETED') {\n return '完成';\n }\n\n if (status === 'PASSED') {\n return '通過';\n }\n\n if (status === 'SKIPPED') {\n return '略過';\n }\n\n if (status === 'STOPPED') {\n return '已停止';\n }\n\n if (status === 'WAITING') {\n return '將等待簽核';\n }\n\n return status;\n}\n\nfunction readWorkflowNodeTypeLabel(nodeType: string): string {\n return nodeType in NODE_TYPE_LABELS\n ? NODE_TYPE_LABELS[nodeType as WorkflowNode['type']]\n : nodeType;\n}\n\nfunction mergeSelectedOption(\n options: readonly FormVersionSelectOption[],\n selectedOption: FormVersionSelectOption | null,\n): readonly FormVersionSelectOption[] {\n return selectedOption &&\n !options.some((option) => option.id === selectedOption.id)\n ? [selectedOption, ...options]\n : options;\n}\n\nfunction readMemberSelectOptions(\n options: readonly MemberProfileRecord[],\n): readonly MemberSelectOption[] {\n return options.map((option) => ({\n displayName: option.name,\n email: option.email,\n id: option.memberId,\n memberId: option.memberId,\n name: formatMemberDisplayName(option.name, option.email),\n }));\n}\n\nfunction readFallbackMemberSelectOption(memberId: string): MemberSelectOption {\n return {\n displayName: '未知會員',\n email: '',\n id: memberId,\n memberId,\n name: '未知會員',\n };\n}\n\nfunction readMemberSelectOption(\n options: readonly MemberSelectOption[],\n memberId: string,\n): MemberSelectOption {\n return (\n options.find((option) => option.memberId === memberId) ??\n readFallbackMemberSelectOption(memberId)\n );\n}\n\nfunction readPrimaryMemberOption(\n memberIds: readonly string[],\n memberOptions: readonly MemberSelectOption[],\n): MemberSelectOption | null {\n const memberId = memberIds[0];\n\n return memberId ? readMemberSelectOption(memberOptions, memberId) : null;\n}\n\nfunction readSelectedOrgUnitOption(\n orgUnits: readonly OrgUnitRecord[],\n orgUnitId: string,\n): OrgUnitOption | null {\n const orgUnit = orgUnits.find((candidate) => candidate.id === orgUnitId);\n\n return orgUnit ? readOrgUnitOption(orgUnit) : null;\n}\n\nfunction readSelectedPositionOption(\n positions: readonly PositionRecord[],\n positionId: string,\n): PositionOption | null {\n const position = positions.find((candidate) => candidate.id === positionId);\n\n return position ? readPositionOption(position) : null;\n}\n\nfunction readOrgUnitDisplayName(\n orgUnits: readonly OrgUnitRecord[],\n orgUnitId: string,\n): string {\n return readSelectedOrgUnitOption(orgUnits, orgUnitId)?.name ?? '未指定組織';\n}\n\nfunction readPositionDisplayName(\n positions: readonly PositionRecord[],\n positionId: string,\n): string {\n return (\n readSelectedPositionOption(positions, positionId)?.name ?? '未指定職位'\n );\n}\n\nfunction readDryRunInitiatorMetadataSnapshot(\n memberId: string,\n memberships: readonly MembershipRecord[],\n): Readonly<Record<string, unknown>> {\n const today = readTodayDateOnlyString();\n const activeMemberships = memberships.filter(\n (membership) =>\n membership.memberId === memberId &&\n isMembershipActiveOn(membership, today),\n );\n const primaryMembership = activeMemberships.reduce<MembershipRecord | null>(\n (currentPrimary, membership) =>\n currentPrimary &&\n compareMembershipRecord(currentPrimary, membership) <= 0\n ? currentPrimary\n : membership,\n null,\n );\n\n return {\n customFields: {},\n managerMemberId: 'member-002',\n memberId,\n orgCode: 'HQ',\n orgUnitIds: readUniqueTexts(\n activeMemberships.map((membership) => membership.orgUnitId),\n ),\n positionId: primaryMembership?.positionId ?? null,\n positionIds: readUniqueTexts(\n activeMemberships.map((membership) => membership.positionId),\n ),\n primaryOrgUnitId: primaryMembership?.orgUnitId ?? null,\n roles: ['manager'],\n };\n}\n\nfunction readTodayDateOnlyString(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nfunction isMembershipActiveOn(\n membership: MembershipRecord,\n date: string,\n): boolean {\n return (\n membership.effectiveFrom <= date &&\n (!membership.effectiveTo || membership.effectiveTo >= date)\n );\n}\n\nfunction compareMembershipRecord(\n left: MembershipRecord,\n right: MembershipRecord,\n): number {\n if (left.isPrimary !== right.isPrimary) {\n return left.isPrimary ? -1 : 1;\n }\n\n return right.effectiveFrom.localeCompare(left.effectiveFrom);\n}\n\nfunction readUniqueTexts(\n values: readonly (string | null | undefined)[],\n): readonly string[] {\n return values.reduce<readonly string[]>(\n (currentValues, value) =>\n value && !currentValues.includes(value)\n ? [...currentValues, value]\n : currentValues,\n [],\n );\n}\n\nfunction readOrgScopedPositions({\n includeDescendants,\n memberships,\n orgUnitId,\n orgUnits,\n positions,\n}: {\n readonly includeDescendants: boolean;\n readonly memberships: readonly MembershipRecord[];\n readonly orgUnitId: string;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly positions: readonly PositionRecord[];\n}): readonly PositionRecord[] {\n const orgUnitIds = new Set(\n readOrgUnitScopeIds(orgUnits, orgUnitId, includeDescendants),\n );\n const positionIds = new Set(\n memberships\n .filter((membership) => orgUnitIds.has(membership.orgUnitId))\n .map((membership) => membership.positionId)\n .filter((positionId): positionId is string => Boolean(positionId)),\n );\n\n return positions.filter((position) => positionIds.has(position.id));\n}\n\nfunction readOrgUnitScopeIds(\n orgUnits: readonly OrgUnitRecord[],\n orgUnitId: string,\n includeDescendants: boolean,\n): readonly string[] {\n const orgUnit = orgUnits.find((candidate) => candidate.id === orgUnitId);\n\n if (!orgUnit) {\n return orgUnitId.trim() ? [orgUnitId] : [];\n }\n\n if (!includeDescendants) {\n return [orgUnit.id];\n }\n\n return orgUnits\n .filter(\n (candidate) =>\n candidate.id === orgUnit.id ||\n candidate.path.startsWith(`${orgUnit.path}.`),\n )\n .map((candidate) => candidate.id);\n}\n\nfunction mergeMemberOptions(\n currentOptions: readonly MemberSelectOption[],\n nextOptions: readonly MemberSelectOption[],\n): readonly MemberSelectOption[] {\n const currentOptionIds = new Set(\n currentOptions.map((option) => option.memberId),\n );\n const newOptions = nextOptions.filter(\n (option) => !currentOptionIds.has(option.memberId),\n );\n\n return [...currentOptions, ...newOptions];\n}\n\nfunction readWorkflowDirectMemberIds(\n definition: WorkflowDefinition,\n): readonly string[] {\n return [\n ...new Set(\n definition.nodes.flatMap((node) => {\n if (node.type === 'userTask') {\n return node.data.approverResolver.type === 'DIRECT'\n ? node.data.approverResolver.memberIds\n : [];\n }\n\n if (node.type === 'serviceTask') {\n return readServiceTaskMemberIds(node.data.action);\n }\n\n return [];\n }),\n ),\n ];\n}\n\nfunction readNodeApproverSummary(\n node: WorkflowNode,\n memberOptions: readonly MemberSelectOption[],\n orgUnits: readonly OrgUnitRecord[],\n positions: readonly PositionRecord[],\n): string | null {\n if (node.type === 'userTask') {\n return readApproverResolverSummary(\n node.data.approverResolver,\n memberOptions,\n orgUnits,\n positions,\n );\n }\n\n return null;\n}\n\nfunction readApproverResolverSummary(\n resolver: ApproverResolver,\n memberOptions: readonly MemberSelectOption[],\n orgUnits: readonly OrgUnitRecord[],\n positions: readonly PositionRecord[],\n): string {\n if (resolver.type === 'DIRECT') {\n return readMemberEmailSummary(\n resolver.memberIds,\n memberOptions,\n '未指定簽核者',\n );\n }\n\n if (resolver.type === 'ORG_MANAGER') {\n return readManagerLevelOption(resolver.levelsUp).name;\n }\n\n if (resolver.type === 'ORG_UNIT_MANAGER') {\n return `組織主管:${readOrgUnitDisplayName(orgUnits, resolver.orgUnitId)}`;\n }\n\n if (resolver.type === 'ORG_UNIT_MEMBER') {\n return `組織任一人:${readOrgUnitDisplayName(orgUnits, resolver.orgUnitId)}`;\n }\n\n if (resolver.type === 'ORG_UNIT_POSITION') {\n return `組織職位:${readOrgUnitDisplayName(\n orgUnits,\n resolver.orgUnitId,\n )} / ${readPositionDisplayName(positions, resolver.positionId)}`;\n }\n\n if (resolver.type === 'POSITION') {\n return `職位:${readPositionDisplayName(positions, resolver.positionId)}`;\n }\n\n if (resolver.type === 'DYNAMIC_FORM') {\n return `表單欄位:${resolver.formPath || '未設定'}`;\n }\n\n return '自訂表達式';\n}\n\nfunction readNodeApproverLines(\n node: WorkflowNode,\n memberOptions: readonly MemberSelectOption[],\n): readonly string[] | null {\n if (node.type !== 'serviceTask') {\n return null;\n }\n\n const memberIds = readServiceTaskMemberIds(node.data.action);\n\n return memberIds.length === 0\n ? ['未指定知會對象']\n : memberIds.map(\n (memberId) => readMemberSelectOption(memberOptions, memberId).name,\n );\n}\n\nfunction readMemberEmailSummary(\n memberIds: readonly string[],\n memberOptions: readonly MemberSelectOption[],\n emptyLabel: string,\n): string {\n const memberLabels = memberIds.map(\n (memberId) => readMemberSelectOption(memberOptions, memberId).name,\n );\n\n if (memberLabels.length === 0) {\n return emptyLabel;\n }\n\n if (memberLabels.length <= 2) {\n return memberLabels.join('、');\n }\n\n return `${memberLabels.slice(0, 2).join('、')} 等 ${memberLabels.length} 人`;\n}\n\nfunction formatMemberDisplayName(name: string, email: string): string {\n return `${name} (${email})`;\n}\n\nfunction readWorkflowViewport(\n definition: WorkflowDefinition,\n canvasElement: HTMLDivElement | null,\n): Viewport | null {\n const canvasRect = canvasElement?.getBoundingClientRect();\n\n if (!canvasRect || definition.nodes.length === 0) {\n return null;\n }\n\n const bounds = definition.nodes.reduce(\n (currentBounds, node) => {\n const dimensions = readWorkflowNodeDimensions(node);\n\n return {\n maxX: Math.max(currentBounds.maxX, node.position.x + dimensions.width),\n maxY: Math.max(currentBounds.maxY, node.position.y + dimensions.height),\n minX: Math.min(currentBounds.minX, node.position.x),\n minY: Math.min(currentBounds.minY, node.position.y),\n };\n },\n {\n maxX: Number.NEGATIVE_INFINITY,\n maxY: Number.NEGATIVE_INFINITY,\n minX: Number.POSITIVE_INFINITY,\n minY: Number.POSITIVE_INFINITY,\n },\n );\n\n return getViewportForBounds(\n {\n height: bounds.maxY - bounds.minY,\n width: bounds.maxX - bounds.minX,\n x: bounds.minX,\n y: bounds.minY,\n },\n canvasRect.width,\n canvasRect.height,\n 0.1,\n 1,\n 0.2,\n );\n}\n\nfunction readWorkflowDefinitionIssue(\n definition: WorkflowDefinition,\n): string | null {\n const incompleteUserTaskNode = definition.nodes.find(\n (node) =>\n node.type === 'userTask' &&\n Boolean(readApproverResolverIssue(node.data.approverResolver)),\n );\n const incompleteNotifyNode = definition.nodes.find(\n (node) =>\n node.type === 'serviceTask' &&\n node.data.action.type === 'NOTIFY' &&\n readServiceTaskMemberIds(node.data.action).length === 0,\n );\n const incompleteConditionEdge = definition.edges.find(\n (edge) =>\n isExclusiveGatewaySourceEdge(edge, definition.nodes) &&\n !edge.data.isDefault &&\n !edge.data.condition,\n );\n\n if (incompleteUserTaskNode && incompleteUserTaskNode.type === 'userTask') {\n return readApproverResolverIssue(\n incompleteUserTaskNode.data.approverResolver,\n );\n }\n\n if (incompleteNotifyNode) {\n return '知會節點需要至少一位知會對象。';\n }\n\n if (incompleteConditionEdge) {\n return '條件分流的每條輸出連線都需要先設定條件。';\n }\n\n return null;\n}\n\nfunction readApproverResolverIssue(resolver: ApproverResolver): string | null {\n if (resolver.type === 'DIRECT' && resolver.memberIds.length === 0) {\n return '簽核節點需要指定簽核會員。';\n }\n\n if (resolver.type === 'ORG_MANAGER' && resolver.levelsUp < 1) {\n return '簽核節點需要指定有效的主管層級。';\n }\n\n if (resolver.type === 'ORG_UNIT_MANAGER' && !resolver.orgUnitId.trim()) {\n return '簽核節點需要指定組織。';\n }\n\n if (resolver.type === 'ORG_UNIT_MEMBER' && !resolver.orgUnitId.trim()) {\n return '簽核節點需要指定組織。';\n }\n\n if (\n resolver.type === 'ORG_UNIT_POSITION' &&\n (!resolver.orgUnitId.trim() || !resolver.positionId.trim())\n ) {\n return '簽核節點需要指定組織與職位。';\n }\n\n if (\n (resolver.type === 'ORG_MANAGER' || resolver.type === 'ORG_UNIT_MANAGER') &&\n resolver.fallback?.type === 'DIRECT' &&\n !resolver.fallback.memberId.trim()\n ) {\n return '簽核節點需要指定改派固定人。';\n }\n\n if (resolver.type === 'POSITION' && !resolver.positionId.trim()) {\n return '簽核節點需要指定職位。';\n }\n\n return null;\n}\n\nfunction hasConfiguredConditionEdges(definition: WorkflowDefinition): boolean {\n return definition.edges.some(\n (edge) =>\n isExclusiveGatewaySourceEdge(edge, definition.nodes) &&\n Boolean(\n edge.data.condition ||\n edge.data.conditionFieldKey ||\n edge.data.conditionOperator ||\n edge.data.conditionValue,\n ),\n );\n}\n\nfunction readConditionFieldOptions(\n schema: FormDefinitionSchema | null,\n): readonly ConditionFieldOption[] {\n return (\n schema?.fields.map((field) => ({\n fieldType: field.type,\n id: field.fieldKey,\n name: `${field.label} (${field.fieldKey})`,\n })) ?? []\n );\n}\n\nfunction readConditionField(\n schema: FormDefinitionSchema | null,\n fieldKey: string | null,\n): FormFieldDefinition | null {\n return fieldKey\n ? (schema?.fields.find((field) => field.fieldKey === fieldKey) ?? null)\n : null;\n}\n\nfunction readConditionOperatorOptions(\n field: FormFieldDefinition | null,\n): readonly ConditionOperatorOption[] {\n if (!field) {\n return [];\n }\n\n const operatorIds = readConditionOperatorIds(field);\n\n return CONDITION_OPERATOR_OPTIONS.filter((option) =>\n operatorIds.includes(option.id),\n );\n}\n\nfunction readConditionOperator(\n value: string | null,\n): WorkflowEdgeConditionOperator | null {\n return CONDITION_OPERATOR_OPTIONS.some((option) => option.id === value)\n ? (value as WorkflowEdgeConditionOperator)\n : null;\n}\n\nfunction readConditionOperatorIds(\n field: FormFieldDefinition,\n): readonly WorkflowEdgeConditionOperator[] {\n if (field.type === 'file_upload') {\n return ['IS_FILLED', 'IS_EMPTY'];\n }\n\n if (field.type === 'boolean') {\n return ['EQUALS', 'NOT_EQUALS', 'IS_FILLED', 'IS_EMPTY'];\n }\n\n if (\n field.type === 'date' ||\n field.type === 'datetime' ||\n field.type === 'money' ||\n field.type === 'number'\n ) {\n return [\n 'EQUALS',\n 'NOT_EQUALS',\n 'GREATER_THAN',\n 'GREATER_THAN_OR_EQUALS',\n 'LESS_THAN',\n 'LESS_THAN_OR_EQUALS',\n 'IS_FILLED',\n 'IS_EMPTY',\n ];\n }\n\n return ['EQUALS', 'NOT_EQUALS', 'IS_FILLED', 'IS_EMPTY'];\n}\n\nfunction readConditionValueOptions(\n field: FormFieldDefinition | null,\n): readonly ConditionValueOption[] {\n if (!field) {\n return [];\n }\n\n if (field.type === 'boolean') {\n return [\n { id: 'true', name: '是' },\n { id: 'false', name: '否' },\n ];\n }\n\n if (\n field.type === 'checkbox' ||\n field.type === 'radio' ||\n field.type === 'select'\n ) {\n return field.options.map((option) => ({\n id: option.value,\n name: option.label,\n }));\n }\n\n return [];\n}\n\nfunction readNextConditionOperator(\n field: FormFieldDefinition | null,\n operator: WorkflowEdgeConditionOperator | null,\n): WorkflowEdgeConditionOperator | undefined {\n if (!field) {\n return undefined;\n }\n\n const operatorIds = readConditionOperatorIds(field);\n\n return operator && operatorIds.includes(operator) ? operator : operatorIds[0];\n}\n\nfunction readNextConditionValue(\n field: FormFieldDefinition | null,\n operator: WorkflowEdgeConditionOperator | undefined,\n value: string | null,\n): string | undefined {\n if (!field || !operator || !shouldConditionOperatorUseValue(operator)) {\n return undefined;\n }\n\n const valueOptions = readConditionValueOptions(field);\n\n if (valueOptions.length === 0) {\n return value ?? undefined;\n }\n\n return valueOptions.some((option) => option.id === value)\n ? (value ?? undefined)\n : valueOptions[0]?.id;\n}\n\nfunction shouldConditionOperatorUseValue(\n operator: WorkflowEdgeConditionOperator,\n): boolean {\n return CONDITION_OPERATORS_REQUIRING_VALUE.includes(operator);\n}\n\nfunction readConditionLabel(\n field: FormFieldDefinition | null,\n operator: WorkflowEdgeConditionOperator | undefined,\n value: string | undefined,\n): string | undefined {\n if (!field || !operator) {\n return undefined;\n }\n\n const operatorLabel = readConditionOperatorLabel(operator);\n\n if (!shouldConditionOperatorUseValue(operator)) {\n return `${field.label} ${operatorLabel}`;\n }\n\n if (!value) {\n return undefined;\n }\n\n return `${field.label} ${operatorLabel} ${readConditionValueLabel(\n field,\n value,\n )}`;\n}\n\nfunction readConditionOperatorLabel(\n operator: WorkflowEdgeConditionOperator,\n): string {\n return (\n CONDITION_OPERATOR_OPTIONS.find((option) => option.id === operator)?.name ??\n operator\n );\n}\n\nfunction readConditionValueLabel(\n field: FormFieldDefinition,\n value: string,\n): string {\n if (field.type === 'boolean') {\n return value === 'true' ? '是' : '否';\n }\n\n if (\n field.type === 'checkbox' ||\n field.type === 'radio' ||\n field.type === 'select'\n ) {\n return readFormFieldOption(field.options, value)?.label ?? value;\n }\n\n return value;\n}\n\nfunction readFormFieldOption(\n options: readonly FormFieldOption[],\n value: string,\n): FormFieldOption | null {\n return options.find((option) => option.value === value) ?? null;\n}\n\nfunction readConditionExpression(\n field: FormFieldDefinition | null,\n operator: WorkflowEdgeConditionOperator | undefined,\n value: string | undefined,\n): string | undefined {\n if (!field || !operator) {\n return undefined;\n }\n\n const fieldReference = readFormFieldReference(field.fieldKey);\n\n if (operator === 'IS_FILLED') {\n return `${fieldReference} != null && ${fieldReference} != \"\"`;\n }\n\n if (operator === 'IS_EMPTY') {\n return `${fieldReference} == null || ${fieldReference} == \"\"`;\n }\n\n if (!value) {\n return undefined;\n }\n\n return `${fieldReference} ${readConditionExpressionOperator(\n operator,\n )} ${readConditionExpressionValue(field, value)}`;\n}\n\nfunction readFormFieldReference(fieldKey: string): string {\n return /^[A-Za-z_][A-Za-z0-9_]*$/u.test(fieldKey)\n ? `form.${fieldKey}`\n : `form[${JSON.stringify(fieldKey)}]`;\n}\n\nfunction readConditionExpressionOperator(\n operator: WorkflowEdgeConditionOperator,\n): string {\n if (operator === 'EQUALS') {\n return '==';\n }\n\n if (operator === 'NOT_EQUALS') {\n return '!=';\n }\n\n if (operator === 'GREATER_THAN') {\n return '>';\n }\n\n if (operator === 'GREATER_THAN_OR_EQUALS') {\n return '>=';\n }\n\n if (operator === 'LESS_THAN') {\n return '<';\n }\n\n return '<=';\n}\n\nfunction readConditionExpressionValue(\n field: FormFieldDefinition,\n value: string,\n): string {\n if (field.type === 'boolean') {\n return value === 'true' ? 'true' : 'false';\n }\n\n if (field.type === 'money' || field.type === 'number') {\n return Number.isFinite(Number(value)) ? value : JSON.stringify(value);\n }\n\n return JSON.stringify(value);\n}\n\nfunction readEdgeCanvasLabel(\n edge: WorkflowEdge,\n nodes: readonly WorkflowNode[],\n): string | undefined {\n if (edge.data.label) {\n return edge.data.label;\n }\n\n if (isExclusiveGatewaySourceEdge(edge, nodes)) {\n return readExclusiveGatewayPathLabel(edge);\n }\n\n if (isParallelGatewaySourceEdge(edge, nodes)) {\n return '同時進行';\n }\n\n return undefined;\n}\n\nfunction readExclusiveGatewayPathLabel(edge: WorkflowEdge): string {\n if (edge.data.isDefault) {\n return '其他情況';\n }\n\n return '請設定條件';\n}\n\nfunction isExclusiveGatewaySourceEdge(\n edge: WorkflowEdge,\n nodes: readonly WorkflowNode[],\n): boolean {\n return nodes.some(\n (node) => node.id === edge.source && node.type === 'exclusiveGateway',\n );\n}\n\nfunction isParallelGatewaySourceEdge(\n edge: WorkflowEdge,\n nodes: readonly WorkflowNode[],\n): boolean {\n return nodes.some(\n (node) => node.id === edge.source && node.type === 'parallelGateway',\n );\n}\n\nfunction readServiceTaskMemberIds(action: ServiceAction): readonly string[] {\n return action.type === 'NOTIFY' && action.recipients.type === 'DIRECT'\n ? action.recipients.memberIds\n : [];\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
2
|
-
export interface TemplateCategoryOption {
|
|
3
|
-
readonly categoryId: string | null;
|
|
4
|
-
readonly id: string;
|
|
5
|
-
readonly name: string;
|
|
6
|
-
}
|
|
7
|
-
interface TemplateNameModalProps {
|
|
8
|
-
readonly confirmText: string;
|
|
9
|
-
readonly categoryOptions: readonly TemplateCategoryOption[];
|
|
10
|
-
readonly initialName: string;
|
|
11
|
-
readonly loading: boolean;
|
|
12
|
-
readonly onClose: () => void;
|
|
13
|
-
readonly onSubmit: (input: {
|
|
14
|
-
readonly categoryId: string | null;
|
|
15
|
-
readonly name: string;
|
|
16
|
-
}) => Promise<void>;
|
|
17
|
-
readonly open: boolean;
|
|
18
|
-
readonly title: string;
|
|
19
|
-
}
|
|
20
|
-
export declare function TemplateNameModal({ confirmText, categoryOptions, initialName, loading, onClose, onSubmit, open, title, }: TemplateNameModalProps): ReactElement;
|
|
21
|
-
export declare const UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION: TemplateCategoryOption;
|
|
22
|
-
export {};
|