@rytass/bpm-core-react 0.6.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/chunks/compose-DYmvSyVR.cjs +2 -0
- package/dist/chunks/compose-DYmvSyVR.cjs.map +1 -0
- package/dist/chunks/{compose-PMrmi-LE.js → compose-Dmp3vP-j.js} +50 -46
- package/dist/chunks/compose-Dmp3vP-j.js.map +1 -0
- package/dist/chunks/designer-CEw0v0sY.cjs +65 -0
- package/dist/chunks/designer-CEw0v0sY.cjs.map +1 -0
- package/dist/chunks/{designer-mOMxJ0Py.js → designer-yYAdrQDt.js} +19 -2
- package/dist/chunks/designer-yYAdrQDt.js.map +1 -0
- package/dist/chunks/orgs-C1JFfk_Y.cjs +2 -0
- package/dist/chunks/orgs-C1JFfk_Y.cjs.map +1 -0
- package/dist/chunks/{orgs-Cc18umVt.js → orgs-DQ_wob4O.js} +620 -535
- package/dist/chunks/orgs-DQ_wob4O.js.map +1 -0
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.js +1 -1
- package/dist/pages/templates/compose/index.cjs +1 -1
- package/dist/pages/templates/compose/index.cjs.map +1 -1
- package/dist/pages/templates/compose/index.d.ts +13 -1
- package/dist/pages/templates/compose/index.js +9 -5
- package/dist/pages/templates/compose/index.js.map +1 -1
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +1 -1
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -1
- package/dist/views/templates/compose/TemplateComposeWizardView.d.ts +13 -1
- package/dist/views/templates/compose/index.cjs +1 -1
- package/dist/views/templates/compose/index.js +1 -1
- package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +12 -1
- package/dist/views/templates/designer/TemplateDesignerView.d.ts +4 -2
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunks/compose-PMrmi-LE.js.map +0 -1
- package/dist/chunks/compose-ziVbRYdo.cjs +0 -2
- package/dist/chunks/compose-ziVbRYdo.cjs.map +0 -1
- package/dist/chunks/designer-DCn6_v4b.cjs +0 -65
- package/dist/chunks/designer-DCn6_v4b.cjs.map +0 -1
- package/dist/chunks/designer-mOMxJ0Py.js.map +0 -1
- package/dist/chunks/orgs-BIiqzHvb.cjs +0 -2
- package/dist/chunks/orgs-BIiqzHvb.cjs.map +0 -1
- package/dist/chunks/orgs-Cc18umVt.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rytass/bpm-core-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "BPM approval workflow React components and views for the Rytass BPM stack. Ships AuthProvider, NotificationDrawer + bell widget, host-facing hooks (useBPMMember / useBPMLogout / useBPMRoutes), and full page-body views for inbox / instances / templates / forms / admin / settings on top of Mezzanine UI and the BPM client functions. The host owns the navigation shell — BPM does not bundle a layout.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bpm",
|
|
@@ -280,8 +280,8 @@
|
|
|
280
280
|
"peerDependencies": {
|
|
281
281
|
"@mezzanine-ui/icons": "^1.0.2",
|
|
282
282
|
"@mezzanine-ui/react": "^1.1.0",
|
|
283
|
-
"@rytass/bpm-core-client": "^0.
|
|
284
|
-
"@rytass/bpm-core-shared": "^0.
|
|
283
|
+
"@rytass/bpm-core-client": "^0.4.0",
|
|
284
|
+
"@rytass/bpm-core-shared": "^0.4.0",
|
|
285
285
|
"react": "^18.0.0 || ^19.0.0",
|
|
286
286
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
287
287
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compose-PMrmi-LE.js","names":[],"sources":["../../src/views/templates/compose/steps/ComposeFormStep.tsx","../../src/views/templates/compose/steps/ComposeReviewStep.tsx","../../src/views/templates/compose/steps/ComposeWorkflowStep.tsx","../../src/views/templates/compose/use-template-compose-wizard.ts","../../src/views/templates/compose/TemplateComposeWizardView.tsx"],"sourcesContent":["'use client';\n\nimport type { ChangeEvent, ReactElement } from 'react';\nimport { useEffect, useState } from 'react';\nimport { FormField, Input, Select, Typography } from '@mezzanine-ui/react';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { SelectValue } from '@mezzanine-ui/react/Select';\nimport type {\n FormDefinitionSchema,\n FormUiSchema,\n} from '@rytass/bpm-core-shared/form';\nimport {\n ApprovalTemplateCategoryRecord,\n listApprovalTemplateCategoriesPage,\n} from '@rytass/bpm-core-client/template';\nimport { FormBuilderView } from '../../../forms/builder';\n\nconst UNCATEGORIZED_OPTION: SelectValue = {\n id: 'UNCATEGORIZED',\n name: '未分類',\n};\n\nconst CATEGORY_PAGE_SIZE = 100;\n\nexport interface ComposeFormStepProps {\n readonly name: string;\n readonly categoryId: string | null;\n readonly formSchema: FormDefinitionSchema;\n readonly formUiSchema: FormUiSchema;\n readonly onNameChange: (value: string) => void;\n readonly onCategoryIdChange: (value: string | null) => void;\n readonly onFormChange: (next: {\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n }) => void;\n}\n\nexport function ComposeFormStep({\n categoryId,\n formSchema,\n formUiSchema,\n name,\n onCategoryIdChange,\n onFormChange,\n onNameChange,\n}: ComposeFormStepProps): ReactElement {\n const [categoryOptions, setCategoryOptions] = useState<\n readonly ApprovalTemplateCategoryRecord[]\n >([]);\n\n useEffect((): (() => void) => {\n let active = true;\n\n void (async (): Promise<void> => {\n try {\n const result = await listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n });\n\n if (active) {\n setCategoryOptions(result.categories);\n }\n } catch {\n if (active) {\n setCategoryOptions([]);\n }\n }\n })();\n\n return (): void => {\n active = false;\n };\n }, []);\n\n const selectOptions: SelectValue[] = [\n UNCATEGORIZED_OPTION,\n ...categoryOptions.map((category) => ({\n id: category.id,\n name: category.name,\n })),\n ];\n const selectedOption =\n selectOptions.find((option) => option.id === categoryId) ??\n UNCATEGORIZED_OPTION;\n\n return (\n <>\n <div style={BASICS_GRID_STYLE}>\n <FormField\n label=\"名稱\"\n layout={FormFieldLayout.VERTICAL}\n name=\"composeName\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onNameChange(event.target.value)\n }\n placeholder=\"例如:請款簽核\"\n value={name}\n />\n </FormField>\n <FormField\n label=\"分類(選填)\"\n layout={FormFieldLayout.VERTICAL}\n name=\"composeCategory\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onCategoryIdChange(\n option && option.id !== UNCATEGORIZED_OPTION.id\n ? option.id\n : null,\n )\n }\n options={selectOptions}\n placeholder=\"未分類\"\n value={selectedOption}\n />\n </FormField>\n </div>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 先設計表單欄位,下一步的流程條件分流即可直接引用這些欄位。\n </Typography>\n <FormBuilderView\n onChange={onFormChange}\n value={{ schema: formSchema, uiSchema: formUiSchema }}\n />\n </>\n );\n}\n\nconst BASICS_GRID_STYLE = {\n display: 'grid',\n gap: 16,\n gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))',\n} as const;\n","'use client';\n\nimport type { CSSProperties, ReactElement } from 'react';\nimport { Empty, Table, Tag, Typography } from '@mezzanine-ui/react';\nimport type { TableColumn } from '@mezzanine-ui/core/table';\nimport type {\n FormDefinitionSchema,\n FormUiSchema,\n} from '@rytass/bpm-core-shared/form';\nimport type {\n WorkflowDefinition,\n WorkflowNode,\n} from '@rytass/bpm-core-shared/workflow';\nimport { FormRenderer } from '../../../forms/renderer/FormRendererView';\n\ntype FlowNodeRow = Readonly<\n Record<string, unknown> & {\n detail: string;\n key: string;\n label: string;\n typeLabel: string;\n }\n>;\n\ntype BranchRow = Readonly<\n Record<string, unknown> & {\n condition: string;\n key: string;\n source: string;\n target: string;\n }\n>;\n\nexport interface ComposeReviewStepProps {\n readonly name: string;\n readonly formSchema: FormDefinitionSchema;\n readonly formUiSchema: FormUiSchema;\n readonly workflowDefinition: WorkflowDefinition | null;\n readonly initiatorPolicyCel: string | null;\n readonly publishError: string | null;\n}\n\nexport function ComposeReviewStep({\n formSchema,\n formUiSchema,\n initiatorPolicyCel,\n name,\n publishError,\n workflowDefinition,\n}: ComposeReviewStepProps): ReactElement {\n const nodes = workflowDefinition?.nodes ?? [];\n const edges = workflowDefinition?.edges ?? [];\n const fieldCount = formSchema.fields.length;\n const nodeLabelById = new Map(\n nodes.map((node) => [node.id, node.data.label] as const),\n );\n const nodeRows: FlowNodeRow[] = nodes.map((node) => ({\n detail: readNodeDetail(node) ?? '—',\n key: node.id,\n label: node.data.label,\n typeLabel: readNodeTypeLabel(node),\n }));\n const branchRows: BranchRow[] = edges\n .filter((edge) => Boolean(edge.data.condition))\n .map((edge) => ({\n condition: edge.data.condition ?? '',\n key: edge.id,\n source: nodeLabelById.get(edge.source) ?? edge.source,\n target: nodeLabelById.get(edge.target) ?? edge.target,\n }));\n\n return (\n <div style={STACK_STYLE}>\n <Typography component=\"h2\" style={TITLE_STYLE} variant=\"h2\">\n {name || '(未命名)'}\n </Typography>\n\n <div style={STACK_STYLE}>\n <Typography variant=\"h3\">表單預覽</Typography>\n {fieldCount > 0 ? (\n <FormRenderer readonly schema={formSchema} uiSchema={formUiSchema} />\n ) : (\n <Empty title=\"尚未設計表單欄位\" />\n )}\n </div>\n\n <div style={STACK_STYLE}>\n <Typography variant=\"h3\">流程概覽</Typography>\n {nodes.length > 0 ? (\n <Table columns={NODE_COLUMNS} dataSource={nodeRows} fullWidth />\n ) : (\n <Empty title=\"尚未設計流程節點\" />\n )}\n {branchRows.length > 0 ? (\n <>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 條件分流\n </Typography>\n <Table columns={BRANCH_COLUMNS} dataSource={branchRows} fullWidth />\n </>\n ) : null}\n {initiatorPolicyCel ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 發起權限:{initiatorPolicyCel}\n </Typography>\n ) : null}\n </div>\n\n {publishError ? (\n <Typography color=\"text-error\" variant=\"body\">\n {publishError}\n </Typography>\n ) : null}\n </div>\n );\n}\n\nconst NODE_COLUMNS: TableColumn<FlowNodeRow>[] = [\n {\n key: 'type',\n render: (record: FlowNodeRow): ReactElement => (\n <Tag label={record.typeLabel} size=\"sub\" type=\"static\" />\n ),\n title: '類型',\n width: 130,\n },\n { dataIndex: 'label', key: 'label', title: '節點' },\n { dataIndex: 'detail', key: 'detail', title: '簽核方式', width: 160 },\n];\n\nconst BRANCH_COLUMNS: TableColumn<BranchRow>[] = [\n { dataIndex: 'source', key: 'source', title: '來源', width: 180 },\n { dataIndex: 'target', key: 'target', title: '目標', width: 180 },\n { dataIndex: 'condition', key: 'condition', title: '條件' },\n];\n\nfunction readNodeTypeLabel(node: WorkflowNode): string {\n switch (node.type) {\n case 'startEvent':\n return '開始';\n case 'endEvent':\n return node.data.endState === 'REJECTED' ? '結束(駁回)' : '結束(核准)';\n case 'userTask':\n return '簽核';\n case 'serviceTask':\n return '服務';\n case 'exclusiveGateway':\n return '條件閘道';\n case 'parallelGateway':\n return '平行閘道';\n default:\n return '節點';\n }\n}\n\nfunction readNodeDetail(node: WorkflowNode): string | null {\n if (node.type !== 'userTask') {\n return null;\n }\n\n switch (node.data.approverResolver.type) {\n case 'DIRECT':\n return '指定成員';\n case 'POSITION':\n return '指定職位';\n case 'ORG_UNIT_MEMBER':\n return '單位成員';\n case 'ORG_UNIT_POSITION':\n return '單位職位';\n case 'ORG_MANAGER':\n return '主管';\n case 'ORG_UNIT_MANAGER':\n return '單位主管';\n case 'DYNAMIC_FORM':\n return '表單動態指派';\n case 'EXPRESSION':\n return '運算式';\n default:\n return '簽核人';\n }\n}\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 12,\n};\n\n// Match the breathing room between the stepper and the PageHeader, which is the\n// Section's top padding token.\nconst TITLE_STYLE: CSSProperties = {\n marginTop: 'var(--mzn-spacing-padding-vertical-spacious)',\n};\n","'use client';\n\nimport type { ReactElement } from 'react';\nimport { Typography } from '@mezzanine-ui/react';\nimport type { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';\nimport type { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';\nimport { TemplateDesignerView } from '../../designer';\n\nexport interface ComposeWorkflowStepProps {\n readonly formSchema: FormDefinitionSchema;\n readonly workflowDefinition: WorkflowDefinition | null;\n readonly initiatorPolicyCel: string | null;\n readonly onWorkflowChange: (definition: WorkflowDefinition) => void;\n readonly onInitiatorPolicyChange: (cel: string | null) => void;\n}\n\nexport function ComposeWorkflowStep({\n formSchema,\n initiatorPolicyCel,\n onInitiatorPolicyChange,\n onWorkflowChange,\n workflowDefinition,\n}: ComposeWorkflowStepProps): ReactElement {\n return (\n <>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 設計簽核節點與條件分流;條件可直接引用上一步設計的表單欄位。\n </Typography>\n <TemplateDesignerView\n embedded\n formSchemaOverride={formSchema}\n initialInitiatorPolicyCel={initiatorPolicyCel}\n initialWorkflowDefinition={workflowDefinition ?? undefined}\n onInitiatorPolicyChange={onInitiatorPolicyChange}\n onWorkflowChange={onWorkflowChange}\n />\n </>\n );\n}\n","'use client';\n\nimport { useCallback, useState } from 'react';\nimport type {\n FormDefinitionSchema,\n FormUiSchema,\n} from '@rytass/bpm-core-shared/form';\nimport type { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';\nimport {\n ComposeApprovalTemplateWithFormResult,\n composeApprovalTemplateWithForm,\n} from '@rytass/bpm-core-client/template';\n\nexport type ComposeWizardStep = 0 | 1 | 2;\n\nexport type ComposePublishPhase = 'error' | 'idle' | 'submitting' | 'success';\n\nexport const EMPTY_COMPOSE_FORM_SCHEMA: FormDefinitionSchema = {\n fields: [],\n schemaVersion: 1,\n};\n\nexport const EMPTY_COMPOSE_FORM_UI_SCHEMA: FormUiSchema = {\n layout: [],\n schemaVersion: 1,\n};\n\nexport interface TemplateComposeWizard {\n readonly currentStep: ComposeWizardStep;\n /**\n * Single user-facing name. Persisted to both the template and the form\n * (`templateName` / `formName`) at the `composeApprovalTemplateWithForm`\n * boundary — the DB keeps two columns, the UI keeps one field.\n */\n readonly name: string;\n readonly categoryId: string | null;\n readonly formSchema: FormDefinitionSchema;\n readonly formUiSchema: FormUiSchema;\n readonly workflowDefinition: WorkflowDefinition | null;\n readonly initiatorPolicyCel: string | null;\n readonly publishPhase: ComposePublishPhase;\n readonly publishError: string | null;\n readonly canLeaveBasics: boolean;\n readonly goToStep: (step: ComposeWizardStep) => void;\n readonly goNext: () => void;\n readonly goBack: () => void;\n readonly setName: (value: string) => void;\n readonly setCategoryId: (value: string | null) => void;\n readonly setFormValue: (next: {\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n }) => void;\n readonly setWorkflowDefinition: (definition: WorkflowDefinition) => void;\n readonly setInitiatorPolicyCel: (cel: string | null) => void;\n readonly publish: () => Promise<ComposeApprovalTemplateWithFormResult | null>;\n}\n\n/**\n * Owns the cross-step state for the unified \"form + flow\" template wizard.\n *\n * Step 0 (表單) edits `formSchema`/`formUiSchema`; that same in-memory schema\n * feeds Step 1 (流程) as the field source for condition branches, so the\n * embedded designer never needs a published form version. Step 2 (檢視發佈)\n * submits everything through the atomic `composeApprovalTemplateWithForm`\n * mutation.\n */\nexport function useTemplateComposeWizard(): TemplateComposeWizard {\n const [currentStep, setCurrentStep] = useState<ComposeWizardStep>(0);\n const [name, setName] = useState('');\n const [categoryId, setCategoryId] = useState<string | null>(null);\n const [formSchema, setFormSchema] = useState<FormDefinitionSchema>(\n EMPTY_COMPOSE_FORM_SCHEMA,\n );\n const [formUiSchema, setFormUiSchema] = useState<FormUiSchema>(\n EMPTY_COMPOSE_FORM_UI_SCHEMA,\n );\n const [workflowDefinition, setWorkflowDefinitionState] =\n useState<WorkflowDefinition | null>(null);\n const [initiatorPolicyCel, setInitiatorPolicyCelState] = useState<\n string | null\n >(null);\n const [publishPhase, setPublishPhase] = useState<ComposePublishPhase>('idle');\n const [publishError, setPublishError] = useState<string | null>(null);\n\n const canLeaveBasics = name.trim().length > 0 && formSchema.fields.length > 0;\n\n const goToStep = useCallback((step: ComposeWizardStep): void => {\n setCurrentStep(step);\n }, []);\n\n const goNext = useCallback((): void => {\n setCurrentStep((step) =>\n step < 2 ? ((step + 1) as ComposeWizardStep) : step,\n );\n }, []);\n\n const goBack = useCallback((): void => {\n setCurrentStep((step) =>\n step > 0 ? ((step - 1) as ComposeWizardStep) : step,\n );\n }, []);\n\n const setFormValue = useCallback(\n (next: {\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n }): void => {\n setFormSchema(next.schema);\n setFormUiSchema(next.uiSchema);\n },\n [],\n );\n\n const setWorkflowDefinition = useCallback(\n (definition: WorkflowDefinition): void => {\n setWorkflowDefinitionState(definition);\n },\n [],\n );\n\n const setInitiatorPolicyCel = useCallback((cel: string | null): void => {\n setInitiatorPolicyCelState(cel);\n }, []);\n\n const publish =\n useCallback(async (): Promise<ComposeApprovalTemplateWithFormResult | null> => {\n setPublishPhase('submitting');\n setPublishError(null);\n\n try {\n const result = await composeApprovalTemplateWithForm({\n category: null,\n categoryId,\n formDefinitionId: null,\n formDescription: null,\n // One UI name fans out to both persisted columns.\n formName: name,\n initiatorPolicyCel,\n notificationConfig: null,\n publish: true,\n schema: formSchema,\n slaDefaults: null,\n templateDescription: null,\n templateId: null,\n templateName: name,\n uiSchema: formUiSchema,\n workflowDefinition: workflowDefinition ?? EMPTY_WORKFLOW_DEFINITION,\n });\n\n setPublishPhase('success');\n\n return result;\n } catch (requestError: unknown) {\n setPublishError(readErrorMessage(requestError));\n setPublishPhase('error');\n\n return null;\n }\n }, [\n categoryId,\n formSchema,\n formUiSchema,\n initiatorPolicyCel,\n name,\n workflowDefinition,\n ]);\n\n return {\n canLeaveBasics,\n categoryId,\n currentStep,\n formSchema,\n formUiSchema,\n goBack,\n goNext,\n goToStep,\n initiatorPolicyCel,\n name,\n publish,\n publishError,\n publishPhase,\n setCategoryId,\n setFormValue,\n setInitiatorPolicyCel,\n setName,\n setWorkflowDefinition,\n workflowDefinition,\n };\n}\n\nconst EMPTY_WORKFLOW_DEFINITION: WorkflowDefinition = {\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\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n","'use client';\n\nimport type { ReactElement } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Step,\n Stepper,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { ComposeFormStep } from './steps/ComposeFormStep';\nimport { ComposeReviewStep } from './steps/ComposeReviewStep';\nimport { ComposeWorkflowStep } from './steps/ComposeWorkflowStep';\nimport { useTemplateComposeWizard } from './use-template-compose-wizard';\n\n/**\n * Unified \"form + flow\" template creation wizard. Walks the user through\n * Step 0 表單設計 → Step 1 流程設計 → Step 2 檢視並發佈, then commits both\n * sides atomically through `composeApprovalTemplateWithForm`. Coexists with\n * the separate `/forms` and `/templates` entry points.\n */\nexport function TemplateComposeWizardView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const wizard = useTemplateComposeWizard();\n const submitting = wizard.publishPhase === 'submitting';\n\n async function handlePublish(): Promise<void> {\n const result = await wizard.publish();\n\n if (result) {\n router.push(routes.templateDesigner(result.templateId));\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"一次完成表單與流程設計,發佈後即可直接發起。\"\n title=\"建立模板(表單 + 流程)\"\n >\n <Button\n disabled={submitting}\n onClick={(): void => router.push(routes.templates())}\n variant=\"base-secondary\"\n >\n 返回模板列表\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Stepper currentStep={wizard.currentStep}>\n <Step description=\"設計欄位與版面\" title=\"表單設計\" />\n <Step description=\"設計簽核節點與條件\" title=\"流程設計\" />\n <Step description=\"確認後發佈\" title=\"檢視並發佈\" />\n </Stepper>\n\n {wizard.currentStep === 0 ? (\n <ComposeFormStep\n categoryId={wizard.categoryId}\n formSchema={wizard.formSchema}\n formUiSchema={wizard.formUiSchema}\n name={wizard.name}\n onCategoryIdChange={wizard.setCategoryId}\n onFormChange={wizard.setFormValue}\n onNameChange={wizard.setName}\n />\n ) : null}\n\n {wizard.currentStep === 1 ? (\n <ComposeWorkflowStep\n formSchema={wizard.formSchema}\n initiatorPolicyCel={wizard.initiatorPolicyCel}\n onInitiatorPolicyChange={wizard.setInitiatorPolicyCel}\n onWorkflowChange={wizard.setWorkflowDefinition}\n workflowDefinition={wizard.workflowDefinition}\n />\n ) : null}\n\n {wizard.currentStep === 2 ? (\n <ComposeReviewStep\n formSchema={wizard.formSchema}\n formUiSchema={wizard.formUiSchema}\n initiatorPolicyCel={wizard.initiatorPolicyCel}\n name={wizard.name}\n publishError={wizard.publishError}\n workflowDefinition={wizard.workflowDefinition}\n />\n ) : null}\n\n <div style={FOOTER_STYLE}>\n {wizard.currentStep === 0 && !wizard.canLeaveBasics ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 請填寫模板名稱、表單名稱,並至少新增一個表單欄位。\n </Typography>\n ) : (\n <span />\n )}\n <div style={FOOTER_ACTIONS_STYLE}>\n <Button\n disabled={wizard.currentStep === 0 || submitting}\n onClick={wizard.goBack}\n variant=\"base-secondary\"\n >\n 上一步\n </Button>\n {wizard.currentStep < 2 ? (\n <Button\n disabled={wizard.currentStep === 0 && !wizard.canLeaveBasics}\n onClick={wizard.goNext}\n variant=\"base-primary\"\n >\n 下一步\n </Button>\n ) : (\n <Button\n disabled={submitting}\n loading={submitting}\n onClick={(): void => {\n void handlePublish();\n }}\n variant=\"base-primary\"\n >\n 發佈\n </Button>\n )}\n </div>\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nconst FOOTER_STYLE = {\n alignItems: 'center',\n display: 'flex',\n // Match the breathing room used elsewhere (the Section's top padding token).\n marginTop: 'var(--mzn-spacing-padding-vertical-spacious)',\n justifyContent: 'space-between',\n gap: 16,\n} as const;\n\nconst FOOTER_ACTIONS_STYLE = {\n display: 'flex',\n gap: 8,\n} as const;\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use client";const e=require("./chunk-CMqjfN_6.cjs"),t=require("./router-adapter--gYs13E8.cjs"),n=require("./routes-config-fDVHmvXi.cjs"),r=require("./FormRendererView-BwVsH2eX.cjs"),i=require("./FormBuilderView-B_KGPjlp.cjs"),a=require("./designer-DCn6_v4b.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@mezzanine-ui/react/ContentHeader");l=e.t(l,1);let u=require("@mezzanine-ui/core/form"),d=require("@rytass/bpm-core-client/template");var f={id:`UNCATEGORIZED`,name:`未分類`},p=100;function m({categoryId:e,formSchema:t,formUiSchema:n,name:r,onCategoryIdChange:a,onFormChange:l,onNameChange:m}){let[g,_]=(0,o.useState)([]);(0,o.useEffect)(()=>{let e=!0;return(async()=>{try{let t=await(0,d.listApprovalTemplateCategoriesPage)({page:1,pageSize:p,searchText:``,status:`ACTIVE`});e&&_(t.categories)}catch{e&&_([])}})(),()=>{e=!1}},[]);let v=[f,...g.map(e=>({id:e.id,name:e.name}))],y=v.find(t=>t.id===e)??f;return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsxs)(`div`,{style:h,children:[(0,c.jsx)(s.FormField,{label:`名稱`,layout:u.FormFieldLayout.VERTICAL,name:`composeName`,children:(0,c.jsx)(s.Input,{fullWidth:!0,onChange:e=>m(e.target.value),placeholder:`例如:請款簽核`,value:r})}),(0,c.jsx)(s.FormField,{label:`分類(選填)`,layout:u.FormFieldLayout.VERTICAL,name:`composeCategory`,children:(0,c.jsx)(s.Select,{clearable:!1,fullWidth:!0,onChange:e=>a(e&&e.id!==f.id?e.id:null),options:v,placeholder:`未分類`,value:y})})]}),(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:`先設計表單欄位,下一步的流程條件分流即可直接引用這些欄位。`}),(0,c.jsx)(i.t,{onChange:l,value:{schema:t,uiSchema:n}})]})}var h={display:`grid`,gap:16,gridTemplateColumns:`repeat(auto-fit, minmax(220px, 1fr))`};function g({formSchema:e,formUiSchema:t,initiatorPolicyCel:n,name:i,publishError:a,workflowDefinition:o}){let l=o?.nodes??[],u=o?.edges??[],d=e.fields.length,f=new Map(l.map(e=>[e.id,e.data.label])),p=l.map(e=>({detail:b(e)??`—`,key:e.id,label:e.data.label,typeLabel:y(e)})),m=u.filter(e=>!!e.data.condition).map(e=>({condition:e.data.condition??``,key:e.id,source:f.get(e.source)??e.source,target:f.get(e.target)??e.target}));return(0,c.jsxs)(`div`,{style:x,children:[(0,c.jsx)(s.Typography,{component:`h2`,style:S,variant:`h2`,children:i||`(未命名)`}),(0,c.jsxs)(`div`,{style:x,children:[(0,c.jsx)(s.Typography,{variant:`h3`,children:`表單預覽`}),d>0?(0,c.jsx)(r.t,{readonly:!0,schema:e,uiSchema:t}):(0,c.jsx)(s.Empty,{title:`尚未設計表單欄位`})]}),(0,c.jsxs)(`div`,{style:x,children:[(0,c.jsx)(s.Typography,{variant:`h3`,children:`流程概覽`}),l.length>0?(0,c.jsx)(s.Table,{columns:_,dataSource:p,fullWidth:!0}):(0,c.jsx)(s.Empty,{title:`尚未設計流程節點`}),m.length>0?(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:`條件分流`}),(0,c.jsx)(s.Table,{columns:v,dataSource:m,fullWidth:!0})]}):null,n?(0,c.jsxs)(s.Typography,{color:`text-neutral`,variant:`caption`,children:[`發起權限:`,n]}):null]}),a?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:a}):null]})}var _=[{key:`type`,render:e=>(0,c.jsx)(s.Tag,{label:e.typeLabel,size:`sub`,type:`static`}),title:`類型`,width:130},{dataIndex:`label`,key:`label`,title:`節點`},{dataIndex:`detail`,key:`detail`,title:`簽核方式`,width:160}],v=[{dataIndex:`source`,key:`source`,title:`來源`,width:180},{dataIndex:`target`,key:`target`,title:`目標`,width:180},{dataIndex:`condition`,key:`condition`,title:`條件`}];function y(e){switch(e.type){case`startEvent`:return`開始`;case`endEvent`:return e.data.endState===`REJECTED`?`結束(駁回)`:`結束(核准)`;case`userTask`:return`簽核`;case`serviceTask`:return`服務`;case`exclusiveGateway`:return`條件閘道`;case`parallelGateway`:return`平行閘道`;default:return`節點`}}function b(e){if(e.type!==`userTask`)return null;switch(e.data.approverResolver.type){case`DIRECT`:return`指定成員`;case`POSITION`:return`指定職位`;case`ORG_UNIT_MEMBER`:return`單位成員`;case`ORG_UNIT_POSITION`:return`單位職位`;case`ORG_MANAGER`:return`主管`;case`ORG_UNIT_MANAGER`:return`單位主管`;case`DYNAMIC_FORM`:return`表單動態指派`;case`EXPRESSION`:return`運算式`;default:return`簽核人`}}var x={display:`grid`,gap:12},S={marginTop:`var(--mzn-spacing-padding-vertical-spacious)`};function C({formSchema:e,initiatorPolicyCel:t,onInitiatorPolicyChange:n,onWorkflowChange:r,workflowDefinition:i}){return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:`設計簽核節點與條件分流;條件可直接引用上一步設計的表單欄位。`}),(0,c.jsx)(a.t,{embedded:!0,formSchemaOverride:e,initialInitiatorPolicyCel:t,initialWorkflowDefinition:i??void 0,onInitiatorPolicyChange:n,onWorkflowChange:r})]})}var w={fields:[],schemaVersion:1},T={layout:[],schemaVersion:1};function E(){let[e,t]=(0,o.useState)(0),[n,r]=(0,o.useState)(``),[i,a]=(0,o.useState)(null),[s,c]=(0,o.useState)(w),[l,u]=(0,o.useState)(T),[f,p]=(0,o.useState)(null),[m,h]=(0,o.useState)(null),[g,_]=(0,o.useState)(`idle`),[v,y]=(0,o.useState)(null),b=n.trim().length>0&&s.fields.length>0,x=(0,o.useCallback)(e=>{t(e)},[]),S=(0,o.useCallback)(()=>{t(e=>e<2?e+1:e)},[]),C=(0,o.useCallback)(()=>{t(e=>e>0?e-1:e)},[]),E=(0,o.useCallback)(e=>{c(e.schema),u(e.uiSchema)},[]),k=(0,o.useCallback)(e=>{p(e)},[]),A=(0,o.useCallback)(e=>{h(e)},[]);return{canLeaveBasics:b,categoryId:i,currentStep:e,formSchema:s,formUiSchema:l,goBack:C,goNext:S,goToStep:x,initiatorPolicyCel:m,name:n,publish:(0,o.useCallback)(async()=>{_(`submitting`),y(null);try{let e=await(0,d.composeApprovalTemplateWithForm)({category:null,categoryId:i,formDefinitionId:null,formDescription:null,formName:n,initiatorPolicyCel:m,notificationConfig:null,publish:!0,schema:s,slaDefaults:null,templateDescription:null,templateId:null,templateName:n,uiSchema:l,workflowDefinition:f??D});return _(`success`),e}catch(e){return y(O(e)),_(`error`),null}},[i,s,l,m,n,f]),publishError:v,publishPhase:g,setCategoryId:a,setFormValue:E,setInitiatorPolicyCel:A,setName:r,setWorkflowDefinition:k,workflowDefinition:f}}var D={edges:[],meta:{schemaVersion:1},nodes:[{data:{label:`開始`},id:`start`,position:{x:80,y:160},type:`startEvent`},{data:{endState:`APPROVED`,label:`完成`,triggerMode:`AND`},id:`end`,position:{x:560,y:160},type:`endEvent`}]};function O(e){return e instanceof Error?e.message:`發生未知錯誤`}function k(){let e=t.r(),r=n.r(),i=E(),a=i.publishPhase===`submitting`;async function o(){let t=await i.publish();t&&e.push(r.templateDesigner(t.templateId))}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(l.default,{description:`一次完成表單與流程設計,發佈後即可直接發起。`,title:`建立模板(表單 + 流程)`,children:(0,c.jsx)(s.Button,{disabled:a,onClick:()=>e.push(r.templates()),variant:`base-secondary`,children:`返回模板列表`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{children:[(0,c.jsxs)(s.Stepper,{currentStep:i.currentStep,children:[(0,c.jsx)(s.Step,{description:`設計欄位與版面`,title:`表單設計`}),(0,c.jsx)(s.Step,{description:`設計簽核節點與條件`,title:`流程設計`}),(0,c.jsx)(s.Step,{description:`確認後發佈`,title:`檢視並發佈`})]}),i.currentStep===0?(0,c.jsx)(m,{categoryId:i.categoryId,formSchema:i.formSchema,formUiSchema:i.formUiSchema,name:i.name,onCategoryIdChange:i.setCategoryId,onFormChange:i.setFormValue,onNameChange:i.setName}):null,i.currentStep===1?(0,c.jsx)(C,{formSchema:i.formSchema,initiatorPolicyCel:i.initiatorPolicyCel,onInitiatorPolicyChange:i.setInitiatorPolicyCel,onWorkflowChange:i.setWorkflowDefinition,workflowDefinition:i.workflowDefinition}):null,i.currentStep===2?(0,c.jsx)(g,{formSchema:i.formSchema,formUiSchema:i.formUiSchema,initiatorPolicyCel:i.initiatorPolicyCel,name:i.name,publishError:i.publishError,workflowDefinition:i.workflowDefinition}):null,(0,c.jsxs)(`div`,{style:A,children:[i.currentStep===0&&!i.canLeaveBasics?(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:`請填寫模板名稱、表單名稱,並至少新增一個表單欄位。`}):(0,c.jsx)(`span`,{}),(0,c.jsxs)(`div`,{style:j,children:[(0,c.jsx)(s.Button,{disabled:i.currentStep===0||a,onClick:i.goBack,variant:`base-secondary`,children:`上一步`}),i.currentStep<2?(0,c.jsx)(s.Button,{disabled:i.currentStep===0&&!i.canLeaveBasics,onClick:i.goNext,variant:`base-primary`,children:`下一步`}):(0,c.jsx)(s.Button,{disabled:a,loading:a,onClick:()=>{o()},variant:`base-primary`,children:`發佈`})]})]})]})})]})}var A={alignItems:`center`,display:`flex`,marginTop:`var(--mzn-spacing-padding-vertical-spacious)`,justifyContent:`space-between`,gap:16},j={display:`flex`,gap:8};Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return k}});
|
|
2
|
-
//# sourceMappingURL=compose-ziVbRYdo.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compose-ziVbRYdo.cjs","names":[],"sources":["../../src/views/templates/compose/steps/ComposeFormStep.tsx","../../src/views/templates/compose/steps/ComposeReviewStep.tsx","../../src/views/templates/compose/steps/ComposeWorkflowStep.tsx","../../src/views/templates/compose/use-template-compose-wizard.ts","../../src/views/templates/compose/TemplateComposeWizardView.tsx"],"sourcesContent":["'use client';\n\nimport type { ChangeEvent, ReactElement } from 'react';\nimport { useEffect, useState } from 'react';\nimport { FormField, Input, Select, Typography } from '@mezzanine-ui/react';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { SelectValue } from '@mezzanine-ui/react/Select';\nimport type {\n FormDefinitionSchema,\n FormUiSchema,\n} from '@rytass/bpm-core-shared/form';\nimport {\n ApprovalTemplateCategoryRecord,\n listApprovalTemplateCategoriesPage,\n} from '@rytass/bpm-core-client/template';\nimport { FormBuilderView } from '../../../forms/builder';\n\nconst UNCATEGORIZED_OPTION: SelectValue = {\n id: 'UNCATEGORIZED',\n name: '未分類',\n};\n\nconst CATEGORY_PAGE_SIZE = 100;\n\nexport interface ComposeFormStepProps {\n readonly name: string;\n readonly categoryId: string | null;\n readonly formSchema: FormDefinitionSchema;\n readonly formUiSchema: FormUiSchema;\n readonly onNameChange: (value: string) => void;\n readonly onCategoryIdChange: (value: string | null) => void;\n readonly onFormChange: (next: {\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n }) => void;\n}\n\nexport function ComposeFormStep({\n categoryId,\n formSchema,\n formUiSchema,\n name,\n onCategoryIdChange,\n onFormChange,\n onNameChange,\n}: ComposeFormStepProps): ReactElement {\n const [categoryOptions, setCategoryOptions] = useState<\n readonly ApprovalTemplateCategoryRecord[]\n >([]);\n\n useEffect((): (() => void) => {\n let active = true;\n\n void (async (): Promise<void> => {\n try {\n const result = await listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n });\n\n if (active) {\n setCategoryOptions(result.categories);\n }\n } catch {\n if (active) {\n setCategoryOptions([]);\n }\n }\n })();\n\n return (): void => {\n active = false;\n };\n }, []);\n\n const selectOptions: SelectValue[] = [\n UNCATEGORIZED_OPTION,\n ...categoryOptions.map((category) => ({\n id: category.id,\n name: category.name,\n })),\n ];\n const selectedOption =\n selectOptions.find((option) => option.id === categoryId) ??\n UNCATEGORIZED_OPTION;\n\n return (\n <>\n <div style={BASICS_GRID_STYLE}>\n <FormField\n label=\"名稱\"\n layout={FormFieldLayout.VERTICAL}\n name=\"composeName\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onNameChange(event.target.value)\n }\n placeholder=\"例如:請款簽核\"\n value={name}\n />\n </FormField>\n <FormField\n label=\"分類(選填)\"\n layout={FormFieldLayout.VERTICAL}\n name=\"composeCategory\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onCategoryIdChange(\n option && option.id !== UNCATEGORIZED_OPTION.id\n ? option.id\n : null,\n )\n }\n options={selectOptions}\n placeholder=\"未分類\"\n value={selectedOption}\n />\n </FormField>\n </div>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 先設計表單欄位,下一步的流程條件分流即可直接引用這些欄位。\n </Typography>\n <FormBuilderView\n onChange={onFormChange}\n value={{ schema: formSchema, uiSchema: formUiSchema }}\n />\n </>\n );\n}\n\nconst BASICS_GRID_STYLE = {\n display: 'grid',\n gap: 16,\n gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))',\n} as const;\n","'use client';\n\nimport type { CSSProperties, ReactElement } from 'react';\nimport { Empty, Table, Tag, Typography } from '@mezzanine-ui/react';\nimport type { TableColumn } from '@mezzanine-ui/core/table';\nimport type {\n FormDefinitionSchema,\n FormUiSchema,\n} from '@rytass/bpm-core-shared/form';\nimport type {\n WorkflowDefinition,\n WorkflowNode,\n} from '@rytass/bpm-core-shared/workflow';\nimport { FormRenderer } from '../../../forms/renderer/FormRendererView';\n\ntype FlowNodeRow = Readonly<\n Record<string, unknown> & {\n detail: string;\n key: string;\n label: string;\n typeLabel: string;\n }\n>;\n\ntype BranchRow = Readonly<\n Record<string, unknown> & {\n condition: string;\n key: string;\n source: string;\n target: string;\n }\n>;\n\nexport interface ComposeReviewStepProps {\n readonly name: string;\n readonly formSchema: FormDefinitionSchema;\n readonly formUiSchema: FormUiSchema;\n readonly workflowDefinition: WorkflowDefinition | null;\n readonly initiatorPolicyCel: string | null;\n readonly publishError: string | null;\n}\n\nexport function ComposeReviewStep({\n formSchema,\n formUiSchema,\n initiatorPolicyCel,\n name,\n publishError,\n workflowDefinition,\n}: ComposeReviewStepProps): ReactElement {\n const nodes = workflowDefinition?.nodes ?? [];\n const edges = workflowDefinition?.edges ?? [];\n const fieldCount = formSchema.fields.length;\n const nodeLabelById = new Map(\n nodes.map((node) => [node.id, node.data.label] as const),\n );\n const nodeRows: FlowNodeRow[] = nodes.map((node) => ({\n detail: readNodeDetail(node) ?? '—',\n key: node.id,\n label: node.data.label,\n typeLabel: readNodeTypeLabel(node),\n }));\n const branchRows: BranchRow[] = edges\n .filter((edge) => Boolean(edge.data.condition))\n .map((edge) => ({\n condition: edge.data.condition ?? '',\n key: edge.id,\n source: nodeLabelById.get(edge.source) ?? edge.source,\n target: nodeLabelById.get(edge.target) ?? edge.target,\n }));\n\n return (\n <div style={STACK_STYLE}>\n <Typography component=\"h2\" style={TITLE_STYLE} variant=\"h2\">\n {name || '(未命名)'}\n </Typography>\n\n <div style={STACK_STYLE}>\n <Typography variant=\"h3\">表單預覽</Typography>\n {fieldCount > 0 ? (\n <FormRenderer readonly schema={formSchema} uiSchema={formUiSchema} />\n ) : (\n <Empty title=\"尚未設計表單欄位\" />\n )}\n </div>\n\n <div style={STACK_STYLE}>\n <Typography variant=\"h3\">流程概覽</Typography>\n {nodes.length > 0 ? (\n <Table columns={NODE_COLUMNS} dataSource={nodeRows} fullWidth />\n ) : (\n <Empty title=\"尚未設計流程節點\" />\n )}\n {branchRows.length > 0 ? (\n <>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 條件分流\n </Typography>\n <Table columns={BRANCH_COLUMNS} dataSource={branchRows} fullWidth />\n </>\n ) : null}\n {initiatorPolicyCel ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 發起權限:{initiatorPolicyCel}\n </Typography>\n ) : null}\n </div>\n\n {publishError ? (\n <Typography color=\"text-error\" variant=\"body\">\n {publishError}\n </Typography>\n ) : null}\n </div>\n );\n}\n\nconst NODE_COLUMNS: TableColumn<FlowNodeRow>[] = [\n {\n key: 'type',\n render: (record: FlowNodeRow): ReactElement => (\n <Tag label={record.typeLabel} size=\"sub\" type=\"static\" />\n ),\n title: '類型',\n width: 130,\n },\n { dataIndex: 'label', key: 'label', title: '節點' },\n { dataIndex: 'detail', key: 'detail', title: '簽核方式', width: 160 },\n];\n\nconst BRANCH_COLUMNS: TableColumn<BranchRow>[] = [\n { dataIndex: 'source', key: 'source', title: '來源', width: 180 },\n { dataIndex: 'target', key: 'target', title: '目標', width: 180 },\n { dataIndex: 'condition', key: 'condition', title: '條件' },\n];\n\nfunction readNodeTypeLabel(node: WorkflowNode): string {\n switch (node.type) {\n case 'startEvent':\n return '開始';\n case 'endEvent':\n return node.data.endState === 'REJECTED' ? '結束(駁回)' : '結束(核准)';\n case 'userTask':\n return '簽核';\n case 'serviceTask':\n return '服務';\n case 'exclusiveGateway':\n return '條件閘道';\n case 'parallelGateway':\n return '平行閘道';\n default:\n return '節點';\n }\n}\n\nfunction readNodeDetail(node: WorkflowNode): string | null {\n if (node.type !== 'userTask') {\n return null;\n }\n\n switch (node.data.approverResolver.type) {\n case 'DIRECT':\n return '指定成員';\n case 'POSITION':\n return '指定職位';\n case 'ORG_UNIT_MEMBER':\n return '單位成員';\n case 'ORG_UNIT_POSITION':\n return '單位職位';\n case 'ORG_MANAGER':\n return '主管';\n case 'ORG_UNIT_MANAGER':\n return '單位主管';\n case 'DYNAMIC_FORM':\n return '表單動態指派';\n case 'EXPRESSION':\n return '運算式';\n default:\n return '簽核人';\n }\n}\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 12,\n};\n\n// Match the breathing room between the stepper and the PageHeader, which is the\n// Section's top padding token.\nconst TITLE_STYLE: CSSProperties = {\n marginTop: 'var(--mzn-spacing-padding-vertical-spacious)',\n};\n","'use client';\n\nimport type { ReactElement } from 'react';\nimport { Typography } from '@mezzanine-ui/react';\nimport type { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';\nimport type { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';\nimport { TemplateDesignerView } from '../../designer';\n\nexport interface ComposeWorkflowStepProps {\n readonly formSchema: FormDefinitionSchema;\n readonly workflowDefinition: WorkflowDefinition | null;\n readonly initiatorPolicyCel: string | null;\n readonly onWorkflowChange: (definition: WorkflowDefinition) => void;\n readonly onInitiatorPolicyChange: (cel: string | null) => void;\n}\n\nexport function ComposeWorkflowStep({\n formSchema,\n initiatorPolicyCel,\n onInitiatorPolicyChange,\n onWorkflowChange,\n workflowDefinition,\n}: ComposeWorkflowStepProps): ReactElement {\n return (\n <>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 設計簽核節點與條件分流;條件可直接引用上一步設計的表單欄位。\n </Typography>\n <TemplateDesignerView\n embedded\n formSchemaOverride={formSchema}\n initialInitiatorPolicyCel={initiatorPolicyCel}\n initialWorkflowDefinition={workflowDefinition ?? undefined}\n onInitiatorPolicyChange={onInitiatorPolicyChange}\n onWorkflowChange={onWorkflowChange}\n />\n </>\n );\n}\n","'use client';\n\nimport { useCallback, useState } from 'react';\nimport type {\n FormDefinitionSchema,\n FormUiSchema,\n} from '@rytass/bpm-core-shared/form';\nimport type { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';\nimport {\n ComposeApprovalTemplateWithFormResult,\n composeApprovalTemplateWithForm,\n} from '@rytass/bpm-core-client/template';\n\nexport type ComposeWizardStep = 0 | 1 | 2;\n\nexport type ComposePublishPhase = 'error' | 'idle' | 'submitting' | 'success';\n\nexport const EMPTY_COMPOSE_FORM_SCHEMA: FormDefinitionSchema = {\n fields: [],\n schemaVersion: 1,\n};\n\nexport const EMPTY_COMPOSE_FORM_UI_SCHEMA: FormUiSchema = {\n layout: [],\n schemaVersion: 1,\n};\n\nexport interface TemplateComposeWizard {\n readonly currentStep: ComposeWizardStep;\n /**\n * Single user-facing name. Persisted to both the template and the form\n * (`templateName` / `formName`) at the `composeApprovalTemplateWithForm`\n * boundary — the DB keeps two columns, the UI keeps one field.\n */\n readonly name: string;\n readonly categoryId: string | null;\n readonly formSchema: FormDefinitionSchema;\n readonly formUiSchema: FormUiSchema;\n readonly workflowDefinition: WorkflowDefinition | null;\n readonly initiatorPolicyCel: string | null;\n readonly publishPhase: ComposePublishPhase;\n readonly publishError: string | null;\n readonly canLeaveBasics: boolean;\n readonly goToStep: (step: ComposeWizardStep) => void;\n readonly goNext: () => void;\n readonly goBack: () => void;\n readonly setName: (value: string) => void;\n readonly setCategoryId: (value: string | null) => void;\n readonly setFormValue: (next: {\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n }) => void;\n readonly setWorkflowDefinition: (definition: WorkflowDefinition) => void;\n readonly setInitiatorPolicyCel: (cel: string | null) => void;\n readonly publish: () => Promise<ComposeApprovalTemplateWithFormResult | null>;\n}\n\n/**\n * Owns the cross-step state for the unified \"form + flow\" template wizard.\n *\n * Step 0 (表單) edits `formSchema`/`formUiSchema`; that same in-memory schema\n * feeds Step 1 (流程) as the field source for condition branches, so the\n * embedded designer never needs a published form version. Step 2 (檢視發佈)\n * submits everything through the atomic `composeApprovalTemplateWithForm`\n * mutation.\n */\nexport function useTemplateComposeWizard(): TemplateComposeWizard {\n const [currentStep, setCurrentStep] = useState<ComposeWizardStep>(0);\n const [name, setName] = useState('');\n const [categoryId, setCategoryId] = useState<string | null>(null);\n const [formSchema, setFormSchema] = useState<FormDefinitionSchema>(\n EMPTY_COMPOSE_FORM_SCHEMA,\n );\n const [formUiSchema, setFormUiSchema] = useState<FormUiSchema>(\n EMPTY_COMPOSE_FORM_UI_SCHEMA,\n );\n const [workflowDefinition, setWorkflowDefinitionState] =\n useState<WorkflowDefinition | null>(null);\n const [initiatorPolicyCel, setInitiatorPolicyCelState] = useState<\n string | null\n >(null);\n const [publishPhase, setPublishPhase] = useState<ComposePublishPhase>('idle');\n const [publishError, setPublishError] = useState<string | null>(null);\n\n const canLeaveBasics = name.trim().length > 0 && formSchema.fields.length > 0;\n\n const goToStep = useCallback((step: ComposeWizardStep): void => {\n setCurrentStep(step);\n }, []);\n\n const goNext = useCallback((): void => {\n setCurrentStep((step) =>\n step < 2 ? ((step + 1) as ComposeWizardStep) : step,\n );\n }, []);\n\n const goBack = useCallback((): void => {\n setCurrentStep((step) =>\n step > 0 ? ((step - 1) as ComposeWizardStep) : step,\n );\n }, []);\n\n const setFormValue = useCallback(\n (next: {\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n }): void => {\n setFormSchema(next.schema);\n setFormUiSchema(next.uiSchema);\n },\n [],\n );\n\n const setWorkflowDefinition = useCallback(\n (definition: WorkflowDefinition): void => {\n setWorkflowDefinitionState(definition);\n },\n [],\n );\n\n const setInitiatorPolicyCel = useCallback((cel: string | null): void => {\n setInitiatorPolicyCelState(cel);\n }, []);\n\n const publish =\n useCallback(async (): Promise<ComposeApprovalTemplateWithFormResult | null> => {\n setPublishPhase('submitting');\n setPublishError(null);\n\n try {\n const result = await composeApprovalTemplateWithForm({\n category: null,\n categoryId,\n formDefinitionId: null,\n formDescription: null,\n // One UI name fans out to both persisted columns.\n formName: name,\n initiatorPolicyCel,\n notificationConfig: null,\n publish: true,\n schema: formSchema,\n slaDefaults: null,\n templateDescription: null,\n templateId: null,\n templateName: name,\n uiSchema: formUiSchema,\n workflowDefinition: workflowDefinition ?? EMPTY_WORKFLOW_DEFINITION,\n });\n\n setPublishPhase('success');\n\n return result;\n } catch (requestError: unknown) {\n setPublishError(readErrorMessage(requestError));\n setPublishPhase('error');\n\n return null;\n }\n }, [\n categoryId,\n formSchema,\n formUiSchema,\n initiatorPolicyCel,\n name,\n workflowDefinition,\n ]);\n\n return {\n canLeaveBasics,\n categoryId,\n currentStep,\n formSchema,\n formUiSchema,\n goBack,\n goNext,\n goToStep,\n initiatorPolicyCel,\n name,\n publish,\n publishError,\n publishPhase,\n setCategoryId,\n setFormValue,\n setInitiatorPolicyCel,\n setName,\n setWorkflowDefinition,\n workflowDefinition,\n };\n}\n\nconst EMPTY_WORKFLOW_DEFINITION: WorkflowDefinition = {\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\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n","'use client';\n\nimport type { ReactElement } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Step,\n Stepper,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { ComposeFormStep } from './steps/ComposeFormStep';\nimport { ComposeReviewStep } from './steps/ComposeReviewStep';\nimport { ComposeWorkflowStep } from './steps/ComposeWorkflowStep';\nimport { useTemplateComposeWizard } from './use-template-compose-wizard';\n\n/**\n * Unified \"form + flow\" template creation wizard. Walks the user through\n * Step 0 表單設計 → Step 1 流程設計 → Step 2 檢視並發佈, then commits both\n * sides atomically through `composeApprovalTemplateWithForm`. Coexists with\n * the separate `/forms` and `/templates` entry points.\n */\nexport function TemplateComposeWizardView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const wizard = useTemplateComposeWizard();\n const submitting = wizard.publishPhase === 'submitting';\n\n async function handlePublish(): Promise<void> {\n const result = await wizard.publish();\n\n if (result) {\n router.push(routes.templateDesigner(result.templateId));\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"一次完成表單與流程設計,發佈後即可直接發起。\"\n title=\"建立模板(表單 + 流程)\"\n >\n <Button\n disabled={submitting}\n onClick={(): void => router.push(routes.templates())}\n variant=\"base-secondary\"\n >\n 返回模板列表\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Stepper currentStep={wizard.currentStep}>\n <Step description=\"設計欄位與版面\" title=\"表單設計\" />\n <Step description=\"設計簽核節點與條件\" title=\"流程設計\" />\n <Step description=\"確認後發佈\" title=\"檢視並發佈\" />\n </Stepper>\n\n {wizard.currentStep === 0 ? (\n <ComposeFormStep\n categoryId={wizard.categoryId}\n formSchema={wizard.formSchema}\n formUiSchema={wizard.formUiSchema}\n name={wizard.name}\n onCategoryIdChange={wizard.setCategoryId}\n onFormChange={wizard.setFormValue}\n onNameChange={wizard.setName}\n />\n ) : null}\n\n {wizard.currentStep === 1 ? (\n <ComposeWorkflowStep\n formSchema={wizard.formSchema}\n initiatorPolicyCel={wizard.initiatorPolicyCel}\n onInitiatorPolicyChange={wizard.setInitiatorPolicyCel}\n onWorkflowChange={wizard.setWorkflowDefinition}\n workflowDefinition={wizard.workflowDefinition}\n />\n ) : null}\n\n {wizard.currentStep === 2 ? (\n <ComposeReviewStep\n formSchema={wizard.formSchema}\n formUiSchema={wizard.formUiSchema}\n initiatorPolicyCel={wizard.initiatorPolicyCel}\n name={wizard.name}\n publishError={wizard.publishError}\n workflowDefinition={wizard.workflowDefinition}\n />\n ) : null}\n\n <div style={FOOTER_STYLE}>\n {wizard.currentStep === 0 && !wizard.canLeaveBasics ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 請填寫模板名稱、表單名稱,並至少新增一個表單欄位。\n </Typography>\n ) : (\n <span />\n )}\n <div style={FOOTER_ACTIONS_STYLE}>\n <Button\n disabled={wizard.currentStep === 0 || submitting}\n onClick={wizard.goBack}\n variant=\"base-secondary\"\n >\n 上一步\n </Button>\n {wizard.currentStep < 2 ? (\n <Button\n disabled={wizard.currentStep === 0 && !wizard.canLeaveBasics}\n onClick={wizard.goNext}\n variant=\"base-primary\"\n >\n 下一步\n </Button>\n ) : (\n <Button\n disabled={submitting}\n loading={submitting}\n onClick={(): void => {\n void handlePublish();\n }}\n variant=\"base-primary\"\n >\n 發佈\n </Button>\n )}\n </div>\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nconst FOOTER_STYLE = {\n alignItems: 'center',\n display: 'flex',\n // Match the breathing room used elsewhere (the Section's top padding token).\n marginTop: 'var(--mzn-spacing-padding-vertical-spacious)',\n justifyContent: 'space-between',\n gap: 16,\n} as const;\n\nconst FOOTER_ACTIONS_STYLE = {\n display: 'flex',\n gap: 8,\n} as const;\n"],"mappings":"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"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"use client";const e=require("./chunk-CMqjfN_6.cjs"),t=require("./router-adapter--gYs13E8.cjs"),n=require("./routes-config-fDVHmvXi.cjs"),r=require("./admin-pickers-Btvij1at.cjs"),i=require("./bpm-form-field-Bc6k4ZEO.cjs"),a=require("./FormBuilderView-B_KGPjlp.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@mezzanine-ui/react/Drawer");l=e.t(l,1);let u=require("@mezzanine-ui/react/ContentHeader");u=e.t(u,1);let d=require("@mezzanine-ui/icons"),f=require("ai"),p=require("@rytass/bpm-core-shared"),m=require("@rytass/bpm-core-client/form"),h=require("@rytass/bpm-core-client/organization"),g=require("@xyflow/react"),_=require("dagre");_=e.t(_,1);let v=require("@rytass/bpm-core-client/template"),y=require("@ai-sdk/react");function ee({directory:e,initialState:t,layout:n,onLayout:r}){let[i,a]=(0,o.useState)(t),s=(0,o.useRef)(t),c=(0,o.useRef)(e);c.current=e;let l=(0,o.useCallback)(e=>{if(!e.changed&&!e.error)return e;let t=e.effects.layout?n(e.state.definition):e.state.definition,i={...e.state,definition:t};return s.current=i,a(i),e.effects.layout&&r?.(t),{...e,state:i}},[n,r]),u=(0,o.useCallback)(e=>l((0,p.applyWorkflowCommand)(s.current,e)),[l]),d=(0,o.useCallback)(e=>l((0,p.applyWorkflowMacroCommand)(s.current,e)),[l]),f=(0,o.useCallback)(async(e,t)=>{let n=await(0,p.executeWorkflowTool)(s.current,e,t,{directory:c.current});if(n.ok&&(n.kind===`mutation`||n.kind===`macro`)){let e=l(n.result);return{...n,result:e,snapshot:(0,p.readWorkflowSnapshot)(e.state)}}return n},[l]),m=(0,o.useCallback)(e=>{let t=typeof e==`function`?e(s.current):e;s.current=t,a(t)},[]),h=(0,o.useCallback)(()=>s.current,[]),g=(0,o.useMemo)(()=>(0,p.readWorkflowSnapshot)(i),[i]);return(0,o.useMemo)(()=>({dispatch:u,dispatchMacro:d,executeTool:f,getState:h,replaceState:m,snapshot:g,state:i,tools:p.WORKFLOW_TOOLSET}),[u,d,f,h,m,g,i])}function te({controller:e,api:t=`/api/chat`}){let n=(0,y.useChat)({transport:(0,o.useMemo)(()=>new f.DefaultChatTransport({api:t}),[t]),sendAutomaticallyWhen:f.lastAssistantMessageIsCompleteWithToolCalls,async onToolCall({toolCall:t}){let r=await e.executeTool(t.toolName,t.input);if(r.ok){n.addToolOutput({output:r.kind===`query`?r.data:r.snapshot,tool:t.toolName,toolCallId:t.toolCallId});return}n.addToolOutput({errorText:r.error,state:`output-error`,tool:t.toolName,toolCallId:t.toolCallId})}});return n}var ne=12;function re(){let e=globalThis.LanguageModel;return e&&typeof e==`object`?e:null}var ie={additionalProperties:!1,properties:{action:{enum:[`tool`,`message`],type:`string`},input:{type:`object`},text:{type:`string`},tool:{type:`string`}},required:[`action`],type:`object`};function ae(){return`你是「簽核流程設計器」頁面的離線 AI 助理。只能透過下列工具操作這個流程畫布,其他請求一律婉拒並引導回流程設計。
|
|
2
|
-
|
|
3
|
-
每一步只輸出一個 JSON 決策物件:
|
|
4
|
-
- 呼叫工具:{"action":"tool","tool":"<工具名>","input":{...}}
|
|
5
|
-
- 回覆使用者(完成或詢問):{"action":"message","text":"<繁體中文訊息>"}
|
|
6
|
-
|
|
7
|
-
規則:先用 get_workflow_snapshot 了解現況再規劃;完成後用 validate_workflow 檢查並以 message 說明做了什麼。
|
|
8
|
-
|
|
9
|
-
可用工具:
|
|
10
|
-
${p.WORKFLOW_TOOLSET.map(e=>`- ${e.name}(${JSON.stringify(e.inputSchema.properties??{})}): ${e.description}`).join(`
|
|
11
|
-
`)}`}function oe({controller:e}){let[t,n]=(0,o.useState)(!1),[r,i]=(0,o.useState)([]),[a,s]=(0,o.useState)(`ready`),c=(0,o.useRef)(0);(0,o.useEffect)(()=>{let e=re();e&&e.availability().then(e=>{n(e!==`unavailable`)}).catch(()=>n(!1))},[]);let l=(0,o.useCallback)((e,t)=>{c.current+=1,i(n=>[...n,{id:`chrome-${c.current}`,parts:[{text:t,type:`text`}],role:e}])},[]);return{available:t,messages:r,send:(0,o.useCallback)(t=>{let n=re();!n||a!==`ready`||(l(`user`,t),s(`submitted`),se({appendMessage:l,controller:e,model:n,userText:t}).then(()=>s(`ready`)).catch(e=>{l(`assistant`,ce(e)),s(`error`)}))},[l,e,a]),status:a}}async function se({appendMessage:e,controller:t,model:n,userText:r}){let i=await n.create({initialPrompts:[{content:ae(),role:`system`}]});try{let n=`使用者需求:${r}\n目前流程:${JSON.stringify(t.snapshot)}`;for(let r=0;r<ne;r+=1){let r=b(await i.prompt(n,{responseConstraint:ie}));if(!r||r.action===`message`){e(`assistant`,r?.text??`我已完成可處理的部分。`);return}if(!r.tool){e(`assistant`,`我已完成可處理的部分。`);return}let a=await t.executeTool(r.tool,r.input??{});if(a.ok){let t=a.kind===`query`?a.data:a.snapshot;e(`assistant`,`⚙ ${r.tool}`),n=`工具 ${r.tool} 已執行。最新流程:${JSON.stringify(t)}\n請決定下一步。`}else n=`工具 ${r.tool} 失敗:${a.error}\n請改用其他方式或回覆使用者。`}e(`assistant`,`已達到單次操作步數上限,請告訴我下一步。`)}finally{i.destroy()}}function b(e){try{let t=JSON.parse(e);return typeof t==`object`&&t&&t.action!==void 0?t:null}catch{return null}}function ce(e){return e instanceof Error?`離線模式發生錯誤:${e.message}`:`離線模式發生未知錯誤。`}var x={display:`flex`,flexDirection:`column`,gap:12,height:`100%`},le={display:`flex`,flex:1,flexDirection:`column`,gap:12,minHeight:0,overflowY:`auto`},ue={display:`flex`,gap:8,paddingBottom:4},de={borderTop:`1px solid var(--mzn-color-border-neutral, #e5e7eb)`,display:`flex`,flexDirection:`column`,gap:8,paddingTop:12},fe={display:`flex`,justifyContent:`flex-end`},pe={width:`100%`},me=`workflow-chat-input-field`,he=`
|
|
12
|
-
.${me}.mzn-text-field {
|
|
13
|
-
width: 100%;
|
|
14
|
-
}
|
|
15
|
-
`,ge={color:`var(--mzn-color-text-secondary, #6b7280)`,fontSize:12,padding:`2px 0`},_e={"input-available":`執行中…`,"input-streaming":`準備中…`,"output-available":`完成`,"output-error":`失敗`};function ve(e){let t=e===`user`;return{alignSelf:t?`flex-end`:`flex-start`,background:t?`var(--mzn-color-primary, #2563eb)`:`var(--mzn-color-surface, #f3f4f6)`,borderRadius:10,color:t?`#fff`:`var(--mzn-color-text-primary, #111827)`,maxWidth:`85%`,padding:`8px 12px`,whiteSpace:`pre-wrap`,wordBreak:`break-word`}}function ye({api:e,controller:t,onClose:n,open:r}){let i=te({api:e,controller:t}),a=oe({controller:t}),[u,d]=(0,o.useState)(`online`),[f,p]=(0,o.useState)(``),m=u===`offline`?{messages:a.messages,send:a.send,status:a.status}:{messages:i.messages,send:e=>{i.sendMessage({text:e})},status:i.status},{messages:h,send:g}=m,_=m.status===`submitted`||m.status===`streaming`,v=(0,o.useCallback)(()=>{let e=f.trim();!e||_||(p(``),g(e))},[_,f,g]),y=(0,o.useCallback)(e=>{e.nativeEvent.isComposing||e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),v())},[v]);return(0,c.jsxs)(l.default,{headerTitle:`AI 流程助理`,isHeaderDisplay:!0,onClose:n,open:r,size:`medium`,children:[(0,c.jsx)(`style`,{children:he}),(0,c.jsxs)(`div`,{style:x,children:[a.available?(0,c.jsxs)(`div`,{style:ue,children:[(0,c.jsx)(s.Button,{onClick:()=>d(`online`),variant:u===`online`?`base-primary`:`base-tertiary`,children:`線上`}),(0,c.jsx)(s.Button,{onClick:()=>d(`offline`),variant:u===`offline`?`base-primary`:`base-tertiary`,children:`離線(裝置內,實驗)`})]}):null,(0,c.jsxs)(`div`,{role:`log`,style:le,children:[h.length===0?(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:`用一句話描述你想要的流程,例如:「建立三關簽核:部門主管 → 經理 → 財務,金額大於十萬走財務複核」。我會直接在畫布上幫你繪製。`}):null,h.map(e=>(0,c.jsx)(o.Fragment,{children:be(e)},e.id)),_?(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:`思考中…`}):null]}),(0,c.jsxs)(`div`,{style:de,children:[(0,c.jsx)(s.Textarea,{className:me,disabled:_,maxLength:2e3,onChange:e=>p(e.target.value),onKeyDown:y,placeholder:`描述你想要的流程…(Enter 送出,Shift + Enter 換行)`,rows:3,style:pe,value:f}),(0,c.jsx)(`div`,{style:fe,children:(0,c.jsx)(s.Button,{disabled:_||f.trim().length===0,loading:_,onClick:v,type:`button`,variant:`base-primary`,children:`送出`})})]})]})]})}function be(e){return e.parts.map((t,n)=>t.type===`text`?(0,c.jsx)(`div`,{style:ve(e.role),children:t.text},`${e.id}-${n}`):t.type===`dynamic-tool`||(0,f.isToolUIPart)(t)?(0,c.jsx)(`div`,{style:ge,children:`⚙ ${(0,f.getToolName)(t)} · ${_e[t.state]??t.state}`},`${e.id}-${n}`):null)}var xe={display:`grid`,gap:16},Se={alignItems:`start`,display:`grid`,gap:16,gridTemplateColumns:`minmax(0, 1fr) 420px`},Ce={border:`1px solid var(--mzn-color-border-neutral)`,borderRadius:6,height:620,minWidth:0,overflow:`hidden`},we={alignItems:`center`,boxSizing:`border-box`,color:`var(--mzn-color-text-error)`,display:`flex`,height:26,justifyContent:`center`,lineHeight:0,padding:0,width:26},Te={alignItems:`center`,display:`flex`,height:`100%`,justifyContent:`center`,width:`100%`},Ee=`workflow-designer-side-panel`,De=96,Oe=`
|
|
16
|
-
.${Ee} .mzn-form-field--stretch .mzn-form-field__label-area,
|
|
17
|
-
.${Ee} .mzn-form-field--horizontal .mzn-form-field__label-area {
|
|
18
|
-
flex: 0 0 ${De}px;
|
|
19
|
-
width: ${De}px;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.${Ee} .mzn-form-field--stretch .mzn-form-field__data-entry,
|
|
23
|
-
.${Ee} .mzn-form-field--horizontal .mzn-form-field__data-entry {
|
|
24
|
-
min-width: 0;
|
|
25
|
-
}
|
|
26
|
-
`,S=`#2563eb`,C=`#64748b`,ke=`var(--mzn-color-text-error, #dc2626)`,w=`drop-shadow(0 0 3px rgba(0, 87, 255, 0.85)) drop-shadow(0 0 9px rgba(0, 87, 255, 0.36))`,Ae=`
|
|
27
|
-
.workflow-selection-delete-control.react-flow__controls-button {
|
|
28
|
-
align-items: center !important;
|
|
29
|
-
display: flex !important;
|
|
30
|
-
height: 26px !important;
|
|
31
|
-
justify-content: center !important;
|
|
32
|
-
padding: 0 !important;
|
|
33
|
-
width: 26px !important;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.workflow-selection-delete-control .mzn-icon {
|
|
37
|
-
align-items: center;
|
|
38
|
-
display: flex;
|
|
39
|
-
justify-content: center;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.workflow-selection-delete-control .mzn-icon svg {
|
|
43
|
-
height: 16px !important;
|
|
44
|
-
max-height: none !important;
|
|
45
|
-
max-width: none !important;
|
|
46
|
-
width: 16px !important;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.workflow-edge--selected .react-flow__edge-path,
|
|
50
|
-
.react-flow__edge-path.workflow-edge--selected {
|
|
51
|
-
filter: ${w};
|
|
52
|
-
opacity: 1 !important;
|
|
53
|
-
stroke: ${C} !important;
|
|
54
|
-
stroke-opacity: 1 !important;
|
|
55
|
-
stroke-width: 1.5px !important;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.workflow-edge--selected {
|
|
59
|
-
--xy-edge-stroke: ${C};
|
|
60
|
-
--xy-edge-stroke-selected: ${C};
|
|
61
|
-
--xy-edge-stroke-width: 1.5px;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
`,je={display:`grid`,gap:12},T={display:`grid`,gap:12},Me={border:`1px solid var(--mzn-color-border-neutral)`,borderRadius:6,display:`grid`,gap:8,maxHeight:360,overflow:`auto`,padding:12},Ne={borderBottom:`1px solid var(--mzn-color-border-neutral)`,display:`grid`,gap:4,padding:`0 0 8px`},Pe={display:`flex`,flexWrap:`wrap`,gap:8},Fe={alignItems:`center`,display:`flex`,gap:8},Ie={flex:`1 1 auto`,minWidth:0},Le={flex:`0 0 auto`},Re={display:`grid`,gap:8},E={alignContent:`center`,background:`var(--mzn-color-bg-surface)`,border:`1px solid var(--mzn-color-border-neutral)`,borderRadius:6,boxShadow:`0 8px 20px rgba(15, 23, 42, 0.08)`,boxSizing:`border-box`,display:`grid`,gap:4,height:`100%`,minWidth:132,overflow:`visible`,padding:`10px 12px`,textAlign:`center`,width:`100%`},ze=`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)`,D=64,Be=160,Ve=20,He=64,Ue=180,O={...E,display:`grid`,gap:8,padding:`10px 12px`},We={...O,background:`#eff6ff`,border:`1px solid #2563eb`},Ge={...O,background:`#f0fdfa`,border:`1px solid #0f766e`},Ke={...E,background:`#ffffff`},k={...E,background:`#ecfdf3`,border:`1px solid #2f855a`},qe={...E,background:`#fff4ed`,border:`1px solid #c2410c`},A={display:`block`,maxWidth:`100%`,minWidth:0},Je={display:`grid`,gap:2,minWidth:0},j=`input`,Ye=`output`,Xe={endEvent:`結束`,exclusiveGateway:`條件分流`,parallelGateway:`並行處理`,serviceTask:`系統`,startEvent:`開始`,userTask:`簽核`},Ze=[{icon:d.UserIcon,label:`簽核節點`,type:`userTask`},{icon:d.MailIcon,label:`知會節點`,type:`serviceTask`}],Qe=[{icon:d.FilterIcon,label:`條件分流`,type:`exclusiveGateway`}],$e=[{id:`AND`,name:`全部前置完成`},{id:`OR`,name:`任一前置完成`}],et=[{id:`RESTART`,name:`重新送出後從開始重跑`},{id:`FROM_RETURN_POINT`,name:`重新送出後回到退回節點`}],tt=[{id:`DIRECT`,name:`指定會員`},{id:`ORG_MANAGER`,name:`發起人主管`},{id:`ORG_UNIT_MANAGER`,name:`指定組織主管`},{id:`ORG_UNIT_MEMBER`,name:`組織任一人`},{id:`ORG_UNIT_POSITION`,name:`組織特定職位`},{id:`POSITION`,name:`指定職位`}],M=[{id:`1`,name:`直屬主管`,value:1},{id:`2`,name:`第二層主管`,value:2},{id:`3`,name:`第三層主管`,value:3}],nt=[{id:`NONE`,name:`停止流程並提示`},{id:`DIRECT`,name:`固定改派`}],rt=[{id:`EQUALS`,name:`等於`},{id:`NOT_EQUALS`,name:`不等於`},{id:`GREATER_THAN`,name:`大於`},{id:`GREATER_THAN_OR_EQUALS`,name:`大於等於`},{id:`LESS_THAN`,name:`小於`},{id:`LESS_THAN_OR_EQUALS`,name:`小於等於`},{id:`IS_FILLED`,name:`已填寫`},{id:`IS_EMPTY`,name:`未填寫`}],it=[`EQUALS`,`GREATER_THAN`,`GREATER_THAN_OR_EQUALS`,`LESS_THAN`,`LESS_THAN_OR_EQUALS`,`NOT_EQUALS`],at=[{id:`NONE`,name:`未設定`},{id:`ALL`,name:`所有人`},{id:`ORG_UNIT`,name:`指定組織`},{id:`ORG_UNIT_POSITION`,name:`指定組織職位`}],ot={id:`CUSTOM`,name:`既有自訂規則`},st=`member-001`,ct={display:`flex`,flexDirection:`column`,height:`100%`},lt={flex:1,minHeight:0,overflowY:`auto`},ut={borderTop:`1px solid var(--mzn-color-border-neutral)`,display:`flex`,gap:8,paddingTop:12},dt={fields:[],schemaVersion:1},ft={layout:[],schemaVersion:1},pt={endEvent:P,exclusiveGateway:P,parallelGateway:P,serviceTask:P,startEvent:P,userTask:P};function N(e,t){return typeof e==`function`?e(t):e}function mt({aiAssistantAvailable:e=!0,embedded:f=!1,formSchemaOverride:p,initialInitiatorPolicyCel:_,initialWorkflowDefinition:y,onInitiatorPolicyChange:te,onWorkflowChange:ne,showAiAssistant:re=!1,showDryRun:ie=!0,templateId:ae}){let oe=t.r(),se=n.r(),[b,ce]=(0,o.useState)(null),[x,le]=(0,o.useState)(null),[ue,de]=(0,o.useState)(``),[fe,pe]=(0,o.useState)(null),[me,he]=(0,o.useState)(null),ge=(0,o.useRef)(null),[_e,ve]=(0,o.useState)(void 0),be=(0,o.useRef)([]),De=(0,o.useRef)([]),S=ee({directory:(0,o.useMemo)(()=>({listOrgUnits:async()=>be.current.map(e=>({id:e.id,name:e.name})),listPositions:async()=>De.current.map(e=>({id:e.id,name:e.name})),searchMembers:async e=>an(await(0,v.searchMemberOptions)(e)).map(e=>({email:e.email,id:e.memberId,name:e.name}))}),[]),initialState:{definition:f&&y!=null?y:Tt(),editingEdgeId:null,formDefinitionVersionId:null,formSchema:null,initiatorPolicyCel:f&&_!==void 0?_:null,selectedEdgeIds:[],selectedNodeId:f&&y!=null?y.nodes[0]?.id??`start`:`start`},layout:Dt,onLayout:e=>{let t=Sn(e,ge.current);t&&ve(t)}}),C=S.state.definition,w=S.state.formDefinitionVersionId,E=S.state.initiatorPolicyCel,ze=S.state.selectedNodeId,D=S.state.selectedEdgeIds,Be=S.state.editingEdgeId,Ve=e=>S.replaceState(t=>({...t,definition:N(e,t.definition)})),He=e=>S.replaceState(t=>({...t,formDefinitionVersionId:N(e,t.formDefinitionVersionId)})),Ue=e=>S.replaceState(t=>({...t,initiatorPolicyCel:N(e,t.initiatorPolicyCel)})),O=e=>S.replaceState(t=>({...t,selectedNodeId:N(e,t.selectedNodeId)})),We=e=>S.replaceState(t=>({...t,selectedEdgeIds:N(e,t.selectedEdgeIds)})),Ge=e=>S.replaceState(t=>({...t,editingEdgeId:N(e,t.editingEdgeId)})),[Ke,k]=(0,o.useState)(null),[qe,A]=(0,o.useState)(!0),[Je,j]=(0,o.useState)(!1),[Ye,rt]=(0,o.useState)(!1),[it,mt]=(0,o.useState)([]),P=(0,o.useMemo)(()=>JSON.stringify({formDefinitionVersionId:w,initiatorPolicyCel:E,workflowDefinition:C}),[w,E,C]),F=!!ue&&P!==ue,[gt,_t]=(0,o.useState)(!1),[I,L]=(0,o.useState)([]),[R,yt]=(0,o.useState)([]),[z,xt]=(0,o.useState)([]),[Ct,wt]=(0,o.useState)([]);be.current=R,De.current=z;let[Lt,Bt]=(0,o.useState)(!1),[Ht,qt]=(0,o.useState)(!1),[Jt,Yt]=(0,o.useState)(`{}`),[V,en]=(0,o.useState)(null),[H,U]=(0,o.useState)(null),[fn,pn]=(0,o.useState)(!1),[mn,W]=(0,o.useState)(!1),[G,K]=(0,o.useState)(null),[vn,yn]=(0,o.useState)(!1),[bn,xn]=(0,o.useState)(!1),wn=F||vn?`保存並發布`:x?`發布草稿`:`已發布`;(0,o.useEffect)(()=>{f?Yn():Xn()},[f,ae]),(0,o.useEffect)(()=>{function e(e){F&&(e.preventDefault(),e.returnValue=``)}return window.addEventListener(`beforeunload`,e),()=>{window.removeEventListener(`beforeunload`,e)}},[F]),(0,o.useEffect)(()=>{Qn(C)},[C,I]),(0,o.useEffect)(()=>{Ve(e=>St(e))},[C.edges,C.nodes]);function An(){F&&!window.confirm(`目前有尚未儲存的流程草稿,確定要離開嗎?`)||oe.push(se.templates())}let q=(0,o.useMemo)(()=>C.nodes.find(e=>e.id===ze)??null,[ze,C.nodes]),Pn=q?Kt(q):!1,In=D.length>0||Pn,Ln=(0,o.useCallback)(()=>{S.getState().selectedEdgeIds.forEach(e=>S.dispatch({edgeId:e,type:`deleteEdge`})),q&&Kt(q)&&S.dispatch({nodeId:q.id,type:`deleteNode`})},[S,q]);(0,o.useEffect)(()=>{if(!In)return;function e(e){e.key!==`Delete`&&e.key!==`Backspace`||Xt(e.target)||(e.preventDefault(),Ln())}return window.addEventListener(`keydown`,e),()=>{window.removeEventListener(`keydown`,e)}},[In,Ln]);let Rn=(0,o.useMemo)(()=>C.edges.find(e=>e.id===Be)??null,[Be,C.edges]),zn=(0,o.useMemo)(()=>D.length===1?C.edges.find(e=>e.id===D[0])??null:null,[D,C.edges]),Bn=(0,o.useMemo)(()=>D.map(e=>C.edges.find(t=>t.id===e)??null).filter(e=>!!e),[D,C.edges]),X=(0,o.useMemo)(()=>me??Rt(E,fe),[E,me,fe]),Vn=(0,o.useMemo)(()=>C.nodes.map(e=>vt(e,I,R,z,e.id===ze,X)),[X,I,R,z,ze,C.nodes]),Hn=(0,o.useMemo)(()=>C.edges.map(e=>bt(e,C.nodes,D.includes(e.id))),[D,C.edges,C.nodes]),Z=(0,o.useMemo)(()=>B(it,w)??B(Zt(b?.formVersions??[]),w),[w,it,b?.formVersions]),Un=(0,o.useMemo)(()=>rn(it,Z),[it,Z]),Wn=Z?.schema??null,Gn=f?p??null:Wn;(0,o.useEffect)(()=>{S.getState().formSchema!==Gn&&S.replaceState(e=>({...e,formSchema:Gn}))},[S,Gn]);let Kn=(0,o.useMemo)(()=>Cn(C),[C]),qn=(0,o.useMemo)(()=>Tn(C),[C]),Jn=(0,o.useMemo)(()=>zt(X),[X]);(0,o.useEffect)(()=>{f&&ne?.(C)},[f,C]),(0,o.useEffect)(()=>{f&&te?.(E)},[f,E]);async function Yn(){A(!0),k(null);try{let e=await(0,h.readOrganizationDashboard)();yt(e.orgUnits),xt(e.positions),wt(e.memberships)}catch(e){k(Y(e))}finally{A(!1)}}async function Xn(){A(!0),k(null);try{let[e,t]=await Promise.all([(0,v.readTemplateDesigner)(ae),(0,h.readOrganizationDashboard)()]),n=e.versions.find(e=>e.status===`DRAFT`)??null,r=n??e.versions[0]??null;ce(e),le(n),yt(t.orgUnits),xt(t.positions),wt(t.memberships),mt(Zt(e.formVersions));let i=r?.workflowDefinition??Tt(),a=r?.formDefinitionVersionId??e.formVersions[0]?.id??null,o=r?.initiatorPolicyCel??null;Ve(i),He(a),Ue(o),de(JSON.stringify({formDefinitionVersionId:a,initiatorPolicyCel:o,workflowDefinition:i})),pe(r&&!e.template.currentVersionId&&!r.initiatorPolicyCel&&Et(r.workflowDefinition)?`NONE`:null),he(null),O(r?.workflowDefinition.nodes[0]?.id??`start`),We([]),Ge(null),K(null),yn(!1)}catch(e){k(Y(e))}finally{A(!1)}}async function Zn(e){rt(!0),k(null);try{mt(rn(Zt(await(0,v.searchPublishedFormVersionOptions)(e)),Z))}catch(e){k(Y(e))}finally{rt(!1)}}async function Q(e){_t(!0),k(null);try{let t=await(0,v.searchMemberOptions)(e);L(e=>gn(e,an(t)))}catch(e){k(Y(e))}finally{_t(!1)}}async function Qn(e){let t=_n(e).filter(e=>!I.some(t=>t.memberId===e));if(t.length!==0)try{let e=await(0,v.resolveMemberOptions)(t);L(t=>gn(t,an(e)))}catch{L(e=>gn(e,t.map(on)))}}async function $n(e){j(!0),k(null);try{let t=Cn(C),n=zt(X);if(t||n){let e=t??n??`流程設定未完成`;throw k(e),Error(e)}if(vn&&G!==null)await(0,v.composeApprovalTemplateWithForm)({category:b?.template.category??null,categoryId:b?.template.categoryId??null,formDefinitionId:Z?.formDefinitionId??null,formDescription:null,formName:Z?.formName??b?.template.name??`表單`,initiatorPolicyCel:E,notificationConfig:null,publish:e,schema:G.schema,slaDefaults:null,templateDescription:null,templateId:ae??null,templateName:b?.template.name??`模板`,uiSchema:G.uiSchema,workflowDefinition:C}),yn(!1),K(null),await Xn();else{let t=await(0,v.updateApprovalTemplateDraft)({formDefinitionVersionId:w,initiatorPolicyCel:E,versionId:(x??await(0,v.forkApprovalTemplate)(ae)).id,workflowDefinition:C});le(t),e&&await(0,v.publishApprovalTemplateVersion)(t.id),await Xn()}}catch(e){throw k(Y(e)),e}finally{j(!1)}}async function er(){await $n(!1)}async function tr(){await $n(!0)}function nr(){Yt(JSON.stringify(Qt(Z),null,2)),en(null),U(null),Bt(!0)}function rr(){Ht||Bt(!1)}async function ir(){qt(!0),U(null),en(null);try{en(await(0,v.dryRunApprovalWorkflow)({formData:$t(Jt),initiatorMemberId:st,initiatorMetadataSnapshot:dn(st,Ct),workflowDefinition:C}))}catch(e){U(Y(e))}finally{qt(!1)}}async function ar(){if(W(!0),G!==null)return;let e=Z?.formDefinitionId??null;if(!e){K({schema:dt,uiSchema:ft});return}xn(!0);try{let t=await(0,m.readFormBuilder)(e),n=t.versions.find(e=>e.status===`DRAFT`)??t.versions.find(e=>e.id===t.definition.currentVersionId)??t.versions[0]??null;K({schema:n?.schema??dt,uiSchema:n?.uiSchema??ft})}catch(e){k(Y(e))}finally{xn(!1)}}function or(e){let t=(0,g.applyNodeChanges)(e,Vn);Ve(e=>({...e,nodes:e.nodes.map(e=>{let n=t.find(t=>t.id===e.id);return n?{...e,position:n.position}:e})}))}function sr(e){!Wt(e,C.nodes)||!e.source||!e.target||S.dispatch({source:e.source,target:e.target,type:`connectEdge`})}function cr(e,t){e.stopPropagation(),We(n=>e.shiftKey||e.metaKey||e.ctrlKey?Gt(n,t.id):[t.id]),O(null)}function lr(){Ge(null)}function ur(e){S.dispatch({nodeType:e,type:`addNode`})}function dr(e){q&&S.dispatch({label:e,nodeId:q.id,type:`renameNode`})}function $(e){!q||q.type!==`userTask`||S.dispatch({approverResolver:e,nodeId:q.id,type:`setUserTaskApprover`})}function fr(e){!q||q.type!==`userTask`||S.dispatch({nodeId:q.id,resubmitStrategy:e,type:`setUserTaskReturnResubmitStrategy`})}function pr(e){!q||q.type!==`serviceTask`||S.dispatch({action:e,nodeId:q.id,type:`setServiceAction`})}function mr(e){he(e.mode===`ALL`||e.mode===`CUSTOM`?null:e),pe(e.mode===`ALL`||e.mode===`CUSTOM`?null:e.mode),Ue(Vt(e,R))}function hr(e){!q||q.type===`startEvent`||S.dispatch({nodeId:q.id,triggerMode:e,type:`setNodeTriggerMode`})}function gr(e,t){S.dispatch({edgeId:e,isDefault:t,type:`setEdgeDefault`})}function _r({edgeId:e,fieldKey:t,operator:n,value:r}){S.dispatch({edgeId:e,fieldKey:t,operator:n,type:`setEdgeCondition`,value:r})}function vr(){S.dispatch({type:`autoLayout`})}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(`style`,{children:Oe}),f?null:(0,c.jsx)(s.PageHeader,{children:(0,c.jsxs)(u.default,{description:`${x?`草稿 v${x.version}`:`尚未建立草稿`} ·${b?.template.currentVersionId?` 已發布版本`:` 尚未發布`}`,onBackClick:An,title:b?.template.name??`流程設計器`,children:[re?(0,c.jsx)(s.Button,{disabled:!e,onClick:()=>pn(e=>!e),variant:fn?`base-primary`:`base-secondary`,children:e?`AI 助理`:`AI 助理(未設定)`}):null,(0,c.jsx)(s.Button,{"aria-label":`儲存草稿`,disabled:Je||!!Kn||!!Jn,icon:d.SaveIcon,iconType:`icon-only`,onClick:()=>void er(),variant:`base-secondary`,children:`儲存草稿`}),ie?(0,c.jsx)(s.Button,{disabled:qe||!!Kn||!!Jn,icon:d.EyeIcon,iconType:`leading`,onClick:nr,variant:`base-secondary`,children:`試跑流程`}):null,(0,c.jsx)(s.Button,{disabled:Je||!x&&!F&&!vn||!!Kn||!!Jn,icon:d.CheckedIcon,iconType:`leading`,onClick:()=>void tr(),variant:`base-primary`,children:wn})]})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsx)(s.Section,{children:(0,c.jsxs)(`div`,{style:xe,children:[Ke?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:Ke}):null,Kn?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:Kn}):null,Jn?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:Jn}):null,f?null:(0,c.jsx)(`div`,{style:T,children:(0,c.jsx)(i.t,{hintText:qn?`已設定條件分流條件。請先移除所有條件,才能更換綁定表單版本。`:void 0,label:`綁定表單版本`,name:`formDefinitionVersionId`,required:!0,children:(0,c.jsxs)(`div`,{style:Fe,children:[(0,c.jsx)(`div`,{style:Ie,children:(0,c.jsx)(s.AutoComplete,{asyncData:!0,disabled:qe||qn,disabledOptionsFilter:!0,emptyText:`沒有符合的已發布表單版本`,isForceClearable:!!w&&!qn,loading:Ye,loadingText:`搜尋表單版本中...`,mode:`single`,onChange:e=>{qn||He(e?.id??null)},onClear:()=>{qn||He(null)},onSearch:Zn,onVisibilityChange:e=>{e&&!qn&&Zn(``)},options:[...Un],placeholder:`選擇已發布表單版本`,searchDebounceTime:300,value:Z})}),(0,c.jsx)(s.Button,{disabled:qe,onClick:()=>{ar()},style:Le,variant:`base-secondary`,children:`編輯表單`})]})})}),(0,c.jsxs)(`div`,{style:Se,children:[(0,c.jsx)(`div`,{ref:ge,style:Ce,children:(0,c.jsxs)(g.ReactFlow,{connectionMode:g.ConnectionMode.Strict,edges:Hn,fitView:!0,isValidConnection:e=>Wt(e,C.nodes),nodeTypes:pt,nodes:Vn,deleteKeyCode:null,multiSelectionKeyCode:[`Shift`,`Meta`,`Control`],onConnect:sr,onEdgeClick:cr,onNodeClick:(e,t)=>{O(t.id),We([])},onNodesChange:or,onPaneClick:()=>{O(null),We([])},onViewportChange:ve,viewport:_e,children:[(0,c.jsx)(g.Background,{}),(0,c.jsx)(`style`,{children:Ae}),(0,c.jsx)(g.Controls,{children:In?(0,c.jsx)(g.ControlButton,{"aria-label":`刪除選取項目`,className:`workflow-selection-delete-control`,onClick:Ln,style:we,title:`刪除選取項目`,children:(0,c.jsx)(`span`,{style:Te,children:(0,c.jsx)(s.Icon,{color:`error`,icon:d.TrashIcon,size:16})})}):null}),(0,c.jsx)(ht,{onApplyAutoLayout:vr}),(0,c.jsx)(g.MiniMap,{})]})}),(0,c.jsxs)(`div`,{className:Ee,style:je,children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`h3`,children:`流程工具`}),(0,c.jsxs)(`div`,{style:Re,children:[(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:`動作節點`}),(0,c.jsx)(`div`,{style:Pe,children:Ze.map(e=>(0,c.jsx)(s.Button,{icon:e.icon,iconType:`leading`,onClick:()=>ur(e.type),size:`sub`,variant:`base-secondary`,children:e.label},e.type))})]}),(0,c.jsxs)(`div`,{style:Re,children:[(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:`流程控制`}),(0,c.jsx)(`div`,{style:Pe,children:Qe.map(e=>(0,c.jsx)(s.Button,{icon:e.icon,iconType:`leading`,onClick:()=>ur(e.type),size:`sub`,variant:`base-secondary`,children:e.label},e.type))})]}),Bn.length>1?Tr(Bn):null,Bn.length===1&&zn?Er(zn):null,Bn.length===0&&q?br(q):null]})]})]})})}),Dr(Rn),!f&&ie?yr():null,!f&&re&&e?(0,c.jsx)(ye,{controller:S,onClose:()=>pn(!1),open:fn}):null,f?null:(0,c.jsx)(l.default,{headerTitle:`編輯表單`,isHeaderDisplay:!0,onClose:()=>W(!1),open:mn,size:`wide`,children:(0,c.jsxs)(`div`,{style:ct,children:[(0,c.jsx)(`div`,{style:lt,children:bn?(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:`載入中…`}):(0,c.jsx)(a.t,{onChange:e=>{K(e)},value:G??{schema:dt,uiSchema:ft}})}),(0,c.jsxs)(`div`,{style:ut,children:[(0,c.jsx)(s.Button,{disabled:bn,onClick:()=>{G!==null&&(yn(!0),S.replaceState(e=>({...e,formSchema:G.schema}))),W(!1)},variant:`base-primary`,children:`套用`}),(0,c.jsx)(s.Button,{onClick:()=>W(!1),variant:`base-secondary`,children:`取消`})]})]})})]});function yr(){return(0,c.jsx)(s.Modal,{cancelText:`關閉`,confirmText:`執行試跑`,loading:Ht,modalType:`standard`,onCancel:rr,onClose:rr,onConfirm:()=>void ir(),open:Lt,showModalFooter:!0,showModalHeader:!0,size:`wide`,supportingText:`使用 ${st} 與範例表單資料模擬目前畫布流程,不會建立案件。`,title:`試跑流程`,children:(0,c.jsxs)(`div`,{style:T,children:[(0,c.jsx)(i.t,{label:`表單資料 JSON`,name:`dryRunFormDataJson`,required:!0,children:(0,c.jsx)(s.Textarea,{onChange:e=>Yt(e.target.value),resize:`vertical`,rows:8,value:Jt})}),H?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:H}):null,V?(0,c.jsxs)(`div`,{style:Me,children:[(0,c.jsx)(s.Typography,{color:V.valid?`text-success`:`text-error`,variant:`label-primary-highlight`,children:V.valid?`試跑通過`:`試跑失敗`}),V.errors.map(e=>(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:e},e)),V.steps.map(e=>(0,c.jsxs)(`div`,{style:Ne,children:[(0,c.jsxs)(s.Typography,{variant:`label-primary-highlight`,children:[e.nodeLabel,` · `,tn(e.status)]}),(0,c.jsxs)(s.Typography,{color:`text-neutral`,variant:`caption`,children:[nn(e.nodeType),e.assigneeMemberId?` · 處理者:${e.assigneeMemberId}`:``,e.edgeLabel?` · 來源線段:${e.edgeLabel}`:``]}),e.edgeReason?(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:e.edgeReason}):null,e.entryCondition?(0,c.jsxs)(s.Typography,{color:`text-neutral`,variant:`caption`,children:[`進入條件:`,e.entryConditionMatched?`符合`:`不符合`,` ·`,` `,e.entryCondition]}):null,(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:e.message})]},e.id))]}):null]})})}function br(e){return(0,c.jsxs)(`div`,{style:T,children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`h3`,children:`節點屬性`}),(0,c.jsxs)(s.Typography,{color:`text-neutral`,variant:`body`,children:[Xe[e.type],` · `,e.id]}),(0,c.jsx)(i.t,{label:`顯示名稱`,name:`nodeLabel`,required:!0,children:(0,c.jsx)(s.Input,{onChange:e=>dr(e.target.value),value:e.data.label,variant:`base`})}),e.type===`startEvent`?xr():null,e.type===`startEvent`?null:Sr(e),e.type===`userTask`?Cr(e):null,e.type===`serviceTask`?wr(e):null]})}function xr(){let e=X.mode===`CUSTOM`?[...at,ot]:[...at],t=X.mode===`ORG_UNIT`||X.mode===`ORG_UNIT_POSITION`?ln(R,X.orgUnitId??``):null,n=X.mode===`ORG_UNIT_POSITION`?un(z,X.positionId??``):null,a=X.mode===`ORG_UNIT_POSITION`?hn({includeDescendants:!!X.includeDescendants,memberships:Ct,orgUnitId:X.orgUnitId??``,orgUnits:R,positions:z}):[];return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i.t,{hintText:X.mode===`CUSTOM`?`這是舊版表達式規則;切換成標準選項後會改由 UI 管理。`:void 0,label:`發起權限`,name:`initiatorPolicyMode`,required:!0,children:(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>{if(e?.id===`CUSTOM`){pe(null),he(null);return}let t=It(e?.id??null),n=Ut(t);pe(t===`ALL`?null:t),he(t===`ALL`?null:n),Ue(Vt(n,R))},options:e,placeholder:`選擇誰可以發起`,value:B(e,X.mode)})}),X.mode===`ORG_UNIT`||X.mode===`ORG_UNIT_POSITION`?(0,c.jsx)(i.t,{label:`組織`,name:`initiatorOrgUnitId`,required:!0,children:(0,c.jsx)(r.n,{name:`initiatorOrgUnitId`,onChange:e=>mr({...X,orgUnitId:e?.id??``,positionId:``,value:e?.id??``}),orgUnits:R,placeholder:`選擇組織`,value:t})}):null,X.mode===`ORG_UNIT`||X.mode===`ORG_UNIT_POSITION`?(0,c.jsx)(i.t,{label:`包含下層`,name:`initiatorIncludeDescendants`,children:(0,c.jsx)(s.Toggle,{checked:!!X.includeDescendants,onChange:e=>mr({...X,includeDescendants:e.target.checked,...X.mode===`ORG_UNIT_POSITION`?{positionId:``}:{}})})}):null,X.mode===`ORG_UNIT_POSITION`?(0,c.jsx)(i.t,{label:`職位`,name:`initiatorPositionId`,required:!0,children:(0,c.jsx)(r.r,{disabled:!X.orgUnitId?.trim(),name:`initiatorPositionId`,onChange:e=>mr({...X,positionId:e?.id??``}),placeholder:X.orgUnitId?.trim()?`選擇職位`:`請先選擇組織`,positions:a,value:n})}):null]})}function Sr(e){let t=C.edges.filter(t=>t.target===e.id).length,n=t<2,r=n?`AND`:e.data.triggerMode??`AND`;return(0,c.jsx)(i.t,{hintText:n?`需要至少兩條前置連線,才可切換為任一前置完成。`:t>1?`${t} 條前置連線會依此規則觸發。`:`只有一條前置連線時,兩種設定效果相同。`,label:`前置條件`,name:`triggerMode`,required:!0,children:(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>n?void 0:hr(Ot(e?.id??null)),options:[...$e],readOnly:n,value:B($e,r)})})}function Cr(e){let t=e.data.approverResolver,n=At(t.type),a=t.type===`DIRECT`?cn(t.memberIds,I):null,o=t.type===`ORG_UNIT_MANAGER`||t.type===`ORG_UNIT_MEMBER`||t.type===`ORG_UNIT_POSITION`?ln(R,t.orgUnitId):null,l=t.type===`POSITION`||t.type===`ORG_UNIT_POSITION`?un(z,t.positionId):null,u=t.type===`ORG_UNIT_POSITION`?hn({includeDescendants:!!t.includeDescendants,memberships:Ct,orgUnitId:t.orgUnitId,orgUnits:R,positions:z}):[],d=t.type===`ORG_MANAGER`?Pt(t.levelsUp):M[0],f=t.type===`ORG_MANAGER`||t.type===`ORG_UNIT_MANAGER`?t.fallback??{type:`NONE`}:{type:`NONE`},p=f.type===`DIRECT`?sn(I,f.memberId):null,m=e.data.returnBehavior.resubmitStrategy??`RESTART`;return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i.t,{label:`簽核來源`,name:`approverResolverType`,required:!0,children:(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>$(jt(e?.id??null)),options:[...tt],value:B(tt,n)})}),t.type===`DIRECT`?(0,c.jsx)(i.t,{label:`簽核者`,name:`memberId`,required:!0,children:(0,c.jsx)(s.AutoComplete,{asyncData:!0,disabledOptionsFilter:!0,emptyText:`沒有符合的成員`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:`workflow-approver-search`,spellCheck:!1},loading:gt,loadingText:`搜尋成員中...`,mode:`single`,onChange:e=>$({memberIds:e?.id?[e.id]:[],type:`DIRECT`}),onSearch:Q,onVisibilityChange:e=>{e&&Q(``)},options:[...I],placeholder:`搜尋姓名或信箱`,searchDebounceTime:300,value:a})}):null,t.type===`ORG_MANAGER`?(0,c.jsx)(i.t,{hintText:`依發起人的有效會員歸屬與主管解析規則決定簽核人。`,label:`主管層級`,name:`managerLevelsUp`,required:!0,children:(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>$({baseFromInitiator:!0,levelsUp:Ft(e?.id??null).value,type:`ORG_MANAGER`}),options:[...M],value:d})}):null,t.type===`ORG_UNIT_MANAGER`||t.type===`ORG_UNIT_MEMBER`||t.type===`ORG_UNIT_POSITION`?(0,c.jsx)(i.t,{hintText:t.type===`ORG_UNIT_MANAGER`?`依指定組織或其上層的主管解析規則決定簽核人。`:`依指定組織目前有效會員歸屬建立候選簽核人。`,label:`組織`,name:`orgUnitId`,required:!0,children:(0,c.jsx)(r.n,{name:`orgUnitId`,onChange:e=>$(t.type===`ORG_UNIT_MEMBER`?{includeDescendants:t.includeDescendants,orgUnitId:e?.id??``,type:`ORG_UNIT_MEMBER`}:t.type===`ORG_UNIT_POSITION`?{includeDescendants:t.includeDescendants,orgUnitId:e?.id??``,positionId:``,type:`ORG_UNIT_POSITION`}:{fallback:t.fallback,orgUnitId:e?.id??``,type:`ORG_UNIT_MANAGER`}),orgUnits:R,placeholder:`選擇組織`,value:o})}):null,t.type===`ORG_MANAGER`||t.type===`ORG_UNIT_MANAGER`?(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i.t,{hintText:`預設會停止流程並提示;若設定固定人,找不到主管時會改派給該會員。`,label:`無主管時`,name:`approverFallbackMode`,required:!0,children:(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>$(Nt(t,Mt(e?.id??null)===`DIRECT`?{memberId:``,type:`DIRECT`}:{type:`NONE`})),options:[...nt],value:B(nt,f.type)})}),f.type===`DIRECT`?(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i.t,{label:`改派人員`,name:`approverFallbackMemberId`,required:!0,children:(0,c.jsx)(s.AutoComplete,{asyncData:!0,disabledOptionsFilter:!0,emptyText:`沒有符合的成員`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:`workflow-approver-fallback-search`,spellCheck:!1},loading:gt,loadingText:`搜尋成員中...`,mode:`single`,onChange:e=>$(Nt(t,{allowInitiatorSelfApproval:f.allowInitiatorSelfApproval,memberId:e?.id??``,type:`DIRECT`})),onSearch:Q,onVisibilityChange:e=>{e&&Q(``)},options:[...I],placeholder:`搜尋姓名或信箱`,searchDebounceTime:300,value:p})}),(0,c.jsx)(i.t,{hintText:`預設禁止申請人簽自己的案件;只有此流程允許自簽時才開啟。`,label:`允許自簽`,name:`allowInitiatorSelfApproval`,children:(0,c.jsx)(s.Toggle,{checked:!!f.allowInitiatorSelfApproval,onChange:e=>$(Nt(t,{allowInitiatorSelfApproval:e.target.checked,memberId:f.memberId,type:`DIRECT`}))})})]}):null]}):null,t.type===`ORG_UNIT_MEMBER`||t.type===`ORG_UNIT_POSITION`?(0,c.jsx)(i.t,{label:`包含下層`,name:`includeDescendants`,children:(0,c.jsx)(s.Toggle,{checked:!!t.includeDescendants,onChange:e=>$({...t,includeDescendants:e.target.checked,...t.type===`ORG_UNIT_POSITION`?{positionId:``}:{}})})}):null,t.type===`POSITION`?(0,c.jsx)(i.t,{hintText:`指派給目前有效歸屬中擁有此職位的會員;主要歸屬優先。`,label:`職位`,name:`positionId`,required:!0,children:(0,c.jsx)(r.r,{name:`positionId`,onChange:e=>$({positionId:e?.id??``,type:`POSITION`}),placeholder:`選擇職位`,positions:z,value:l})}):null,t.type===`ORG_UNIT_POSITION`?(0,c.jsx)(i.t,{hintText:`只納入指定組織範圍內擁有此職位的有效會員。`,label:`職位`,name:`orgUnitPositionId`,required:!0,children:(0,c.jsx)(r.r,{disabled:!t.orgUnitId.trim(),name:`orgUnitPositionId`,onChange:e=>$({includeDescendants:t.includeDescendants,orgUnitId:t.orgUnitId,positionId:e?.id??``,type:`ORG_UNIT_POSITION`}),placeholder:t.orgUnitId.trim()?`選擇職位`:`請先選擇組織`,positions:u,value:l})}):null,e.data.returnBehavior.allowReturn?(0,c.jsx)(i.t,{hintText:`退回發起人後,重新送出時要從流程開始重跑,或直接回到退回的簽核節點。`,label:`重送策略`,name:`returnResubmitStrategy`,required:!0,children:(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>fr(kt(e?.id??null)),options:[...et],value:B(et,m)})}):null]})}function wr(e){let t=Fn(e.data.action).map(e=>sn(I,e));return(0,c.jsx)(i.t,{label:`知會對象`,name:`notifyMemberIds`,required:!0,children:(0,c.jsx)(s.AutoComplete,{asyncData:!0,disabledOptionsFilter:!0,emptyText:`沒有符合的成員`,loading:gt,loadingText:`搜尋成員中...`,mode:`multiple`,onChange:e=>pr({channels:[`IN_APP`],recipients:{memberIds:e.map(e=>e.id),type:`DIRECT`},type:`NOTIFY`}),onSearch:Q,onVisibilityChange:e=>{e&&Q(``)},options:[...I],overflowStrategy:`wrap`,placeholder:`搜尋姓名或信箱`,searchDebounceTime:300,value:[...t]})})}function Tr(e){return(0,c.jsxs)(`div`,{style:T,children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`h3`,children:`已選取線段`}),(0,c.jsxs)(s.Typography,{color:`text-neutral`,variant:`body`,children:[`已選取 `,e.length,` 條線段,可使用 Delete 或控制面板刪除。`]})]})}function Er(e){let t=J(e,C.nodes);return(0,c.jsxs)(`div`,{style:T,children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`h3`,children:t?`條件設定`:`線段屬性`}),(0,c.jsxs)(s.Typography,{color:`text-neutral`,variant:`body`,children:[e.source,` → `,e.target]}),t?Or(e):(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:`這條線會直接把流程送到下一個節點。`})]})}function Dr(e){return!e||!J(e,C.nodes)?null:(0,c.jsx)(s.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!e.data.isDefault&&!e.data.condition},confirmText:`完成`,modalType:`standard`,onCancel:lr,onClose:lr,onConfirm:lr,open:!!Be,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`條件分流的輸出連線需要指定條件,條件會直接顯示在線上。`,title:`條件設定`,children:Or(e)})}function Or(e){let t=Nn(e,C.nodes),n=En(Z?.schema??null),r=Dn(Z?.schema??null,e.data.conditionFieldKey??null),a=On(r),o=jn(r),l=B(a,e.data.conditionOperator??null);return(0,c.jsxs)(`div`,{style:T,children:[(0,c.jsxs)(s.Typography,{color:`text-neutral`,variant:`body`,children:[`畫布上的這條線目前會顯示「`,(0,c.jsx)(`span`,{style:{color:!e.data.isDefault&&!e.data.condition?ke:void 0},children:t??`請設定條件`}),`」。`]}),(0,c.jsx)(s.Toggle,{checked:!!e.data.isDefault,label:`其他情況走這條`,onChange:t=>gr(e.id,t.target.checked)}),e.data.isDefault?(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:`其他條件都不符合時,流程會走這條線。`}):(0,c.jsxs)(c.Fragment,{children:[Z?null:(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:`請先綁定表單版本,才能選擇條件欄位。`}),(0,c.jsx)(i.t,{label:`條件欄位`,name:`edgeConditionField`,required:!0,children:(0,c.jsx)(s.Select,{clearable:!1,onChange:t=>_r({edgeId:e.id,fieldKey:t?.id??null,operator:null,value:null}),options:[...n],placeholder:`選擇條件欄位`,value:B(n,e.data.conditionFieldKey??null)})}),(0,c.jsx)(i.t,{label:`條件判斷`,name:`edgeConditionOperator`,required:!0,children:(0,c.jsx)(s.Select,{clearable:!1,onChange:t=>_r({edgeId:e.id,operator:kn(t?.id??null),value:null}),options:[...a],placeholder:`選擇判斷方式`,value:l})}),l&&Mn(l.id)?(0,c.jsx)(i.t,{label:`條件值`,name:`edgeConditionValue`,required:!0,children:o.length>0?(0,c.jsx)(s.Select,{clearable:!1,onChange:t=>_r({edgeId:e.id,value:t?.id??null}),options:[...o],placeholder:`選擇條件值`,value:B(o,e.data.conditionValue??null)}):(0,c.jsx)(s.Input,{onChange:t=>_r({edgeId:e.id,value:t.target.value}),placeholder:`輸入要比對的值`,value:e.data.conditionValue??``,variant:`base`})}):null]})]})}}function ht({onApplyAutoLayout:e}){function t(){e()}return(0,c.jsx)(g.Panel,{position:`top-right`,children:(0,c.jsx)(s.Button,{icon:d.DotGridIcon,iconType:`leading`,onClick:t,size:`sub`,variant:`base-secondary`,children:`自動排版`})})}function P({data:e,selected:t,type:n}){let r=e.approverLines??[e.approverSummary??e.label],i=F(e);return(0,c.jsxs)(`div`,{style:gt(n,t),children:[I(e),(0,c.jsx)(`div`,{style:Je,children:r.map((e,t)=>(0,c.jsx)(s.Typography,{component:`span`,ellipsis:!0,style:A,title:e,variant:`label-primary`,children:e},`${e}_${t}`))}),(0,c.jsx)(s.Typography,{color:`text-neutral`,component:`span`,ellipsis:!0,style:A,title:i,variant:`caption`,children:i})]})}function F(e){return e.nodeKind===`startEvent`?e.initiatorPolicySummary??`所有人`:e.approverSummary||e.approverLines?e.label:e.nodeKind===`exclusiveGateway`?`條件在線上`:e.nodeKind===`parallelGateway`?`多條路徑同時進行`:Xe[e.nodeKind]}function gt(e,t){let n=_t(e);return t?{...n,border:`1px solid var(--mzn-color-primary, #0057ff)`,boxShadow:ze}:n}function _t(e){return e===`exclusiveGateway`?We:e===`parallelGateway`?Ge:e===`startEvent`?k:e===`endEvent`?qe:e===`userTask`?Ke:E}function I(e){return!e.hasInput&&e.hasOutput?(0,c.jsx)(g.Handle,{id:Ye,position:g.Position.Right,type:`source`}):e.hasInput&&!e.hasOutput?(0,c.jsx)(g.Handle,{id:j,position:g.Position.Left,type:`target`}):!e.hasInput&&!e.hasOutput?null:[(0,c.jsx)(g.Handle,{id:j,position:g.Position.Left,type:`target`},`target`),(0,c.jsx)(g.Handle,{id:Ye,position:g.Position.Right,type:`source`},`source`)]}function vt(e,t,n,r,i,a){let o=L(e);return{data:{approverLines:yn(e,t),approverSummary:K(e,t,n,r),hasInput:qt(e),hasOutput:Jt(e),initiatorPolicySummary:e.type===`startEvent`?Ht(a,n,r):null,label:e.data.label,nodeKind:e.type},height:o.height,handles:R(e),id:e.id,initialHeight:o.height,initialWidth:o.width,position:e.position,selected:i,sourcePosition:g.Position.Right,targetPosition:g.Position.Left,type:e.type,width:o.width}}function L(e){return e.type===`exclusiveGateway`||e.type===`parallelGateway`?{height:He,width:Ue}:e.type===`serviceTask`?{height:D+(Math.max(1,Fn(e.data.action).length)-1)*Ve,width:Be}:{height:D,width:Be}}function R(e){let t=L(e);return[...qt(e)?[yt(t)]:[],...Jt(e)?[z(t)]:[]]}function yt({height:e}){let t=e/2-9/2;return{height:9,id:j,position:g.Position.Left,type:`target`,width:9,x:-9/2,y:t}}function z({height:e,width:t}){let n=e/2-9/2;return{height:9,id:Ye,position:g.Position.Right,type:`source`,width:9,x:t-9/2,y:n}}function bt(e,t,n){let r=Nn(e,t),i=J(e,t),a=i&&!e.data.isDefault&&!e.data.condition,o=a?ke:i?S:`#475569`,s=a?`#fef2f2`:i?`#eff6ff`:`#ffffff`,c=a?ke:i?S:C;return{className:n?`workflow-edge--selected`:void 0,data:e.data,id:e.id,label:r,labelBgBorderRadius:6,labelBgPadding:[8,4],labelBgStyle:{fill:s,stroke:c,strokeWidth:1},labelShowBg:!!r,labelStyle:{fill:o,fontSize:12,fontWeight:600},selected:n,source:e.source,sourceHandle:e.sourceHandle,style:{filter:n?w:void 0,opacity:1,stroke:C,strokeOpacity:1,strokeWidth:1.5},target:e.target,targetHandle:e.targetHandle,type:e.type??`smoothstep`}}function xt(e,t){return e.type===`startEvent`?e:(e.type===`endEvent`||e.type===`userTask`||e.type===`serviceTask`||e.type,{...e,data:{...e.data,triggerMode:t}})}function St(e){return wt(Ct(e))}function Ct(e){let t=new Set(e.nodes.filter(e=>Yt(e)).map(e=>e.id)),n=e.edges.filter(e=>!t.has(e.source));return n.length===e.edges.length?e:{...e,edges:n}}function wt(e){let t=e.edges.reduce((e,t)=>({...e,[t.target]:(e[t.target]??0)+1}),{}),n=e.nodes.map(e=>e.type===`startEvent`?e:(t[e.id]??0)<2&&e.data.triggerMode!==`AND`?xt(e,`AND`):e);return n.some((t,n)=>t!==e.nodes[n])?{...e,nodes:n}:e}function Tt(){return{edges:[],meta:{schemaVersion:1},nodes:[{data:{label:`開始`},id:`start`,position:{x:80,y:160},type:`startEvent`},{data:{endState:`APPROVED`,label:`完成`,triggerMode:`AND`},id:`end`,position:{x:560,y:160},type:`endEvent`}]}}function Et(e){return e.edges.length===0&&e.nodes.length===2&&e.nodes.some(e=>e.type===`startEvent`)&&e.nodes.some(e=>e.type===`endEvent`)}function Dt(e){let t=new _.graphlib.Graph;return t.setDefaultEdgeLabel(()=>({})),t.setGraph({rankdir:`LR`,ranksep:120}),e.nodes.forEach(e=>{t.setNode(e.id,L(e))}),e.edges.forEach(e=>{t.setEdge(e.source,e.target)}),_.layout(t),{...e,nodes:e.nodes.map(e=>{let n=t.node(e.id);return n?{...e,position:{x:n.x-L(e).width/2,y:n.y-L(e).height/2}}:e})}}function B(e,t){return t?e.find(e=>e.id===t)??null:null}function Ot(e){return e===`OR`?`OR`:`AND`}function kt(e){return e===`FROM_RETURN_POINT`?`FROM_RETURN_POINT`:`RESTART`}function At(e){return e===`ORG_MANAGER`||e===`ORG_UNIT_MANAGER`||e===`ORG_UNIT_MEMBER`||e===`ORG_UNIT_POSITION`||e===`POSITION`?e:`DIRECT`}function jt(e){let t=At(e??`DIRECT`);return t===`ORG_MANAGER`?{baseFromInitiator:!0,levelsUp:1,type:`ORG_MANAGER`}:t===`ORG_UNIT_MANAGER`?{orgUnitId:``,type:`ORG_UNIT_MANAGER`}:t===`ORG_UNIT_MEMBER`?{includeDescendants:!1,orgUnitId:``,type:`ORG_UNIT_MEMBER`}:t===`ORG_UNIT_POSITION`?{includeDescendants:!1,orgUnitId:``,positionId:``,type:`ORG_UNIT_POSITION`}:t===`POSITION`?{positionId:``,type:`POSITION`}:{memberIds:[],type:`DIRECT`}}function Mt(e){return e===`DIRECT`?`DIRECT`:`NONE`}function Nt(e,t){return e.type===`ORG_MANAGER`||e.type===`ORG_UNIT_MANAGER`?{...e,fallback:t}:e}function Pt(e){return M.find(t=>t.value===e)??M[0]}function Ft(e){return M.find(t=>t.id===e)??M[0]}function It(e){return e===`ORG_UNIT`||e===`ORG_UNIT_POSITION`||e===`NONE`?e:`ALL`}function Lt(e){let t=e?.trim();if(!t)return{mode:`ALL`,value:``};let n=Bt(t,/"([^"]+)" in subject\.orgUnitIds/gu),r=Bt(t,/"([^"]+)" in subject\.positionIds/gu);return n.length>0&&r.length>0?{includeDescendants:n.length>1,mode:`ORG_UNIT_POSITION`,orgUnitId:n[0],positionId:r[0],value:n[0]??``}:n.length>0?{includeDescendants:n.length>1,mode:`ORG_UNIT`,orgUnitId:n[0],value:n[0]??``}:{mode:`CUSTOM`,value:t}}function Rt(e,t){let n=Lt(e);return!t||t===`ALL`||t===`NONE`?t===`ALL`||t===`NONE`?{mode:t,value:``}:n:n.mode===t?n:Ut(t)}function zt(e){return e.mode===`NONE`?`發起權限需要選擇誰可以發起。`:(e.mode===`ORG_UNIT`||e.mode===`ORG_UNIT_POSITION`)&&!e.orgUnitId?.trim()?`指定組織發起時,需要選擇組織。`:e.mode===`ORG_UNIT_POSITION`&&!e.positionId?.trim()?`指定組織職位發起時,需要選擇職位。`:null}function Bt(e,t){return[...e.matchAll(t)].map(e=>e[1]).filter(e=>!!e)}function Vt(e,t){if(e.mode===`ALL`||e.mode===`NONE`)return null;let n=e.orgUnitId?.trim()??``;if(!n)return null;let r=G(t,n,!!e.includeDescendants).map(e=>`${JSON.stringify(e)} in subject.orgUnitIds`).join(` || `);if(e.mode===`ORG_UNIT`)return r?`(${r})`:null;let i=e.positionId?.trim()??``;return i&&r?`(${r}) && ${JSON.stringify(i)} in subject.positionIds`:null}function Ht(e,t,n){return e.mode===`NONE`?`未設定`:e.mode===`ORG_UNIT`?e.orgUnitId?`組織:${H(t,e.orgUnitId)}`:`指定組織`:e.mode===`ORG_UNIT_POSITION`?e.orgUnitId&&e.positionId?`組織職位:${H(t,e.orgUnitId)} / ${U(n,e.positionId)}`:`指定組織職位`:e.mode===`CUSTOM`?`既有自訂規則`:`所有人`}function Ut(e){return{includeDescendants:!0,mode:e,orgUnitId:``,positionId:``,value:``}}function Wt(e,t){let n=e.source?t.find(t=>t.id===e.source)??null:null,r=e.target?t.find(t=>t.id===e.target)??null:null;return!!n&&!!r&&e.source!==e.target&&e.sourceHandle===Ye&&e.targetHandle===j&&!!(n&&Jt(n))&&!!(r&&qt(r))}function Gt(e,t){return e.includes(t)?e.filter(e=>e!==t):[...e,t]}function Kt(e){return e.type!==`startEvent`&&e.type!==`endEvent`}function qt(e){return e.type!==`startEvent`}function Jt(e){return e.type!==`endEvent`&&!Yt(e)}function Yt(e){return e.type===`serviceTask`&&e.data.action.type===`NOTIFY`}function Xt(e){return e instanceof HTMLElement?e.isContentEditable||e.tagName===`INPUT`||e.tagName===`TEXTAREA`||e.tagName===`SELECT`||!!e.closest(`[contenteditable="true"]`):!1}function Zt(e){return e.map(e=>({formDefinitionId:e.formDefinitionId,formName:e.formName,id:e.id,name:`${e.formName} | v${e.version}`,schema:e.schema}))}function Qt(e){return(e?.schema.fields??[]).reduce((e,t)=>({...e,[t.fieldKey]:V(t)}),{})}function V(e){return e.type===`number`?1e3:e.type===`boolean`?!0:e.type===`select`?e.options[0]?.value??``:e.type===`checkbox`?e.options[0]?[e.options[0].value]:[]:e.type===`date`?`2026-05-08`:e.type===`datetime`?`2026-05-08T09:00:00+08:00`:e.placeholder??e.label}function $t(e){let t=JSON.parse(e);if(!en(t))throw Error(`表單資料 JSON 必須是物件。`);return t}function en(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function tn(e){return e===`COMPLETED`?`完成`:e===`PASSED`?`通過`:e===`SKIPPED`?`略過`:e===`STOPPED`?`已停止`:e===`WAITING`?`將等待簽核`:e}function nn(e){return e in Xe?Xe[e]:e}function rn(e,t){return t&&!e.some(e=>e.id===t.id)?[t,...e]:e}function an(e){return e.map(e=>({displayName:e.name,email:e.email,id:e.memberId,memberId:e.memberId,name:xn(e.name,e.email)}))}function on(e){return{displayName:`未知會員`,email:``,id:e,memberId:e,name:`未知會員`}}function sn(e,t){return e.find(e=>e.memberId===t)??on(t)}function cn(e,t){let n=e[0];return n?sn(t,n):null}function ln(e,t){let n=e.find(e=>e.id===t);return n?r.a(n):null}function un(e,t){let n=e.find(e=>e.id===t);return n?r.o(n):null}function H(e,t){return ln(e,t)?.name??`未指定組織`}function U(e,t){return un(e,t)?.name??`未指定職位`}function dn(e,t){let n=fn(),r=t.filter(t=>t.memberId===e&&pn(t,n)),i=r.reduce((e,t)=>e&&mn(e,t)<=0?e:t,null);return{customFields:{},managerMemberId:`member-002`,memberId:e,orgCode:`HQ`,orgUnitIds:W(r.map(e=>e.orgUnitId)),positionId:i?.positionId??null,positionIds:W(r.map(e=>e.positionId)),primaryOrgUnitId:i?.orgUnitId??null,roles:[`manager`]}}function fn(){return new Date().toISOString().slice(0,10)}function pn(e,t){return e.effectiveFrom<=t&&(!e.effectiveTo||e.effectiveTo>=t)}function mn(e,t){return e.isPrimary===t.isPrimary?t.effectiveFrom.localeCompare(e.effectiveFrom):e.isPrimary?-1:1}function W(e){return e.reduce((e,t)=>t&&!e.includes(t)?[...e,t]:e,[])}function hn({includeDescendants:e,memberships:t,orgUnitId:n,orgUnits:r,positions:i}){let a=new Set(G(r,n,e)),o=new Set(t.filter(e=>a.has(e.orgUnitId)).map(e=>e.positionId).filter(e=>!!e));return i.filter(e=>o.has(e.id))}function G(e,t,n){let r=e.find(e=>e.id===t);return r?n?e.filter(e=>e.id===r.id||e.path.startsWith(`${r.path}.`)).map(e=>e.id):[r.id]:t.trim()?[t]:[]}function gn(e,t){let n=new Set(e.map(e=>e.memberId)),r=t.filter(e=>!n.has(e.memberId));return[...e,...r]}function _n(e){return[...new Set(e.nodes.flatMap(e=>e.type===`userTask`?e.data.approverResolver.type===`DIRECT`?e.data.approverResolver.memberIds:[]:e.type===`serviceTask`?Fn(e.data.action):[]))]}function K(e,t,n,r){return e.type===`userTask`?vn(e.data.approverResolver,t,n,r):null}function vn(e,t,n,r){return e.type===`DIRECT`?bn(e.memberIds,t,`未指定簽核者`):e.type===`ORG_MANAGER`?Pt(e.levelsUp).name:e.type===`ORG_UNIT_MANAGER`?`組織主管:${H(n,e.orgUnitId)}`:e.type===`ORG_UNIT_MEMBER`?`組織任一人:${H(n,e.orgUnitId)}`:e.type===`ORG_UNIT_POSITION`?`組織職位:${H(n,e.orgUnitId)} / ${U(r,e.positionId)}`:e.type===`POSITION`?`職位:${U(r,e.positionId)}`:e.type===`DYNAMIC_FORM`?`表單欄位:${e.formPath||`未設定`}`:`自訂表達式`}function yn(e,t){if(e.type!==`serviceTask`)return null;let n=Fn(e.data.action);return n.length===0?[`未指定知會對象`]:n.map(e=>sn(t,e).name)}function bn(e,t,n){let r=e.map(e=>sn(t,e).name);return r.length===0?n:r.length<=2?r.join(`、`):`${r.slice(0,2).join(`、`)} 等 ${r.length} 人`}function xn(e,t){return`${e} (${t})`}function Sn(e,t){let n=t?.getBoundingClientRect();if(!n||e.nodes.length===0)return null;let r=e.nodes.reduce((e,t)=>{let n=L(t);return{maxX:Math.max(e.maxX,t.position.x+n.width),maxY:Math.max(e.maxY,t.position.y+n.height),minX:Math.min(e.minX,t.position.x),minY:Math.min(e.minY,t.position.y)}},{maxX:-1/0,maxY:-1/0,minX:1/0,minY:1/0});return(0,g.getViewportForBounds)({height:r.maxY-r.minY,width:r.maxX-r.minX,x:r.minX,y:r.minY},n.width,n.height,.1,1,.2)}function Cn(e){let t=e.nodes.find(e=>e.type===`userTask`&&!!wn(e.data.approverResolver)),n=e.nodes.find(e=>e.type===`serviceTask`&&e.data.action.type===`NOTIFY`&&Fn(e.data.action).length===0),r=e.edges.find(t=>J(t,e.nodes)&&!t.data.isDefault&&!t.data.condition);return t&&t.type===`userTask`?wn(t.data.approverResolver):n?`知會節點需要至少一位知會對象。`:r?`條件分流的每條輸出連線都需要先設定條件。`:null}function wn(e){return e.type===`DIRECT`&&e.memberIds.length===0?`簽核節點需要指定簽核會員。`:e.type===`ORG_MANAGER`&&e.levelsUp<1?`簽核節點需要指定有效的主管層級。`:e.type===`ORG_UNIT_MANAGER`&&!e.orgUnitId.trim()||e.type===`ORG_UNIT_MEMBER`&&!e.orgUnitId.trim()?`簽核節點需要指定組織。`:e.type===`ORG_UNIT_POSITION`&&(!e.orgUnitId.trim()||!e.positionId.trim())?`簽核節點需要指定組織與職位。`:(e.type===`ORG_MANAGER`||e.type===`ORG_UNIT_MANAGER`)&&e.fallback?.type===`DIRECT`&&!e.fallback.memberId.trim()?`簽核節點需要指定改派固定人。`:e.type===`POSITION`&&!e.positionId.trim()?`簽核節點需要指定職位。`:null}function Tn(e){return e.edges.some(t=>J(t,e.nodes)&&!!(t.data.condition||t.data.conditionFieldKey||t.data.conditionOperator||t.data.conditionValue))}function En(e){return e?.fields.map(e=>({fieldType:e.type,id:e.fieldKey,name:`${e.label} (${e.fieldKey})`}))??[]}function Dn(e,t){return t?e?.fields.find(e=>e.fieldKey===t)??null:null}function On(e){if(!e)return[];let t=An(e);return rt.filter(e=>t.includes(e.id))}function kn(e){return rt.some(t=>t.id===e)?e:null}function An(e){return e.type===`file_upload`?[`IS_FILLED`,`IS_EMPTY`]:e.type===`boolean`?[`EQUALS`,`NOT_EQUALS`,`IS_FILLED`,`IS_EMPTY`]:e.type===`date`||e.type===`datetime`||e.type===`money`||e.type===`number`?[`EQUALS`,`NOT_EQUALS`,`GREATER_THAN`,`GREATER_THAN_OR_EQUALS`,`LESS_THAN`,`LESS_THAN_OR_EQUALS`,`IS_FILLED`,`IS_EMPTY`]:[`EQUALS`,`NOT_EQUALS`,`IS_FILLED`,`IS_EMPTY`]}function jn(e){return e?e.type===`boolean`?[{id:`true`,name:`是`},{id:`false`,name:`否`}]:e.type===`checkbox`||e.type===`radio`||e.type===`select`?e.options.map(e=>({id:e.value,name:e.label})):[]:[]}function Mn(e){return it.includes(e)}function Nn(e,t){if(e.data.label)return e.data.label;if(J(e,t))return q(e);if(Pn(e,t))return`同時進行`}function q(e){return e.data.isDefault?`其他情況`:`請設定條件`}function J(e,t){return t.some(t=>t.id===e.source&&t.type===`exclusiveGateway`)}function Pn(e,t){return t.some(t=>t.id===e.source&&t.type===`parallelGateway`)}function Fn(e){return e.type===`NOTIFY`&&e.recipients.type===`DIRECT`?e.recipients.memberIds:[]}function Y(e){return e instanceof Error?e.message:`發生未知錯誤`}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return mt}});
|
|
65
|
-
//# sourceMappingURL=designer-DCn6_v4b.cjs.map
|