@rytass/bpm-core-react 0.3.8 → 0.4.1
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 +154 -0
- package/README.md +69 -4
- package/dist/chunks/approval-instance-list-page-BF2r5D2-.js +278 -0
- package/dist/chunks/approval-instance-list-page-BF2r5D2-.js.map +1 -0
- package/dist/chunks/approval-instance-list-page-C5ZKPHdA.cjs +2 -0
- package/dist/chunks/approval-instance-list-page-C5ZKPHdA.cjs.map +1 -0
- package/dist/chunks/auth-provider-4BeCw7cI.cjs +2 -0
- package/dist/chunks/auth-provider-4BeCw7cI.cjs.map +1 -0
- package/dist/chunks/auth-provider-B5oPmvk2.js +83 -0
- package/dist/chunks/auth-provider-B5oPmvk2.js.map +1 -0
- package/dist/chunks/{builder-D950gct_.js → builder-BLVnnpnP.js} +474 -478
- package/dist/chunks/builder-BLVnnpnP.js.map +1 -0
- package/dist/chunks/builder-DVE9zIKH.cjs +3 -0
- package/dist/chunks/builder-DVE9zIKH.cjs.map +1 -0
- package/dist/chunks/categories-B6QZKZRt.cjs +2 -0
- package/dist/chunks/categories-B6QZKZRt.cjs.map +1 -0
- package/dist/chunks/categories-DBPoSrsi.js +382 -0
- package/dist/chunks/categories-DBPoSrsi.js.map +1 -0
- package/dist/chunks/chunk-CMqjfN_6.cjs +1 -0
- package/dist/chunks/dashboard-page-CddG1MnK.cjs +2 -0
- package/dist/chunks/dashboard-page-CddG1MnK.cjs.map +1 -0
- package/dist/chunks/dashboard-page-Ib8srCMy.js +119 -0
- package/dist/chunks/dashboard-page-Ib8srCMy.js.map +1 -0
- package/dist/chunks/delegations-C2wLWsDQ.cjs +2 -0
- package/dist/chunks/delegations-C2wLWsDQ.cjs.map +1 -0
- package/dist/chunks/delegations-DDEk-WI6.cjs +2 -0
- package/dist/chunks/delegations-DDEk-WI6.cjs.map +1 -0
- package/dist/chunks/delegations-ZNtodFaD.js +568 -0
- package/dist/chunks/delegations-ZNtodFaD.js.map +1 -0
- package/dist/chunks/delegations-iVnRi3QE.js +641 -0
- package/dist/chunks/delegations-iVnRi3QE.js.map +1 -0
- package/dist/chunks/detail-Dcr5mM8g.cjs +2 -0
- package/dist/chunks/detail-Dcr5mM8g.cjs.map +1 -0
- package/dist/chunks/detail-u9DdLhDW.js +1518 -0
- package/dist/chunks/detail-u9DdLhDW.js.map +1 -0
- package/dist/chunks/format-date-time-XxBzF0F5.cjs +2 -0
- package/dist/chunks/{format-date-time-26_pFvv4.cjs.map → format-date-time-XxBzF0F5.cjs.map} +1 -1
- package/dist/chunks/login-9bCXyjbX.cjs +2 -0
- package/dist/chunks/{login-CQ9MfwcC.cjs.map → login-9bCXyjbX.cjs.map} +1 -1
- package/dist/chunks/{login-C20yVxbc.js → login-BKxpLibd.js} +3 -2
- package/dist/chunks/{login-C20yVxbc.js.map → login-BKxpLibd.js.map} +1 -1
- package/dist/chunks/notifications-BKs4--96.cjs +2 -0
- package/dist/chunks/notifications-BKs4--96.cjs.map +1 -0
- package/dist/chunks/notifications-CSulztkU.js +193 -0
- package/dist/chunks/notifications-CSulztkU.js.map +1 -0
- package/dist/chunks/orgs-BIiqzHvb.cjs +2 -0
- package/dist/chunks/orgs-BIiqzHvb.cjs.map +1 -0
- package/dist/chunks/orgs-Cc18umVt.js +1944 -0
- package/dist/chunks/orgs-Cc18umVt.js.map +1 -0
- package/dist/chunks/router-adapter--gYs13E8.cjs +2 -0
- package/dist/chunks/router-adapter--gYs13E8.cjs.map +1 -0
- package/dist/chunks/router-adapter-DftlFTOd.js +23 -0
- package/dist/chunks/router-adapter-DftlFTOd.js.map +1 -0
- package/dist/chunks/templates-D44FSB46.js +380 -0
- package/dist/chunks/templates-D44FSB46.js.map +1 -0
- package/dist/chunks/templates-w96t83N-.cjs +2 -0
- package/dist/chunks/templates-w96t83N-.cjs.map +1 -0
- package/dist/chunks/users-CUY139DF.js +214 -0
- package/dist/chunks/users-CUY139DF.js.map +1 -0
- package/dist/chunks/users-qghSMtLn.cjs +2 -0
- package/dist/chunks/users-qghSMtLn.cjs.map +1 -0
- package/dist/components/approval-instance-list-page.d.ts +1 -2
- package/dist/components/bpm-notification-bell-button.d.ts +22 -0
- package/dist/components/dashboard-page.d.ts +1 -4
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +206 -97
- package/dist/index.js.map +1 -1
- package/dist/lib/notification-drawer-provider.d.ts +3 -2
- package/dist/lib/notification-unread-provider.d.ts +6 -5
- package/dist/lib/providers.d.ts +3 -2
- package/dist/lib/use-bpm-logout.d.ts +12 -0
- package/dist/lib/use-bpm-member.d.ts +11 -0
- package/dist/next/BPMNextProviders.d.ts +1 -1
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +13 -23
- package/dist/next/index.js.map +1 -1
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.js +1 -1
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.js +1 -1
- package/dist/pages/admin/users/index.cjs +1 -1
- package/dist/pages/admin/users/index.js +1 -1
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.js +1 -1
- package/dist/pages/forms/builder/index.cjs +1 -1
- package/dist/pages/forms/builder/index.js +1 -1
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/login/index.cjs +1 -1
- package/dist/pages/login/index.js +1 -1
- package/dist/pages/settings/notifications/index.cjs +1 -1
- package/dist/pages/settings/notifications/index.js +1 -1
- package/dist/pages/templates/categories/index.cjs +1 -1
- package/dist/pages/templates/categories/index.js +1 -1
- package/dist/pages/templates/index.cjs +1 -1
- package/dist/pages/templates/index.js +1 -1
- package/dist/views/admin/delegations/AdminDelegationsView.d.ts +1 -4
- package/dist/views/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +3 -3
- package/dist/views/admin/orgs/AdminOrgsView.d.ts +1 -4
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -1
- package/dist/views/admin/users/AdminUsersView.d.ts +1 -4
- package/dist/views/admin/users/index.cjs +1 -1
- package/dist/views/admin/users/index.js +1 -1
- package/dist/views/cc/CcView.d.ts +1 -3
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.cjs.map +1 -1
- package/dist/views/cc/index.js +2 -3
- package/dist/views/cc/index.js.map +1 -1
- package/dist/views/dashboard/DashboardView.d.ts +1 -3
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.cjs.map +1 -1
- package/dist/views/dashboard/index.js +3 -3
- package/dist/views/dashboard/index.js.map +1 -1
- package/dist/views/delegations/DelegationsView.d.ts +1 -4
- package/dist/views/delegations/index.cjs +1 -1
- package/dist/views/delegations/index.js +1 -1
- package/dist/views/forms/FormsView.d.ts +1 -3
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/index.cjs +1 -1
- package/dist/views/forms/index.cjs.map +1 -1
- package/dist/views/forms/index.js +95 -99
- package/dist/views/forms/index.js.map +1 -1
- package/dist/views/inbox/InboxView.d.ts +1 -3
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.cjs.map +1 -1
- package/dist/views/inbox/index.js +91 -94
- package/dist/views/inbox/index.js.map +1 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.cjs.map +1 -1
- package/dist/views/instances/new/index.js +71 -77
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/login/index.cjs +1 -1
- package/dist/views/login/index.js +1 -1
- package/dist/views/root/RootView.d.ts +1 -3
- package/dist/views/search/SearchView.d.ts +1 -3
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.cjs.map +1 -1
- package/dist/views/search/index.js +2 -3
- package/dist/views/search/index.js.map +1 -1
- package/dist/views/sent/SentView.d.ts +1 -3
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.cjs.map +1 -1
- package/dist/views/sent/index.js +2 -3
- package/dist/views/sent/index.js.map +1 -1
- package/dist/views/settings/index.cjs +1 -1
- package/dist/views/settings/index.js +1 -1
- package/dist/views/settings/notifications/SettingsNotificationsView.d.ts +1 -4
- package/dist/views/settings/notifications/index.cjs +1 -1
- package/dist/views/settings/notifications/index.js +1 -1
- package/dist/views/templates/TemplatesView.d.ts +1 -4
- package/dist/views/templates/categories/TemplateCategoriesView.d.ts +1 -4
- package/dist/views/templates/categories/index.cjs +1 -1
- package/dist/views/templates/categories/index.js +1 -1
- package/dist/views/templates/designer/TemplateDesignerView.d.ts +1 -2
- package/dist/views/templates/designer/index.cjs +7 -7
- package/dist/views/templates/designer/index.cjs.map +1 -1
- package/dist/views/templates/designer/index.js +707 -711
- package/dist/views/templates/designer/index.js.map +1 -1
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.js +2 -2
- package/dist/views/templates/versions/TemplateVersionsView.d.ts +1 -2
- package/dist/views/templates/versions/index.cjs +1 -1
- package/dist/views/templates/versions/index.cjs.map +1 -1
- package/dist/views/templates/versions/index.js +45 -49
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/app-navigation.css +0 -1
- package/dist/chunks/app-navigation-BSkMsEhy.js +0 -268
- package/dist/chunks/app-navigation-BSkMsEhy.js.map +0 -1
- package/dist/chunks/app-navigation-KnlJCUp1.cjs +0 -2
- package/dist/chunks/app-navigation-KnlJCUp1.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs +0 -2
- package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-CqNdoZqx.js +0 -282
- package/dist/chunks/approval-instance-list-page-CqNdoZqx.js.map +0 -1
- package/dist/chunks/auth-provider-BV8Iiwfb.cjs +0 -2
- package/dist/chunks/auth-provider-BV8Iiwfb.cjs.map +0 -1
- package/dist/chunks/auth-provider-Bnox5gsx.js +0 -98
- package/dist/chunks/auth-provider-Bnox5gsx.js.map +0 -1
- package/dist/chunks/builder-CMlJfQHE.cjs +0 -3
- package/dist/chunks/builder-CMlJfQHE.cjs.map +0 -1
- package/dist/chunks/builder-D950gct_.js.map +0 -1
- package/dist/chunks/categories-5yEM3p3N.cjs +0 -2
- package/dist/chunks/categories-5yEM3p3N.cjs.map +0 -1
- package/dist/chunks/categories-BIpOG451.js +0 -387
- package/dist/chunks/categories-BIpOG451.js.map +0 -1
- package/dist/chunks/dashboard-page-Bx1-Ys3e.js +0 -122
- package/dist/chunks/dashboard-page-Bx1-Ys3e.js.map +0 -1
- package/dist/chunks/dashboard-page-CQNRbMkJ.cjs +0 -2
- package/dist/chunks/dashboard-page-CQNRbMkJ.cjs.map +0 -1
- package/dist/chunks/delegations-B2j-wNEO.js +0 -646
- package/dist/chunks/delegations-B2j-wNEO.js.map +0 -1
- package/dist/chunks/delegations-CsB9ozLu.cjs +0 -2
- package/dist/chunks/delegations-CsB9ozLu.cjs.map +0 -1
- package/dist/chunks/delegations-CvtwTXNP.cjs +0 -2
- package/dist/chunks/delegations-CvtwTXNP.cjs.map +0 -1
- package/dist/chunks/delegations-dKodb0WW.js +0 -573
- package/dist/chunks/delegations-dKodb0WW.js.map +0 -1
- package/dist/chunks/detail-BcGAqJ_R.js +0 -1523
- package/dist/chunks/detail-BcGAqJ_R.js.map +0 -1
- package/dist/chunks/detail-CqjqLd65.cjs +0 -2
- package/dist/chunks/detail-CqjqLd65.cjs.map +0 -1
- package/dist/chunks/format-date-time-26_pFvv4.cjs +0 -2
- package/dist/chunks/login-CQ9MfwcC.cjs +0 -2
- package/dist/chunks/notifications-2swRqDPF.js +0 -198
- package/dist/chunks/notifications-2swRqDPF.js.map +0 -1
- package/dist/chunks/notifications-BaYDebFt.cjs +0 -2
- package/dist/chunks/notifications-BaYDebFt.cjs.map +0 -1
- package/dist/chunks/orgs-CuHxxd_n.js +0 -1949
- package/dist/chunks/orgs-CuHxxd_n.js.map +0 -1
- package/dist/chunks/orgs-YMiVLNvL.cjs +0 -2
- package/dist/chunks/orgs-YMiVLNvL.cjs.map +0 -1
- package/dist/chunks/templates-DTkbSgFY.cjs +0 -2
- package/dist/chunks/templates-DTkbSgFY.cjs.map +0 -1
- package/dist/chunks/templates-DoDWM68t.js +0 -384
- package/dist/chunks/templates-DoDWM68t.js.map +0 -1
- package/dist/chunks/users-3ySyUW4u.cjs +0 -2
- package/dist/chunks/users-3ySyUW4u.cjs.map +0 -1
- package/dist/chunks/users-sMfrSjRQ.js +0 -219
- package/dist/chunks/users-sMfrSjRQ.js.map +0 -1
- package/dist/components/app-navigation.d.ts +0 -41
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"orgs-YMiVLNvL.cjs","names":[],"sources":["../../src/lib/org-tree-draft.ts","../../src/components/org-unit-tree-draft-editor.module.scss","../../src/components/org-unit-tree-draft-editor.tsx","../../src/views/admin/orgs/orgs.module.scss","../../src/views/admin/orgs/AdminOrgsView.tsx"],"sourcesContent":["import type { OrgUnitRecord } from '@rytass/bpm-core-client/organization';\n\nexport type OrgUnitParentDraftMap = ReadonlyMap<string, string | null>;\n\nexport type OrgUnitHierarchyDraftChange = Readonly<{\n orgUnitId: string;\n parentId: string | null;\n previousParentId: string | null;\n}>;\n\nexport type OrgUnitParentAssignmentResult = Readonly<{\n message: string;\n parentDraft: OrgUnitParentDraftMap;\n status: 'INVALID' | 'UNCHANGED' | 'UPDATED';\n}>;\n\nexport function createOrgUnitParentDraftMap(\n orgUnits: readonly OrgUnitRecord[],\n): OrgUnitParentDraftMap {\n return new Map(\n orgUnits.map((orgUnit): readonly [string, string | null] => [\n orgUnit.id,\n orgUnit.parentId,\n ]),\n );\n}\n\nexport function assignOrgUnitDraftParent({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string | null;\n}): OrgUnitParentAssignmentResult {\n const normalizedParentId = parentId === orgUnitId ? orgUnitId : parentId;\n const validationMessage = readOrgUnitParentValidationMessage({\n orgUnitId,\n parentDraft,\n parentId: normalizedParentId,\n });\n\n if (validationMessage) {\n return {\n message: validationMessage,\n parentDraft,\n status: 'INVALID',\n };\n }\n\n if ((parentDraft.get(orgUnitId) ?? null) === normalizedParentId) {\n return {\n message: '父子關係沒有變更。',\n parentDraft,\n status: 'UNCHANGED',\n };\n }\n\n const nextDraft = new Map(parentDraft);\n nextDraft.set(orgUnitId, normalizedParentId);\n\n return {\n message: normalizedParentId ? '已暫存新的上層組織。' : '已暫存為根節點。',\n parentDraft: nextDraft,\n status: 'UPDATED',\n };\n}\n\nexport function readOrgUnitHierarchyDraftChanges({\n orgUnits,\n parentDraft,\n}: {\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly parentDraft: OrgUnitParentDraftMap;\n}): readonly OrgUnitHierarchyDraftChange[] {\n return orgUnits\n .map((orgUnit): OrgUnitHierarchyDraftChange | null => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n\n return parentId === orgUnit.parentId\n ? null\n : {\n orgUnitId: orgUnit.id,\n parentId,\n previousParentId: orgUnit.parentId,\n };\n })\n .filter((change): change is OrgUnitHierarchyDraftChange => Boolean(change));\n}\n\nexport function readOrgUnitParentValidationMessage({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string | null;\n}): string | null {\n if (!parentDraft.has(orgUnitId)) {\n return '找不到要搬移的組織節點。';\n }\n\n if (!parentId) {\n return null;\n }\n\n if (!parentDraft.has(parentId)) {\n return '找不到新的上層組織。';\n }\n\n if (parentId === orgUnitId) {\n return '組織不可成為自己的上層。';\n }\n\n return createsOrgUnitParentCycle({ orgUnitId, parentDraft, parentId })\n ? '不可搬移到自己的下層組織。'\n : null;\n}\n\nfunction createsOrgUnitParentCycle({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string;\n}): boolean {\n const visitedIds = new Set<string>();\n let currentParentId: string | null = parentId;\n\n while (currentParentId) {\n if (currentParentId === orgUnitId || visitedIds.has(currentParentId)) {\n return true;\n }\n\n visitedIds.add(currentParentId);\n currentParentId = parentDraft.get(currentParentId) ?? null;\n }\n\n return false;\n}\n",".orgTreeEditor {\n display: grid;\n gap: 12px;\n min-width: 0;\n}\n\n.orgTreeSummary {\n display: grid;\n gap: 6px;\n min-width: 0;\n padding: 10px 12px;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: var(--mzn-color-bg, #fff);\n}\n\n.orgTreeChangeList {\n display: grid;\n gap: 4px;\n max-height: 128px;\n margin: 0;\n padding-left: 18px;\n overflow: auto;\n color: var(--mzn-color-text-neutral, #5f6673);\n font-size: 13px;\n}\n\n.orgTreeCanvas {\n width: 100%;\n height: min(720px, calc(100vh - 300px));\n min-height: 520px;\n overflow: hidden;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: #f7f9fc;\n}\n\n.orgTreeNode {\n display: grid;\n gap: 6px;\n width: 232px;\n min-height: 118px;\n padding: 12px;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: #fff;\n box-shadow: 0 4px 12px rgb(20 28 44 / 8%);\n}\n\n.orgTreeNodeRoot {\n min-height: 86px;\n border-style: dashed;\n background: #eef4ff;\n}\n\n.orgTreeNodeSelected {\n border-color: var(--mzn-color-primary, #0057ff);\n box-shadow: 0 0 0 3px rgb(0 87 255 / 14%);\n}\n\n.orgTreeNodeChanged {\n border-color: var(--mzn-color-primary, #0057ff);\n}\n\n.orgTreeNodeDeleted {\n opacity: 0.58;\n}\n\n.orgTreeNodeHeader {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 8px;\n min-width: 0;\n}\n\n.orgTreeNodeHeader > :global(.mzn-typography) {\n min-width: 0;\n}\n\n.orgTreeNodeBadge {\n flex: 0 0 auto;\n padding: 2px 6px;\n border-radius: 999px;\n background: #e4f0ff;\n color: var(--mzn-color-primary, #0057ff);\n font-size: 12px;\n line-height: 18px;\n}\n\n.orgTreeNodeActions {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding-top: 2px;\n}\n","'use client';\n\nimport {\n ReactElement,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from 'react';\nimport {\n Background,\n Connection,\n ConnectionMode,\n Controls,\n Edge,\n Handle,\n MiniMap,\n Node,\n NodeProps,\n NodeTypes,\n OnNodeDrag,\n OnNodesChange,\n Position,\n ReactFlow,\n applyNodeChanges,\n} from '@xyflow/react';\nimport * as dagre from 'dagre';\nimport { Button, Typography } from '@mezzanine-ui/react';\nimport { EditIcon, PlusIcon } from '@mezzanine-ui/icons';\nimport type { OrgUnitRecord, OrgUnitType } from '@rytass/bpm-core-client/organization';\nimport {\n OrgUnitHierarchyDraftChange,\n OrgUnitParentDraftMap,\n assignOrgUnitDraftParent,\n createOrgUnitParentDraftMap,\n readOrgUnitHierarchyDraftChanges,\n readOrgUnitParentValidationMessage,\n} from '../lib/org-tree-draft';\nimport styles from './org-unit-tree-draft-editor.module.scss';\n\ntype OrgUnitTreeFlowData = Readonly<{\n changed: boolean;\n code: string;\n deleted: boolean;\n isEditing: boolean;\n isSyntheticRoot: boolean;\n name: string;\n onCreateChild: (parentId: string | null) => void;\n onEdit: (orgUnitId: string) => void;\n orgUnitId: string | null;\n parentLabel: string;\n path: string;\n typeLabel: string;\n}>;\n\ntype OrgUnitTreeNode = Node<OrgUnitTreeFlowData, 'orgUnit'>;\ntype OrgUnitTreeEdge = Edge<Record<string, never>>;\n\nexport type OrgUnitTreeDraftEditorHandle = Readonly<{\n cancelEditing: () => void;\n saveDraft: () => Promise<void>;\n startEditing: () => void;\n}>;\n\nexport type OrgUnitTreeDraftEditorState = Readonly<{\n hasDraftChanges: boolean;\n isEditing: boolean;\n}>;\n\ntype OrgUnitTreeDraftEditorProps = Readonly<{\n onCreateChild: (parentId: string) => void;\n onCreateRoot: () => void;\n onEditOrgUnit: (orgUnit: OrgUnitRecord) => void;\n onSaveDraft?: (\n changes: readonly OrgUnitHierarchyDraftChange[],\n ) => Promise<void>;\n onStateChange: (state: OrgUnitTreeDraftEditorState) => void;\n orgUnits: readonly OrgUnitRecord[];\n saving: boolean;\n}>;\n\nconst ORG_TREE_ROOT_ID = '__org-tree-root__';\nconst ORG_TREE_NODE_WIDTH = 232;\nconst ORG_TREE_NODE_HEIGHT = 118;\nconst ORG_TREE_ROOT_WIDTH = 232;\nconst ORG_TREE_ROOT_HEIGHT = 86;\nconst ORG_TREE_DROP_DISTANCE = 320;\n\nconst ORG_UNIT_TYPE_LABELS: Readonly<Record<Uppercase<OrgUnitType>, string>> = {\n COMPANY: '公司',\n DEPARTMENT: '部門',\n DIVISION: '事業群',\n TEAM: '小組',\n};\n\nconst orgUnitTreeNodeTypes: NodeTypes = {\n orgUnit: OrgUnitTreeNodeCard,\n};\n\nexport const OrgUnitTreeDraftEditor = forwardRef<\n OrgUnitTreeDraftEditorHandle,\n OrgUnitTreeDraftEditorProps\n>(function OrgUnitTreeDraftEditor(\n {\n onCreateChild,\n onCreateRoot,\n onEditOrgUnit,\n onSaveDraft,\n onStateChange,\n orgUnits,\n },\n ref,\n): ReactElement {\n const [isEditing, setIsEditing] = useState(false);\n const [draftMessage, setDraftMessage] = useState<string | null>(null);\n const [selectedOrgUnitId, setSelectedOrgUnitId] = useState<string | null>(\n null,\n );\n const [parentDraft, setParentDraft] = useState<OrgUnitParentDraftMap>(() =>\n createOrgUnitParentDraftMap(orgUnits),\n );\n const [flowNodes, setFlowNodes] = useState<readonly OrgUnitTreeNode[]>([]);\n\n const orgUnitsById = useMemo(\n (): ReadonlyMap<string, OrgUnitRecord> =>\n new Map(orgUnits.map((orgUnit) => [orgUnit.id, orgUnit])),\n [orgUnits],\n );\n const draftChanges = useMemo(\n (): readonly OrgUnitHierarchyDraftChange[] =>\n readOrgUnitHierarchyDraftChanges({ orgUnits, parentDraft }),\n [orgUnits, parentDraft],\n );\n const flowElements = useMemo(\n (): Readonly<{\n edges: readonly OrgUnitTreeEdge[];\n nodes: readonly OrgUnitTreeNode[];\n }> =>\n createOrgUnitTreeFlowElements({\n isEditing,\n onCreateChild: (parentId): void => {\n if (parentId) {\n onCreateChild(parentId);\n } else {\n onCreateRoot();\n }\n },\n onEditOrgUnit: (orgUnitId): void => {\n const orgUnit = orgUnitsById.get(orgUnitId);\n\n if (orgUnit) {\n onEditOrgUnit(orgUnit);\n }\n },\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n }),\n [\n isEditing,\n onCreateChild,\n onCreateRoot,\n onEditOrgUnit,\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n ],\n );\n const hasDraftChanges = draftChanges.length > 0;\n\n useImperativeHandle(\n ref,\n (): OrgUnitTreeDraftEditorHandle => ({\n cancelEditing,\n saveDraft,\n startEditing,\n }),\n );\n\n useEffect((): void => {\n onStateChange({ hasDraftChanges, isEditing });\n }, [hasDraftChanges, isEditing, onStateChange]);\n\n useEffect((): void => {\n setParentDraft(createOrgUnitParentDraftMap(orgUnits));\n setSelectedOrgUnitId(null);\n setDraftMessage(null);\n setIsEditing(false);\n }, [orgUnits]);\n\n useEffect((): void => {\n setFlowNodes(flowElements.nodes);\n }, [flowElements.nodes]);\n\n const assignDraftParent = useCallback(\n (orgUnitId: string, parentId: string | null): void => {\n setParentDraft((currentDraft) => {\n const result = assignOrgUnitDraftParent({\n orgUnitId,\n parentDraft: currentDraft,\n parentId,\n });\n\n setDraftMessage(result.message);\n\n return result.parentDraft;\n });\n },\n [],\n );\n\n const handleConnect = useCallback(\n (connection: Connection): void => {\n if (!isEditing || !connection.target || !connection.source) {\n return;\n }\n\n const nextParentId =\n connection.source === ORG_TREE_ROOT_ID ? null : connection.source;\n\n if (connection.target === ORG_TREE_ROOT_ID) {\n setDraftMessage('根節點不能搬移到其他節點下。');\n return;\n }\n\n assignDraftParent(connection.target, nextParentId);\n },\n [assignDraftParent, isEditing],\n );\n\n const handleNodeChanges = useCallback<OnNodesChange<OrgUnitTreeNode>>(\n (changes): void => {\n if (!isEditing) {\n return;\n }\n\n setFlowNodes((currentNodes) =>\n applyNodeChanges(changes, [...currentNodes]),\n );\n },\n [isEditing],\n );\n\n const handleNodeDragStop = useCallback<OnNodeDrag<OrgUnitTreeNode>>(\n (event, node, nodes): void => {\n if (!isEditing || node.id === ORG_TREE_ROOT_ID) {\n return;\n }\n\n const nearestParent =\n readNearestParentNodeIdFromPointer(event, node.id) ??\n readNearestParentNodeId(node, nodes);\n\n if (nearestParent === undefined) {\n setDraftMessage('拖曳到目標父節點附近,或從父節點拉線到子節點。');\n return;\n }\n\n assignDraftParent(\n node.id,\n nearestParent === ORG_TREE_ROOT_ID ? null : nearestParent,\n );\n },\n [assignDraftParent, isEditing],\n );\n\n function startEditing(): void {\n setIsEditing(true);\n setParentDraft(createOrgUnitParentDraftMap(orgUnits));\n setDraftMessage('已進入編輯模式,拖曳節點或拉線只會更新前端草稿。');\n }\n\n function cancelEditing(): void {\n setIsEditing(false);\n setParentDraft(createOrgUnitParentDraftMap(orgUnits));\n setDraftMessage('已取消草稿變更。');\n }\n\n async function saveDraft(): Promise<void> {\n if (!onSaveDraft) {\n setDraftMessage('批次儲存 API 尚未接上,草稿仍保留在前端。');\n return;\n }\n\n await onSaveDraft(draftChanges);\n setIsEditing(false);\n setDraftMessage('組織樹草稿已儲存。');\n }\n\n return (\n <div className={styles.orgTreeEditor}>\n <div className={styles.orgTreeSummary}>\n <Typography color=\"text-neutral\" variant=\"caption\">\n {draftMessage ??\n (hasDraftChanges\n ? `目前有 ${draftChanges.length} 筆父子關係草稿變更。`\n : '目前沒有草稿變更。')}\n </Typography>\n {hasDraftChanges ? (\n <ul className={styles.orgTreeChangeList}>\n {draftChanges.map((change) => (\n <li key={change.orgUnitId}>\n {readOrgUnitName(change.orgUnitId, orgUnitsById)}\n {':'}\n {readOrgUnitName(change.previousParentId, orgUnitsById)}\n {' -> '}\n {readOrgUnitName(change.parentId, orgUnitsById)}\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n <div className={styles.orgTreeCanvas}>\n <ReactFlow\n connectionMode={ConnectionMode.Strict}\n edges={[...flowElements.edges]}\n fitView\n fitViewOptions={{ padding: 0.18 }}\n isValidConnection={(connection): boolean =>\n isOrgTreeConnectionValid(\n { source: connection.source, target: connection.target },\n parentDraft,\n )\n }\n maxZoom={1.4}\n minZoom={0.25}\n nodeTypes={orgUnitTreeNodeTypes}\n nodes={[...flowNodes]}\n nodesConnectable={isEditing}\n nodesDraggable={isEditing}\n onConnect={handleConnect}\n onNodeClick={(_, node): void => {\n setSelectedOrgUnitId(node.id === ORG_TREE_ROOT_ID ? null : node.id);\n }}\n onNodeDoubleClick={(_, node): void => {\n if (node.id !== ORG_TREE_ROOT_ID) {\n const orgUnit = orgUnitsById.get(node.id);\n\n if (orgUnit) {\n onEditOrgUnit(orgUnit);\n }\n }\n }}\n onNodeDragStop={handleNodeDragStop}\n onNodesChange={handleNodeChanges}\n onPaneClick={(): void => setSelectedOrgUnitId(null)}\n panOnDrag\n proOptions={{ hideAttribution: true }}\n >\n <Background />\n <Controls />\n <MiniMap pannable zoomable />\n </ReactFlow>\n </div>\n </div>\n );\n});\n\nfunction OrgUnitTreeNodeCard({\n data,\n selected,\n}: NodeProps<OrgUnitTreeNode>): ReactElement {\n return (\n <div\n className={[\n styles.orgTreeNode,\n data.isSyntheticRoot ? styles.orgTreeNodeRoot : '',\n data.changed ? styles.orgTreeNodeChanged : '',\n data.deleted ? styles.orgTreeNodeDeleted : '',\n selected ? styles.orgTreeNodeSelected : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {data.isSyntheticRoot ? null : (\n <Handle\n id=\"target\"\n isConnectable={data.isEditing}\n position={Position.Top}\n type=\"target\"\n />\n )}\n <Handle\n id=\"source\"\n isConnectable={data.isEditing}\n position={Position.Bottom}\n type=\"source\"\n />\n <div className={styles.orgTreeNodeHeader}>\n <Typography\n component=\"span\"\n ellipsis\n title={data.name}\n variant=\"label-primary\"\n >\n {data.name}\n </Typography>\n {data.changed ? (\n <span className={styles.orgTreeNodeBadge}>草稿</span>\n ) : null}\n </div>\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n title={data.code}\n variant=\"caption\"\n >\n {data.isSyntheticRoot\n ? '根節點容器'\n : `${data.typeLabel} · ${data.code}`}\n </Typography>\n {data.isSyntheticRoot ? null : (\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n title={data.parentLabel}\n variant=\"caption\"\n >\n 上層:{data.parentLabel}\n </Typography>\n )}\n <div className={styles.orgTreeNodeActions}>\n {data.isSyntheticRoot ? (\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => data.onCreateChild(null)}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 新增根節點\n </Button>\n ) : (\n <>\n <Button\n icon={EditIcon}\n iconType=\"leading\"\n onClick={(): void => {\n if (data.orgUnitId) {\n data.onEdit(data.orgUnitId);\n }\n }}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 編輯\n </Button>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => data.onCreateChild(data.orgUnitId)}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 新增子節點\n </Button>\n </>\n )}\n </div>\n </div>\n );\n}\n\nfunction createOrgUnitTreeFlowElements({\n isEditing,\n onCreateChild,\n onEditOrgUnit,\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n}: {\n readonly isEditing: boolean;\n readonly onCreateChild: (parentId: string | null) => void;\n readonly onEditOrgUnit: (orgUnitId: string) => void;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly orgUnitsById: ReadonlyMap<string, OrgUnitRecord>;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly selectedOrgUnitId: string | null;\n}): Readonly<{\n edges: readonly OrgUnitTreeEdge[];\n nodes: readonly OrgUnitTreeNode[];\n}> {\n const graph = new dagre.graphlib.Graph();\n graph.setDefaultEdgeLabel(() => ({}));\n graph.setGraph({ marginx: 36, marginy: 36, nodesep: 44, rankdir: 'TB' });\n graph.setNode(ORG_TREE_ROOT_ID, {\n height: ORG_TREE_ROOT_HEIGHT,\n width: ORG_TREE_ROOT_WIDTH,\n });\n orgUnits.forEach((orgUnit): void => {\n graph.setNode(orgUnit.id, {\n height: ORG_TREE_NODE_HEIGHT,\n width: ORG_TREE_NODE_WIDTH,\n });\n });\n orgUnits.forEach((orgUnit): void => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n graph.setEdge(parentId ?? ORG_TREE_ROOT_ID, orgUnit.id);\n });\n dagre.layout(graph);\n\n const rootNode = createOrgUnitTreeNode({\n data: {\n changed: false,\n code: ORG_TREE_ROOT_ID,\n deleted: false,\n isEditing,\n isSyntheticRoot: true,\n name: '組織根節點',\n onCreateChild,\n onEdit: onEditOrgUnit,\n orgUnitId: null,\n parentLabel: '',\n path: '',\n typeLabel: '',\n },\n graph,\n height: ORG_TREE_ROOT_HEIGHT,\n id: ORG_TREE_ROOT_ID,\n selected: selectedOrgUnitId === null,\n width: ORG_TREE_ROOT_WIDTH,\n });\n const orgNodes = orgUnits.map((orgUnit): OrgUnitTreeNode => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n const parentLabel = readOrgUnitName(parentId, orgUnitsById);\n\n return createOrgUnitTreeNode({\n data: {\n changed: parentId !== orgUnit.parentId,\n code: orgUnit.code,\n deleted: Boolean(orgUnit.deletedAt),\n isEditing,\n isSyntheticRoot: false,\n name: orgUnit.name,\n onCreateChild,\n onEdit: onEditOrgUnit,\n orgUnitId: orgUnit.id,\n parentLabel,\n path: orgUnit.path,\n typeLabel: readOrgUnitTypeLabel(orgUnit.type),\n },\n graph,\n height: ORG_TREE_NODE_HEIGHT,\n id: orgUnit.id,\n selected: selectedOrgUnitId === orgUnit.id,\n width: ORG_TREE_NODE_WIDTH,\n });\n });\n const edges = orgUnits.map((orgUnit): OrgUnitTreeEdge => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n const changed = parentId !== orgUnit.parentId;\n\n return {\n animated: isEditing && changed,\n data: {},\n id: `org-tree-edge-${parentId ?? 'root'}-${orgUnit.id}`,\n source: parentId ?? ORG_TREE_ROOT_ID,\n sourceHandle: 'source',\n style: changed\n ? { stroke: 'var(--mzn-color-primary, #0057ff)', strokeWidth: 2 }\n : undefined,\n target: orgUnit.id,\n targetHandle: 'target',\n type: 'smoothstep',\n };\n });\n\n return {\n edges,\n nodes: [rootNode, ...orgNodes],\n };\n}\n\nfunction createOrgUnitTreeNode({\n data,\n graph,\n height,\n id,\n selected,\n width,\n}: {\n readonly data: OrgUnitTreeFlowData;\n readonly graph: dagre.graphlib.Graph;\n readonly height: number;\n readonly id: string;\n readonly selected: boolean;\n readonly width: number;\n}): OrgUnitTreeNode {\n const positionedNode = graph.node(id) as\n | Readonly<{ x: number; y: number }>\n | undefined;\n\n return {\n data,\n height,\n id,\n initialHeight: height,\n initialWidth: width,\n position: positionedNode\n ? {\n x: positionedNode.x - width / 2,\n y: positionedNode.y - height / 2,\n }\n : { x: 0, y: 0 },\n selected,\n sourcePosition: Position.Bottom,\n targetPosition: Position.Top,\n type: 'orgUnit',\n width,\n };\n}\n\nfunction readNearestParentNodeId(\n draggedNode: OrgUnitTreeNode,\n nodes: readonly OrgUnitTreeNode[],\n): string | undefined {\n const draggedCenter = readNodeCenter(draggedNode);\n const candidates = nodes\n .filter((node) => node.id !== draggedNode.id)\n .map(\n (node): Readonly<{ distance: number; id: string }> => ({\n distance: readDistance(draggedCenter, readNodeCenter(node)),\n id: node.id,\n }),\n )\n .filter((candidate) => candidate.distance <= ORG_TREE_DROP_DISTANCE)\n .sort((left, right) => left.distance - right.distance);\n\n return candidates[0]?.id;\n}\n\nfunction readNearestParentNodeIdFromPointer(\n event: unknown,\n draggedNodeId: string,\n): string | undefined {\n const point = readPointerPoint(event);\n\n if (!point) {\n return undefined;\n }\n\n const candidates = Array.from(\n document.querySelectorAll<HTMLElement>('.react-flow__node[data-id]'),\n )\n .map((element): Readonly<{ distance: number; id: string }> | null => {\n const id = element.dataset['id'];\n\n if (!id || id === draggedNodeId) {\n return null;\n }\n\n const rect = element.getBoundingClientRect();\n const center = {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n\n return {\n distance: readDistance(point, center),\n id,\n };\n })\n .filter(\n (\n candidate,\n ): candidate is Readonly<{ distance: number; id: string }> =>\n Boolean(candidate),\n )\n .filter((candidate) => candidate.distance <= ORG_TREE_DROP_DISTANCE)\n .sort((left, right) => left.distance - right.distance);\n\n return candidates[0]?.id;\n}\n\nfunction readPointerPoint(\n event: unknown,\n): Readonly<{ x: number; y: number }> | null {\n if (!isPointerEventLike(event)) {\n return null;\n }\n\n return { x: event.clientX, y: event.clientY };\n}\n\nfunction isPointerEventLike(\n event: unknown,\n): event is Readonly<{ clientX: number; clientY: number }> {\n return (\n typeof event === 'object' &&\n event !== null &&\n 'clientX' in event &&\n 'clientY' in event &&\n typeof event.clientX === 'number' &&\n typeof event.clientY === 'number'\n );\n}\n\nfunction readNodeCenter(\n node: OrgUnitTreeNode,\n): Readonly<{ x: number; y: number }> {\n return {\n x: node.position.x + (node.width ?? ORG_TREE_NODE_WIDTH) / 2,\n y: node.position.y + (node.height ?? ORG_TREE_NODE_HEIGHT) / 2,\n };\n}\n\nfunction readDistance(\n source: Readonly<{ x: number; y: number }>,\n target: Readonly<{ x: number; y: number }>,\n): number {\n return Math.hypot(source.x - target.x, source.y - target.y);\n}\n\nfunction isOrgTreeConnectionValid(\n connection: Readonly<{ source: string | null; target: string | null }>,\n parentDraft: OrgUnitParentDraftMap,\n): boolean {\n if (!connection.source || !connection.target) {\n return false;\n }\n\n if (connection.target === ORG_TREE_ROOT_ID) {\n return false;\n }\n\n return (\n readOrgUnitParentValidationMessage({\n orgUnitId: connection.target,\n parentDraft,\n parentId:\n connection.source === ORG_TREE_ROOT_ID ? null : connection.source,\n }) === null\n );\n}\n\nfunction readOrgUnitName(\n orgUnitId: string | null,\n orgUnitsById: ReadonlyMap<string, OrgUnitRecord>,\n): string {\n if (!orgUnitId) {\n return '根節點';\n }\n\n const orgUnit = orgUnitsById.get(orgUnitId);\n\n return orgUnit ? `${orgUnit.name} · ${orgUnit.code}` : '未知組織';\n}\n\nfunction readOrgUnitTypeLabel(type: OrgUnitType): string {\n const normalizedType = type.toUpperCase() as Uppercase<OrgUnitType>;\n\n return ORG_UNIT_TYPE_LABELS[normalizedType] ?? '未知類型';\n}\n",".tableIntroActions {\n display: inline-flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n flex: 0 0 auto;\n max-width: 100%;\n}\n\n.tableIntroActions > :global(.mzn-button) {\n flex: 0 0 auto;\n}\n\n.modalFields {\n display: grid;\n gap: 12px;\n width: 100%;\n\n :global(.mzn-form-field--horizontal) {\n align-items: flex-start;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label-area) {\n flex: 0 0 120px;\n width: 120px;\n min-width: 120px;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label) {\n flex-wrap: nowrap;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__data-entry) {\n flex: 1 1 auto;\n align-items: stretch;\n min-width: 0;\n max-width: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-auto-complete) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-picker),\n :global(.mzn-select),\n :global(.mzn-select-trigger),\n :global(.mzn-text-field) {\n width: 100%;\n min-width: 0 !important;\n }\n\n :global(.mzn-select-trigger__input) {\n width: 100%;\n min-width: 0 !important;\n text-overflow: ellipsis;\n }\n}\n\n.tableIntro {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n min-width: 0;\n max-width: 100%;\n margin-bottom: 12px;\n}\n\n.tableIntro > div {\n min-width: 0;\n}\n\n.tableIntro > div > * {\n overflow-wrap: anywhere;\n}\n\n.tableFrame {\n width: 100%;\n min-width: 0;\n max-width: 100%;\n overflow-x: auto;\n}\n\n.orgFilterArea {\n margin-bottom: 12px;\n\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n flex-wrap: nowrap;\n }\n\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-form-field__label-area) {\n display: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n}\n\n.membershipFilterArea {\n overflow-x: auto;\n\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n align-items: center;\n flex-wrap: nowrap !important;\n min-width: 760px;\n }\n\n :global(.mzn-filter),\n :global(.mzn-filter-area__filter) {\n flex: 1 1 0;\n min-width: 0;\n }\n\n :global(.mzn-filter:nth-child(3)),\n :global(.mzn-filter-area__filter:nth-child(3)) {\n flex: 0 0 180px;\n }\n\n :global(.mzn-autocomplete) {\n width: 100%;\n min-width: 0;\n }\n}\n\n.scopeLabel {\n display: inline-flex;\n align-items: center;\n min-height: 24px;\n}\n\n@media (max-width: 960px) {\n .tableIntro {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .tableIntroActions {\n justify-content: flex-start;\n }\n\n .tableIntroActions {\n flex-wrap: wrap;\n }\n\n .orgFilterArea {\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n flex-wrap: wrap;\n }\n }\n\n .membershipFilterArea {\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n align-items: stretch;\n flex-wrap: nowrap !important;\n }\n\n :global(.mzn-form-field--horizontal) {\n align-items: center;\n }\n }\n}\n","'use client';\n\nimport {\n ChangeEvent,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n AutoComplete,\n Button,\n DatePicker,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n CloseIcon,\n EditIcon,\n PlusIcon,\n SaveIcon,\n} from '@mezzanine-ui/icons';\nimport type { IconDefinition } from '@mezzanine-ui/icons';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport {\n MemberOption,\n OrgUnitPicker,\n OrgUnitOption,\n PositionOption,\n PositionPicker,\n MemberPicker,\n readMemberOption,\n readOrgUnitOption,\n readPositionOption,\n} from '../../../components/admin-pickers';\nimport {\n commitOrgUnitTreeDraft,\n createManagerResolution,\n createMembership,\n createOrgUnit,\n createPosition,\n deleteManagerResolution,\n deleteMembership,\n deleteOrgUnit,\n ManagerResolutionRecord,\n ManagerResolutionScopeType,\n MembershipRecord,\n OrgUnitRecord,\n OrgUnitType,\n PositionRecord,\n readOrganizationDashboard,\n updateManagerResolution,\n updateMembership,\n updateOrgUnit,\n updatePosition,\n} from '@rytass/bpm-core-client/organization';\nimport { MemberProfileRecord, resolveMembers } from '@rytass/bpm-core-client';\nimport {\n OrgUnitTreeDraftEditor,\n OrgUnitTreeDraftEditorHandle,\n OrgUnitTreeDraftEditorState,\n} from '../../../components/org-unit-tree-draft-editor';\nimport type { OrgUnitHierarchyDraftChange } from '../../../lib/org-tree-draft';\nimport styles from './orgs.module.scss';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { AppLayout } from '../../../components/app-navigation';\n\ntype AdminOrgTab = 'MANAGERS' | 'MEMBERSHIPS' | 'ORG_UNITS' | 'POSITIONS';\ntype OrgUnitViewMode = 'FLOW' | 'TABLE';\n\nconst INITIAL_ORG_TREE_EDITOR_STATE: OrgUnitTreeDraftEditorState = {\n hasDraftChanges: false,\n isEditing: false,\n};\n\ntype OrgUnitRow = Readonly<\n Record<string, unknown> &\n OrgUnitRecord & {\n key: string;\n parentName: string;\n typeLabel: string;\n }\n>;\n\ntype PositionRow = Readonly<\n Record<string, unknown> &\n PositionRecord & {\n key: string;\n }\n>;\n\ntype MembershipRow = Readonly<\n Record<string, unknown> &\n MembershipRecord & {\n key: string;\n memberName: string;\n orgUnitName: string;\n positionName: string;\n }\n>;\n\ntype ManagerResolutionRow = Readonly<\n Record<string, unknown> &\n ManagerResolutionRecord & {\n key: string;\n managerName: string;\n scopeLabel: string;\n }\n>;\n\ntype OrgModalState = Readonly<{\n parentId?: string | null;\n record: OrgUnitRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype PositionModalState = Readonly<{\n record: PositionRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype MembershipModalState = Readonly<{\n record: MembershipRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype ManagerModalState = Readonly<{\n record: ManagerResolutionRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype DeleteConfirmationState = Readonly<{\n confirmText: string;\n description: string;\n id: string;\n title: string;\n type: 'MANAGER_RESOLUTION' | 'MEMBERSHIP' | 'ORG_UNIT';\n}>;\n\ntype OrgUnitTypeOption = Readonly<{\n id: OrgUnitType;\n name: string;\n}>;\n\ntype OrgUnitTypeFilterOption = Readonly<{\n id: 'ALL' | OrgUnitType;\n name: string;\n}>;\n\ntype ScopeTypeOption = Readonly<{\n id: ManagerResolutionScopeType;\n name: string;\n}>;\n\ntype ScopeTypeFilterOption = Readonly<{\n id: 'ALL' | ManagerResolutionScopeType;\n name: string;\n}>;\n\ntype ActiveFilterOption = Readonly<{\n activeOnly: boolean;\n id: 'ACTIVE' | 'ALL';\n name: string;\n}>;\n\ntype PrimaryOption = Readonly<{\n id: 'false' | 'true';\n name: string;\n value: boolean;\n}>;\n\ntype TablePaginationState = Readonly<{\n onPageChange: (page: number) => void;\n onPageSizeChange: (pageSize: number) => void;\n page: number;\n pageSize: number;\n total: number;\n}>;\n\nconst ORG_UNIT_TYPES: readonly OrgUnitTypeOption[] = [\n { id: 'COMPANY', name: '公司' },\n { id: 'DIVISION', name: '事業群' },\n { id: 'DEPARTMENT', name: '部門' },\n { id: 'TEAM', name: '小組' },\n];\nconst ALL_ORG_UNIT_TYPE_FILTER: OrgUnitTypeFilterOption = {\n id: 'ALL',\n name: '全部類型',\n};\nconst ORG_UNIT_TYPE_FILTER_OPTIONS: readonly OrgUnitTypeFilterOption[] = [\n ALL_ORG_UNIT_TYPE_FILTER,\n ...ORG_UNIT_TYPES,\n];\n\nconst SCOPE_TYPES: readonly ScopeTypeOption[] = [\n { id: 'MEMBER', name: '指定會員' },\n { id: 'ORG_UNIT', name: '指定組織' },\n { id: 'POSITION', name: '指定職位' },\n];\nconst ALL_SCOPE_TYPE_FILTER: ScopeTypeFilterOption = {\n id: 'ALL',\n name: '全部範圍',\n};\nconst SCOPE_TYPE_FILTER_OPTIONS: readonly ScopeTypeFilterOption[] = [\n ALL_SCOPE_TYPE_FILTER,\n ...SCOPE_TYPES,\n];\nconst ALL_ACTIVE_FILTER: ActiveFilterOption = {\n activeOnly: false,\n id: 'ALL',\n name: '全部狀態',\n};\nconst ACTIVE_FILTER_OPTIONS: readonly ActiveFilterOption[] = [\n ALL_ACTIVE_FILTER,\n { activeOnly: true, id: 'ACTIVE', name: '目前有效' },\n];\n\nconst PRIMARY_OPTIONS: readonly PrimaryOption[] = [\n { id: 'true', name: '主要歸屬', value: true },\n { id: 'false', name: '一般歸屬', value: false },\n];\nconst ORGANIZATION_TABLE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst ORG_UNIT_TABLE_MIN_WIDTH = 1368;\nconst POSITION_TABLE_MIN_WIDTH = 908;\nconst MEMBERSHIP_TABLE_MIN_WIDTH = 1292;\nconst MANAGER_TABLE_MIN_WIDTH = 1124;\n\nexport interface AdminOrgsViewProps {\n readonly activeHref?: string;\n}\n\nexport function AdminOrgsView({\n activeHref,\n}: AdminOrgsViewProps = {}): ReactElement {\n const routes = useBPMRoutes();\n const resolvedActiveHref = activeHref ?? routes.adminOrgs();\n const [activeTab, setActiveTab] = useState<AdminOrgTab>('ORG_UNITS');\n const [deleteConfirmation, setDeleteConfirmation] =\n useState<DeleteConfirmationState | null>(null);\n const [lastDeleteConfirmation, setLastDeleteConfirmation] =\n useState<DeleteConfirmationState | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [managerModal, setManagerModal] = useState<ManagerModalState | null>(\n null,\n );\n const [managerActiveFilter, setManagerActiveFilter] =\n useState<ActiveFilterOption>(ALL_ACTIVE_FILTER);\n const [managerPage, setManagerPage] = useState(1);\n const [managerPageSize, setManagerPageSize] = useState(10);\n const [managerScopeTypeFilter, setManagerScopeTypeFilter] =\n useState<ScopeTypeFilterOption>(ALL_SCOPE_TYPE_FILTER);\n const [managerTotalCount, setManagerTotalCount] = useState(0);\n const [memberProfiles, setMemberProfiles] = useState<\n readonly MemberProfileRecord[]\n >([]);\n const [membershipActiveFilter, setMembershipActiveFilter] =\n useState<ActiveFilterOption | null>(null);\n const [membershipModal, setMembershipModal] =\n useState<MembershipModalState | null>(null);\n const [membershipOrgUnitFilter, setMembershipOrgUnitFilter] =\n useState<OrgUnitOption | null>(null);\n const [membershipPage, setMembershipPage] = useState(1);\n const [membershipPageSize, setMembershipPageSize] = useState(10);\n const [membershipPositionFilter, setMembershipPositionFilter] =\n useState<PositionOption | null>(null);\n const [membershipTotalCount, setMembershipTotalCount] = useState(0);\n const [orgModal, setOrgModal] = useState<OrgModalState | null>(null);\n const [orgUnitPage, setOrgUnitPage] = useState(1);\n const [orgUnitPageSize, setOrgUnitPageSize] = useState(10);\n const [orgUnitSearchText, setOrgUnitSearchText] = useState('');\n const [orgUnitTotalCount, setOrgUnitTotalCount] = useState(0);\n const [orgUnitTypeFilter, setOrgUnitTypeFilter] =\n useState<OrgUnitTypeFilterOption>(ALL_ORG_UNIT_TYPE_FILTER);\n const [orgUnitViewMode, setOrgUnitViewMode] =\n useState<OrgUnitViewMode>('TABLE');\n const [orgUnits, setOrgUnits] = useState<readonly OrgUnitRecord[]>([]);\n const [visibleOrgUnits, setVisibleOrgUnits] = useState<\n readonly OrgUnitRecord[]\n >([]);\n const [visiblePositions, setVisiblePositions] = useState<\n readonly PositionRecord[]\n >([]);\n const [positionModal, setPositionModal] = useState<PositionModalState | null>(\n null,\n );\n const [positionPage, setPositionPage] = useState(1);\n const [positionPageSize, setPositionPageSize] = useState(10);\n const [positionSearchText, setPositionSearchText] = useState('');\n const [positionTotalCount, setPositionTotalCount] = useState(0);\n const [positions, setPositions] = useState<readonly PositionRecord[]>([]);\n const [visibleManagerResolutions, setVisibleManagerResolutions] = useState<\n readonly ManagerResolutionRecord[]\n >([]);\n const [visibleMemberships, setVisibleMemberships] = useState<\n readonly MembershipRecord[]\n >([]);\n const [saving, setSaving] = useState(false);\n\n useEffect((): void => {\n if (deleteConfirmation) {\n setLastDeleteConfirmation(deleteConfirmation);\n }\n }, [deleteConfirmation]);\n\n const visibleDeleteConfirmation =\n deleteConfirmation ?? lastDeleteConfirmation;\n\n const refreshOrganization = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const dashboard = await readOrganizationDashboard({\n managerActiveOnly: managerActiveFilter.activeOnly,\n managerPage,\n managerPageSize,\n managerScopeType:\n managerScopeTypeFilter.id === 'ALL'\n ? null\n : managerScopeTypeFilter.id,\n membershipActiveOnly: membershipActiveFilter?.activeOnly ?? false,\n membershipOrgUnitId: membershipOrgUnitFilter?.id ?? null,\n membershipPage,\n membershipPageSize,\n membershipPositionId: membershipPositionFilter?.id ?? null,\n orgUnitPage,\n orgUnitPageSize,\n orgUnitSearchText,\n orgUnitType:\n orgUnitTypeFilter.id === 'ALL' ? null : orgUnitTypeFilter.id,\n positionPage,\n positionPageSize,\n positionSearchText,\n });\n const memberIds = readReferencedMemberIds(\n dashboard.memberships,\n dashboard.managerResolutions,\n );\n const profiles = await resolveMembers(memberIds);\n\n setMemberProfiles(profiles);\n setOrgUnits(dashboard.orgUnits);\n setOrgUnitTotalCount(dashboard.orgUnitCount);\n setVisibleOrgUnits(dashboard.filteredOrgUnits);\n setPositions(dashboard.positions);\n setPositionTotalCount(dashboard.positionCount);\n setVisiblePositions(dashboard.filteredPositions);\n setMembershipTotalCount(dashboard.membershipCount);\n setVisibleMemberships(dashboard.filteredMemberships);\n setManagerTotalCount(dashboard.managerResolutionCount);\n setVisibleManagerResolutions(dashboard.filteredManagerResolutions);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [\n managerActiveFilter,\n managerPage,\n managerPageSize,\n managerScopeTypeFilter,\n membershipActiveFilter,\n membershipOrgUnitFilter,\n membershipPage,\n membershipPageSize,\n membershipPositionFilter,\n orgUnitPage,\n orgUnitPageSize,\n orgUnitSearchText,\n orgUnitTypeFilter,\n positionPage,\n positionPageSize,\n positionSearchText,\n ]);\n\n useEffect((): void => {\n void refreshOrganization();\n }, [refreshOrganization]);\n\n const orgUnitsById = useMemo(\n (): ReadonlyMap<string, OrgUnitRecord> =>\n new Map(orgUnits.map((orgUnit) => [orgUnit.id, orgUnit])),\n [orgUnits],\n );\n const positionsById = useMemo(\n (): ReadonlyMap<string, PositionRecord> =>\n new Map(positions.map((position) => [position.id, position])),\n [positions],\n );\n const membersById = useMemo(\n (): ReadonlyMap<string, MemberProfileRecord> =>\n new Map(memberProfiles.map((member) => [member.memberId, member])),\n [memberProfiles],\n );\n\n const orgRows = useMemo(\n (): OrgUnitRow[] =>\n visibleOrgUnits.map((orgUnit) => ({\n ...orgUnit,\n key: orgUnit.id,\n parentName: orgUnit.parentId\n ? readOrgUnitLabel(orgUnitsById.get(orgUnit.parentId))\n : '根節點',\n typeLabel: readOrgUnitTypeLabel(orgUnit.type),\n })),\n [visibleOrgUnits, orgUnitsById],\n );\n const positionRows = useMemo(\n (): PositionRow[] =>\n visiblePositions.map((position) => ({\n ...position,\n key: position.id,\n })),\n [visiblePositions],\n );\n const membershipRows = useMemo(\n (): MembershipRow[] =>\n visibleMemberships.map((membership) => ({\n ...membership,\n key: membership.id,\n memberName: readMemberLabel(membersById.get(membership.memberId)),\n orgUnitName: readOrgUnitLabel(orgUnitsById.get(membership.orgUnitId)),\n positionName: membership.positionId\n ? readPositionLabel(positionsById.get(membership.positionId))\n : '未指定',\n })),\n [membersById, visibleMemberships, orgUnitsById, positionsById],\n );\n const managerRows = useMemo(\n (): ManagerResolutionRow[] =>\n visibleManagerResolutions.map((resolution) => ({\n ...resolution,\n key: resolution.id,\n managerName: readMemberLabel(\n membersById.get(resolution.managerMemberId),\n ),\n scopeLabel: readScopeLabel(resolution, {\n membersById,\n orgUnitsById,\n positionsById,\n }),\n })),\n [visibleManagerResolutions, membersById, orgUnitsById, positionsById],\n );\n\n const orgActions = useMemo(\n (): TableActions<OrgUnitRow> => ({\n render: (record): ReturnType<TableActions<OrgUnitRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setOrgModal({ record, type: 'EDIT' }),\n },\n {\n name: '停用',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '停用組織',\n description: `停用「${record.name}」後,這個組織節點將不再出現在可用組織清單中。`,\n id: record.id,\n title: '停用組織節點',\n type: 'ORG_UNIT',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n const positionActions = useMemo(\n (): TableActions<PositionRow> => ({\n render: (record): ReturnType<TableActions<PositionRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setPositionModal({ record, type: 'EDIT' }),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [],\n );\n const membershipActions = useMemo(\n (): TableActions<MembershipRow> => ({\n render: (record): ReturnType<TableActions<MembershipRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setMembershipModal({ record, type: 'EDIT' }),\n },\n {\n name: '刪除',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '刪除歸屬',\n description: `刪除「${record.memberName}」在「${record.orgUnitName}」的會員歸屬。`,\n id: record.id,\n title: '刪除會員歸屬',\n type: 'MEMBERSHIP',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n const managerActions = useMemo(\n (): TableActions<ManagerResolutionRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ManagerResolutionRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setManagerModal({ record, type: 'EDIT' }),\n },\n {\n name: '刪除',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '刪除主管規則',\n description: `刪除「${record.scopeLabel}」指派給「${record.managerName}」的主管解析規則。`,\n id: record.id,\n title: '刪除主管解析規則',\n type: 'MANAGER_RESOLUTION',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n\n function updateOrgUnitSearchText(value: string): void {\n setOrgUnitPage(1);\n setOrgUnitSearchText(value);\n }\n\n function updateOrgUnitTypeFilter(value: OrgUnitTypeFilterOption): void {\n setOrgUnitPage(1);\n setOrgUnitTypeFilter(value);\n }\n\n function updatePositionSearchText(value: string): void {\n setPositionPage(1);\n setPositionSearchText(value);\n }\n\n function updateMembershipActiveFilter(value: ActiveFilterOption | null): void {\n setMembershipPage(1);\n setMembershipActiveFilter(value);\n }\n\n function updateMembershipOrgUnitFilter(value: OrgUnitOption | null): void {\n setMembershipPage(1);\n setMembershipOrgUnitFilter(value);\n }\n\n function updateMembershipPositionFilter(value: PositionOption | null): void {\n setMembershipPage(1);\n setMembershipPositionFilter(value);\n }\n\n function updateManagerActiveFilter(value: ActiveFilterOption): void {\n setManagerPage(1);\n setManagerActiveFilter(value);\n }\n\n function updateManagerScopeTypeFilter(value: ScopeTypeFilterOption): void {\n setManagerPage(1);\n setManagerScopeTypeFilter(value);\n }\n\n function closeDeleteConfirmation(): void {\n if (saving) {\n return;\n }\n\n setDeleteConfirmation(null);\n }\n\n async function handleConfirmDelete(): Promise<void> {\n if (!deleteConfirmation) {\n return;\n }\n\n await runMutation(async (): Promise<void> => {\n if (deleteConfirmation.type === 'ORG_UNIT') {\n await deleteOrgUnit(deleteConfirmation.id);\n }\n\n if (deleteConfirmation.type === 'MEMBERSHIP') {\n await deleteMembership(deleteConfirmation.id);\n }\n\n if (deleteConfirmation.type === 'MANAGER_RESOLUTION') {\n await deleteManagerResolution(deleteConfirmation.id);\n }\n\n setDeleteConfirmation(null);\n });\n }\n\n async function saveOrgUnitTreeDraft(\n changes: readonly OrgUnitHierarchyDraftChange[],\n ): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await commitOrgUnitTreeDraft({\n moves: changes.map((change) => {\n const orgUnit = orgUnitsById.get(change.orgUnitId);\n\n return {\n baseUpdatedAt: orgUnit?.updatedAt ?? '',\n id: change.orgUnitId,\n parentId: change.parentId,\n };\n }),\n });\n await refreshOrganization();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n throw requestError;\n } finally {\n setSaving(false);\n }\n }\n\n async function runMutation(mutation: () => Promise<void>): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await mutation();\n await refreshOrganization();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <AppLayout activeHref={resolvedActiveHref}>\n <PageHeader>\n <ContentHeader\n description=\"維護組織樹、職位、會員歸屬與簽核主管解析規則。\"\n title=\"組織管理\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section\n tab={\n <Tab\n activeKey={activeTab}\n onChange={(key): void => setActiveTab(readAdminOrgTab(key))}\n >\n <TabItem key=\"ORG_UNITS\">組織樹</TabItem>\n <TabItem key=\"POSITIONS\">職位</TabItem>\n <TabItem key=\"MEMBERSHIPS\">會員歸屬</TabItem>\n <TabItem key=\"MANAGERS\">簽核主管</TabItem>\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {activeTab === 'ORG_UNITS' ? (\n <OrgUnitPanel\n actions={orgActions}\n loading={loading}\n onCreate={(): void =>\n setOrgModal({ parentId: null, record: null, type: 'CREATE' })\n }\n onCreateChild={(parentId): void =>\n setOrgModal({ parentId, record: null, type: 'CREATE' })\n }\n onEditOrgUnit={(record): void =>\n setOrgModal({ record, type: 'EDIT' })\n }\n onPageChange={setOrgUnitPage}\n onSaveDraft={saveOrgUnitTreeDraft}\n onPageSizeChange={(pageSize): void => {\n setOrgUnitPage(1);\n setOrgUnitPageSize(pageSize);\n }}\n onSearchTextChange={updateOrgUnitSearchText}\n onTypeFilterChange={updateOrgUnitTypeFilter}\n orgUnits={orgUnits}\n page={orgUnitPage}\n pageSize={orgUnitPageSize}\n rows={orgRows}\n searchText={orgUnitSearchText}\n saving={saving}\n total={orgUnitTotalCount}\n typeFilter={orgUnitTypeFilter}\n viewMode={orgUnitViewMode}\n onViewModeChange={setOrgUnitViewMode}\n />\n ) : null}\n {activeTab === 'POSITIONS' ? (\n <PositionPanel\n actions={positionActions}\n loading={loading}\n onCreate={(): void =>\n setPositionModal({ record: null, type: 'CREATE' })\n }\n onPageChange={setPositionPage}\n onPageSizeChange={(pageSize): void => {\n setPositionPage(1);\n setPositionPageSize(pageSize);\n }}\n onSearchTextChange={updatePositionSearchText}\n page={positionPage}\n pageSize={positionPageSize}\n rows={positionRows}\n searchText={positionSearchText}\n total={positionTotalCount}\n />\n ) : null}\n {activeTab === 'MEMBERSHIPS' ? (\n <MembershipPanel\n actions={membershipActions}\n loading={loading}\n onCreate={(): void =>\n setMembershipModal({ record: null, type: 'CREATE' })\n }\n onActiveFilterChange={updateMembershipActiveFilter}\n onOrgUnitFilterChange={updateMembershipOrgUnitFilter}\n onPageChange={setMembershipPage}\n onPageSizeChange={(pageSize): void => {\n setMembershipPage(1);\n setMembershipPageSize(pageSize);\n }}\n onPositionFilterChange={updateMembershipPositionFilter}\n orgUnitFilter={membershipOrgUnitFilter}\n orgUnits={orgUnits}\n page={membershipPage}\n pageSize={membershipPageSize}\n positionFilter={membershipPositionFilter}\n positions={positions}\n rows={membershipRows}\n statusFilter={membershipActiveFilter}\n total={membershipTotalCount}\n />\n ) : null}\n {activeTab === 'MANAGERS' ? (\n <ManagerPanel\n actions={managerActions}\n loading={loading}\n onCreate={(): void =>\n setManagerModal({ record: null, type: 'CREATE' })\n }\n onActiveFilterChange={updateManagerActiveFilter}\n onPageChange={setManagerPage}\n onPageSizeChange={(pageSize): void => {\n setManagerPage(1);\n setManagerPageSize(pageSize);\n }}\n onScopeTypeFilterChange={updateManagerScopeTypeFilter}\n page={managerPage}\n pageSize={managerPageSize}\n rows={managerRows}\n scopeTypeFilter={managerScopeTypeFilter}\n statusFilter={managerActiveFilter}\n total={managerTotalCount}\n />\n ) : null}\n </Section>\n </SectionGroup>\n\n <OrgUnitModal\n modal={orgModal}\n onClose={(): void => setOrgModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (orgModal?.type === 'EDIT' && orgModal.record) {\n await updateOrgUnit({\n ...input,\n id: orgModal.record.id,\n metadataJson: null,\n });\n } else {\n await createOrgUnit({\n code: input.code ?? '',\n metadataJson: '{}',\n name: input.name ?? '',\n parentId: input.parentId,\n type: input.type ?? 'DEPARTMENT',\n });\n }\n setOrgModal(null);\n })\n }\n orgUnits={orgUnits}\n saving={saving}\n />\n <PositionModal\n modal={positionModal}\n onClose={(): void => setPositionModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (positionModal?.type === 'EDIT' && positionModal.record) {\n await updatePosition({\n ...input,\n id: positionModal.record.id,\n metadataJson: null,\n });\n } else {\n await createPosition({\n code: input.code ?? '',\n level: input.level ?? 0,\n metadataJson: '{}',\n name: input.name ?? '',\n });\n }\n setPositionModal(null);\n })\n }\n saving={saving}\n />\n <MembershipModal\n membersById={membersById}\n modal={membershipModal}\n onClose={(): void => setMembershipModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (membershipModal?.type === 'EDIT' && membershipModal.record) {\n await updateMembership({\n ...input,\n id: membershipModal.record.id,\n });\n } else {\n await createMembership({\n effectiveFrom: input.effectiveFrom ?? today(),\n effectiveTo: input.effectiveTo,\n isPrimary: input.isPrimary ?? false,\n memberId: input.memberId ?? '',\n orgUnitId: input.orgUnitId ?? '',\n positionId: input.positionId,\n });\n }\n setMembershipModal(null);\n })\n }\n orgUnits={orgUnits}\n positions={positions}\n saving={saving}\n />\n <ManagerResolutionModal\n membersById={membersById}\n modal={managerModal}\n onClose={(): void => setManagerModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (managerModal?.type === 'EDIT' && managerModal.record) {\n await updateManagerResolution({\n ...input,\n id: managerModal.record.id,\n });\n } else {\n await createManagerResolution({\n effectiveFrom: input.effectiveFrom ?? today(),\n effectiveTo: input.effectiveTo,\n managerMemberId: input.managerMemberId ?? '',\n priority: input.priority ?? 0,\n scopeId: input.scopeId ?? '',\n scopeType: input.scopeType ?? 'MEMBER',\n });\n }\n setManagerModal(null);\n })\n }\n orgUnits={orgUnits}\n positions={positions}\n saving={saving}\n />\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ variant: 'destructive-primary' }}\n confirmText={visibleDeleteConfirmation?.confirmText ?? ''}\n loading={saving}\n modalStatusType=\"error\"\n modalType=\"standard\"\n onCancel={closeDeleteConfirmation}\n onClose={closeDeleteConfirmation}\n onConfirm={(): void => void handleConfirmDelete()}\n open={Boolean(deleteConfirmation)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"此操作會立即套用,請確認後再繼續。\"\n title={visibleDeleteConfirmation?.title ?? ''}\n >\n <Typography color=\"text-neutral\" variant=\"body\">\n {visibleDeleteConfirmation?.description ?? ''}\n </Typography>\n </Modal>\n </AppLayout>\n );\n}\n\nfunction OrgUnitPanel({\n actions,\n loading,\n onCreate,\n onCreateChild,\n onEditOrgUnit,\n onPageChange,\n onSaveDraft,\n onPageSizeChange,\n onSearchTextChange,\n onTypeFilterChange,\n onViewModeChange,\n orgUnits,\n page,\n pageSize,\n rows,\n searchText,\n saving,\n total,\n typeFilter,\n viewMode,\n}: {\n readonly actions: TableActions<OrgUnitRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onCreateChild: (parentId: string) => void;\n readonly onEditOrgUnit: (record: OrgUnitRecord) => void;\n readonly onPageChange: (page: number) => void;\n readonly onSaveDraft: (\n changes: readonly OrgUnitHierarchyDraftChange[],\n ) => Promise<void>;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onSearchTextChange: (value: string) => void;\n readonly onTypeFilterChange: (value: OrgUnitTypeFilterOption) => void;\n readonly onViewModeChange: (mode: OrgUnitViewMode) => void;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly OrgUnitRow[];\n readonly searchText: string;\n readonly saving: boolean;\n readonly total: number;\n readonly typeFilter: OrgUnitTypeFilterOption;\n readonly viewMode: OrgUnitViewMode;\n}): ReactElement {\n const treeEditorRef = useRef<OrgUnitTreeDraftEditorHandle | null>(null);\n const [treeEditorState, setTreeEditorState] =\n useState<OrgUnitTreeDraftEditorState>(INITIAL_ORG_TREE_EDITOR_STATE);\n const nextViewMode: OrgUnitViewMode = viewMode === 'TABLE' ? 'FLOW' : 'TABLE';\n const viewModeToggleLabel = viewMode === 'TABLE' ? '切換樹狀圖' : '切換表格';\n const isTreeMode = viewMode === 'FLOW';\n const primaryActionLabel = readOrgUnitPrimaryActionLabel({\n isTreeMode,\n isTreeEditing: treeEditorState.isEditing,\n });\n const primaryActionIcon = readOrgUnitPrimaryActionIcon({\n isTreeMode,\n isTreeEditing: treeEditorState.isEditing,\n });\n const primaryActionDisabled = readOrgUnitPrimaryActionDisabled({\n hasDraftChanges: treeEditorState.hasDraftChanges,\n isTreeEditing: treeEditorState.isEditing,\n isTreeMode,\n loading,\n saving,\n });\n const columns = useMemo(\n (): TableColumn<OrgUnitRow>[] => [\n { dataIndex: 'code', key: 'code', title: '代碼', width: 180 },\n { dataIndex: 'name', key: 'name', title: '名稱', width: 240 },\n { dataIndex: 'typeLabel', key: 'typeLabel', title: '類型', width: 120 },\n { dataIndex: 'parentName', key: 'parentName', title: '上層', width: 280 },\n { dataIndex: 'path', key: 'path', title: 'Path', width: 420 },\n ],\n [],\n );\n\n useEffect((): void => {\n if (viewMode === 'TABLE') {\n setTreeEditorState(INITIAL_ORG_TREE_EDITOR_STATE);\n }\n }, [viewMode]);\n\n return (\n <>\n <PanelIntro\n actionDisabled={primaryActionDisabled}\n actionIcon={primaryActionIcon}\n actionLabel={primaryActionLabel}\n actions={\n <>\n <Button\n onClick={(): void => onViewModeChange(nextViewMode)}\n variant=\"base-secondary\"\n >\n {viewModeToggleLabel}\n </Button>\n {isTreeMode && treeEditorState.isEditing ? (\n <Button\n disabled={saving}\n icon={CloseIcon}\n iconType=\"leading\"\n onClick={(): void => treeEditorRef.current?.cancelEditing()}\n variant=\"base-secondary\"\n >\n 取消\n </Button>\n ) : null}\n </>\n }\n description=\"組織節點使用 ltree path 維護階層,搬移節點會同步更新子節點 path。\"\n onCreate={(): void => {\n if (!isTreeMode) {\n onCreate();\n return;\n }\n\n if (treeEditorState.isEditing) {\n void treeEditorRef.current?.saveDraft();\n return;\n }\n\n treeEditorRef.current?.startEditing();\n }}\n title=\"組織樹\"\n />\n {viewMode === 'TABLE' ? (\n <>\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"orgUnitSearchText\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onSearchTextChange(event.target.value)\n }\n placeholder=\"搜尋組織名稱或代碼\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"orgUnitTypeFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onTypeFilterChange(readOrgUnitTypeFilterOption(option))\n }\n options={[...ORG_UNIT_TYPE_FILTER_OPTIONS]}\n placeholder=\"類型\"\n size=\"sub\"\n value={typeFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: ORG_UNIT_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n ) : (\n <OrgUnitTreeDraftEditor\n ref={treeEditorRef}\n onCreateChild={onCreateChild}\n onCreateRoot={onCreate}\n onEditOrgUnit={onEditOrgUnit}\n onSaveDraft={onSaveDraft}\n onStateChange={setTreeEditorState}\n orgUnits={orgUnits}\n saving={saving}\n />\n )}\n </>\n );\n}\n\nfunction PositionPanel({\n actions,\n loading,\n onCreate,\n onPageChange,\n onPageSizeChange,\n onSearchTextChange,\n page,\n pageSize,\n rows,\n searchText,\n total,\n}: {\n readonly actions: TableActions<PositionRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onSearchTextChange: (value: string) => void;\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly PositionRow[];\n readonly searchText: string;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<PositionRow>[] => [\n { dataIndex: 'code', key: 'code', title: '代碼', width: 180 },\n { dataIndex: 'name', key: 'name', title: '名稱', width: 280 },\n { dataIndex: 'level', key: 'level', title: '職等', width: 96 },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增職位\"\n description=\"職位提供會員歸屬與主管解析規則使用。\"\n onCreate={onCreate}\n title=\"職位\"\n />\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"positionSearchText\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onSearchTextChange(event.target.value)\n }\n placeholder=\"搜尋職位名稱或代碼\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: POSITION_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction MembershipPanel({\n actions,\n loading,\n onCreate,\n onActiveFilterChange,\n onOrgUnitFilterChange,\n onPageChange,\n onPageSizeChange,\n onPositionFilterChange,\n orgUnitFilter,\n orgUnits,\n page,\n pageSize,\n positionFilter,\n positions,\n rows,\n statusFilter,\n total,\n}: {\n readonly actions: TableActions<MembershipRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onActiveFilterChange: (value: ActiveFilterOption | null) => void;\n readonly onOrgUnitFilterChange: (value: OrgUnitOption | null) => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onPositionFilterChange: (value: PositionOption | null) => void;\n readonly orgUnitFilter: OrgUnitOption | null;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly page: number;\n readonly pageSize: number;\n readonly positionFilter: PositionOption | null;\n readonly positions: readonly PositionRecord[];\n readonly rows: readonly MembershipRow[];\n readonly statusFilter: ActiveFilterOption | null;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<MembershipRow>[] => [\n { dataIndex: 'memberName', key: 'memberName', title: '會員', width: 280 },\n {\n dataIndex: 'orgUnitName',\n key: 'orgUnitName',\n title: '組織',\n width: 280,\n },\n {\n dataIndex: 'positionName',\n key: 'positionName',\n title: '職位',\n width: 220,\n },\n {\n key: 'isPrimary',\n render: (record: MembershipRow): string =>\n record.isPrimary ? '主要' : '一般',\n title: '類型',\n width: 104,\n },\n {\n dataIndex: 'effectiveFrom',\n key: 'effectiveFrom',\n title: '生效日',\n width: 140,\n },\n {\n dataIndex: 'effectiveTo',\n key: 'effectiveTo',\n title: '結束日',\n width: 140,\n },\n ],\n [],\n );\n const orgUnitOptions = useMemo(\n (): readonly OrgUnitOption[] => orgUnits.map(readOrgUnitOption),\n [orgUnits],\n );\n const positionOptions = useMemo(\n (): readonly PositionOption[] => positions.map(readPositionOption),\n [positions],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增歸屬\"\n description=\"會員歸屬是 BPM 內部組織權限、主管解析與條件判斷的來源。\"\n onCreate={onCreate}\n title=\"會員歸屬\"\n />\n <FilterArea\n className={[styles.orgFilterArea, styles.membershipFilterArea].join(\n ' ',\n )}\n size=\"sub\"\n >\n <FilterLine>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipOrgUnitFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的組織\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipOrgUnitFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipOrgUnitFilter\"\n onChange={(option): void =>\n onOrgUnitFilterChange(readOrgUnitOptionFromValue(option))\n }\n options={[...orgUnitOptions]}\n placeholder=\"全部組織\"\n size=\"sub\"\n value={orgUnitFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipPositionFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的職位\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipPositionFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipPositionFilter\"\n onChange={(option): void =>\n onPositionFilterChange(readPositionOptionFromValue(option))\n }\n options={[...positionOptions]}\n placeholder=\"全部職位\"\n size=\"sub\"\n value={positionFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipStatusFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的狀態\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipStatusFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipStatusFilter\"\n onChange={(option): void =>\n onActiveFilterChange(readNullableActiveFilterOption(option))\n }\n options={[...ACTIVE_FILTER_OPTIONS]}\n placeholder=\"全部狀態\"\n size=\"sub\"\n value={statusFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: MEMBERSHIP_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction ManagerPanel({\n actions,\n loading,\n onCreate,\n onActiveFilterChange,\n onPageChange,\n onPageSizeChange,\n onScopeTypeFilterChange,\n page,\n pageSize,\n rows,\n scopeTypeFilter,\n statusFilter,\n total,\n}: {\n readonly actions: TableActions<ManagerResolutionRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onActiveFilterChange: (value: ActiveFilterOption) => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onScopeTypeFilterChange: (value: ScopeTypeFilterOption) => void;\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly ManagerResolutionRow[];\n readonly scopeTypeFilter: ScopeTypeFilterOption;\n readonly statusFilter: ActiveFilterOption;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<ManagerResolutionRow>[] => [\n {\n dataIndex: 'scopeLabel',\n key: 'scopeLabel',\n title: '套用範圍',\n width: 320,\n },\n {\n dataIndex: 'managerName',\n key: 'managerName',\n title: '簽核主管',\n width: 300,\n },\n { dataIndex: 'priority', key: 'priority', title: '優先序', width: 96 },\n {\n dataIndex: 'effectiveFrom',\n key: 'effectiveFrom',\n title: '生效日',\n width: 140,\n },\n {\n dataIndex: 'effectiveTo',\n key: 'effectiveTo',\n title: '結束日',\n width: 140,\n },\n ],\n [],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增主管規則\"\n description=\"簽核主管規則獨立於組織樹 parent,解析優先序為會員、組織、職位。\"\n onCreate={onCreate}\n title=\"簽核主管\"\n />\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"managerScopeTypeFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onScopeTypeFilterChange(readScopeTypeFilterOption(option))\n }\n options={[...SCOPE_TYPE_FILTER_OPTIONS]}\n placeholder=\"套用範圍\"\n size=\"sub\"\n value={scopeTypeFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"managerStatusFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onActiveFilterChange(readActiveFilterOption(option))\n }\n options={[...ACTIVE_FILTER_OPTIONS]}\n placeholder=\"狀態\"\n size=\"sub\"\n value={statusFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: MANAGER_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n}: TablePaginationState): {\n current: number;\n onChange: (page: number) => void;\n onChangePageSize: (pageSize: number) => void;\n pageSize: number;\n pageSizeLabel: string;\n pageSizeOptions: number[];\n renderResultSummary: (from: number, to: number, total: number) => string;\n showPageSizeOptions: true;\n total: number;\n} {\n return {\n current: page,\n onChange: onPageChange,\n onChangePageSize: onPageSizeChange,\n pageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: [...ORGANIZATION_TABLE_PAGE_SIZE_OPTIONS],\n renderResultSummary: (from, to, resultTotal): string =>\n `顯示 ${from}-${to} 筆,共 ${resultTotal} 筆`,\n showPageSizeOptions: true,\n total,\n };\n}\n\nfunction readOrgUnitPrimaryActionLabel({\n isTreeEditing,\n isTreeMode,\n}: {\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n}): string {\n if (!isTreeMode) {\n return '新增組織';\n }\n\n return isTreeEditing ? '儲存' : '開始編輯';\n}\n\nfunction readOrgUnitPrimaryActionIcon({\n isTreeEditing,\n isTreeMode,\n}: {\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n}): IconDefinition {\n if (!isTreeMode) {\n return PlusIcon;\n }\n\n return isTreeEditing ? SaveIcon : EditIcon;\n}\n\nfunction readOrgUnitPrimaryActionDisabled({\n hasDraftChanges,\n isTreeEditing,\n isTreeMode,\n loading,\n saving,\n}: {\n readonly hasDraftChanges: boolean;\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n readonly loading: boolean;\n readonly saving: boolean;\n}): boolean {\n if (!isTreeMode) {\n return false;\n }\n\n if (!isTreeEditing) {\n return loading;\n }\n\n return !hasDraftChanges || saving;\n}\n\nfunction PanelIntro({\n actionDisabled = false,\n actionIcon = PlusIcon,\n actionLabel,\n actions,\n description,\n onCreate,\n title,\n}: {\n readonly actionDisabled?: boolean;\n readonly actionIcon?: IconDefinition;\n readonly actionLabel: string;\n readonly actions?: ReactElement;\n readonly description: string;\n readonly onCreate: () => void;\n readonly title: string;\n}): ReactElement {\n return (\n <div className={styles.tableIntro}>\n <div>\n <Typography component=\"h2\" variant=\"h3\">\n {title}\n </Typography>\n <Typography color=\"text-neutral\" variant=\"body\">\n {description}\n </Typography>\n </div>\n <div className={styles.tableIntroActions}>\n {actions}\n <Button\n disabled={actionDisabled}\n icon={actionIcon}\n iconType=\"leading\"\n onClick={onCreate}\n >\n {actionLabel}\n </Button>\n </div>\n </div>\n );\n}\n\nfunction OrgUnitModal({\n modal,\n onClose,\n onSubmit,\n orgUnits,\n saving,\n}: {\n readonly modal: OrgModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly code: string | null;\n readonly name: string | null;\n readonly parentId: string | null;\n readonly type: OrgUnitType | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [code, setCode] = useState('');\n const [name, setName] = useState('');\n const [parent, setParent] = useState<OrgUnitOption | null>(null);\n const [type, setType] = useState<OrgUnitTypeOption>(ORG_UNIT_TYPES[2]);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const parentId = record?.parentId ?? modal.parentId ?? null;\n const parentOrgUnit = parentId\n ? (orgUnits.find((orgUnit) => orgUnit.id === parentId) ?? null)\n : null;\n\n setCode(record?.code ?? '');\n setName(record?.name ?? '');\n setParent(parentOrgUnit ? readOrgUnitOption(parentOrgUnit) : null);\n setType(\n ORG_UNIT_TYPES.find((option) => option.id === record?.type) ??\n ORG_UNIT_TYPES[2],\n );\n }, [modal, orgUnits]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !code || !name }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n code,\n name,\n parentId: parent?.id ?? null,\n type: type.id,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯組織' : '新增組織'}\n >\n <div className={styles.modalFields}>\n <OrgModalTextField\n label=\"代碼\"\n name=\"orgCode\"\n onChange={setCode}\n placeholder=\"例如 FIN-TW\"\n value={code}\n />\n <OrgModalTextField\n label=\"名稱\"\n name=\"orgName\"\n onChange={setName}\n placeholder=\"例如 財務部\"\n value={name}\n />\n <BPMFormField label=\"類型\" name=\"orgType\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => setType(readOrgUnitTypeOption(option))}\n options={[...ORG_UNIT_TYPES]}\n placeholder=\"選擇組織類型\"\n value={type}\n />\n </BPMFormField>\n <BPMFormField label=\"上層組織\" name=\"parentId\">\n <OrgUnitPicker\n name=\"parentId\"\n onChange={setParent}\n orgUnits={orgUnits.filter(\n (orgUnit) => orgUnit.id !== modal?.record?.id,\n )}\n placeholder=\"選擇上層組織\"\n value={parent}\n />\n </BPMFormField>\n </div>\n </Modal>\n );\n}\n\nfunction PositionModal({\n modal,\n onClose,\n onSubmit,\n saving,\n}: {\n readonly modal: PositionModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly code: string | null;\n readonly level: number | null;\n readonly name: string | null;\n }) => Promise<void>;\n readonly saving: boolean;\n}): ReactElement {\n const [code, setCode] = useState('');\n const [level, setLevel] = useState('0');\n const [name, setName] = useState('');\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n setCode(modal.record?.code ?? '');\n setLevel(String(modal.record?.level ?? 0));\n setName(modal.record?.name ?? '');\n }, [modal]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !code || !name }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n code,\n level: Number(level),\n name,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯職位' : '新增職位'}\n >\n <div className={styles.modalFields}>\n <OrgModalTextField\n label=\"代碼\"\n name=\"positionCode\"\n onChange={setCode}\n placeholder=\"例如 FIN-MGR\"\n value={code}\n />\n <OrgModalTextField\n label=\"名稱\"\n name=\"positionName\"\n onChange={setName}\n placeholder=\"例如 財務主管\"\n value={name}\n />\n <OrgModalTextField\n label=\"職等\"\n name=\"positionLevel\"\n onChange={setLevel}\n placeholder=\"例如 5\"\n value={level}\n />\n </div>\n </Modal>\n );\n}\n\nfunction MembershipModal({\n membersById,\n modal,\n onClose,\n onSubmit,\n orgUnits,\n positions,\n saving,\n}: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly modal: MembershipModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly effectiveFrom: string | null;\n readonly effectiveTo: string | null;\n readonly isPrimary: boolean | null;\n readonly memberId: string | null;\n readonly orgUnitId: string | null;\n readonly positionId: string | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly positions: readonly PositionRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [effectiveFrom, setEffectiveFrom] = useState(today());\n const [effectiveTo, setEffectiveTo] = useState('');\n const [isPrimary, setIsPrimary] = useState<PrimaryOption>(PRIMARY_OPTIONS[1]);\n const [member, setMember] = useState<MemberOption | null>(null);\n const [orgUnit, setOrgUnit] = useState<OrgUnitOption | null>(null);\n const [position, setPosition] = useState<PositionOption | null>(null);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const profile = record ? membersById.get(record.memberId) : null;\n\n setEffectiveFrom(record?.effectiveFrom ?? today());\n setEffectiveTo(record?.effectiveTo ?? '');\n setIsPrimary(\n PRIMARY_OPTIONS.find((option) => option.value === record?.isPrimary) ??\n PRIMARY_OPTIONS[1],\n );\n setMember(profile ? readMemberOption(profile) : null);\n setOrgUnit(\n readNullableOption(\n orgUnits.find((candidate) => candidate.id === record?.orgUnitId),\n readOrgUnitOption,\n ),\n );\n setPosition(\n readNullableOption(\n positions.find((candidate) => candidate.id === record?.positionId),\n readPositionOption,\n ),\n );\n }, [membersById, modal, orgUnits, positions]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !member || !orgUnit }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n effectiveFrom,\n effectiveTo: effectiveTo || null,\n isPrimary: isPrimary.value,\n memberId: member?.id ?? null,\n orgUnitId: orgUnit?.id ?? null,\n positionId: position?.id ?? null,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯會員歸屬' : '新增會員歸屬'}\n >\n <div className={styles.modalFields}>\n <BPMFormField label=\"會員\" name=\"memberId\">\n <MemberPicker\n name=\"memberId\"\n onChange={setMember}\n placeholder=\"搜尋會員姓名或信箱\"\n value={member}\n />\n </BPMFormField>\n <BPMFormField label=\"組織\" name=\"orgUnitId\">\n <OrgUnitPicker\n name=\"orgUnitId\"\n onChange={setOrgUnit}\n orgUnits={orgUnits}\n placeholder=\"選擇歸屬組織\"\n value={orgUnit}\n />\n </BPMFormField>\n <BPMFormField label=\"職位\" name=\"positionId\">\n <PositionPicker\n name=\"positionId\"\n onChange={setPosition}\n placeholder=\"選擇職位\"\n positions={positions}\n value={position}\n />\n </BPMFormField>\n <BPMFormField label=\"歸屬類型\" name=\"isPrimary\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => setIsPrimary(readPrimaryOption(option))}\n options={[...PRIMARY_OPTIONS]}\n placeholder=\"選擇歸屬類型\"\n value={isPrimary}\n />\n </BPMFormField>\n <DateField\n label=\"生效日\"\n name=\"membershipEffectiveFrom\"\n onChange={setEffectiveFrom}\n placeholder=\"YYYY-MM-DD\"\n value={effectiveFrom}\n />\n <DateField\n label=\"結束日\"\n name=\"membershipEffectiveTo\"\n onChange={setEffectiveTo}\n placeholder=\"YYYY-MM-DD,未設定代表無期限\"\n value={effectiveTo}\n />\n </div>\n </Modal>\n );\n}\n\nfunction ManagerResolutionModal({\n membersById,\n modal,\n onClose,\n onSubmit,\n orgUnits,\n positions,\n saving,\n}: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly modal: ManagerModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly effectiveFrom: string | null;\n readonly effectiveTo: string | null;\n readonly managerMemberId: string | null;\n readonly priority: number | null;\n readonly scopeId: string | null;\n readonly scopeType: ManagerResolutionScopeType | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly positions: readonly PositionRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [effectiveFrom, setEffectiveFrom] = useState(today());\n const [effectiveTo, setEffectiveTo] = useState('');\n const [manager, setManager] = useState<MemberOption | null>(null);\n const [priority, setPriority] = useState('0');\n const [scopeMember, setScopeMember] = useState<MemberOption | null>(null);\n const [scopeOrgUnit, setScopeOrgUnit] = useState<OrgUnitOption | null>(null);\n const [scopePosition, setScopePosition] = useState<PositionOption | null>(\n null,\n );\n const [scopeType, setScopeType] = useState<ScopeTypeOption>(SCOPE_TYPES[0]);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const nextScopeType =\n SCOPE_TYPES.find((option) => option.id === record?.scopeType) ??\n SCOPE_TYPES[0];\n\n setEffectiveFrom(record?.effectiveFrom ?? today());\n setEffectiveTo(record?.effectiveTo ?? '');\n setManager(\n readNullableOption(\n record ? membersById.get(record.managerMemberId) : null,\n readMemberOption,\n ),\n );\n setPriority(String(record?.priority ?? 0));\n setScopeMember(\n nextScopeType.id === 'MEMBER'\n ? readNullableOption(\n record ? membersById.get(record.scopeId) : null,\n readMemberOption,\n )\n : null,\n );\n setScopeOrgUnit(\n nextScopeType.id === 'ORG_UNIT'\n ? readNullableOption(\n orgUnits.find((candidate) => candidate.id === record?.scopeId),\n readOrgUnitOption,\n )\n : null,\n );\n setScopePosition(\n nextScopeType.id === 'POSITION'\n ? readNullableOption(\n positions.find((candidate) => candidate.id === record?.scopeId),\n readPositionOption,\n )\n : null,\n );\n setScopeType(nextScopeType);\n }, [membersById, modal, orgUnits, positions]);\n\n const scopeId =\n scopeType.id === 'MEMBER'\n ? scopeMember?.id\n : scopeType.id === 'ORG_UNIT'\n ? scopeOrgUnit?.id\n : scopePosition?.id;\n const isSelfManagerResolution = Boolean(\n scopeType.id === 'MEMBER' &&\n scopeMember?.id &&\n manager?.id &&\n scopeMember.id === manager.id,\n );\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !manager || !scopeId || isSelfManagerResolution,\n }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n effectiveFrom,\n effectiveTo: effectiveTo || null,\n managerMemberId: manager?.id ?? null,\n priority: Number(priority),\n scopeId: scopeId ?? null,\n scopeType: scopeType.id,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯主管規則' : '新增主管規則'}\n >\n <div className={styles.modalFields}>\n <BPMFormField label=\"套用範圍\" name=\"scopeType\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n setScopeType(readScopeTypeOption(option))\n }\n options={[...SCOPE_TYPES]}\n placeholder=\"選擇套用範圍\"\n value={scopeType}\n />\n </BPMFormField>\n {scopeType.id === 'MEMBER' ? (\n <BPMFormField label=\"會員\" name=\"scopeMemberId\">\n <MemberPicker\n name=\"scopeMemberId\"\n onChange={setScopeMember}\n placeholder=\"搜尋套用會員\"\n value={scopeMember}\n />\n </BPMFormField>\n ) : null}\n {scopeType.id === 'ORG_UNIT' ? (\n <BPMFormField label=\"組織\" name=\"scopeOrgUnitId\">\n <OrgUnitPicker\n name=\"scopeOrgUnitId\"\n onChange={setScopeOrgUnit}\n orgUnits={orgUnits}\n placeholder=\"選擇套用組織\"\n value={scopeOrgUnit}\n />\n </BPMFormField>\n ) : null}\n {scopeType.id === 'POSITION' ? (\n <BPMFormField label=\"職位\" name=\"scopePositionId\">\n <PositionPicker\n name=\"scopePositionId\"\n onChange={setScopePosition}\n placeholder=\"選擇套用職位\"\n positions={positions}\n value={scopePosition}\n />\n </BPMFormField>\n ) : null}\n <BPMFormField label=\"簽核主管\" name=\"managerMemberId\">\n <MemberPicker\n name=\"managerMemberId\"\n onChange={setManager}\n placeholder=\"搜尋簽核主管\"\n value={manager}\n />\n </BPMFormField>\n {isSelfManagerResolution ? (\n <Typography color=\"text-error\" variant=\"caption\">\n 簽核主管不可設定為套用會員本人。\n </Typography>\n ) : null}\n <OrgModalTextField\n label=\"優先序\"\n name=\"managerPriority\"\n onChange={setPriority}\n placeholder=\"例如 10\"\n value={priority}\n />\n <DateField\n label=\"生效日\"\n name=\"managerEffectiveFrom\"\n onChange={setEffectiveFrom}\n placeholder=\"YYYY-MM-DD\"\n value={effectiveFrom}\n />\n <DateField\n label=\"結束日\"\n name=\"managerEffectiveTo\"\n onChange={setEffectiveTo}\n placeholder=\"YYYY-MM-DD,未設定代表無期限\"\n value={effectiveTo}\n />\n </div>\n </Modal>\n );\n}\n\nfunction OrgModalTextField({\n label,\n name,\n onChange,\n placeholder,\n value,\n}: {\n readonly label: string;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly value: string;\n}): ReactElement {\n return (\n <BPMFormField label={label} name={name}>\n <Input\n fullWidth\n name={name}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(event.target.value)\n }\n placeholder={placeholder}\n value={value}\n />\n </BPMFormField>\n );\n}\n\nfunction DateField({\n label,\n name,\n onChange,\n placeholder,\n value,\n}: {\n readonly label: string;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly value: string;\n}): ReactElement {\n return (\n <BPMFormField label={label} name={name}>\n <DatePicker\n format=\"YYYY-MM-DD\"\n fullWidth\n inputProps={{ name }}\n onChange={(nextValue): void => onChange(formatDateOnly(nextValue))}\n placeholder={placeholder}\n value={value.trim() ? value : undefined}\n />\n </BPMFormField>\n );\n}\n\nfunction readReferencedMemberIds(\n memberships: readonly MembershipRecord[],\n managerResolutions: readonly ManagerResolutionRecord[],\n): readonly string[] {\n return [\n ...new Set([\n ...memberships.map((membership) => membership.memberId),\n ...managerResolutions.map((resolution) => resolution.managerMemberId),\n ...managerResolutions\n .filter((resolution) => resolution.scopeType === 'MEMBER')\n .map((resolution) => resolution.scopeId),\n ]),\n ];\n}\n\nfunction readScopeLabel(\n resolution: ManagerResolutionRecord,\n lookup: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly orgUnitsById: ReadonlyMap<string, OrgUnitRecord>;\n readonly positionsById: ReadonlyMap<string, PositionRecord>;\n },\n): string {\n if (resolution.scopeType === 'MEMBER') {\n return `會員:${readMemberLabel(lookup.membersById.get(resolution.scopeId))}`;\n }\n\n if (resolution.scopeType === 'ORG_UNIT') {\n return `組織:${readOrgUnitLabel(lookup.orgUnitsById.get(resolution.scopeId))}`;\n }\n\n return `職位:${readPositionLabel(lookup.positionsById.get(resolution.scopeId))}`;\n}\n\nfunction readMemberLabel(member: MemberProfileRecord | undefined): string {\n return member ? `${member.name} · ${member.email}` : '未知會員';\n}\n\nfunction readOrgUnitLabel(orgUnit: OrgUnitRecord | undefined): string {\n return orgUnit ? `${orgUnit.name} · ${orgUnit.code}` : '未知組織';\n}\n\nfunction readOrgUnitTypeLabel(type: OrgUnitType): string {\n return (\n ORG_UNIT_TYPES.find(\n (option) => option.id.toLowerCase() === type.toLowerCase(),\n )?.name ?? '未知類型'\n );\n}\n\nfunction readPositionLabel(position: PositionRecord | undefined): string {\n return position ? `${position.name} · ${position.code}` : '未指定';\n}\n\nfunction readAdminOrgTab(value: unknown): AdminOrgTab {\n return value === 'MANAGERS' ||\n value === 'MEMBERSHIPS' ||\n value === 'POSITIONS'\n ? value\n : 'ORG_UNITS';\n}\n\nfunction readOrgUnitTypeOption(value: unknown): OrgUnitTypeOption {\n const record = isRecord(value) ? value : null;\n\n if (typeof record?.id === 'string') {\n const id = record.id;\n\n return (\n ORG_UNIT_TYPES.find(\n (option) => option.id.toLowerCase() === id.toLowerCase(),\n ) ?? ORG_UNIT_TYPES[2]\n );\n }\n\n return ORG_UNIT_TYPES[2];\n}\n\nfunction readOrgUnitTypeFilterOption(value: unknown): OrgUnitTypeFilterOption {\n const record = isRecord(value) ? value : null;\n\n if (typeof record?.id === 'string') {\n const id = record.id;\n\n return (\n ORG_UNIT_TYPE_FILTER_OPTIONS.find(\n (option) => option.id.toLowerCase() === id.toLowerCase(),\n ) ?? ALL_ORG_UNIT_TYPE_FILTER\n );\n }\n\n return ALL_ORG_UNIT_TYPE_FILTER;\n}\n\nfunction readScopeTypeOption(value: unknown): ScopeTypeOption {\n return readOption(value, SCOPE_TYPES, SCOPE_TYPES[0]);\n}\n\nfunction readScopeTypeFilterOption(value: unknown): ScopeTypeFilterOption {\n return readOption(value, SCOPE_TYPE_FILTER_OPTIONS, ALL_SCOPE_TYPE_FILTER);\n}\n\nfunction readActiveFilterOption(value: unknown): ActiveFilterOption {\n return readOption(value, ACTIVE_FILTER_OPTIONS, ALL_ACTIVE_FILTER);\n}\n\nfunction readNullableActiveFilterOption(\n value: unknown,\n): ActiveFilterOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n\n return ACTIVE_FILTER_OPTIONS.find((option) => option.id === id) ?? null;\n}\n\nfunction readOrgUnitOptionFromValue(value: unknown): OrgUnitOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n const name = typeof record?.name === 'string' ? record.name : null;\n\n return id && name ? { id, name } : null;\n}\n\nfunction readPositionOptionFromValue(value: unknown): PositionOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n const name = typeof record?.name === 'string' ? record.name : null;\n\n return id && name ? { id, name } : null;\n}\n\nfunction readPrimaryOption(value: unknown): PrimaryOption {\n return readOption(value, PRIMARY_OPTIONS, PRIMARY_OPTIONS[1]);\n}\n\nfunction readOption<TOption extends { readonly id: string }>(\n value: unknown,\n options: readonly TOption[],\n fallback: TOption,\n): TOption {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n\n return options.find((option) => option.id === id) ?? fallback;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readNullableOption<TValue, TOption>(\n value: TValue | null | undefined,\n mapper: (value: TValue) => TOption,\n): TOption | null {\n return value ? mapper(value) : null;\n}\n\nfunction today(): string {\n return formatDateParts(new Date());\n}\n\nfunction formatDateOnly(value: string | undefined): string {\n const date = value ? new Date(value) : null;\n\n return date && !Number.isNaN(date.getTime()) ? formatDateParts(date) : '';\n}\n\nfunction formatDateParts(date: Date): string {\n return `${date.getFullYear()}-${padDatePart(date.getMonth() + 1)}-${padDatePart(\n date.getDate(),\n )}`;\n}\n\nfunction padDatePart(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取組織資料失敗。';\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use client";const e=require("./app-navigation-KnlJCUp1.cjs"),t=require("./auth-provider-BV8Iiwfb.cjs"),n=require("./format-date-time-26_pFvv4.cjs"),r=require("./routes-config-2aKbWq2H.cjs"),i=require("./bpm-form-field-Bc6k4ZEO.cjs"),a=require("./categories-5yEM3p3N.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@rytass/bpm-core-client/workflow"),u=require("@mezzanine-ui/icons"),d=require("@mezzanine-ui/react/ContentHeader");d=e.o(d,1);let f=require("@mezzanine-ui/core/form"),p=require("@rytass/bpm-core-client/template");function m({confirmText:e,categoryOptions:t,initialName:n,loading:r,onClose:a,onSubmit:l,open:u,title:d}){let[f,p]=(0,o.useState)(n),[m,v]=(0,o.useState)(t[0]??g),[y,b]=(0,o.useState)(null),x=f.trim();(0,o.useEffect)(()=>{u&&(p(n),v(t[0]??g),b(null))},[t,n,u]);async function S(){if(!x){b(`請輸入模板名稱`);return}try{await l({categoryId:m.categoryId,name:x})}catch(e){b(h(e))}}return(0,c.jsxs)(s.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!x},confirmText:e,loading:r,modalType:`standard`,onCancel:a,onClose:a,onConfirm:()=>void S(),open:u,showModalFooter:!0,showModalHeader:!0,size:`narrow`,title:d,children:[(0,c.jsx)(i.t,{label:`模板名稱`,name:`templateName`,required:!0,children:(0,c.jsx)(s.Input,{autoFocus:!0,fullWidth:!0,onChange:e=>{p(e.target.value),b(null)},placeholder:`例如:費用申請流程`,value:f,variant:`base`})}),(0,c.jsx)(i.t,{label:`分類`,name:`templateCategory`,children:(0,c.jsx)(s.Select,{clearable:!1,fullWidth:!0,onChange:e=>{v(_(e,t)),b(null)},options:[...t],placeholder:`選擇分類`,value:m})}),y?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:y}):null]})}function h(e){return e instanceof Error?e.message:`發生未知錯誤`}var g={categoryId:null,id:`UNCATEGORIZED`,name:`未分類`};function _(e,t){if(!v(e))return g;let n=typeof e.id==`string`?e.id:null;return t.find(e=>e.id===n)??g}function v(e){return typeof e==`object`&&!!e}var y=[10,20,50],b=[{key:`ALL`,label:`全部`},{key:`PUBLISHED`,label:`已發布`},{key:`DRAFT`,label:`草稿`}],x=100;function S({activeHref:i}={}){let h=t.a(),_=r.r(),v=i??_.templates(),[S,j]=(0,o.useState)([]),[M,N]=(0,o.useState)(E),[P,F]=(0,o.useState)([]),[I,L]=(0,o.useState)(new Set),[R,z]=(0,o.useState)(!1),[B,V]=(0,o.useState)(!1),[H,U]=(0,o.useState)(null),[W,G]=(0,o.useState)(!0),[K,q]=(0,o.useState)(1),[J,Y]=(0,o.useState)(10),[X,Z]=(0,o.useState)(``),[Q,te]=(0,o.useState)(`ALL`),[ne,re]=(0,o.useState)(0),$=(0,o.useCallback)(async()=>{G(!0),U(null);try{let[e,t,n]=await Promise.all([(0,p.listApprovalTemplatesPage)({categoryId:M.categoryId,page:K,pageSize:J,searchText:X,status:Q===`ALL`?null:Q}),(0,l.listLaunchableTemplates)(),(0,p.listApprovalTemplateCategoriesPage)({page:1,pageSize:x,searchText:``,status:`ACTIVE`})]);F([...n.categories.map(D)]),j(e.templates),re(e.totalCount),L(new Set(t.map(e=>e.id)))}catch(e){U(C(e))}finally{G(!1)}},[M,K,J,X,Q]);(0,o.useEffect)(()=>{$()},[$]);let ie=(0,o.useMemo)(()=>S.map(e=>({...e,categoryLabel:A(e),key:e.id,status:e.currentVersionId?`PUBLISHED`:`DRAFT`,updatedAt:n.t(e.updatedAt)})),[S]),ae=(0,o.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`模板名稱`,width:220},{key:`status`,render:e=>(0,c.jsx)(w,{status:e.status}),title:`狀態`,width:120},{key:`category`,render:e=>(0,c.jsx)(T,{record:e}),title:`分類`,width:160},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:220}],[]),oe=(0,o.useMemo)(()=>({render:e=>[{disabled:e=>!I.has(e.id),name:`發起`,onClick:()=>h.push(_.caseNew(e.id)),variant:`base-primary`},{name:`設計`,onClick:()=>h.push(_.templateDesigner(e.id))},{name:`版本`,onClick:()=>h.push(_.templateVersions(e.id))}],variant:`base-secondary`,width:192}),[I,h]);async function se({categoryId:e,name:t}){V(!0),U(null);try{let n=await(0,p.createApprovalTemplate)({categoryId:e,name:t});z(!1),h.push(_.templateDesigner(n))}finally{V(!1)}}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsxs)(e.t,{activeHref:v,children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(d.default,{description:`建立流程模板、維護草稿與發布版本。`,title:`簽核模板`,children:(0,c.jsx)(s.Button,{disabled:B,icon:u.PlusIcon,iconType:`leading`,onClick:()=>z(!0),variant:`base-primary`,children:`建立模板`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{filterArea:(0,c.jsx)(s.FilterArea,{className:a.n.templateFilterArea,size:`sub`,children:(0,c.jsxs)(s.FilterLine,{children:[(0,c.jsx)(s.Filter,{span:3,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:f.FormFieldLayout.VERTICAL,name:`templateSearchText`,children:(0,c.jsx)(s.Input,{fullWidth:!0,onChange:e=>{Z(e.target.value),q(1)},placeholder:`關鍵字:搜尋模板名稱、分類或描述`,size:`sub`,value:X,variant:`base`})})}),(0,c.jsx)(s.Filter,{span:2,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:f.FormFieldLayout.VERTICAL,name:`templateCategoryFilter`,children:(0,c.jsx)(s.Select,{clearable:!1,fullWidth:!0,onChange:e=>{N(O(e,P)),q(1)},options:[E,...P],placeholder:`分類`,renderValue:e=>`分類:${k(e)}`,size:`sub`,value:M})})})]})}),tab:(0,c.jsx)(s.Tab,{activeKey:Q,onChange:e=>{te(ee(e)),q(1)},children:b.map(e=>(0,c.jsx)(s.TabItem,{children:e.label},e.key))}),children:[H?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:H}):null,(0,c.jsx)(s.Table,{actions:oe,columns:ae,dataSource:ie,fullWidth:!0,loading:W,pagination:{current:K,onChange:e=>{q(e)},onChangePageSize:e=>{q(1),Y(e)},pageSize:J,pageSizeLabel:`每頁筆數`,pageSizeOptions:y,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:ne}})]})})]}),(0,c.jsx)(m,{categoryOptions:[g,...P],confirmText:`建立`,initialName:``,loading:B,onClose:()=>z(!1),onSubmit:se,open:R,title:`建立簽核模板`})]})}function C(e){return e instanceof Error?e.message:`發生未知錯誤`}function ee(e){return e===`PUBLISHED`||e===`DRAFT`?e:`ALL`}function w({status:e}){return e===`PUBLISHED`?(0,c.jsx)(s.Badge,{size:`sub`,text:`已發布`,variant:`dot-success`}):(0,c.jsx)(s.Badge,{size:`sub`,text:`草稿`,variant:`dot-inactive`})}function T({record:e}){return e.categoryDetail?.isActive===!1?(0,c.jsx)(s.Badge,{size:`sub`,text:`${e.categoryLabel}(停用)`,variant:`dot-inactive`}):(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.categoryLabel})}var E={categoryId:null,id:`ALL_CATEGORIES`,name:`全部分類`};function D(e){return{categoryId:e.id,id:e.id,name:e.name}}function O(e,t){if(!j(e))return E;let n=typeof e.id==`string`?e.id:null;return n===E.id?E:t.find(e=>e.id===n)??E}function k(e){return Array.isArray(e)||!j(e)?E.name:typeof e.name==`string`?e.name:E.name}function A(e){return e.categoryDetail?.name??e.category??`未分類`}function j(e){return typeof e==`object`&&!!e}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return S}});
|
|
2
|
-
//# sourceMappingURL=templates-DTkbSgFY.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"templates-DTkbSgFY.cjs","names":[],"sources":["../../src/views/templates/template-name-modal.tsx","../../src/views/templates/TemplatesView.tsx"],"sourcesContent":["'use client';\n\nimport { ChangeEvent, ReactElement, useEffect, useState } from 'react';\nimport { Input, Modal, Select, Typography } from '@mezzanine-ui/react';\nimport { BPMFormField } from '../../components/bpm-form-field';\n\nexport interface TemplateCategoryOption {\n readonly categoryId: string | null;\n readonly id: string;\n readonly name: string;\n}\n\ninterface TemplateNameModalProps {\n readonly confirmText: string;\n readonly categoryOptions: readonly TemplateCategoryOption[];\n readonly initialName: string;\n readonly loading: boolean;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly categoryId: string | null;\n readonly name: string;\n }) => Promise<void>;\n readonly open: boolean;\n readonly title: string;\n}\n\nexport function TemplateNameModal({\n confirmText,\n categoryOptions,\n initialName,\n loading,\n onClose,\n onSubmit,\n open,\n title,\n}: TemplateNameModalProps): ReactElement {\n const [name, setName] = useState(initialName);\n const [category, setCategory] = useState<TemplateCategoryOption>(\n categoryOptions[0] ?? UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n );\n const [error, setError] = useState<string | null>(null);\n const trimmedName = name.trim();\n\n useEffect((): void => {\n if (!open) {\n return;\n }\n\n setName(initialName);\n setCategory(categoryOptions[0] ?? UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION);\n setError(null);\n }, [categoryOptions, initialName, open]);\n\n async function handleConfirm(): Promise<void> {\n if (!trimmedName) {\n setError('請輸入模板名稱');\n return;\n }\n\n try {\n await onSubmit({ categoryId: category.categoryId, name: trimmedName });\n } catch (submitError: unknown) {\n setError(readErrorMessage(submitError));\n }\n }\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !trimmedName }}\n confirmText={confirmText}\n loading={loading}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void => void handleConfirm()}\n open={open}\n showModalFooter\n showModalHeader\n size=\"narrow\"\n title={title}\n >\n <BPMFormField label=\"模板名稱\" name=\"templateName\" required>\n <Input\n autoFocus\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void => {\n setName(event.target.value);\n setError(null);\n }}\n placeholder=\"例如:費用申請流程\"\n value={name}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"分類\" name=\"templateCategory\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategory(readCategoryOption(option, categoryOptions));\n setError(null);\n }}\n options={[...categoryOptions]}\n placeholder=\"選擇分類\"\n value={category}\n />\n </BPMFormField>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n </Modal>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nexport const UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'UNCATEGORIZED',\n name: '未分類',\n};\n\nfunction readCategoryOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION\n );\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n","'use client';\n\nimport type { ChangeEvent, Key, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport styles from './templates.module.scss';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { AppLayout } from '../../components/app-navigation';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\nimport {\n TemplateCategoryOption,\n TemplateNameModal,\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n} from './template-name-modal';\nimport {\n ApprovalTemplateListStatus,\n ApprovalTemplateRecord,\n ApprovalTemplateCategoryRecord,\n createApprovalTemplate,\n listApprovalTemplateCategoriesPage,\n listApprovalTemplatesPage,\n} from '@rytass/bpm-core-client/template';\nimport { listLaunchableTemplates } from '@rytass/bpm-core-client/workflow';\n\nconst TEMPLATE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst TEMPLATE_STATUS_TABS: readonly {\n readonly key: TemplateStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'PUBLISHED', label: '已發布' },\n { key: 'DRAFT', label: '草稿' },\n];\n\nconst TEMPLATE_CATEGORY_PAGE_SIZE = 100;\n\ntype TemplateStatusTabKey = 'ALL' | ApprovalTemplateListStatus;\n\ntype TemplateRow = Readonly<\n Record<string, unknown> &\n ApprovalTemplateRecord & {\n categoryLabel: string;\n key: string;\n status: ApprovalTemplateListStatus;\n }\n>;\n\nexport interface TemplatesViewProps {\n readonly activeHref?: string;\n}\n\nexport function TemplatesView({\n activeHref,\n}: TemplatesViewProps = {}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const resolvedActiveHref = activeHref ?? routes.templates();\n const [templates, setTemplates] = useState<readonly ApprovalTemplateRecord[]>(\n [],\n );\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategoryOption>(\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n );\n const [categoryOptions, setCategoryOptions] = useState<\n readonly TemplateCategoryOption[]\n >([]);\n const [launchableTemplateIds, setLaunchableTemplateIds] = useState<\n ReadonlySet<string>\n >(new Set());\n const [createModalOpen, setCreateModalOpen] = useState(false);\n const [creating, setCreating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [templatePage, setTemplatePage] = useState(1);\n const [templatePageSize, setTemplatePageSize] = useState(10);\n const [templateSearchText, setTemplateSearchText] = useState('');\n const [templateStatus, setTemplateStatus] =\n useState<TemplateStatusTabKey>('ALL');\n const [templateTotalCount, setTemplateTotalCount] = useState(0);\n\n const refreshTemplates = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const [\n templatePageResult,\n nextLaunchableTemplates,\n activeCategoryPageResult,\n ] = await Promise.all([\n listApprovalTemplatesPage({\n categoryId: categoryFilter.categoryId,\n page: templatePage,\n pageSize: templatePageSize,\n searchText: templateSearchText,\n status: templateStatus === 'ALL' ? null : templateStatus,\n }),\n listLaunchableTemplates(),\n listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: TEMPLATE_CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n }),\n ]);\n\n setCategoryOptions([\n ...activeCategoryPageResult.categories.map(readCategoryOption),\n ]);\n setTemplates(templatePageResult.templates);\n setTemplateTotalCount(templatePageResult.totalCount);\n setLaunchableTemplateIds(\n new Set(nextLaunchableTemplates.map((template) => template.id)),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [\n categoryFilter,\n templatePage,\n templatePageSize,\n templateSearchText,\n templateStatus,\n ]);\n\n useEffect((): void => {\n void refreshTemplates();\n }, [refreshTemplates]);\n\n const rows = useMemo(\n (): TemplateRow[] =>\n templates.map((template) => ({\n ...template,\n categoryLabel: readTemplateCategoryLabel(template),\n key: template.id,\n status: template.currentVersionId ? 'PUBLISHED' : 'DRAFT',\n updatedAt: formatDateTime(template.updatedAt),\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<TemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 220 },\n {\n key: 'status',\n render: (record: TemplateRow): ReactElement => (\n <TemplateStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'category',\n render: (record: TemplateRow): ReactElement => (\n <TemplateCategoryLabel record={record} />\n ),\n title: '分類',\n width: 160,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<TemplateRow> => ({\n render: (record): ReturnType<TableActions<TemplateRow>['render']> => [\n {\n disabled: (template): boolean =>\n !launchableTemplateIds.has(template.id),\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n {\n name: '設計',\n onClick: (): void => router.push(routes.templateDesigner(record.id)),\n },\n {\n name: '版本',\n onClick: (): void => router.push(routes.templateVersions(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 192,\n }),\n [launchableTemplateIds, router],\n );\n\n async function handleCreateTemplate({\n categoryId,\n name,\n }: {\n readonly categoryId: string | null;\n readonly name: string;\n }): Promise<void> {\n setCreating(true);\n setError(null);\n\n try {\n const templateId = await createApprovalTemplate({ categoryId, name });\n setCreateModalOpen(false);\n router.push(routes.templateDesigner(templateId));\n } finally {\n setCreating(false);\n }\n }\n\n return (\n <>\n <AppLayout activeHref={resolvedActiveHref}>\n <PageHeader>\n <ContentHeader\n description=\"建立流程模板、維護草稿與發布版本。\"\n title=\"簽核模板\"\n >\n <Button\n disabled={creating}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setCreateModalOpen(true)}\n variant=\"base-primary\"\n >\n 建立模板\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.templateFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setTemplateSearchText(event.target.value);\n setTemplatePage(1);\n }}\n placeholder=\"關鍵字:搜尋模板名稱、分類或描述\"\n size=\"sub\"\n value={templateSearchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateCategoryFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategoryFilter(\n readCategoryFilterOption(option, categoryOptions),\n );\n setTemplatePage(1);\n }}\n options={[\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n ...categoryOptions,\n ]}\n placeholder=\"分類\"\n renderValue={(value): string =>\n `分類:${readTemplateCategoryFilterLabel(value)}`\n }\n size=\"sub\"\n value={categoryFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={templateStatus}\n onChange={(activeKey): void => {\n setTemplateStatus(readTemplateStatusTabKey(activeKey));\n setTemplatePage(1);\n }}\n >\n {TEMPLATE_STATUS_TABS.map((statusTab) => (\n <TabItem key={statusTab.key}>{statusTab.label}</TabItem>\n ))}\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n pagination={{\n current: templatePage,\n onChange: (page): void => {\n setTemplatePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setTemplatePage(1);\n setTemplatePageSize(pageSize);\n },\n pageSize: templatePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: TEMPLATE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: templateTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </AppLayout>\n\n <TemplateNameModal\n categoryOptions={[\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n ...categoryOptions,\n ]}\n confirmText=\"建立\"\n initialName=\"\"\n loading={creating}\n onClose={(): void => setCreateModalOpen(false)}\n onSubmit={handleCreateTemplate}\n open={createModalOpen}\n title=\"建立簽核模板\"\n />\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nfunction readTemplateStatusTabKey(activeKey: Key): TemplateStatusTabKey {\n if (activeKey === 'PUBLISHED' || activeKey === 'DRAFT') {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction TemplateStatusBadge({\n status,\n}: {\n readonly status: ApprovalTemplateListStatus;\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateCategoryLabel({\n record,\n}: {\n readonly record: TemplateRow;\n}): ReactElement {\n if (record.categoryDetail?.isActive === false) {\n return (\n <Badge\n size=\"sub\"\n text={`${record.categoryLabel}(停用)`}\n variant=\"dot-inactive\"\n />\n );\n }\n\n return (\n <Typography component=\"span\" variant=\"body\">\n {record.categoryLabel}\n </Typography>\n );\n}\n\nconst UNCATEGORIZED_TEMPLATE_FILTER_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'ALL_CATEGORIES',\n name: '全部分類',\n};\n\nfunction readCategoryOption(\n category: ApprovalTemplateCategoryRecord,\n): TemplateCategoryOption {\n return {\n categoryId: category.id,\n id: category.id,\n name: category.name,\n };\n}\n\nfunction readCategoryFilterOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n if (id === UNCATEGORIZED_TEMPLATE_FILTER_OPTION.id) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION\n );\n}\n\nfunction readTemplateCategoryFilterLabel(value: unknown): string {\n if (Array.isArray(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n return typeof value.name === 'string'\n ? value.name\n : UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n}\n\nfunction readTemplateCategoryLabel(template: ApprovalTemplateRecord): string {\n return template.categoryDetail?.name ?? template.category ?? '未分類';\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":"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"}
|