@rytass/bpm-core-react 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +54 -6
- package/dist/chunks/{FormBuilderView-CLg-JYmu.js → FormBuilderView-BYL42M0d.js} +13 -33
- package/dist/chunks/FormBuilderView-BYL42M0d.js.map +1 -0
- package/dist/chunks/FormBuilderView-aBcA-_tt.cjs +3 -0
- package/dist/chunks/FormBuilderView-aBcA-_tt.cjs.map +1 -0
- package/dist/chunks/FormRendererView-DRFi_IH7.cjs +4 -0
- package/dist/chunks/FormRendererView-DRFi_IH7.cjs.map +1 -0
- package/dist/chunks/{FormRendererView-DU9LLrOF.js → FormRendererView-cZGOOjU5.js} +319 -332
- package/dist/chunks/FormRendererView-cZGOOjU5.js.map +1 -0
- package/dist/chunks/{admin-pickers-DLlG_1du.js → admin-pickers-DxhzECkD.js} +52 -51
- package/dist/chunks/admin-pickers-DxhzECkD.js.map +1 -0
- package/dist/chunks/admin-pickers-qe3j--gX.cjs +2 -0
- package/dist/chunks/admin-pickers-qe3j--gX.cjs.map +1 -0
- package/dist/chunks/approval-instance-list-page-CPXMP3PL.js.map +1 -1
- package/dist/chunks/approval-instance-list-page-ax0pm8bt.cjs.map +1 -1
- package/dist/chunks/auth-provider-4BeCw7cI.cjs.map +1 -1
- package/dist/chunks/auth-provider-B5oPmvk2.js.map +1 -1
- package/dist/chunks/bpm-form-field-Bc6k4ZEO.cjs.map +1 -1
- package/dist/chunks/bpm-form-field-Cao0rMol.js.map +1 -1
- package/dist/chunks/{categories-DGlxuC6X.js → categories-1gKxeEqw.js} +4 -10
- package/dist/chunks/categories-1gKxeEqw.js.map +1 -0
- package/dist/chunks/{categories-Yid05WAX.cjs → categories-DjENouRm.cjs} +2 -2
- package/dist/chunks/categories-DjENouRm.cjs.map +1 -0
- package/dist/chunks/{compose-BtQPBd1Q.js → compose-Crklayzy.js} +4 -4
- package/dist/chunks/compose-Crklayzy.js.map +1 -0
- package/dist/chunks/{compose-DZhTQOt4.cjs → compose-DZ7RKvUp.cjs} +2 -2
- package/dist/chunks/compose-DZ7RKvUp.cjs.map +1 -0
- package/dist/chunks/dashboard-page-BWQBSGDq.cjs +2 -0
- package/dist/chunks/dashboard-page-BWQBSGDq.cjs.map +1 -0
- package/dist/chunks/{dashboard-page-CeCLV1tp.js → dashboard-page-DdBvV6YI.js} +15 -16
- package/dist/chunks/dashboard-page-DdBvV6YI.js.map +1 -0
- package/dist/chunks/delegations-Ckf03icM.cjs +2 -0
- package/dist/chunks/delegations-Ckf03icM.cjs.map +1 -0
- package/dist/chunks/{delegations-DRupxJ4_.js → delegations-MxF3uJGW.js} +205 -215
- package/dist/chunks/delegations-MxF3uJGW.js.map +1 -0
- package/dist/chunks/delegations-V9HIe3_P.cjs +2 -0
- package/dist/chunks/delegations-V9HIe3_P.cjs.map +1 -0
- package/dist/chunks/{delegations-B8gLSt0i.js → delegations-xUt1tj8d.js} +168 -173
- package/dist/chunks/delegations-xUt1tj8d.js.map +1 -0
- package/dist/chunks/{designer-CrbBRPUU.js → designer-D9eFma1W.js} +1180 -1134
- package/dist/chunks/designer-D9eFma1W.js.map +1 -0
- package/dist/chunks/designer-sJGTGYOf.cjs +65 -0
- package/dist/chunks/designer-sJGTGYOf.cjs.map +1 -0
- package/dist/chunks/detail-DRCTnuKm.cjs +2 -0
- package/dist/chunks/detail-DRCTnuKm.cjs.map +1 -0
- package/dist/chunks/{detail-_c21WQla.js → detail-DScLf42P.js} +849 -836
- package/dist/chunks/detail-DScLf42P.js.map +1 -0
- package/dist/chunks/format-date-time-CB-LxzqT.js.map +1 -1
- package/dist/chunks/format-date-time-D-cx5M8z.cjs.map +1 -1
- package/dist/chunks/format-member-label-DudVI55w.js +13 -0
- package/dist/chunks/format-member-label-DudVI55w.js.map +1 -0
- package/dist/chunks/format-member-label-t7ANTF62.cjs +2 -0
- package/dist/chunks/format-member-label-t7ANTF62.cjs.map +1 -0
- package/dist/chunks/login-AtVxZBsC.cjs.map +1 -1
- package/dist/chunks/login-C6qlTC6F.js.map +1 -1
- package/dist/chunks/notifications-Bc4mgSds.cjs.map +1 -1
- package/dist/chunks/notifications-DJ5wzCye.js.map +1 -1
- package/dist/chunks/{orgs-BpqVu5ka.js → orgs-CY0i1fie.js} +787 -766
- package/dist/chunks/orgs-CY0i1fie.js.map +1 -0
- package/dist/chunks/orgs-Dr0FFoZo.cjs +2 -0
- package/dist/chunks/orgs-Dr0FFoZo.cjs.map +1 -0
- package/dist/chunks/providers-DHtDZFNA.cjs.map +1 -1
- package/dist/chunks/providers-J5eyByQj.js.map +1 -1
- package/dist/chunks/router-adapter--gYs13E8.cjs.map +1 -1
- package/dist/chunks/router-adapter-DftlFTOd.js.map +1 -1
- package/dist/chunks/routes-config-C1j_vFKo.cjs.map +1 -1
- package/dist/chunks/routes-config-yZbESPlw.js.map +1 -1
- package/dist/chunks/task-node-label-BF6UllxP.cjs.map +1 -1
- package/dist/chunks/task-node-label-CWZgOBj0.js.map +1 -1
- package/dist/chunks/use-bpm-member-D57LKe_u.js.map +1 -1
- package/dist/chunks/use-bpm-member-DpNAQtNC.cjs.map +1 -1
- package/dist/chunks/users-BCyePbwB.js +422 -0
- package/dist/chunks/users-BCyePbwB.js.map +1 -0
- package/dist/chunks/users-DVBJluFR.cjs +2 -0
- package/dist/chunks/users-DVBJluFR.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/format-member-label.d.ts +12 -0
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js.map +1 -1
- package/dist/next/workflow-chat-route.cjs.map +1 -1
- package/dist/next/workflow-chat-route.js.map +1 -1
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.cjs.map +1 -1
- package/dist/pages/admin/delegations/index.js +1 -1
- package/dist/pages/admin/delegations/index.js.map +1 -1
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.cjs.map +1 -1
- package/dist/pages/admin/orgs/index.js +1 -1
- package/dist/pages/admin/orgs/index.js.map +1 -1
- package/dist/pages/admin/users/index.cjs +1 -1
- package/dist/pages/admin/users/index.cjs.map +1 -1
- package/dist/pages/admin/users/index.js +1 -1
- package/dist/pages/admin/users/index.js.map +1 -1
- package/dist/pages/admin/webhook-endpoints/index.cjs.map +1 -1
- package/dist/pages/admin/webhook-endpoints/index.js.map +1 -1
- package/dist/pages/cc/index.cjs.map +1 -1
- package/dist/pages/cc/index.js.map +1 -1
- package/dist/pages/dashboard/index.cjs.map +1 -1
- package/dist/pages/dashboard/index.js.map +1 -1
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.cjs.map +1 -1
- package/dist/pages/delegations/index.js +1 -1
- package/dist/pages/delegations/index.js.map +1 -1
- package/dist/pages/inbox/index.cjs.map +1 -1
- package/dist/pages/inbox/index.js.map +1 -1
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.cjs.map +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/instances/detail/index.js.map +1 -1
- package/dist/pages/instances/new/index.cjs.map +1 -1
- package/dist/pages/instances/new/index.js.map +1 -1
- package/dist/pages/login/index.cjs.map +1 -1
- package/dist/pages/login/index.js.map +1 -1
- package/dist/pages/root/index.cjs.map +1 -1
- package/dist/pages/root/index.js.map +1 -1
- package/dist/pages/search/index.cjs.map +1 -1
- package/dist/pages/search/index.js.map +1 -1
- package/dist/pages/sent/index.cjs.map +1 -1
- package/dist/pages/sent/index.js.map +1 -1
- package/dist/pages/settings/notifications/index.cjs.map +1 -1
- package/dist/pages/settings/notifications/index.js.map +1 -1
- package/dist/pages/templates/categories/index.cjs +1 -1
- package/dist/pages/templates/categories/index.cjs.map +1 -1
- package/dist/pages/templates/categories/index.js +1 -1
- package/dist/pages/templates/categories/index.js.map +1 -1
- package/dist/pages/templates/compose/index.cjs +1 -1
- package/dist/pages/templates/compose/index.cjs.map +1 -1
- package/dist/pages/templates/compose/index.js +1 -1
- package/dist/pages/templates/compose/index.js.map +1 -1
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.cjs.map +1 -1
- package/dist/pages/templates/designer/index.js +1 -1
- package/dist/pages/templates/designer/index.js.map +1 -1
- package/dist/pages/templates/index.cjs.map +1 -1
- package/dist/pages/templates/index.js.map +1 -1
- package/dist/pages/templates/versions/index.cjs.map +1 -1
- package/dist/pages/templates/versions/index.js.map +1 -1
- package/dist/views/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -2
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +3 -3
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -2
- package/dist/views/admin/users/MemberTaskReassignModal.d.ts +13 -0
- package/dist/views/admin/users/index.cjs +1 -1
- package/dist/views/admin/users/index.js +1 -2
- package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
- package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
- package/dist/views/cc/index.cjs.map +1 -1
- package/dist/views/cc/index.js.map +1 -1
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.cjs.map +1 -1
- package/dist/views/dashboard/index.js +1 -1
- package/dist/views/dashboard/index.js.map +1 -1
- package/dist/views/delegations/index.cjs +1 -1
- package/dist/views/delegations/index.js +1 -2
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -2
- package/dist/views/forms/renderer/index.cjs +1 -1
- package/dist/views/forms/renderer/index.js +1 -2
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.cjs.map +1 -1
- package/dist/views/inbox/index.js +1 -5
- 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 -2
- package/dist/views/instances/index.js +1 -2
- 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 +4 -11
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/login/index.js +1 -2
- package/dist/views/search/index.cjs.map +1 -1
- package/dist/views/search/index.js.map +1 -1
- package/dist/views/sent/index.cjs.map +1 -1
- package/dist/views/sent/index.js.map +1 -1
- package/dist/views/settings/index.js +1 -2
- package/dist/views/settings/notifications/index.js +1 -2
- package/dist/views/templates/categories/index.cjs +1 -1
- package/dist/views/templates/categories/index.js +1 -2
- package/dist/views/templates/compose/index.cjs +1 -1
- package/dist/views/templates/compose/index.js +1 -2
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -2
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.cjs.map +1 -1
- package/dist/views/templates/index.js +1 -1
- package/dist/views/templates/index.js.map +1 -1
- package/dist/views/templates/versions/index.cjs.map +1 -1
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunks/FormBuilderView-6bCbIkz6.cjs +0 -3
- package/dist/chunks/FormBuilderView-6bCbIkz6.cjs.map +0 -1
- package/dist/chunks/FormBuilderView-CLg-JYmu.js.map +0 -1
- package/dist/chunks/FormRendererView-DU9LLrOF.js.map +0 -1
- package/dist/chunks/FormRendererView-gctFIqwC.cjs +0 -4
- package/dist/chunks/FormRendererView-gctFIqwC.cjs.map +0 -1
- package/dist/chunks/admin-pickers-Btvij1at.cjs +0 -2
- package/dist/chunks/admin-pickers-Btvij1at.cjs.map +0 -1
- package/dist/chunks/admin-pickers-DLlG_1du.js.map +0 -1
- package/dist/chunks/categories-DGlxuC6X.js.map +0 -1
- package/dist/chunks/categories-Yid05WAX.cjs.map +0 -1
- package/dist/chunks/compose-BtQPBd1Q.js.map +0 -1
- package/dist/chunks/compose-DZhTQOt4.cjs.map +0 -1
- package/dist/chunks/dashboard-page-CeCLV1tp.js.map +0 -1
- package/dist/chunks/dashboard-page-DooFJsxM.cjs +0 -2
- package/dist/chunks/dashboard-page-DooFJsxM.cjs.map +0 -1
- package/dist/chunks/delegations-8LsxcQM4.cjs +0 -2
- package/dist/chunks/delegations-8LsxcQM4.cjs.map +0 -1
- package/dist/chunks/delegations-B8gLSt0i.js.map +0 -1
- package/dist/chunks/delegations-DRupxJ4_.js.map +0 -1
- package/dist/chunks/delegations-DlYwMiAW.cjs +0 -2
- package/dist/chunks/delegations-DlYwMiAW.cjs.map +0 -1
- package/dist/chunks/designer-CrbBRPUU.js.map +0 -1
- package/dist/chunks/designer-D3_lWmfa.cjs +0 -65
- package/dist/chunks/designer-D3_lWmfa.cjs.map +0 -1
- package/dist/chunks/detail-CVXb5Vy8.cjs +0 -2
- package/dist/chunks/detail-CVXb5Vy8.cjs.map +0 -1
- package/dist/chunks/detail-_c21WQla.js.map +0 -1
- package/dist/chunks/orgs-BpqVu5ka.js.map +0 -1
- package/dist/chunks/orgs-D0-5BaHT.cjs +0 -2
- package/dist/chunks/orgs-D0-5BaHT.cjs.map +0 -1
- package/dist/chunks/users-C9LA-Rd7.cjs +0 -2
- package/dist/chunks/users-C9LA-Rd7.cjs.map +0 -1
- package/dist/chunks/users-FWrb3ehW.js +0 -214
- package/dist/chunks/users-FWrb3ehW.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/views/admin/webhook-endpoints/AdminWebhookEndpointsView.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon, TrashIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { NotifyWebhookParameterType } from '@rytass/bpm-core-shared/workflow';\nimport {\n WorkflowWebhookEndpointAuditRecord,\n WorkflowWebhookEndpointManagementRecord,\n WorkflowWebhookEndpointTestResultRecord,\n WorkflowWebhookManagedEndpointRecord,\n createWorkflowWebhookEndpoint,\n listWorkflowWebhookEndpointAudits,\n listWorkflowWebhookManagedEndpoints,\n readWorkflowWebhookEndpointManagement,\n rotateWorkflowWebhookEndpointSecret,\n setWorkflowWebhookEndpointActive,\n testWorkflowWebhookEndpoint,\n updateWorkflowWebhookEndpoint,\n} from '@rytass/bpm-core-client/template';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype SelectOption = Readonly<{ id: string; name: string }>;\n\ntype EndpointRow = Readonly<\n Record<string, unknown> & {\n endpoint: WorkflowWebhookManagedEndpointRecord;\n key: string;\n }\n>;\n\ntype AuditRow = Readonly<\n Record<string, unknown> & {\n audit: WorkflowWebhookEndpointAuditRecord;\n key: string;\n }\n>;\n\ntype ParameterDraft = Readonly<{\n description: string;\n key: string;\n label: string;\n required: boolean;\n type: NotifyWebhookParameterType;\n}>;\n\ntype HeaderDraft = Readonly<{ name: string; value: string }>;\n\n/**\n * `mode` decides what can change: a new endpoint (or a new version of one)\n * sets everything; editing keeps the parameter contract and only replaces\n * headers when asked to.\n */\ntype EndpointDraft = Readonly<{\n deprecated: boolean;\n description: string;\n endpointId: string | null;\n headers: readonly HeaderDraft[];\n key: string;\n label: string;\n method: string;\n mode: 'create' | 'edit' | 'version';\n /** The stored URL when editing, to spot a move to another host. */\n originalUrl: string;\n parameters: readonly ParameterDraft[];\n replaceHeaders: boolean;\n signingSecret: string;\n timeoutMs: string;\n url: string;\n version: string;\n}>;\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n};\n\nconst ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto',\n};\n\nconst HEADER_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 2fr) auto',\n};\n\nconst METHOD_OPTIONS: readonly SelectOption[] = [\n { id: 'POST', name: 'POST' },\n { id: 'PUT', name: 'PUT' },\n { id: 'PATCH', name: 'PATCH' },\n];\n\nconst PARAMETER_TYPE_OPTIONS: readonly SelectOption[] = [\n { id: 'string', name: '文字' },\n { id: 'number', name: '數字' },\n { id: 'boolean', name: '是/否' },\n { id: 'stringArray', name: '文字清單' },\n { id: 'json', name: 'JSON' },\n];\n\nconst AUDIT_ACTION_LABELS: Readonly<\n Record<WorkflowWebhookEndpointAuditRecord['action'], string>\n> = {\n CREATED: '建立',\n DISABLED: '停用',\n ENABLED: '啟用',\n SECRET_ROTATED: '輪替金鑰',\n TEST_SENT: '測試送出',\n UPDATED: '更新',\n};\n\nconst EMPTY_DRAFT: EndpointDraft = {\n deprecated: false,\n description: '',\n endpointId: null,\n headers: [],\n key: '',\n label: '',\n method: 'POST',\n mode: 'create',\n originalUrl: '',\n parameters: [],\n replaceHeaders: true,\n signingSecret: '',\n timeoutMs: '',\n url: '',\n version: '1',\n};\n\n/**\n * Back-office management of database webhook endpoints (ADR 18 §3.13):\n * create, edit, disable, rotate the signing secret, test-send and read the\n * change history. Header values and secrets are entered here and never shown\n * again. Administrator-only on the server.\n */\nexport function AdminWebhookEndpointsView(): ReactElement {\n const [management, setManagement] =\n useState<WorkflowWebhookEndpointManagementRecord | null>(null);\n const [endpoints, setEndpoints] = useState<\n readonly WorkflowWebhookManagedEndpointRecord[]\n >([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n const [draft, setDraft] = useState<EndpointDraft | null>(null);\n const [saving, setSaving] = useState(false);\n const [rotating, setRotating] =\n useState<WorkflowWebhookManagedEndpointRecord | null>(null);\n const [nextSecret, setNextSecret] = useState('');\n const [removeSecret, setRemoveSecret] = useState(false);\n const [audits, setAudits] = useState<{\n readonly endpoint: WorkflowWebhookManagedEndpointRecord;\n readonly records: readonly WorkflowWebhookEndpointAuditRecord[];\n } | null>(null);\n\n const refresh = useCallback(async (): Promise<void> => {\n setLoading(true);\n\n try {\n const nextManagement = await readWorkflowWebhookEndpointManagement();\n\n setManagement(nextManagement);\n setEndpoints(\n nextManagement.enabled\n ? await listWorkflowWebhookManagedEndpoints()\n : [],\n );\n setError(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect((): void => {\n void refresh();\n }, [refresh]);\n\n const run = useCallback(\n async (work: () => Promise<string | null>): Promise<boolean> => {\n setError(null);\n setNotice(null);\n\n try {\n setNotice(await work());\n await refresh();\n\n return true;\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n\n return false;\n }\n },\n [refresh],\n );\n\n const rows = useMemo(\n (): EndpointRow[] =>\n endpoints.map((endpoint) => ({ endpoint, key: endpoint.id })),\n [endpoints],\n );\n\n const columns = useMemo(\n (): TableColumn<EndpointRow>[] => [\n {\n key: 'label',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.label}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.key}@{endpoint.version} · 參數{' '}\n {endpoint.parameters.length} 個\n </Typography>\n </div>\n ),\n title: '端點',\n width: 240,\n },\n {\n key: 'url',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {endpoint.method} {endpoint.url}\n </Typography>\n ),\n title: 'URL',\n width: 320,\n },\n {\n key: 'status',\n render: ({ endpoint }: EndpointRow): ReactElement =>\n !endpoint.active ? (\n <Badge size=\"sub\" text=\"已停用\" variant=\"dot-inactive\" />\n ) : endpoint.deprecated ? (\n <Badge size=\"sub\" text=\"不建議使用\" variant=\"dot-warning\" />\n ) : (\n <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'credentials',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.hasSigningSecret ? '已設定簽章金鑰' : '未簽章'}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.headerNames.length\n ? `Header:${endpoint.headerNames.join('、')}`\n : '沒有自訂 header'}\n </Typography>\n </div>\n ),\n title: '憑證',\n width: 200,\n },\n {\n key: 'updatedAt',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(endpoint.updatedAt)}\n </Typography>\n ),\n title: '更新時間',\n width: 180,\n },\n ],\n [],\n );\n\n const actions = useMemo(\n (): TableActions<EndpointRow> => ({\n render: ({\n endpoint,\n }): ReturnType<TableActions<EndpointRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'edit')),\n },\n {\n name: '建立新版本',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'version')),\n },\n {\n name: '測試送出',\n onClick: (): void => {\n void run(async () =>\n readTestNotice(\n endpoint,\n await testWorkflowWebhookEndpoint(endpoint.id),\n ),\n );\n },\n },\n {\n name: '輪替金鑰',\n onClick: (): void => {\n setNextSecret('');\n setRemoveSecret(false);\n setRotating(endpoint);\n },\n },\n {\n name: endpoint.active ? '停用' : '啟用',\n onClick: (): void => {\n void run(async () => {\n await setWorkflowWebhookEndpointActive(\n endpoint.id,\n !endpoint.active,\n );\n\n return `已${endpoint.active ? '停用' : '啟用'}「${endpoint.label}」。`;\n });\n },\n },\n {\n name: '異動紀錄',\n onClick: (): void => {\n void listWorkflowWebhookEndpointAudits(endpoint.id)\n .then((records): void => setAudits({ endpoint, records }))\n .catch((requestError: unknown): void =>\n setError(readErrorMessage(requestError)),\n );\n },\n },\n ],\n variant: 'base-secondary',\n width: 180,\n }),\n [run],\n );\n\n async function handleSaveDraft(): Promise<void> {\n if (!draft) {\n return;\n }\n\n setSaving(true);\n\n const saved = await run(async () => {\n const parameters = draft.parameters.map((parameter) => ({\n description: parameter.description.trim() || null,\n key: parameter.key.trim(),\n label: parameter.label.trim(),\n required: parameter.required,\n type: parameter.type,\n }));\n const headers = draft.headers\n .filter((header) => header.name.trim())\n .map((header) => ({ name: header.name.trim(), value: header.value }));\n const timeoutMs = draft.timeoutMs.trim() ? Number(draft.timeoutMs) : null;\n\n if (draft.mode === 'edit' && draft.endpointId) {\n await updateWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers:\n draft.replaceHeaders || isOriginChanged(draft) ? headers : null,\n id: draft.endpointId,\n label: draft.label,\n method: draft.method,\n parameters,\n timeoutMs,\n url: draft.url,\n });\n\n return `已更新「${draft.label}」。`;\n }\n\n await createWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers,\n key: draft.key,\n label: draft.label,\n method: draft.method,\n parameters,\n signingSecret: draft.signingSecret || null,\n timeoutMs,\n url: draft.url,\n version: Number(draft.version),\n });\n\n return `已建立「${draft.label}」v${draft.version},設計器現在可以選用。`;\n });\n\n setSaving(false);\n\n if (saved) {\n setDraft(null);\n }\n }\n\n async function handleRotate(): Promise<void> {\n if (!rotating) {\n return;\n }\n\n const endpoint = rotating;\n const done = await run(async () => {\n await rotateWorkflowWebhookEndpointSecret(\n endpoint.id,\n removeSecret ? null : nextSecret,\n );\n\n return removeSecret\n ? `已移除「${endpoint.label}」的簽章金鑰,之後的請求不再簽章。`\n : `已輪替「${endpoint.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`;\n });\n\n if (done) {\n setRotating(null);\n setNextSecret('');\n }\n }\n\n const enabled = Boolean(management?.enabled);\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"維護知會節點可呼叫的外部系統端點。Header 值與簽章金鑰加密保存,儲存後不會再顯示。\"\n title=\"Webhook 端點\"\n >\n <Button\n disabled={!enabled}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setDraft(EMPTY_DRAFT)}\n variant=\"base-primary\"\n >\n 新增端點\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={STACK_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {notice ? (\n <Typography color=\"text-success\" variant=\"body\">\n {notice}\n </Typography>\n ) : null}\n {management && !enabled ? (\n <Typography color=\"text-warning\" variant=\"body\">\n 此伺服器未啟用後台維護的 Webhook 端點:需要設定\n workflowWebhookTargetSources 含 DATABASE、URL\n 白名單與加密金鑰。程式註冊的端點不受影響。\n </Typography>\n ) : null}\n {enabled ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 允許的 URL:{management?.allowedUrlPatterns.join('、')}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </div>\n </Section>\n </SectionGroup>\n\n {draft ? (\n <EndpointDraftModal\n draft={draft}\n onCancel={(): void => setDraft(null)}\n onChange={setDraft}\n onConfirm={(): void => void handleSaveDraft()}\n saving={saving}\n />\n ) : null}\n\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !removeSecret && !nextSecret }}\n confirmText={removeSecret ? '移除金鑰' : '輪替金鑰'}\n modalType=\"standard\"\n onCancel={(): void => setRotating(null)}\n onClose={(): void => setRotating(null)}\n onConfirm={(): void => void handleRotate()}\n open={Boolean(rotating)}\n showModalFooter\n showModalHeader\n supportingText=\"新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。\"\n title={`輪替簽章金鑰:${rotating?.label ?? ''}`}\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"移除金鑰\" name=\"removeSigningSecret\">\n <Toggle\n checked={removeSecret}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setRemoveSecret(event.target.checked)\n }\n />\n </BPMFormField>\n {removeSecret ? null : (\n <BPMFormField label=\"新金鑰\" name=\"nextSigningSecret\" required>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setNextSecret(event.target.value)\n }\n value={nextSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n </div>\n </Modal>\n\n <Modal\n confirmText=\"關閉\"\n modalType=\"standard\"\n onClose={(): void => setAudits(null)}\n onConfirm={(): void => setAudits(null)}\n open={Boolean(audits)}\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText=\"只記錄誰在何時變更了哪些欄位,不記錄任何值。\"\n title={`異動紀錄:${audits?.endpoint.label ?? ''}`}\n >\n <Table\n columns={AUDIT_COLUMNS}\n dataSource={(audits?.records ?? []).map((audit): AuditRow => ({\n audit,\n key: audit.id,\n }))}\n fullWidth\n />\n </Modal>\n </>\n );\n}\n\nconst AUDIT_COLUMNS: TableColumn<AuditRow>[] = [\n {\n key: 'createdAt',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(audit.createdAt)}\n </Typography>\n ),\n title: '時間',\n width: 180,\n },\n {\n key: 'action',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {AUDIT_ACTION_LABELS[audit.action]}\n </Typography>\n ),\n title: '動作',\n width: 120,\n },\n {\n key: 'changedFields',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.changedFields.join('、') || '—'}\n </Typography>\n ),\n title: '欄位',\n width: 280,\n },\n {\n key: 'actor',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.actorMemberId ?? '系統'}\n </Typography>\n ),\n title: '操作者',\n width: 160,\n },\n];\n\nfunction EndpointDraftModal({\n draft,\n onCancel,\n onChange,\n onConfirm,\n saving,\n}: {\n readonly draft: EndpointDraft;\n readonly onCancel: () => void;\n readonly onChange: (draft: EndpointDraft) => void;\n readonly onConfirm: () => void;\n readonly saving: boolean;\n}): ReactElement {\n const editing = draft.mode === 'edit';\n // Stored header values must not follow the URL to another host, so a new\n // host always means entering the headers again.\n const originChanged = isOriginChanged(draft);\n const replaceHeaders = draft.replaceHeaders || originChanged;\n const update = (patch: Partial<EndpointDraft>): void =>\n onChange({ ...draft, ...patch });\n const updateParameter = (\n index: number,\n patch: Partial<ParameterDraft>,\n ): void =>\n update({\n parameters: draft.parameters.map((parameter, current) =>\n current === index ? { ...parameter, ...patch } : parameter,\n ),\n });\n const updateHeader = (index: number, patch: Partial<HeaderDraft>): void =>\n update({\n headers: draft.headers.map((header, current) =>\n current === index ? { ...header, ...patch } : header,\n ),\n });\n const text =\n (field: keyof EndpointDraft) =>\n (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void =>\n update({ [field]: event.target.value });\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmText={editing ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onCancel}\n onClose={onCancel}\n onConfirm={onConfirm}\n open\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText={\n editing\n ? '參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。'\n : draft.mode === 'version'\n ? '新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。'\n : 'URL 需符合伺服器設定的白名單。'\n }\n title={\n editing\n ? `編輯端點:${draft.label}`\n : draft.mode === 'version'\n ? `建立新版本:${draft.key}`\n : '新增 Webhook 端點'\n }\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"Key\" name=\"endpointKey\" required>\n <Input\n {...(draft.mode === 'create' ? {} : { readonly: true as const })}\n onChange={text('key')}\n placeholder=\"例如 crm.lead-created\"\n value={draft.key}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"版本\" name=\"endpointVersion\" required>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('version')}\n value={draft.version}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"名稱\" name=\"endpointLabel\" required>\n <Input\n onChange={text('label')}\n placeholder=\"例如 CRM 建立名單\"\n value={draft.label}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"說明\" name=\"endpointDescription\">\n <Textarea\n onChange={text('description')}\n rows={2}\n value={draft.description}\n />\n </BPMFormField>\n <BPMFormField label=\"URL\" name=\"endpointUrl\" required>\n <Input\n onChange={text('url')}\n placeholder=\"https://\"\n value={draft.url}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"Method\" name=\"endpointMethod\" required>\n <Select\n clearable={false}\n onChange={(option): void =>\n update({ method: option?.id ?? 'POST' })\n }\n options={[...METHOD_OPTIONS]}\n value={\n METHOD_OPTIONS.find((option) => option.id === draft.method) ??\n null\n }\n />\n </BPMFormField>\n <BPMFormField\n hintText=\"留空使用預設 10 秒,上限 30000 毫秒。\"\n label=\"逾時(毫秒)\"\n name=\"endpointTimeout\"\n >\n <Input\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('timeoutMs')}\n value={draft.timeoutMs}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"不建議使用\" name=\"endpointDeprecated\">\n <Toggle\n checked={draft.deprecated}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ deprecated: event.target.checked })\n }\n />\n </BPMFormField>\n {editing ? null : (\n <BPMFormField\n hintText=\"選填;設定後 BPM 以 HMAC-SHA256 簽章,儲存後不會再顯示。\"\n label=\"簽章金鑰\"\n name=\"endpointSigningSecret\"\n >\n <Input\n onChange={text('signingSecret')}\n placeholder=\"選填,儲存後不再顯示\"\n value={draft.signingSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n\n <Typography variant=\"label-primary-highlight\">Headers</Typography>\n {editing ? (\n <BPMFormField\n hintText={\n originChanged\n ? 'URL 已改到其他主機,必須重新輸入 header(留空代表不帶任何 header)。'\n : '現有 header 的值不會顯示;開啟後以下列內容取代全部 header。'\n }\n label=\"取代 headers\"\n name=\"endpointReplaceHeaders\"\n >\n <Toggle\n checked={replaceHeaders}\n disabled={originChanged}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ replaceHeaders: event.target.checked })\n }\n />\n </BPMFormField>\n ) : null}\n {replaceHeaders\n ? draft.headers.map((header, index): ReactElement => (\n <div key={index} style={HEADER_ROW_STYLE}>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { name: event.target.value })\n }\n placeholder=\"名稱,例如 Authorization\"\n inputProps={{ autoComplete: 'off' }}\n value={header.name}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { value: event.target.value })\n }\n placeholder=\"值\"\n value={header.value}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n <Button\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n headers: draft.headers.filter(\n (_header, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除 header\n </Button>\n </div>\n ))\n : null}\n {replaceHeaders ? (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({ headers: [...draft.headers, { name: '', value: '' }] })\n }\n variant=\"base-dashed\"\n >\n 新增 header\n </Button>\n </div>\n ) : null}\n\n <Typography variant=\"label-primary-highlight\">參數</Typography>\n {draft.parameters.map((parameter, index): ReactElement => (\n <div key={index} style={ROW_STYLE}>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { key: event.target.value })\n }\n placeholder=\"參數鍵\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.key}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { label: event.target.value })\n }\n placeholder=\"顯示名稱\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.label}\n variant=\"base\"\n />\n <Select\n clearable={false}\n disabled={editing}\n onChange={(option): void =>\n updateParameter(index, {\n type: readParameterType(option?.id ?? null),\n })\n }\n options={[...PARAMETER_TYPE_OPTIONS]}\n value={\n PARAMETER_TYPE_OPTIONS.find(\n (option) => option.id === parameter.type,\n ) ?? null\n }\n />\n <Toggle\n checked={parameter.required}\n disabled={editing}\n label=\"必填\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { required: event.target.checked })\n }\n />\n <Button\n disabled={editing}\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n parameters: draft.parameters.filter(\n (_parameter, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除參數\n </Button>\n </div>\n ))}\n {editing ? null : (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({\n parameters: [\n ...draft.parameters,\n {\n description: '',\n key: '',\n label: '',\n required: false,\n type: 'string',\n },\n ],\n })\n }\n variant=\"base-dashed\"\n >\n 新增參數\n </Button>\n </div>\n )}\n </div>\n </Modal>\n );\n}\n\nfunction readEditDraft(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n mode: 'edit' | 'version',\n): EndpointDraft {\n return {\n deprecated: endpoint.deprecated,\n description: endpoint.description ?? '',\n endpointId: mode === 'edit' ? endpoint.id : null,\n headers: [],\n key: endpoint.key,\n label: endpoint.label,\n method: endpoint.method,\n mode,\n originalUrl: endpoint.url,\n parameters: endpoint.parameters.map((parameter) => ({\n description: parameter.description ?? '',\n key: parameter.key,\n label: parameter.label,\n required: parameter.required,\n type: parameter.type,\n })),\n // A new version starts without credentials: they are not readable.\n replaceHeaders: mode === 'version',\n signingSecret: '',\n timeoutMs: endpoint.timeoutMs ? String(endpoint.timeoutMs) : '',\n url: endpoint.url,\n version: String(\n mode === 'version' ? endpoint.version + 1 : endpoint.version,\n ),\n };\n}\n\nfunction readTestNotice(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n result: WorkflowWebhookEndpointTestResultRecord,\n): string {\n if (result.ok) {\n return `測試送出成功:「${endpoint.label}」回應 HTTP ${result.status ?? ''}。`;\n }\n\n throw new Error(\n `測試送出失敗:「${endpoint.label}」${result.status ? `回應 HTTP ${result.status}` : ''}(${result.errorCode ?? '未知錯誤'})${result.errorDetail ? `:${result.errorDetail}` : ''}`,\n );\n}\n\nfunction isOriginChanged(draft: EndpointDraft): boolean {\n if (draft.mode !== 'edit') {\n return false;\n }\n\n const origin = (url: string): string => {\n try {\n return new URL(url.trim()).origin;\n } catch {\n return url.trim();\n }\n };\n\n return origin(draft.url) !== origin(draft.originalUrl);\n}\n\nfunction readParameterType(id: string | null): NotifyWebhookParameterType {\n return PARAMETER_TYPE_OPTIONS.some((option) => option.id === id)\n ? (id as NotifyWebhookParameterType)\n : 'string';\n}\n\nfunction readErrorMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return '發生未知錯誤';\n }\n\n const message = error.message;\n\n if (message.includes('WORKFLOW_WEBHOOK_URL_NOT_ALLOWED')) {\n return 'URL 不在伺服器允許的白名單內。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT')) {\n return '這個 Key 已由程式註冊的端點使用,請換一個。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED')) {\n return '參數契約不能修改,請改用「建立新版本」。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_TEST_RATE_LIMITED')) {\n return '測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。';\n }\n\n return message;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","formatDateTime","Fragment$1","ContentHeader","STACK_STYLE","ROW_STYLE","HEADER_ROW_STYLE","METHOD_OPTIONS","PARAMETER_TYPE_OPTIONS","AUDIT_ACTION_LABELS","EMPTY_DRAFT","AdminWebhookEndpointsView","management","setManagement","useState","endpoints","setEndpoints","loading","setLoading","error","setError","notice","setNotice","draft","setDraft","saving","setSaving","rotating","setRotating","nextSecret","setNextSecret","removeSecret","setRemoveSecret","audits","setAudits","refresh","useCallback","nextManagement","readWorkflowWebhookEndpointManagement","listWorkflowWebhookManagedEndpoints","requestError","readErrorMessage","run","work","rows","useMemo","endpoint","columns","Typography","Badge","actions","readEditDraft","readTestNotice","testWorkflowWebhookEndpoint","setWorkflowWebhookEndpointActive","handleSaveDraft","saved","parameters","parameter","headers","header","timeoutMs","updateWorkflowWebhookEndpoint","isOriginChanged","createWorkflowWebhookEndpoint","handleRotate","rotateWorkflowWebhookEndpointSecret","enabled","PageHeader","Button","PlusIcon","SectionGroup","Section","Table","EndpointDraftModal","Modal","BPMFormField","Toggle","event","Input","AUDIT_COLUMNS","audit","editing","originChanged","replaceHeaders","update","onChange","patch","updateParameter","current","index","updateHeader","text","field","onCancel","Textarea","Select","option","TrashIcon","readParameterType","mode","result","origin","url","id","message"],"sources":["../../../../src/views/admin/webhook-endpoints/AdminWebhookEndpointsView.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon, TrashIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { NotifyWebhookParameterType } from '@rytass/bpm-core-shared/workflow';\nimport {\n WorkflowWebhookEndpointAuditRecord,\n WorkflowWebhookEndpointManagementRecord,\n WorkflowWebhookEndpointTestResultRecord,\n WorkflowWebhookManagedEndpointRecord,\n createWorkflowWebhookEndpoint,\n listWorkflowWebhookEndpointAudits,\n listWorkflowWebhookManagedEndpoints,\n readWorkflowWebhookEndpointManagement,\n rotateWorkflowWebhookEndpointSecret,\n setWorkflowWebhookEndpointActive,\n testWorkflowWebhookEndpoint,\n updateWorkflowWebhookEndpoint,\n} from '@rytass/bpm-core-client/template';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype SelectOption = Readonly<{ id: string; name: string }>;\n\ntype EndpointRow = Readonly<\n Record<string, unknown> & {\n endpoint: WorkflowWebhookManagedEndpointRecord;\n key: string;\n }\n>;\n\ntype AuditRow = Readonly<\n Record<string, unknown> & {\n audit: WorkflowWebhookEndpointAuditRecord;\n key: string;\n }\n>;\n\ntype ParameterDraft = Readonly<{\n description: string;\n key: string;\n label: string;\n required: boolean;\n type: NotifyWebhookParameterType;\n}>;\n\ntype HeaderDraft = Readonly<{ name: string; value: string }>;\n\n/**\n * `mode` decides what can change: a new endpoint (or a new version of one)\n * sets everything; editing keeps the parameter contract and only replaces\n * headers when asked to.\n */\ntype EndpointDraft = Readonly<{\n deprecated: boolean;\n description: string;\n endpointId: string | null;\n headers: readonly HeaderDraft[];\n key: string;\n label: string;\n method: string;\n mode: 'create' | 'edit' | 'version';\n /** The stored URL when editing, to spot a move to another host. */\n originalUrl: string;\n parameters: readonly ParameterDraft[];\n replaceHeaders: boolean;\n signingSecret: string;\n timeoutMs: string;\n url: string;\n version: string;\n}>;\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n};\n\nconst ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto',\n};\n\nconst HEADER_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 2fr) auto',\n};\n\nconst METHOD_OPTIONS: readonly SelectOption[] = [\n { id: 'POST', name: 'POST' },\n { id: 'PUT', name: 'PUT' },\n { id: 'PATCH', name: 'PATCH' },\n];\n\nconst PARAMETER_TYPE_OPTIONS: readonly SelectOption[] = [\n { id: 'string', name: '文字' },\n { id: 'number', name: '數字' },\n { id: 'boolean', name: '是/否' },\n { id: 'stringArray', name: '文字清單' },\n { id: 'json', name: 'JSON' },\n];\n\nconst AUDIT_ACTION_LABELS: Readonly<\n Record<WorkflowWebhookEndpointAuditRecord['action'], string>\n> = {\n CREATED: '建立',\n DISABLED: '停用',\n ENABLED: '啟用',\n SECRET_ROTATED: '輪替金鑰',\n TEST_SENT: '測試送出',\n UPDATED: '更新',\n};\n\nconst EMPTY_DRAFT: EndpointDraft = {\n deprecated: false,\n description: '',\n endpointId: null,\n headers: [],\n key: '',\n label: '',\n method: 'POST',\n mode: 'create',\n originalUrl: '',\n parameters: [],\n replaceHeaders: true,\n signingSecret: '',\n timeoutMs: '',\n url: '',\n version: '1',\n};\n\n/**\n * Back-office management of database webhook endpoints (ADR 18 §3.13):\n * create, edit, disable, rotate the signing secret, test-send and read the\n * change history. Header values and secrets are entered here and never shown\n * again. Administrator-only on the server.\n */\nexport function AdminWebhookEndpointsView(): ReactElement {\n const [management, setManagement] =\n useState<WorkflowWebhookEndpointManagementRecord | null>(null);\n const [endpoints, setEndpoints] = useState<\n readonly WorkflowWebhookManagedEndpointRecord[]\n >([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n const [draft, setDraft] = useState<EndpointDraft | null>(null);\n const [saving, setSaving] = useState(false);\n const [rotating, setRotating] =\n useState<WorkflowWebhookManagedEndpointRecord | null>(null);\n const [nextSecret, setNextSecret] = useState('');\n const [removeSecret, setRemoveSecret] = useState(false);\n const [audits, setAudits] = useState<{\n readonly endpoint: WorkflowWebhookManagedEndpointRecord;\n readonly records: readonly WorkflowWebhookEndpointAuditRecord[];\n } | null>(null);\n\n const refresh = useCallback(async (): Promise<void> => {\n setLoading(true);\n\n try {\n const nextManagement = await readWorkflowWebhookEndpointManagement();\n\n setManagement(nextManagement);\n setEndpoints(\n nextManagement.enabled\n ? await listWorkflowWebhookManagedEndpoints()\n : [],\n );\n setError(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect((): void => {\n void refresh();\n }, [refresh]);\n\n const run = useCallback(\n async (work: () => Promise<string | null>): Promise<boolean> => {\n setError(null);\n setNotice(null);\n\n try {\n setNotice(await work());\n await refresh();\n\n return true;\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n\n return false;\n }\n },\n [refresh],\n );\n\n const rows = useMemo(\n (): EndpointRow[] =>\n endpoints.map((endpoint) => ({ endpoint, key: endpoint.id })),\n [endpoints],\n );\n\n const columns = useMemo(\n (): TableColumn<EndpointRow>[] => [\n {\n key: 'label',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.label}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.key}@{endpoint.version} · 參數{' '}\n {endpoint.parameters.length} 個\n </Typography>\n </div>\n ),\n title: '端點',\n width: 240,\n },\n {\n key: 'url',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {endpoint.method} {endpoint.url}\n </Typography>\n ),\n title: 'URL',\n width: 320,\n },\n {\n key: 'status',\n render: ({ endpoint }: EndpointRow): ReactElement =>\n !endpoint.active ? (\n <Badge size=\"sub\" text=\"已停用\" variant=\"dot-inactive\" />\n ) : endpoint.deprecated ? (\n <Badge size=\"sub\" text=\"不建議使用\" variant=\"dot-warning\" />\n ) : (\n <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'credentials',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.hasSigningSecret ? '已設定簽章金鑰' : '未簽章'}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.headerNames.length\n ? `Header:${endpoint.headerNames.join('、')}`\n : '沒有自訂 header'}\n </Typography>\n </div>\n ),\n title: '憑證',\n width: 200,\n },\n {\n key: 'updatedAt',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(endpoint.updatedAt)}\n </Typography>\n ),\n title: '更新時間',\n width: 180,\n },\n ],\n [],\n );\n\n const actions = useMemo(\n (): TableActions<EndpointRow> => ({\n render: ({\n endpoint,\n }): ReturnType<TableActions<EndpointRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'edit')),\n },\n {\n name: '建立新版本',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'version')),\n },\n {\n name: '測試送出',\n onClick: (): void => {\n void run(async () =>\n readTestNotice(\n endpoint,\n await testWorkflowWebhookEndpoint(endpoint.id),\n ),\n );\n },\n },\n {\n name: '輪替金鑰',\n onClick: (): void => {\n setNextSecret('');\n setRemoveSecret(false);\n setRotating(endpoint);\n },\n },\n {\n name: endpoint.active ? '停用' : '啟用',\n onClick: (): void => {\n void run(async () => {\n await setWorkflowWebhookEndpointActive(\n endpoint.id,\n !endpoint.active,\n );\n\n return `已${endpoint.active ? '停用' : '啟用'}「${endpoint.label}」。`;\n });\n },\n },\n {\n name: '異動紀錄',\n onClick: (): void => {\n void listWorkflowWebhookEndpointAudits(endpoint.id)\n .then((records): void => setAudits({ endpoint, records }))\n .catch((requestError: unknown): void =>\n setError(readErrorMessage(requestError)),\n );\n },\n },\n ],\n variant: 'base-secondary',\n width: 180,\n }),\n [run],\n );\n\n async function handleSaveDraft(): Promise<void> {\n if (!draft) {\n return;\n }\n\n setSaving(true);\n\n const saved = await run(async () => {\n const parameters = draft.parameters.map((parameter) => ({\n description: parameter.description.trim() || null,\n key: parameter.key.trim(),\n label: parameter.label.trim(),\n required: parameter.required,\n type: parameter.type,\n }));\n const headers = draft.headers\n .filter((header) => header.name.trim())\n .map((header) => ({ name: header.name.trim(), value: header.value }));\n const timeoutMs = draft.timeoutMs.trim() ? Number(draft.timeoutMs) : null;\n\n if (draft.mode === 'edit' && draft.endpointId) {\n await updateWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers:\n draft.replaceHeaders || isOriginChanged(draft) ? headers : null,\n id: draft.endpointId,\n label: draft.label,\n method: draft.method,\n parameters,\n timeoutMs,\n url: draft.url,\n });\n\n return `已更新「${draft.label}」。`;\n }\n\n await createWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers,\n key: draft.key,\n label: draft.label,\n method: draft.method,\n parameters,\n signingSecret: draft.signingSecret || null,\n timeoutMs,\n url: draft.url,\n version: Number(draft.version),\n });\n\n return `已建立「${draft.label}」v${draft.version},設計器現在可以選用。`;\n });\n\n setSaving(false);\n\n if (saved) {\n setDraft(null);\n }\n }\n\n async function handleRotate(): Promise<void> {\n if (!rotating) {\n return;\n }\n\n const endpoint = rotating;\n const done = await run(async () => {\n await rotateWorkflowWebhookEndpointSecret(\n endpoint.id,\n removeSecret ? null : nextSecret,\n );\n\n return removeSecret\n ? `已移除「${endpoint.label}」的簽章金鑰,之後的請求不再簽章。`\n : `已輪替「${endpoint.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`;\n });\n\n if (done) {\n setRotating(null);\n setNextSecret('');\n }\n }\n\n const enabled = Boolean(management?.enabled);\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"維護知會節點可呼叫的外部系統端點。Header 值與簽章金鑰加密保存,儲存後不會再顯示。\"\n title=\"Webhook 端點\"\n >\n <Button\n disabled={!enabled}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setDraft(EMPTY_DRAFT)}\n variant=\"base-primary\"\n >\n 新增端點\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={STACK_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {notice ? (\n <Typography color=\"text-success\" variant=\"body\">\n {notice}\n </Typography>\n ) : null}\n {management && !enabled ? (\n <Typography color=\"text-warning\" variant=\"body\">\n 此伺服器未啟用後台維護的 Webhook 端點:需要設定\n workflowWebhookTargetSources 含 DATABASE、URL\n 白名單與加密金鑰。程式註冊的端點不受影響。\n </Typography>\n ) : null}\n {enabled ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 允許的 URL:{management?.allowedUrlPatterns.join('、')}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </div>\n </Section>\n </SectionGroup>\n\n {draft ? (\n <EndpointDraftModal\n draft={draft}\n onCancel={(): void => setDraft(null)}\n onChange={setDraft}\n onConfirm={(): void => void handleSaveDraft()}\n saving={saving}\n />\n ) : null}\n\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !removeSecret && !nextSecret }}\n confirmText={removeSecret ? '移除金鑰' : '輪替金鑰'}\n modalType=\"standard\"\n onCancel={(): void => setRotating(null)}\n onClose={(): void => setRotating(null)}\n onConfirm={(): void => void handleRotate()}\n open={Boolean(rotating)}\n showModalFooter\n showModalHeader\n supportingText=\"新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。\"\n title={`輪替簽章金鑰:${rotating?.label ?? ''}`}\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"移除金鑰\" name=\"removeSigningSecret\">\n <Toggle\n checked={removeSecret}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setRemoveSecret(event.target.checked)\n }\n />\n </BPMFormField>\n {removeSecret ? null : (\n <BPMFormField label=\"新金鑰\" name=\"nextSigningSecret\" required>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setNextSecret(event.target.value)\n }\n value={nextSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n </div>\n </Modal>\n\n <Modal\n confirmText=\"關閉\"\n modalType=\"standard\"\n onClose={(): void => setAudits(null)}\n onConfirm={(): void => setAudits(null)}\n open={Boolean(audits)}\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText=\"只記錄誰在何時變更了哪些欄位,不記錄任何值。\"\n title={`異動紀錄:${audits?.endpoint.label ?? ''}`}\n >\n <Table\n columns={AUDIT_COLUMNS}\n dataSource={(audits?.records ?? []).map((audit): AuditRow => ({\n audit,\n key: audit.id,\n }))}\n fullWidth\n />\n </Modal>\n </>\n );\n}\n\nconst AUDIT_COLUMNS: TableColumn<AuditRow>[] = [\n {\n key: 'createdAt',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(audit.createdAt)}\n </Typography>\n ),\n title: '時間',\n width: 180,\n },\n {\n key: 'action',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {AUDIT_ACTION_LABELS[audit.action]}\n </Typography>\n ),\n title: '動作',\n width: 120,\n },\n {\n key: 'changedFields',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.changedFields.join('、') || '—'}\n </Typography>\n ),\n title: '欄位',\n width: 280,\n },\n {\n key: 'actor',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.actorMemberId ?? '系統'}\n </Typography>\n ),\n title: '操作者',\n width: 160,\n },\n];\n\nfunction EndpointDraftModal({\n draft,\n onCancel,\n onChange,\n onConfirm,\n saving,\n}: {\n readonly draft: EndpointDraft;\n readonly onCancel: () => void;\n readonly onChange: (draft: EndpointDraft) => void;\n readonly onConfirm: () => void;\n readonly saving: boolean;\n}): ReactElement {\n const editing = draft.mode === 'edit';\n // Stored header values must not follow the URL to another host, so a new\n // host always means entering the headers again.\n const originChanged = isOriginChanged(draft);\n const replaceHeaders = draft.replaceHeaders || originChanged;\n const update = (patch: Partial<EndpointDraft>): void =>\n onChange({ ...draft, ...patch });\n const updateParameter = (\n index: number,\n patch: Partial<ParameterDraft>,\n ): void =>\n update({\n parameters: draft.parameters.map((parameter, current) =>\n current === index ? { ...parameter, ...patch } : parameter,\n ),\n });\n const updateHeader = (index: number, patch: Partial<HeaderDraft>): void =>\n update({\n headers: draft.headers.map((header, current) =>\n current === index ? { ...header, ...patch } : header,\n ),\n });\n const text =\n (field: keyof EndpointDraft) =>\n (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void =>\n update({ [field]: event.target.value });\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmText={editing ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onCancel}\n onClose={onCancel}\n onConfirm={onConfirm}\n open\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText={\n editing\n ? '參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。'\n : draft.mode === 'version'\n ? '新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。'\n : 'URL 需符合伺服器設定的白名單。'\n }\n title={\n editing\n ? `編輯端點:${draft.label}`\n : draft.mode === 'version'\n ? `建立新版本:${draft.key}`\n : '新增 Webhook 端點'\n }\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"Key\" name=\"endpointKey\" required>\n <Input\n {...(draft.mode === 'create' ? {} : { readonly: true as const })}\n onChange={text('key')}\n placeholder=\"例如 crm.lead-created\"\n value={draft.key}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"版本\" name=\"endpointVersion\" required>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('version')}\n value={draft.version}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"名稱\" name=\"endpointLabel\" required>\n <Input\n onChange={text('label')}\n placeholder=\"例如 CRM 建立名單\"\n value={draft.label}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"說明\" name=\"endpointDescription\">\n <Textarea\n onChange={text('description')}\n rows={2}\n value={draft.description}\n />\n </BPMFormField>\n <BPMFormField label=\"URL\" name=\"endpointUrl\" required>\n <Input\n onChange={text('url')}\n placeholder=\"https://\"\n value={draft.url}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"Method\" name=\"endpointMethod\" required>\n <Select\n clearable={false}\n onChange={(option): void =>\n update({ method: option?.id ?? 'POST' })\n }\n options={[...METHOD_OPTIONS]}\n value={\n METHOD_OPTIONS.find((option) => option.id === draft.method) ??\n null\n }\n />\n </BPMFormField>\n <BPMFormField\n hintText=\"留空使用預設 10 秒,上限 30000 毫秒。\"\n label=\"逾時(毫秒)\"\n name=\"endpointTimeout\"\n >\n <Input\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('timeoutMs')}\n value={draft.timeoutMs}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"不建議使用\" name=\"endpointDeprecated\">\n <Toggle\n checked={draft.deprecated}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ deprecated: event.target.checked })\n }\n />\n </BPMFormField>\n {editing ? null : (\n <BPMFormField\n hintText=\"選填;設定後 BPM 以 HMAC-SHA256 簽章,儲存後不會再顯示。\"\n label=\"簽章金鑰\"\n name=\"endpointSigningSecret\"\n >\n <Input\n onChange={text('signingSecret')}\n placeholder=\"選填,儲存後不再顯示\"\n value={draft.signingSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n\n <Typography variant=\"label-primary-highlight\">Headers</Typography>\n {editing ? (\n <BPMFormField\n hintText={\n originChanged\n ? 'URL 已改到其他主機,必須重新輸入 header(留空代表不帶任何 header)。'\n : '現有 header 的值不會顯示;開啟後以下列內容取代全部 header。'\n }\n label=\"取代 headers\"\n name=\"endpointReplaceHeaders\"\n >\n <Toggle\n checked={replaceHeaders}\n disabled={originChanged}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ replaceHeaders: event.target.checked })\n }\n />\n </BPMFormField>\n ) : null}\n {replaceHeaders\n ? draft.headers.map((header, index): ReactElement => (\n <div key={index} style={HEADER_ROW_STYLE}>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { name: event.target.value })\n }\n placeholder=\"名稱,例如 Authorization\"\n inputProps={{ autoComplete: 'off' }}\n value={header.name}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { value: event.target.value })\n }\n placeholder=\"值\"\n value={header.value}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n <Button\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n headers: draft.headers.filter(\n (_header, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除 header\n </Button>\n </div>\n ))\n : null}\n {replaceHeaders ? (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({ headers: [...draft.headers, { name: '', value: '' }] })\n }\n variant=\"base-dashed\"\n >\n 新增 header\n </Button>\n </div>\n ) : null}\n\n <Typography variant=\"label-primary-highlight\">參數</Typography>\n {draft.parameters.map((parameter, index): ReactElement => (\n <div key={index} style={ROW_STYLE}>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { key: event.target.value })\n }\n placeholder=\"參數鍵\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.key}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { label: event.target.value })\n }\n placeholder=\"顯示名稱\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.label}\n variant=\"base\"\n />\n <Select\n clearable={false}\n disabled={editing}\n onChange={(option): void =>\n updateParameter(index, {\n type: readParameterType(option?.id ?? null),\n })\n }\n options={[...PARAMETER_TYPE_OPTIONS]}\n value={\n PARAMETER_TYPE_OPTIONS.find(\n (option) => option.id === parameter.type,\n ) ?? null\n }\n />\n <Toggle\n checked={parameter.required}\n disabled={editing}\n label=\"必填\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { required: event.target.checked })\n }\n />\n <Button\n disabled={editing}\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n parameters: draft.parameters.filter(\n (_parameter, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除參數\n </Button>\n </div>\n ))}\n {editing ? null : (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({\n parameters: [\n ...draft.parameters,\n {\n description: '',\n key: '',\n label: '',\n required: false,\n type: 'string',\n },\n ],\n })\n }\n variant=\"base-dashed\"\n >\n 新增參數\n </Button>\n </div>\n )}\n </div>\n </Modal>\n );\n}\n\nfunction readEditDraft(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n mode: 'edit' | 'version',\n): EndpointDraft {\n return {\n deprecated: endpoint.deprecated,\n description: endpoint.description ?? '',\n endpointId: mode === 'edit' ? endpoint.id : null,\n headers: [],\n key: endpoint.key,\n label: endpoint.label,\n method: endpoint.method,\n mode,\n originalUrl: endpoint.url,\n parameters: endpoint.parameters.map((parameter) => ({\n description: parameter.description ?? '',\n key: parameter.key,\n label: parameter.label,\n required: parameter.required,\n type: parameter.type,\n })),\n // A new version starts without credentials: they are not readable.\n replaceHeaders: mode === 'version',\n signingSecret: '',\n timeoutMs: endpoint.timeoutMs ? String(endpoint.timeoutMs) : '',\n url: endpoint.url,\n version: String(\n mode === 'version' ? endpoint.version + 1 : endpoint.version,\n ),\n };\n}\n\nfunction readTestNotice(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n result: WorkflowWebhookEndpointTestResultRecord,\n): string {\n if (result.ok) {\n return `測試送出成功:「${endpoint.label}」回應 HTTP ${result.status ?? ''}。`;\n }\n\n throw new Error(\n `測試送出失敗:「${endpoint.label}」${result.status ? `回應 HTTP ${result.status}` : ''}(${result.errorCode ?? '未知錯誤'})${result.errorDetail ? `:${result.errorDetail}` : ''}`,\n );\n}\n\nfunction isOriginChanged(draft: EndpointDraft): boolean {\n if (draft.mode !== 'edit') {\n return false;\n }\n\n const origin = (url: string): string => {\n try {\n return new URL(url.trim()).origin;\n } catch {\n return url.trim();\n }\n };\n\n return origin(draft.url) !== origin(draft.originalUrl);\n}\n\nfunction readParameterType(id: string | null): NotifyWebhookParameterType {\n return PARAMETER_TYPE_OPTIONS.some((option) => option.id === id)\n ? (id as NotifyWebhookParameterType)\n : 'string';\n}\n\nfunction readErrorMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return '發生未知錯誤';\n }\n\n const message = error.message;\n\n if (message.includes('WORKFLOW_WEBHOOK_URL_NOT_ALLOWED')) {\n return 'URL 不在伺服器允許的白名單內。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT')) {\n return '這個 Key 已由程式註冊的端點使用,請換一個。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED')) {\n return '參數契約不能修改,請改用「建立新版本」。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_TEST_RATE_LIMITED')) {\n return '測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。';\n }\n\n return message;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/views/cc/CcView.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { ApprovalInstanceListPage } from '../../components/approval-instance-list-page';\n\n\n/**\n * Framework-agnostic view for the BPM \"cc\" inbox — instances the current\n * member is copied on. Mechanical port of\n * `apps/client/src/app/cc/page.tsx`.\n */\nexport function CcView(): ReactElement {\n return (\n <ApprovalInstanceListPage\n defaultState={null}\n description=\"查看抄送給你的簽核案件。\"\n emptyMessage=\"目前沒有抄送給你的簽核案件。\"\n searchPlaceholder=\"關鍵字:搜尋案件、發起人、模板或狀態\"\n title=\"抄送給我\"\n view=\"CC\"\n />\n );\n}\n"],"mappings":"4LAWA,
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["ApprovalInstanceListPage","require_approval_instance_list_page","react_jsx_runtime","CcView"],"sources":["../../../src/views/cc/CcView.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { ApprovalInstanceListPage } from '../../components/approval-instance-list-page';\n\n\n/**\n * Framework-agnostic view for the BPM \"cc\" inbox — instances the current\n * member is copied on. Mechanical port of\n * `apps/client/src/app/cc/page.tsx`.\n */\nexport function CcView(): ReactElement {\n return (\n <ApprovalInstanceListPage\n defaultState={null}\n description=\"查看抄送給你的簽核案件。\"\n emptyMessage=\"目前沒有抄送給你的簽核案件。\"\n searchPlaceholder=\"關鍵字:搜尋案件、發起人、模板或狀態\"\n title=\"抄送給我\"\n view=\"CC\"\n />\n );\n}\n"],"mappings":"4LAWA,SAAgBG,GAAuB,CACrC,OACE,EAAAD,EAAA,IAAA,CAACF,EAAAA,EAAD,CACE,aAAc,KACd,YAAY,eACZ,aAAa,iBACb,kBAAkB,qBAClB,MAAM,OACN,KAAK,IACN,CAAA,CAEL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/views/cc/CcView.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { ApprovalInstanceListPage } from '../../components/approval-instance-list-page';\n\n\n/**\n * Framework-agnostic view for the BPM \"cc\" inbox — instances the current\n * member is copied on. Mechanical port of\n * `apps/client/src/app/cc/page.tsx`.\n */\nexport function CcView(): ReactElement {\n return (\n <ApprovalInstanceListPage\n defaultState={null}\n description=\"查看抄送給你的簽核案件。\"\n emptyMessage=\"目前沒有抄送給你的簽核案件。\"\n searchPlaceholder=\"關鍵字:搜尋案件、發起人、模板或狀態\"\n title=\"抄送給我\"\n view=\"CC\"\n />\n );\n}\n"],"mappings":";;;;AAWA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["ApprovalInstanceListPage","CcView"],"sources":["../../../src/views/cc/CcView.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { ApprovalInstanceListPage } from '../../components/approval-instance-list-page';\n\n\n/**\n * Framework-agnostic view for the BPM \"cc\" inbox — instances the current\n * member is copied on. Mechanical port of\n * `apps/client/src/app/cc/page.tsx`.\n */\nexport function CcView(): ReactElement {\n return (\n <ApprovalInstanceListPage\n defaultState={null}\n description=\"查看抄送給你的簽核案件。\"\n emptyMessage=\"目前沒有抄送給你的簽核案件。\"\n searchPlaceholder=\"關鍵字:搜尋案件、發起人、模板或狀態\"\n title=\"抄送給我\"\n view=\"CC\"\n />\n );\n}\n"],"mappings":";;;;AAWA,SAAgBC,IAAuB;CACrC,OACE,kBAACD,GAAD;EACE,cAAc;EACd,aAAY;EACZ,cAAa;EACb,mBAAkB;EAClB,OAAM;EACN,MAAK;CACN,CAAA;AAEL"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/dashboard-page-
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/dashboard-page-BWQBSGDq.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{})}exports.DashboardView=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/views/dashboard/DashboardView.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { DashboardPage } from '../../components/dashboard-page';\n\n\n/**\n * Framework-agnostic view for the BPM dashboard. Delegates to the shared\n * `<DashboardPage>` component. Mechanical port of\n * `apps/client/src/app/dashboard/page.tsx`.\n */\nexport function DashboardView(): ReactElement {\n return <DashboardPage />;\n}\n"],"mappings":"+KAWA,
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["DashboardPage","require_dashboard_page","react_jsx_runtime","DashboardView"],"sources":["../../../src/views/dashboard/DashboardView.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { DashboardPage } from '../../components/dashboard-page';\n\n\n/**\n * Framework-agnostic view for the BPM dashboard. Delegates to the shared\n * `<DashboardPage>` component. Mechanical port of\n * `apps/client/src/app/dashboard/page.tsx`.\n */\nexport function DashboardView(): ReactElement {\n return <DashboardPage />;\n}\n"],"mappings":"+KAWA,SAAgBG,GAA8B,CAC5C,OAAO,EAAAD,EAAA,IAAA,CAACF,EAAAA,EAAD,CAAgB,CAAA,CACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/views/dashboard/DashboardView.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { DashboardPage } from '../../components/dashboard-page';\n\n\n/**\n * Framework-agnostic view for the BPM dashboard. Delegates to the shared\n * `<DashboardPage>` component. Mechanical port of\n * `apps/client/src/app/dashboard/page.tsx`.\n */\nexport function DashboardView(): ReactElement {\n return <DashboardPage />;\n}\n"],"mappings":";;;;AAWA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["DashboardPage","DashboardView"],"sources":["../../../src/views/dashboard/DashboardView.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { DashboardPage } from '../../components/dashboard-page';\n\n\n/**\n * Framework-agnostic view for the BPM dashboard. Delegates to the shared\n * `<DashboardPage>` component. Mechanical port of\n * `apps/client/src/app/dashboard/page.tsx`.\n */\nexport function DashboardView(): ReactElement {\n return <DashboardPage />;\n}\n"],"mappings":";;;;AAWA,SAAgBC,IAA8B;CAC5C,OAAO,kBAACD,GAAD,CAAgB,CAAA;AACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/delegations-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/delegations-Ckf03icM.cjs");exports.DelegationsView=e.t;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { e as DelegationsView };
|
|
1
|
+
export { t as DelegationsView } from "../../chunks/delegations-MxF3uJGW.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormBuilderView-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormBuilderView-aBcA-_tt.cjs");exports.FormBuilderView=e.t;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { e as FormBuilderView };
|
|
1
|
+
export { t as FormBuilderView } from "../../../chunks/FormBuilderView-BYL42M0d.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-DRFi_IH7.cjs");exports.FormRenderer=e.t,exports.FormRendererView=e.t,exports.isFormDataSourceFieldSubmissionBlocked=e.i,exports.readFormDataSourceFieldStatusMessage=e.a,exports.readFormDataSourceSubmissionBlockMessage=e.o,exports.useFormDataSourceField=e.s;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { i as FormRenderer, i as FormRendererView, t as isFormDataSourceFieldSubmissionBlocked, e as readFormDataSourceFieldStatusMessage, n as readFormDataSourceSubmissionBlockMessage, r as useFormDataSourceField };
|
|
1
|
+
export { t as FormRenderer, t as FormRendererView, i as isFormDataSourceFieldSubmissionBlocked, a as readFormDataSourceFieldStatusMessage, o as readFormDataSourceSubmissionBlockMessage, s as useFormDataSourceField } from "../../../chunks/FormRendererView-cZGOOjU5.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/router-adapter--gYs13E8.cjs"),n=require("../../chunks/auth-provider-4BeCw7cI.cjs"),r=require("../../chunks/format-date-time-D-cx5M8z.cjs"),i=require("../../chunks/routes-config-C1j_vFKo.cjs"),a=require("../../chunks/task-node-label-BF6UllxP.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/react/ContentHeader");u=e.t(u,1);let d=require("@mezzanine-ui/icons");function f(){let e=t.r(),a=i.r(),{member:f}=n.n(),h=f?.memberId??null,[g,_]=(0,o.useState)(`pending`),[v,y]=(0,o.useState)(null),[x,C]=(0,o.useState)([]),[T,E]=(0,o.useState)(!0),[D,O]=(0,o.useState)([]);(0,o.useEffect)(()=>{h&&I()},[h]);let A=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{dataIndex:`statusLabel`,key:`statusLabel`,title:`狀態`,width:120},{key:`slaDueAt`,render:e=>(0,c.jsx)(s.Typography,{color:e.slaStatusColor,component:`span`,variant:`body`,children:e.slaStatusText}),title:`SLA`,width:180},{key:`createdAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:r.t(e.createdAt)}),title:`建立時間`,width:220}],[]),j=(0,o.useMemo)(()=>({render:t=>[{name:`處理`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),M=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{key:`decisionLabel`,render:e=>(0,c.jsx)(s.Typography,{color:b(e.decisionAction),component:`span`,variant:`body`,children:e.decisionLabel}),title:`決議`,width:120},{key:`decisionComment`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.decisionCommentText}),title:`意見`,width:240},{key:`instanceStateLabel`,render:e=>(0,c.jsx)(s.Typography,{color:S(e.instanceState),component:`span`,variant:`body`,children:e.instanceStateLabel}),title:`流程狀態`,width:140},{key:`decidedAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:w(e.decidedAt)}),title:`簽核時間`,width:220}],[]),N=(0,o.useMemo)(()=>({render:t=>[{name:`查看`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),P=(0,o.useMemo)(()=>x.filter(e=>e.instanceState===`RUNNING`),[x]);function F(e){
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/router-adapter--gYs13E8.cjs"),n=require("../../chunks/auth-provider-4BeCw7cI.cjs"),r=require("../../chunks/format-date-time-D-cx5M8z.cjs"),i=require("../../chunks/routes-config-C1j_vFKo.cjs"),a=require("../../chunks/task-node-label-BF6UllxP.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/react/ContentHeader");u=e.t(u,1);let d=require("@mezzanine-ui/icons");function f(){let e=t.r(),a=i.r(),{member:f}=n.n(),h=f?.memberId??null,[g,_]=(0,o.useState)(`pending`),[v,y]=(0,o.useState)(null),[x,C]=(0,o.useState)([]),[T,E]=(0,o.useState)(!0),[D,O]=(0,o.useState)([]);(0,o.useEffect)(()=>{h&&I()},[h]);let A=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{dataIndex:`statusLabel`,key:`statusLabel`,title:`狀態`,width:120},{key:`slaDueAt`,render:e=>(0,c.jsx)(s.Typography,{color:e.slaStatusColor,component:`span`,variant:`body`,children:e.slaStatusText}),title:`SLA`,width:180},{key:`createdAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:r.t(e.createdAt)}),title:`建立時間`,width:220}],[]),j=(0,o.useMemo)(()=>({render:t=>[{name:`處理`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),M=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{key:`decisionLabel`,render:e=>(0,c.jsx)(s.Typography,{color:b(e.decisionAction),component:`span`,variant:`body`,children:e.decisionLabel}),title:`決議`,width:120},{key:`decisionComment`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.decisionCommentText}),title:`意見`,width:240},{key:`instanceStateLabel`,render:e=>(0,c.jsx)(s.Typography,{color:S(e.instanceState),component:`span`,variant:`body`,children:e.instanceStateLabel}),title:`流程狀態`,width:140},{key:`decidedAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:w(e.decidedAt)}),title:`簽核時間`,width:220}],[]),N=(0,o.useMemo)(()=>({render:t=>[{name:`查看`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),P=(0,o.useMemo)(()=>x.filter(e=>e.instanceState===`RUNNING`),[x]);function F(e){_(e===`history`||e===`pending`||e===`tracking`?e:`pending`)}async function I(){E(!0),y(null);try{if(!h){O([]),C([]);return}let[e,t]=await Promise.all([(0,l.listInboxTasks)(h),(0,l.listApprovalHistoryTasks)(h)]),[n,r]=await Promise.all([p(e),m(t)]);O(n),C(r)}catch(e){y(k(e))}finally{E(!1)}}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(u.default,{description:`目前以 ${f?.name??h??`目前登入會員`} 查詢待處理與歷史簽核任務。`,title:`我的待簽`,children:(0,c.jsx)(s.Button,{icon:d.PlusIcon,iconType:`leading`,onClick:()=>e.push(a.caseNew()),variant:`base-primary`,children:`發起簽核`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{children:[v?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:v}):null,(0,c.jsxs)(s.Tab,{activeKey:g,onChange:F,size:`sub`,children:[(0,c.jsx)(s.TabItem,{badgeCount:T?void 0:D.length,children:`待簽核`},`pending`),(0,c.jsx)(s.TabItem,{badgeCount:T?void 0:P.length,children:`已處理未結束`},`tracking`),(0,c.jsx)(s.TabItem,{children:`歷史簽核記錄`},`history`)]}),g===`pending`?(0,c.jsx)(s.Table,{actions:j,columns:A,dataSource:D,fullWidth:!0,loading:T}):null,g===`tracking`?(0,c.jsx)(s.Table,{actions:N,columns:M,dataSource:P,fullWidth:!0,loading:T}):null,g===`history`?(0,c.jsx)(s.Table,{actions:N,columns:M,dataSource:x,fullWidth:!0,loading:T}):null]})})]})}async function p(e){let t=await h(e);return e.map((e,n)=>({...e,caseTitle:g(e,t[n]??null),key:e.id,nodeText:a.t(e),slaStatusColor:E(e.slaDueAt),slaStatusText:T(e.slaDueAt),statusLabel:O(e.status)}))}async function m(e){let[t,n]=await Promise.all([Promise.all(e.map(e=>(0,l.listTaskDecisions)(e.id))),h(e)]);return e.map((e,r)=>{let i=_(t[r]??[]),o=n[r]??null;return{...e,caseTitle:g(e,o),decisionAction:i?.action??null,decisionComment:i?.comment??null,decisionCommentText:C(i?.comment??null),decisionLabel:y(i?.action??null),decidedAt:i?.decidedAt??e.completedAt,instanceState:o?.state??null,instanceStateLabel:x(o?.state??null),key:e.id,nodeText:a.t(e)}})}async function h(e){return Promise.all(e.map(async e=>{try{return(await(0,l.readApprovalInstance)(e.instanceId)).instance}catch{return null}}))}function g(e,t){return t?(0,l.readApprovalInstanceCaseTitle)(t):e.instanceId}function _(e){return[...e].sort(v)[0]??null}function v(e,t){return new Date(t.decidedAt).getTime()-new Date(e.decidedAt).getTime()}function y(e){return e===`APPROVED`?`同意`:e===`REJECTED`?`拒絕`:e===`RETURNED`?`退回`:e===`TRANSFERRED`?`轉派`:`未記錄`}function b(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`RETURNED`?`text-error`:`text-neutral`}function x(e){return e===`RUNNING`?`進行中`:e===`APPROVED`?`已通過`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`CANCELLED`?`已取消`:e===`EXPIRED`?`已逾期`:e===`DRAFT`?`草稿`:`-`}function S(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`CANCELLED`||e===`EXPIRED`?`text-error`:`text-neutral`}function C(e){return(e?.trim()??``)||`-`}function w(e){return r.t(e)}function T(e){if(!e)return`-`;let t=new Date(e).getTime(),n=Date.now(),r=D(Math.abs(t-n));return t<n?`已逾期 ${r}`:`剩餘 ${r}`}function E(e){return e?new Date(e).getTime()<Date.now()?`text-error`:`text-success`:`text-neutral`}function D(e){let t=Math.max(1,Math.ceil(e/6e4)),n=Math.floor(t/1440),r=Math.floor(t%1440/60),i=t%60;return n>0?`${n}天 ${r}小時`:r>0?`${r}小時 ${i}分鐘`:`${i}分鐘`}function O(e){return e===`PENDING`?`待處理`:e===`IN_PROGRESS`?`處理中`:e===`COMPLETED`?`已完成`:e===`TRANSFERRED`?`已轉派`:e===`CANCELLED`?`已取消`:e}function k(e){return e instanceof Error?e.message:`發生未知錯誤`}exports.InboxView=f;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport { type Key, ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\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 type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n ApprovalInstanceRecord,\n listApprovalHistoryTasks,\n listInboxTasks,\n listTaskDecisions,\n readApprovalInstance,\n readApprovalInstanceCaseTitle,\n TaskDecisionRecord,\n TaskRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useAuth } from '../../lib/auth-provider';\nimport { readTaskNodeText } from '../../lib/task-node-label';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\n\ntype InboxTabKey = 'history' | 'pending' | 'tracking';\n\ntype InboxTaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n key: string;\n nodeText: string;\n slaStatusColor: 'text-error' | 'text-neutral' | 'text-success';\n slaStatusText: string;\n statusLabel: string;\n }\n>;\n\ntype ApprovalHistoryRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n decisionAction: TaskDecisionRecord['action'] | null;\n decisionComment: string | null;\n decisionCommentText: string;\n decisionLabel: string;\n decidedAt: string | null;\n instanceState: ApprovalInstanceRecord['state'] | null;\n instanceStateLabel: string;\n key: string;\n nodeText: string;\n }\n>;\n\n\n/**\n * Framework-agnostic view for the BPM \"我的待簽\" inbox. Mechanical port of\n * `apps/client/src/app/inbox/page.tsx` — renders pending tasks, tracking,\n * and history tabs.\n */\nexport function InboxView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activeTab, setActiveTab] = useState<InboxTabKey>('pending');\n const [error, setError] = useState<string | null>(null);\n const [historyRows, setHistoryRows] = useState<ApprovalHistoryRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [pendingRows, setPendingRows] = useState<InboxTaskRow[]>([]);\n\n useEffect((): void => {\n if (!currentMemberId) {\n return;\n }\n\n void refreshTasks();\n }, [currentMemberId]);\n\n const pendingColumns = useMemo(\n (): TableColumn<InboxTaskRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'slaDueAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography\n color={record.slaStatusColor}\n component=\"span\"\n variant=\"body\"\n >\n {record.slaStatusText}\n </Typography>\n ),\n title: 'SLA',\n width: 180,\n },\n {\n key: 'createdAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.createdAt)}\n </Typography>\n ),\n title: '建立時間',\n width: 220,\n },\n ],\n [],\n );\n const pendingTableActions = useMemo(\n (): TableActions<InboxTaskRow> => ({\n render: (record): ReturnType<TableActions<InboxTaskRow>['render']> => [\n {\n name: '處理',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const historyColumns = useMemo(\n (): TableColumn<ApprovalHistoryRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n key: 'decisionLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readTaskDecisionColor(record.decisionAction)}\n component=\"span\"\n variant=\"body\"\n >\n {record.decisionLabel}\n </Typography>\n ),\n title: '決議',\n width: 120,\n },\n {\n key: 'decisionComment',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.decisionCommentText}\n </Typography>\n ),\n title: '意見',\n width: 240,\n },\n {\n key: 'instanceStateLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.instanceState)}\n component=\"span\"\n variant=\"body\"\n >\n {record.instanceStateLabel}\n </Typography>\n ),\n title: '流程狀態',\n width: 140,\n },\n {\n key: 'decidedAt',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatHistoryDateTime(record.decidedAt)}\n </Typography>\n ),\n title: '簽核時間',\n width: 220,\n },\n ],\n [],\n );\n const historyTableActions = useMemo(\n (): TableActions<ApprovalHistoryRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalHistoryRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const trackingRows = useMemo(\n (): ApprovalHistoryRow[] =>\n historyRows.filter((row) => row.instanceState === 'RUNNING'),\n [historyRows],\n );\n\n function handleTabChange(activeKey: Key): void {\n if (\n activeKey === 'history' ||\n activeKey === 'pending' ||\n activeKey === 'tracking'\n ) {\n setActiveTab(activeKey);\n return;\n }\n\n setActiveTab('pending');\n }\n\n async function refreshTasks(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n if (!currentMemberId) {\n setPendingRows([]);\n setHistoryRows([]);\n return;\n }\n\n const [nextPendingTasks, nextHistoryTasks] = await Promise.all([\n listInboxTasks(currentMemberId),\n listApprovalHistoryTasks(currentMemberId),\n ]);\n const [nextPendingRows, nextHistoryRows] = await Promise.all([\n readInboxTaskRows(nextPendingTasks),\n readApprovalHistoryRows(nextHistoryTasks),\n ]);\n\n setPendingRows(nextPendingRows);\n setHistoryRows(nextHistoryRows);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={`目前以 ${member?.name ?? currentMemberId ?? '目前登入會員'} 查詢待處理與歷史簽核任務。`}\n title=\"我的待簽\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.caseNew())}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab activeKey={activeTab} onChange={handleTabChange} size=\"sub\">\n <TabItem\n badgeCount={loading ? undefined : pendingRows.length}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={loading ? undefined : trackingRows.length}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={pendingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={trackingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={historyRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nasync function readInboxTaskRows(\n tasks: readonly TaskRecord[],\n): Promise<InboxTaskRow[]> {\n const instances = await readTaskInstances(tasks);\n\n return tasks.map(\n (task, index): InboxTaskRow => ({\n ...task,\n caseTitle: readTaskCaseTitle(task, instances[index] ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n slaStatusColor: readSlaStatusColor(task.slaDueAt),\n slaStatusText: readSlaStatusText(task.slaDueAt),\n statusLabel: readTaskStatusLabel(task.status),\n }),\n );\n}\n\nasync function readApprovalHistoryRows(\n tasks: readonly TaskRecord[],\n): Promise<ApprovalHistoryRow[]> {\n const [decisionLists, instances] = await Promise.all([\n Promise.all(tasks.map((task) => listTaskDecisions(task.id))),\n readTaskInstances(tasks),\n ]);\n\n return tasks.map((task, index): ApprovalHistoryRow => {\n const decision = readLatestTaskDecision(decisionLists[index] ?? []);\n const instance = instances[index] ?? null;\n\n return {\n ...task,\n caseTitle: readTaskCaseTitle(task, instance),\n decisionAction: decision?.action ?? null,\n decisionComment: decision?.comment ?? null,\n decisionCommentText: readDecisionCommentText(decision?.comment ?? null),\n decisionLabel: readTaskDecisionLabel(decision?.action ?? null),\n decidedAt: decision?.decidedAt ?? task.completedAt,\n instanceState: instance?.state ?? null,\n instanceStateLabel: readInstanceStateLabel(instance?.state ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n };\n });\n}\n\nasync function readTaskInstances(\n tasks: readonly TaskRecord[],\n): Promise<readonly (ApprovalInstanceRecord | null)[]> {\n return Promise.all(\n tasks.map(async (task): Promise<ApprovalInstanceRecord | null> => {\n try {\n return (await readApprovalInstance(task.instanceId)).instance;\n } catch {\n return null;\n }\n }),\n );\n}\n\nfunction readTaskCaseTitle(\n task: TaskRecord,\n instance: ApprovalInstanceRecord | null,\n): string {\n return instance ? readApprovalInstanceCaseTitle(instance) : task.instanceId;\n}\n\nfunction readLatestTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n): TaskDecisionRecord | null {\n return [...decisions].sort(compareTaskDecisionDesc)[0] ?? null;\n}\n\nfunction compareTaskDecisionDesc(\n left: TaskDecisionRecord,\n right: TaskDecisionRecord,\n): number {\n return (\n new Date(right.decidedAt).getTime() - new Date(left.decidedAt).getTime()\n );\n}\n\nfunction readTaskDecisionLabel(\n action: TaskDecisionRecord['action'] | null,\n): string {\n if (action === 'APPROVED') {\n return '同意';\n }\n\n if (action === 'REJECTED') {\n return '拒絕';\n }\n\n if (action === 'RETURNED') {\n return '退回';\n }\n\n if (action === 'TRANSFERRED') {\n return '轉派';\n }\n\n return '未記錄';\n}\n\nfunction readTaskDecisionColor(\n action: TaskDecisionRecord['action'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (action === 'APPROVED') {\n return 'text-success';\n }\n\n if (action === 'REJECTED' || action === 'RETURNED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readInstanceStateLabel(\n state: ApprovalInstanceRecord['state'] | null,\n): string {\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n if (state === 'APPROVED') {\n return '已通過';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n return '-';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceRecord['state'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') {\n return 'text-success';\n }\n\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readDecisionCommentText(comment: string | null): string {\n const trimmedComment = comment?.trim() ?? '';\n\n return trimmedComment || '-';\n}\n\nfunction formatHistoryDateTime(value: string | null): string {\n return formatDateTime(value);\n}\n\nfunction readSlaStatusText(value: string | null): string {\n if (!value) {\n return '-';\n }\n\n const dueAt = new Date(value).getTime();\n const now = Date.now();\n const diffMs = Math.abs(dueAt - now);\n const label = formatDuration(diffMs);\n\n return dueAt < now ? `已逾期 ${label}` : `剩餘 ${label}`;\n}\n\nfunction readSlaStatusColor(\n value: string | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (!value) {\n return 'text-neutral';\n }\n\n return new Date(value).getTime() < Date.now() ? 'text-error' : 'text-success';\n}\n\nfunction formatDuration(value: number): string {\n const totalMinutes = Math.max(1, Math.ceil(value / 60_000));\n const days = Math.floor(totalMinutes / 1440);\n const hours = Math.floor((totalMinutes % 1440) / 60);\n const minutes = totalMinutes % 60;\n\n if (days > 0) {\n return `${days}天 ${hours}小時`;\n }\n\n if (hours > 0) {\n return `${hours}小時 ${minutes}分鐘`;\n }\n\n return `${minutes}分鐘`;\n}\n\nfunction readTaskStatusLabel(status: TaskRecord['status']): string {\n if (status === 'PENDING') {\n return '待處理';\n }\n\n if (status === 'IN_PROGRESS') {\n return '處理中';\n }\n\n if (status === 'COMPLETED') {\n return '已完成';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n if (status === 'CANCELLED') {\n return '已取消';\n }\n\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["useRouterAdapter","useBPMRoutes","useAuth","useState","useMemo","Typography","formatDateTime","listInboxTasks","listApprovalHistoryTasks","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Tab","TabItem","Table","readTaskNodeText","listTaskDecisions","readApprovalInstance","readApprovalInstanceCaseTitle","require_rolldown_runtime","require_router_adapter","require_auth_provider","require_format_date_time","require_routes_config","require_task_node_label","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","error","setError","historyRows","setHistoryRows","loading","setLoading","pendingRows","setPendingRows","refreshTasks","pendingColumns","record","pendingTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","trackingRows","row","handleTabChange","activeKey","nextPendingTasks","nextHistoryTasks","nextPendingRows","nextHistoryRows","readInboxTaskRows","readApprovalHistoryRows","requestError","readErrorMessage","instances","readTaskInstances","tasks","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","decision","readLatestTaskDecision","instance","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","decisions","compareTaskDecisionDesc","right","left","action","state","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport { type Key, ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\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 type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n ApprovalInstanceRecord,\n listApprovalHistoryTasks,\n listInboxTasks,\n listTaskDecisions,\n readApprovalInstance,\n readApprovalInstanceCaseTitle,\n TaskDecisionRecord,\n TaskRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useAuth } from '../../lib/auth-provider';\nimport { readTaskNodeText } from '../../lib/task-node-label';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\n\ntype InboxTabKey = 'history' | 'pending' | 'tracking';\n\ntype InboxTaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n key: string;\n nodeText: string;\n slaStatusColor: 'text-error' | 'text-neutral' | 'text-success';\n slaStatusText: string;\n statusLabel: string;\n }\n>;\n\ntype ApprovalHistoryRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n decisionAction: TaskDecisionRecord['action'] | null;\n decisionComment: string | null;\n decisionCommentText: string;\n decisionLabel: string;\n decidedAt: string | null;\n instanceState: ApprovalInstanceRecord['state'] | null;\n instanceStateLabel: string;\n key: string;\n nodeText: string;\n }\n>;\n\n\n/**\n * Framework-agnostic view for the BPM \"我的待簽\" inbox. Mechanical port of\n * `apps/client/src/app/inbox/page.tsx` — renders pending tasks, tracking,\n * and history tabs.\n */\nexport function InboxView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activeTab, setActiveTab] = useState<InboxTabKey>('pending');\n const [error, setError] = useState<string | null>(null);\n const [historyRows, setHistoryRows] = useState<ApprovalHistoryRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [pendingRows, setPendingRows] = useState<InboxTaskRow[]>([]);\n\n useEffect((): void => {\n if (!currentMemberId) {\n return;\n }\n\n void refreshTasks();\n }, [currentMemberId]);\n\n const pendingColumns = useMemo(\n (): TableColumn<InboxTaskRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'slaDueAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography\n color={record.slaStatusColor}\n component=\"span\"\n variant=\"body\"\n >\n {record.slaStatusText}\n </Typography>\n ),\n title: 'SLA',\n width: 180,\n },\n {\n key: 'createdAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.createdAt)}\n </Typography>\n ),\n title: '建立時間',\n width: 220,\n },\n ],\n [],\n );\n const pendingTableActions = useMemo(\n (): TableActions<InboxTaskRow> => ({\n render: (record): ReturnType<TableActions<InboxTaskRow>['render']> => [\n {\n name: '處理',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const historyColumns = useMemo(\n (): TableColumn<ApprovalHistoryRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n key: 'decisionLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readTaskDecisionColor(record.decisionAction)}\n component=\"span\"\n variant=\"body\"\n >\n {record.decisionLabel}\n </Typography>\n ),\n title: '決議',\n width: 120,\n },\n {\n key: 'decisionComment',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.decisionCommentText}\n </Typography>\n ),\n title: '意見',\n width: 240,\n },\n {\n key: 'instanceStateLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.instanceState)}\n component=\"span\"\n variant=\"body\"\n >\n {record.instanceStateLabel}\n </Typography>\n ),\n title: '流程狀態',\n width: 140,\n },\n {\n key: 'decidedAt',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatHistoryDateTime(record.decidedAt)}\n </Typography>\n ),\n title: '簽核時間',\n width: 220,\n },\n ],\n [],\n );\n const historyTableActions = useMemo(\n (): TableActions<ApprovalHistoryRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalHistoryRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const trackingRows = useMemo(\n (): ApprovalHistoryRow[] =>\n historyRows.filter((row) => row.instanceState === 'RUNNING'),\n [historyRows],\n );\n\n function handleTabChange(activeKey: Key): void {\n if (\n activeKey === 'history' ||\n activeKey === 'pending' ||\n activeKey === 'tracking'\n ) {\n setActiveTab(activeKey);\n return;\n }\n\n setActiveTab('pending');\n }\n\n async function refreshTasks(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n if (!currentMemberId) {\n setPendingRows([]);\n setHistoryRows([]);\n return;\n }\n\n const [nextPendingTasks, nextHistoryTasks] = await Promise.all([\n listInboxTasks(currentMemberId),\n listApprovalHistoryTasks(currentMemberId),\n ]);\n const [nextPendingRows, nextHistoryRows] = await Promise.all([\n readInboxTaskRows(nextPendingTasks),\n readApprovalHistoryRows(nextHistoryTasks),\n ]);\n\n setPendingRows(nextPendingRows);\n setHistoryRows(nextHistoryRows);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={`目前以 ${member?.name ?? currentMemberId ?? '目前登入會員'} 查詢待處理與歷史簽核任務。`}\n title=\"我的待簽\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.caseNew())}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab activeKey={activeTab} onChange={handleTabChange} size=\"sub\">\n <TabItem\n badgeCount={loading ? undefined : pendingRows.length}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={loading ? undefined : trackingRows.length}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={pendingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={trackingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={historyRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nasync function readInboxTaskRows(\n tasks: readonly TaskRecord[],\n): Promise<InboxTaskRow[]> {\n const instances = await readTaskInstances(tasks);\n\n return tasks.map(\n (task, index): InboxTaskRow => ({\n ...task,\n caseTitle: readTaskCaseTitle(task, instances[index] ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n slaStatusColor: readSlaStatusColor(task.slaDueAt),\n slaStatusText: readSlaStatusText(task.slaDueAt),\n statusLabel: readTaskStatusLabel(task.status),\n }),\n );\n}\n\nasync function readApprovalHistoryRows(\n tasks: readonly TaskRecord[],\n): Promise<ApprovalHistoryRow[]> {\n const [decisionLists, instances] = await Promise.all([\n Promise.all(tasks.map((task) => listTaskDecisions(task.id))),\n readTaskInstances(tasks),\n ]);\n\n return tasks.map((task, index): ApprovalHistoryRow => {\n const decision = readLatestTaskDecision(decisionLists[index] ?? []);\n const instance = instances[index] ?? null;\n\n return {\n ...task,\n caseTitle: readTaskCaseTitle(task, instance),\n decisionAction: decision?.action ?? null,\n decisionComment: decision?.comment ?? null,\n decisionCommentText: readDecisionCommentText(decision?.comment ?? null),\n decisionLabel: readTaskDecisionLabel(decision?.action ?? null),\n decidedAt: decision?.decidedAt ?? task.completedAt,\n instanceState: instance?.state ?? null,\n instanceStateLabel: readInstanceStateLabel(instance?.state ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n };\n });\n}\n\nasync function readTaskInstances(\n tasks: readonly TaskRecord[],\n): Promise<readonly (ApprovalInstanceRecord | null)[]> {\n return Promise.all(\n tasks.map(async (task): Promise<ApprovalInstanceRecord | null> => {\n try {\n return (await readApprovalInstance(task.instanceId)).instance;\n } catch {\n return null;\n }\n }),\n );\n}\n\nfunction readTaskCaseTitle(\n task: TaskRecord,\n instance: ApprovalInstanceRecord | null,\n): string {\n return instance ? readApprovalInstanceCaseTitle(instance) : task.instanceId;\n}\n\nfunction readLatestTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n): TaskDecisionRecord | null {\n return [...decisions].sort(compareTaskDecisionDesc)[0] ?? null;\n}\n\nfunction compareTaskDecisionDesc(\n left: TaskDecisionRecord,\n right: TaskDecisionRecord,\n): number {\n return (\n new Date(right.decidedAt).getTime() - new Date(left.decidedAt).getTime()\n );\n}\n\nfunction readTaskDecisionLabel(\n action: TaskDecisionRecord['action'] | null,\n): string {\n if (action === 'APPROVED') {\n return '同意';\n }\n\n if (action === 'REJECTED') {\n return '拒絕';\n }\n\n if (action === 'RETURNED') {\n return '退回';\n }\n\n if (action === 'TRANSFERRED') {\n return '轉派';\n }\n\n return '未記錄';\n}\n\nfunction readTaskDecisionColor(\n action: TaskDecisionRecord['action'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (action === 'APPROVED') {\n return 'text-success';\n }\n\n if (action === 'REJECTED' || action === 'RETURNED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readInstanceStateLabel(\n state: ApprovalInstanceRecord['state'] | null,\n): string {\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n if (state === 'APPROVED') {\n return '已通過';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n return '-';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceRecord['state'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') {\n return 'text-success';\n }\n\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readDecisionCommentText(comment: string | null): string {\n const trimmedComment = comment?.trim() ?? '';\n\n return trimmedComment || '-';\n}\n\nfunction formatHistoryDateTime(value: string | null): string {\n return formatDateTime(value);\n}\n\nfunction readSlaStatusText(value: string | null): string {\n if (!value) {\n return '-';\n }\n\n const dueAt = new Date(value).getTime();\n const now = Date.now();\n const diffMs = Math.abs(dueAt - now);\n const label = formatDuration(diffMs);\n\n return dueAt < now ? `已逾期 ${label}` : `剩餘 ${label}`;\n}\n\nfunction readSlaStatusColor(\n value: string | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (!value) {\n return 'text-neutral';\n }\n\n return new Date(value).getTime() < Date.now() ? 'text-error' : 'text-success';\n}\n\nfunction formatDuration(value: number): string {\n const totalMinutes = Math.max(1, Math.ceil(value / 60_000));\n const days = Math.floor(totalMinutes / 1440);\n const hours = Math.floor((totalMinutes % 1440) / 60);\n const minutes = totalMinutes % 60;\n\n if (days > 0) {\n return `${days}天 ${hours}小時`;\n }\n\n if (hours > 0) {\n return `${hours}小時 ${minutes}分鐘`;\n }\n\n return `${minutes}分鐘`;\n}\n\nfunction readTaskStatusLabel(status: TaskRecord['status']): string {\n if (status === 'PENDING') {\n return '待處理';\n }\n\n if (status === 'IN_PROGRESS') {\n return '處理中';\n }\n\n if (status === 'COMPLETED') {\n return '已完成';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n if (status === 'CANCELLED') {\n return '已取消';\n }\n\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"ioBAoEA,SAAgBmC,GAA0B,CACxC,IAAMC,EAASpC,EAAAA,EAAiB,EAC1BqC,EAASpC,EAAAA,EAAa,EACtB,CAAE,UAAWC,EAAAA,EAAQ,EACrBoC,EAAkBC,GAAQ,UAAY,KACtC,CAACC,EAAWC,IAAA,EAAgBtC,EAAAA,SAAAA,CAAsB,SAAS,EAC3D,CAACuC,EAAOC,IAAA,EAAYxC,EAAAA,SAAAA,CAAwB,IAAI,EAChD,CAACyC,EAAaC,IAAA,EAAkB1C,EAAAA,SAAAA,CAA+B,CAAC,CAAC,EACjE,CAAC2C,EAASC,IAAA,EAAc5C,EAAAA,SAAAA,CAAS,EAAI,EACrC,CAAC6C,EAAaC,IAAA,EAAkB9C,EAAAA,SAAAA,CAAyB,CAAC,CAAC,GAEjE,EAAA0B,EAAA,UAAA,KAAsB,CACfS,GAILY,EAAkB,CACpB,EAAG,CAACZ,CAAe,CAAC,EAEpB,IAAMa,GAAA,EAAiB/C,EAAAA,QAAAA,KACc,CACjC,CAAE,UAAW,YAAa,IAAK,YAAa,MAAO,KAAM,MAAO,GAAI,EACpE,CAAE,UAAW,WAAY,IAAK,WAAY,MAAO,KAAM,MAAO,GAAI,EAClE,CACE,UAAW,cACX,IAAK,cACL,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,WACL,OAAS,IACP,EAAA2B,EAAA,IAAA,CAAC1B,EAAAA,WAAD,CACE,MAAO+C,EAAO,eACd,UAAU,OACV,QAAQ,OAEP,SAAAA,EAAO,aACE,CAAA,EAEd,MAAO,MACP,MAAO,GACT,EACA,CACE,IAAK,YACL,OAAS,IACP,EAAArB,EAAA,IAAA,CAAC1B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAC,EAAAA,EAAe8C,EAAO,SAAS,CACtB,CAAA,EAEd,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EACMC,GAAA,EAAsBjD,EAAAA,QAAAA,MACS,CACjC,OAAS,GAA6D,CACpE,CACE,KAAM,KACN,YAAqBgC,EAAO,KAAKC,EAAO,WAAWe,EAAO,UAAU,CAAC,CACvE,CACF,EACA,QAAS,iBACT,MAAO,EACT,GACA,CAAChB,EAAQC,CAAM,CACjB,EACMiB,GAAA,EAAiBlD,EAAAA,QAAAA,KACoB,CACvC,CAAE,UAAW,YAAa,IAAK,YAAa,MAAO,KAAM,MAAO,GAAI,EACpE,CAAE,UAAW,WAAY,IAAK,WAAY,MAAO,KAAM,MAAO,GAAI,EAClE,CACE,IAAK,gBACL,OAAS,IACP,EAAA2B,EAAA,IAAA,CAAC1B,EAAAA,WAAD,CACE,MAAOkD,EAAsBH,EAAO,cAAc,EAClD,UAAU,OACV,QAAQ,OAEP,SAAAA,EAAO,aACE,CAAA,EAEd,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,kBACL,OAAS,IACP,EAAArB,EAAA,IAAA,CAAC1B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAA+C,EAAO,mBACE,CAAA,EAEd,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,qBACL,OAAS,IACP,EAAArB,EAAA,IAAA,CAAC1B,EAAAA,WAAD,CACE,MAAOmD,EAAuBJ,EAAO,aAAa,EAClD,UAAU,OACV,QAAQ,OAEP,SAAAA,EAAO,kBACE,CAAA,EAEd,MAAO,OACP,MAAO,GACT,EACA,CACE,IAAK,YACL,OAAS,IACP,EAAArB,EAAA,IAAA,CAAC1B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAoD,EAAsBL,EAAO,SAAS,CAC7B,CAAA,EAEd,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EACMM,GAAA,EAAsBtD,EAAAA,QAAAA,MACe,CACvC,OACE,GAC2D,CAC3D,CACE,KAAM,KACN,YAAqBgC,EAAO,KAAKC,EAAO,WAAWe,EAAO,UAAU,CAAC,CACvE,CACF,EACA,QAAS,iBACT,MAAO,EACT,GACA,CAAChB,EAAQC,CAAM,CACjB,EACMsB,GAAA,EAAevD,EAAAA,QAAAA,KAEjBwC,EAAY,OAAQ,GAAQgB,EAAI,gBAAkB,SAAS,EAC7D,CAAChB,CAAW,CACd,EAEA,SAASiB,EAAgB,EAAsB,CAM3CpB,EAJAqB,IAAc,WACdA,IAAc,WACdA,IAAc,WAEDA,EAIF,SAFb,CAGF,CAEA,eAAeZ,GAA8B,CAC3CH,EAAW,EAAI,EACfJ,EAAS,IAAI,EAEb,GAAI,CACF,GAAI,CAACL,EAAiB,CACpBW,EAAe,CAAC,CAAC,EACjBJ,EAAe,CAAC,CAAC,EACjB,MACF,CAEA,GAAM,CAACkB,EAAkBC,GAAoB,MAAM,QAAQ,IAAI,EAAA,EAC7DzD,EAAAA,eAAAA,CAAe+B,CAAe,GAAA,EAC9B9B,EAAAA,yBAAAA,CAAyB8B,CAAe,CAC1C,CAAC,EACK,CAAC2B,EAAiBC,GAAmB,MAAM,QAAQ,IAAI,CAC3DC,EAAkBJ,CAAgB,EAClCK,EAAwBJ,CAAgB,CAC1C,CAAC,EAEDf,EAAegB,CAAe,EAC9BpB,EAAeqB,CAAe,CAChC,OAASG,EAAuB,CAC9B1B,EAAS2B,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRtB,EAAW,EAAK,CAClB,CACF,CAEA,OACE,EAAAhB,EAAA,KAAA,CAAAtB,EAAAA,SAAA,CAAA,SAAA,EACI,EAAAsB,EAAA,IAAA,CAACrB,EAAAA,WAAD,CAAA,UACE,EAAAqB,EAAA,IAAA,CAACpB,EAAAA,QAAD,CACE,YAAa,OAAO4B,GAAQ,MAAQD,GAAmB,SAAS,gBAChE,MAAM,OAEN,UAAA,EAAAP,EAAA,IAAA,CAACnB,EAAAA,OAAD,CACE,KAAMC,EAAAA,SACN,SAAS,UACT,YAAqBuB,EAAO,KAAKC,EAAO,QAAQ,CAAC,EACjD,QAAQ,eACT,SAAA,MAEO,CAAA,CACK,CAAA,CACL,CAAA,GAEZ,EAAAN,EAAA,IAAA,CAACjB,EAAAA,aAAD,CAAA,UACE,EAAAiB,EAAA,KAAA,CAAChB,EAAAA,QAAD,CAAA,SAAA,CACG2B,GACC,EAAAX,EAAA,IAAA,CAAC1B,EAAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,OACpC,SAAAqC,CACS,CAAA,EACV,MACJ,EAAAX,EAAA,KAAA,CAACf,EAAAA,IAAD,CAAK,UAAWwB,EAAW,SAAUqB,EAAiB,KAAK,MAA3D,SAAA,EACE,EAAA9B,EAAA,IAAA,CAACd,EAAAA,QAAD,CACE,WAAY6B,EAAU,IAAA,GAAYE,EAAY,OAE/C,SAAA,KAEQ,EAHH,SAGG,GACT,EAAAjB,EAAA,IAAA,CAACd,EAAAA,QAAD,CACE,WAAY6B,EAAU,IAAA,GAAYa,EAAa,OAEhD,SAAA,QAEQ,EAHH,UAGG,GACT,EAAA5B,EAAA,IAAA,CAACd,EAAAA,QAAD,CAAA,SAAuB,QAAe,EAAzB,SAAyB,CACnC,IAEJuB,IAAc,WACb,EAAAT,EAAA,IAAA,CAACb,EAAAA,MAAD,CACE,QAASmC,EACT,QAASF,EACT,WAAYH,EACZ,UAAA,GACS,SACV,CAAA,EACC,KACHR,IAAc,YACb,EAAAT,EAAA,IAAA,CAACb,EAAAA,MAAD,CACE,QAASwC,EACT,QAASJ,EACT,WAAYK,EACZ,UAAA,GACS,SACV,CAAA,EACC,KACHnB,IAAc,WACb,EAAAT,EAAA,IAAA,CAACb,EAAAA,MAAD,CACE,QAASwC,EACT,QAASJ,EACT,WAAYV,EACZ,UAAA,GACS,SACV,CAAA,EACC,IACG,CAAA,CAAA,CACG,CAAA,CACd,CAAA,CAAA,CAER,CAEA,eAAeuB,EACb,EACyB,CACzB,IAAMI,EAAY,MAAMC,EAAkBC,CAAK,EAE/C,OAAOA,EAAM,KACV,EAAM,KAAyB,CAC9B,GAAGC,EACH,UAAWC,EAAkBD,EAAMH,EAAUK,IAAU,IAAI,EAC3D,IAAKF,EAAK,GACV,SAAUvD,EAAAA,EAAiBuD,CAAI,EAC/B,eAAgBG,EAAmBH,EAAK,QAAQ,EAChD,cAAeI,EAAkBJ,EAAK,QAAQ,EAC9C,YAAaK,EAAoBL,EAAK,MAAM,CAC9C,EACF,CACF,CAEA,eAAeN,EACb,EAC+B,CAC/B,GAAM,CAACY,EAAeT,GAAa,MAAM,QAAQ,IAAI,CACnD,QAAQ,IAAIE,EAAM,IAAK,IAAA,EAASrD,EAAAA,kBAAAA,CAAkBsD,EAAK,EAAE,CAAC,CAAC,EAC3DF,EAAkBC,CAAK,CACzB,CAAC,EAED,OAAOA,EAAM,KAAK,EAAM,IAA8B,CACpD,IAAMQ,EAAWC,EAAuBF,EAAcJ,IAAU,CAAC,CAAC,EAC5DO,EAAWZ,EAAUK,IAAU,KAErC,MAAO,CACL,GAAGF,EACH,UAAWC,EAAkBD,EAAMS,CAAQ,EAC3C,eAAgBF,GAAU,QAAU,KACpC,gBAAiBA,GAAU,SAAW,KACtC,oBAAqBG,EAAwBH,GAAU,SAAW,IAAI,EACtE,cAAeI,EAAsBJ,GAAU,QAAU,IAAI,EAC7D,UAAWA,GAAU,WAAaP,EAAK,YACvC,cAAeS,GAAU,OAAS,KAClC,mBAAoBG,EAAuBH,GAAU,OAAS,IAAI,EAClE,IAAKT,EAAK,GACV,SAAUvD,EAAAA,EAAiBuD,CAAI,CACjC,CACF,CAAC,CACH,CAEA,eAAeF,EACb,EACqD,CACrD,OAAO,QAAQ,IACbC,EAAM,IAAI,KAAO,IAAiD,CAChE,GAAI,CACF,OAAQ,MAAA,EAAMpD,EAAAA,qBAAAA,CAAqBqD,EAAK,UAAU,EAAA,CAAG,QACvD,MAAQ,CACN,OAAO,IACT,CACF,CAAC,CACH,CACF,CAEA,SAASC,EACP,EACA,EACQ,CACR,OAAOQ,GAAA,EAAW7D,EAAAA,8BAAAA,CAA8B6D,CAAQ,EAAIT,EAAK,UACnE,CAEA,SAASQ,EACP,EAC2B,CAC3B,MAAO,CAAC,GAAGK,CAAS,CAAC,CAAC,KAAKC,CAAuB,CAAC,CAAC,IAAM,IAC5D,CAEA,SAASA,EACP,EACA,EACQ,CACR,OACE,IAAI,KAAKC,EAAM,SAAS,CAAC,CAAC,QAAQ,EAAI,IAAI,KAAKC,EAAK,SAAS,CAAC,CAAC,QAAQ,CAE3E,CAEA,SAASL,EACP,EACQ,CAiBR,OAhBIM,IAAW,WACN,KAGLA,IAAW,WACN,KAGLA,IAAW,WACN,KAGLA,IAAW,cACN,KAGF,KACT,CAEA,SAASpC,EACP,EACgD,CAShD,OARIoC,IAAW,WACN,eAGLA,IAAW,YAAcA,IAAW,WAC/B,aAGF,cACT,CAEA,SAASL,EACP,EACQ,CA6BR,OA5BIM,IAAU,UACL,MAGLA,IAAU,WACL,MAGLA,IAAU,WACL,MAGLA,IAAU,WACL,MAGLA,IAAU,YACL,MAGLA,IAAU,UACL,MAGLA,IAAU,QACL,KAGF,GACT,CAEA,SAASpC,EACP,EACgD,CAShD,OARIoC,IAAU,WACL,eAGLA,IAAU,YAAcA,IAAU,aAAeA,IAAU,UACtD,aAGF,cACT,CAEA,SAASR,EAAwB,EAAgC,CAG/D,OAFuBS,GAAS,KAAK,GAAK,KAEjB,GAC3B,CAEA,SAASpC,EAAsB,EAA8B,CAC3D,OAAOnD,EAAAA,EAAewF,CAAK,CAC7B,CAEA,SAAShB,EAAkB,EAA8B,CACvD,GAAI,CAACgB,EACH,MAAO,IAGT,IAAMC,EAAQ,IAAI,KAAKD,CAAK,CAAC,CAAC,QAAQ,EAChCE,EAAM,KAAK,IAAI,EAEfC,EAAQC,EADC,KAAK,IAAIH,EAAQC,CACH,CAAM,EAEnC,OAAOD,EAAQC,EAAM,OAAOC,IAAU,MAAMA,GAC9C,CAEA,SAASpB,EACP,EACgD,CAKhD,OAJKiB,EAIE,IAAI,KAAKA,CAAK,CAAC,CAAC,QAAQ,EAAI,KAAK,IAAI,EAAI,aAAe,eAHtD,cAIX,CAEA,SAASI,EAAe,EAAuB,CAC7C,IAAMC,EAAe,KAAK,IAAI,EAAG,KAAK,KAAKL,EAAQ,GAAM,CAAC,EACpDM,EAAO,KAAK,MAAMD,EAAe,IAAI,EACrCE,EAAQ,KAAK,MAAOF,EAAe,KAAQ,EAAE,EAC7CG,EAAUH,EAAe,GAU/B,OARIC,EAAO,EACF,GAAGA,EAAK,IAAIC,EAAM,IAGvBA,EAAQ,EACH,GAAGA,EAAM,KAAKC,EAAQ,IAGxB,GAAGA,EAAQ,GACpB,CAEA,SAASvB,EAAoB,EAAsC,CAqBjE,OApBIwB,IAAW,UACN,MAGLA,IAAW,cACN,MAGLA,IAAW,YACN,MAGLA,IAAW,cACN,MAGLA,IAAW,YACN,MAGFA,CACT,CAEA,SAASjC,EAAiB,EAAwB,CAChD,OAAO5B,aAAiB,MAAQA,EAAM,QAAU,QAClD"}
|
|
@@ -127,11 +127,7 @@ function E() {
|
|
|
127
127
|
width: 88
|
|
128
128
|
}), [i, x]), K = o(() => M.filter((e) => e.instanceState === "RUNNING"), [M]);
|
|
129
129
|
function q(e) {
|
|
130
|
-
|
|
131
|
-
k(e);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
k("pending");
|
|
130
|
+
k(e === "history" || e === "pending" || e === "tracking" ? e : "pending");
|
|
135
131
|
}
|
|
136
132
|
async function J() {
|
|
137
133
|
L(!0), j(null);
|