@rytass/bpm-core-react 0.20.1 → 0.21.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -1
  3. package/dist/approval-instance-list-page.css +1 -1
  4. package/dist/chunks/FormBuilderView-DjPGrOJ2.cjs +4 -0
  5. package/dist/chunks/FormBuilderView-DjPGrOJ2.cjs.map +1 -0
  6. package/dist/chunks/{FormBuilderView-CFRiw04B.js → FormBuilderView-WtC2iW5f.js} +667 -584
  7. package/dist/chunks/FormBuilderView-WtC2iW5f.js.map +1 -0
  8. package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs → FormRendererView-B-xycC9S.cjs} +3 -3
  9. package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs.map → FormRendererView-B-xycC9S.cjs.map} +1 -1
  10. package/dist/chunks/{FormRendererView-GfbVWEGa.js → FormRendererView-BcQKUi1A.js} +238 -238
  11. package/dist/chunks/{FormRendererView-GfbVWEGa.js.map → FormRendererView-BcQKUi1A.js.map} +1 -1
  12. package/dist/chunks/approval-instance-list-page-Bth7Raya.js +724 -0
  13. package/dist/chunks/approval-instance-list-page-Bth7Raya.js.map +1 -0
  14. package/dist/chunks/approval-instance-list-page-Dcvo6TrT.cjs +2 -0
  15. package/dist/chunks/approval-instance-list-page-Dcvo6TrT.cjs.map +1 -0
  16. package/dist/chunks/{categories-DQUtVEiV.cjs → categories-CyyqG6wG.cjs} +2 -2
  17. package/dist/chunks/{categories-DQUtVEiV.cjs.map → categories-CyyqG6wG.cjs.map} +1 -1
  18. package/dist/chunks/{categories-BAdxjNSA.js → categories-f7E-RJEc.js} +9 -9
  19. package/dist/chunks/{categories-BAdxjNSA.js.map → categories-f7E-RJEc.js.map} +1 -1
  20. package/dist/chunks/{compose-Bb5bUVFd.cjs → compose-BKUTsB2W.cjs} +2 -2
  21. package/dist/chunks/{compose-Bb5bUVFd.cjs.map → compose-BKUTsB2W.cjs.map} +1 -1
  22. package/dist/chunks/{compose-egQlRjuZ.js → compose-DZvIspW3.js} +4 -4
  23. package/dist/chunks/{compose-egQlRjuZ.js.map → compose-DZvIspW3.js.map} +1 -1
  24. package/dist/chunks/{delegations-CVmtpkRn.cjs → delegations-ClRCwD1I.cjs} +2 -2
  25. package/dist/chunks/{delegations-CVmtpkRn.cjs.map → delegations-ClRCwD1I.cjs.map} +1 -1
  26. package/dist/chunks/{delegations-9-yvWWws.js → delegations-CqND-Qtz.js} +5 -5
  27. package/dist/chunks/{delegations-9-yvWWws.js.map → delegations-CqND-Qtz.js.map} +1 -1
  28. package/dist/chunks/{delegations-CrfjsH94.cjs → delegations-D43VDSz1.cjs} +2 -2
  29. package/dist/chunks/{delegations-CrfjsH94.cjs.map → delegations-D43VDSz1.cjs.map} +1 -1
  30. package/dist/chunks/{delegations-CxnNvTCc.js → delegations-zisffLwk.js} +5 -5
  31. package/dist/chunks/{delegations-CxnNvTCc.js.map → delegations-zisffLwk.js.map} +1 -1
  32. package/dist/chunks/{designer-CZDlQ9Nf.js → designer-CWubIE69.js} +1425 -1412
  33. package/dist/chunks/designer-CWubIE69.js.map +1 -0
  34. package/dist/chunks/designer-C_m8DmMl.cjs +69 -0
  35. package/dist/chunks/designer-C_m8DmMl.cjs.map +1 -0
  36. package/dist/chunks/{detail-ByZV1XaI.js → detail-Bv90gvy0.js} +578 -577
  37. package/dist/chunks/detail-Bv90gvy0.js.map +1 -0
  38. package/dist/chunks/detail-DNzqesdI.cjs +5 -0
  39. package/dist/chunks/detail-DNzqesdI.cjs.map +1 -0
  40. package/dist/chunks/instance-error-message-BW464LRQ.cjs +2 -0
  41. package/dist/chunks/instance-error-message-BW464LRQ.cjs.map +1 -0
  42. package/dist/chunks/instance-error-message-CAP1vJhX.js +204 -0
  43. package/dist/chunks/instance-error-message-CAP1vJhX.js.map +1 -0
  44. package/dist/components/approval-instance-field-filter-controls.d.cts +12 -0
  45. package/dist/components/approval-instance-field-filter-controls.d.ts +12 -0
  46. package/dist/components/approval-instance-field-filters.d.cts +86 -0
  47. package/dist/components/approval-instance-field-filters.d.ts +86 -0
  48. package/dist/components/approval-instance-list-page.d.cts +4 -0
  49. package/dist/components/approval-instance-list-page.d.ts +4 -0
  50. package/dist/index.cjs +1 -1
  51. package/dist/index.js +1 -1
  52. package/dist/next/workflow-chat-route.cjs +2 -2
  53. package/dist/next/workflow-chat-route.cjs.map +1 -1
  54. package/dist/next/workflow-chat-route.js +13 -13
  55. package/dist/pages/admin/delegations/index.cjs +1 -1
  56. package/dist/pages/admin/delegations/index.js +1 -1
  57. package/dist/pages/delegations/index.cjs +1 -1
  58. package/dist/pages/delegations/index.js +1 -1
  59. package/dist/pages/instances/detail/index.cjs +1 -1
  60. package/dist/pages/instances/detail/index.js +1 -1
  61. package/dist/pages/templates/categories/index.cjs +1 -1
  62. package/dist/pages/templates/categories/index.js +1 -1
  63. package/dist/pages/templates/compose/index.cjs +1 -1
  64. package/dist/pages/templates/compose/index.js +1 -1
  65. package/dist/pages/templates/designer/index.cjs +1 -1
  66. package/dist/pages/templates/designer/index.js +1 -1
  67. package/dist/views/admin/delegations/index.cjs +1 -1
  68. package/dist/views/admin/delegations/index.js +1 -1
  69. package/dist/views/admin/index.cjs +1 -1
  70. package/dist/views/admin/index.js +1 -1
  71. package/dist/views/admin/webhook-endpoints/index.cjs +1 -1
  72. package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
  73. package/dist/views/admin/webhook-endpoints/index.js +60 -60
  74. package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
  75. package/dist/views/cc/index.cjs +1 -1
  76. package/dist/views/cc/index.js +1 -1
  77. package/dist/views/delegations/index.cjs +1 -1
  78. package/dist/views/delegations/index.js +1 -1
  79. package/dist/views/forms/builder/FormBuilderView.d.cts +8 -1
  80. package/dist/views/forms/builder/FormBuilderView.d.ts +8 -1
  81. package/dist/views/forms/builder/index.cjs +1 -1
  82. package/dist/views/forms/builder/index.js +1 -1
  83. package/dist/views/forms/renderer/index.cjs +1 -1
  84. package/dist/views/forms/renderer/index.js +1 -1
  85. package/dist/views/instances/approver-filled-form.d.cts +8 -5
  86. package/dist/views/instances/approver-filled-form.d.ts +8 -5
  87. package/dist/views/instances/detail/index.cjs +1 -1
  88. package/dist/views/instances/detail/index.js +1 -1
  89. package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +2 -1
  90. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +2 -1
  91. package/dist/views/instances/new/index.cjs +1 -1
  92. package/dist/views/instances/new/index.cjs.map +1 -1
  93. package/dist/views/instances/new/index.js +8 -8
  94. package/dist/views/instances/new/index.js.map +1 -1
  95. package/dist/views/search/index.cjs +1 -1
  96. package/dist/views/search/index.js +1 -1
  97. package/dist/views/sent/index.cjs +1 -1
  98. package/dist/views/sent/index.js +1 -1
  99. package/dist/views/templates/categories/index.cjs +1 -1
  100. package/dist/views/templates/categories/index.js +1 -1
  101. package/dist/views/templates/compose/index.cjs +1 -1
  102. package/dist/views/templates/compose/index.js +1 -1
  103. package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.cts +2 -0
  104. package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.ts +2 -0
  105. package/dist/views/templates/designer/index.cjs +1 -1
  106. package/dist/views/templates/designer/index.js +1 -1
  107. package/dist/views/templates/index.cjs +1 -1
  108. package/dist/views/templates/index.cjs.map +1 -1
  109. package/dist/views/templates/index.js +7 -7
  110. package/package.json +3 -3
  111. package/dist/chunks/FormBuilderView-CFRiw04B.js.map +0 -1
  112. package/dist/chunks/FormBuilderView-CpUgbSbt.cjs +0 -3
  113. package/dist/chunks/FormBuilderView-CpUgbSbt.cjs.map +0 -1
  114. package/dist/chunks/approval-instance-list-page-BnI4t5mD.js +0 -279
  115. package/dist/chunks/approval-instance-list-page-BnI4t5mD.js.map +0 -1
  116. package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs +0 -2
  117. package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs.map +0 -1
  118. package/dist/chunks/designer-CX9bhYJS.cjs +0 -69
  119. package/dist/chunks/designer-CX9bhYJS.cjs.map +0 -1
  120. package/dist/chunks/designer-CZDlQ9Nf.js.map +0 -1
  121. package/dist/chunks/detail-ByZV1XaI.js.map +0 -1
  122. package/dist/chunks/detail-ChseSF55.cjs +0 -5
  123. package/dist/chunks/detail-ChseSF55.cjs.map +0 -1
  124. package/dist/chunks/instance-error-message-DTARGbGo.cjs +0 -2
  125. package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +0 -1
  126. package/dist/chunks/instance-error-message-q6gy5evy.js +0 -120
  127. package/dist/chunks/instance-error-message-q6gy5evy.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useState","useCallback","readWorkflowWebhookEndpointManagement","listWorkflowWebhookManagedEndpoints","useMemo","Typography","Badge","formatDateTime","testWorkflowWebhookEndpoint","setWorkflowWebhookEndpointActive","listWorkflowWebhookEndpointAudits","updateWorkflowWebhookEndpoint","createWorkflowWebhookEndpoint","rotateWorkflowWebhookEndpointSecret","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Table","Modal","BPMFormField","Toggle","Input","Textarea","Select","TrashIcon","require_rolldown_runtime","require_bpm_form_field","require_format_date_time","react","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","_rytass_bpm_core_client_template","STACK_STYLE","ROW_STYLE","HEADER_ROW_STYLE","METHOD_OPTIONS","PARAMETER_TYPE_OPTIONS","AUDIT_ACTION_LABELS","EMPTY_DRAFT","AdminWebhookEndpointsView","management","setManagement","endpoints","setEndpoints","loading","setLoading","error","setError","notice","setNotice","draft","setDraft","saving","setSaving","rotating","setRotating","nextSecret","setNextSecret","removeSecret","setRemoveSecret","audits","setAudits","refresh","nextManagement","requestError","readErrorMessage","run","work","rows","endpoint","columns","actions","readEditDraft","readTestNotice","handleSaveDraft","saved","parameters","parameter","headers","header","timeoutMs","isOriginChanged","handleRotate","enabled","EndpointDraftModal","event","AUDIT_COLUMNS","audit","editing","originChanged","replaceHeaders","update","onChange","patch","updateParameter","current","index","updateHeader","text","field","onCancel","option","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
+ {"version":3,"file":"index.cjs","names":["useState","useCallback","readWorkflowWebhookEndpointManagement","listWorkflowWebhookManagedEndpoints","useMemo","Typography","Badge","formatDateTime","testWorkflowWebhookEndpoint","setWorkflowWebhookEndpointActive","listWorkflowWebhookEndpointAudits","updateWorkflowWebhookEndpoint","createWorkflowWebhookEndpoint","rotateWorkflowWebhookEndpointSecret","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Table","Modal","BPMFormField","Toggle","Input","Textarea","Select","TrashIcon","require_rolldown_runtime","require_bpm_form_field","require_format_date_time","react","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_react_ContentHeader","_rytass_bpm_core_client_template","_mezzanine_ui_icons","STACK_STYLE","ROW_STYLE","HEADER_ROW_STYLE","METHOD_OPTIONS","PARAMETER_TYPE_OPTIONS","AUDIT_ACTION_LABELS","EMPTY_DRAFT","AdminWebhookEndpointsView","management","setManagement","endpoints","setEndpoints","loading","setLoading","error","setError","notice","setNotice","draft","setDraft","saving","setSaving","rotating","setRotating","nextSecret","setNextSecret","removeSecret","setRemoveSecret","audits","setAudits","refresh","nextManagement","requestError","readErrorMessage","run","work","rows","endpoint","columns","actions","readEditDraft","readTestNotice","handleSaveDraft","saved","parameters","parameter","headers","header","timeoutMs","isOriginChanged","handleRotate","enabled","EndpointDraftModal","event","AUDIT_COLUMNS","audit","editing","originChanged","replaceHeaders","update","onChange","patch","updateParameter","current","index","updateHeader","text","field","onCancel","option","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":"A,yeAgGA,IAAMsC,EAA6B,CACjC,QAAS,OACT,IAAK,6BACP,EAEMC,EAA2B,CAC/B,WAAY,SACZ,QAAS,OACT,IAAK,8BACL,oBAAqB,wDACvB,EAEMC,EAAkC,CACtC,WAAY,SACZ,QAAS,OACT,IAAK,8BACL,oBAAqB,oCACvB,EAEMC,EAA0C,CAC9C,CAAE,GAAI,OAAQ,KAAM,MAAO,EAC3B,CAAE,GAAI,MAAO,KAAM,KAAM,EACzB,CAAE,GAAI,QAAS,KAAM,OAAQ,CAC/B,EAEMC,EAAkD,CACtD,CAAE,GAAI,SAAU,KAAM,IAAK,EAC3B,CAAE,GAAI,SAAU,KAAM,IAAK,EAC3B,CAAE,GAAI,UAAW,KAAM,KAAM,EAC7B,CAAE,GAAI,cAAe,KAAM,MAAO,EAClC,CAAE,GAAI,OAAQ,KAAM,MAAO,CAC7B,EAEMC,EAEF,CACF,QAAS,KACT,SAAU,KACV,QAAS,KACT,eAAgB,OAChB,UAAW,OACX,QAAS,IACX,EAEMC,EAA6B,CACjC,WAAY,GACZ,YAAa,GACb,WAAY,KACZ,QAAS,CAAC,EACV,IAAK,GACL,MAAO,GACP,OAAQ,OACR,KAAM,SACN,YAAa,GACb,WAAY,CAAC,EACb,eAAgB,GAChB,cAAe,GACf,UAAW,GACX,IAAK,GACL,QAAS,GACX,EAQA,SAAgBC,GAA0C,CACxD,GAAM,CAACC,EAAYC,IAAA,EACjB/C,EAAAA,SAAAA,CAAyD,IAAI,EACzD,CAACgD,EAAWC,IAAA,EAAgBjD,EAAAA,SAAAA,CAEhC,CAAC,CAAC,EACE,CAACkD,EAASC,IAAA,EAAcnD,EAAAA,SAAAA,CAAS,EAAI,EACrC,CAACoD,EAAOC,IAAA,EAAYrD,EAAAA,SAAAA,CAAwB,IAAI,EAChD,CAACsD,EAAQC,IAAA,EAAavD,EAAAA,SAAAA,CAAwB,IAAI,EAClD,CAACwD,EAAOC,IAAA,EAAYzD,EAAAA,SAAAA,CAA+B,IAAI,EACvD,CAAC0D,EAAQC,IAAA,EAAa3D,EAAAA,SAAAA,CAAS,EAAK,EACpC,CAAC4D,EAAUC,IAAA,EACf7D,EAAAA,SAAAA,CAAsD,IAAI,EACtD,CAAC8D,EAAYC,IAAA,EAAiB/D,EAAAA,SAAAA,CAAS,EAAE,EACzC,CAACgE,EAAcC,IAAA,EAAmBjE,EAAAA,SAAAA,CAAS,EAAK,EAChD,CAACkE,EAAQC,IAAA,EAAanE,EAAAA,SAAAA,CAGlB,IAAI,EAERoE,GAAA,EAAUnE,EAAAA,YAAAA,CAAY,SAA2B,CACrDkD,EAAW,EAAI,EAEf,GAAI,CACF,IAAMkB,EAAiB,MAAA,EAAMnE,EAAAA,sCAAAA,CAAsC,EAEnE6C,EAAcsB,CAAc,EAC5BpB,EACEoB,EAAe,QACX,MAAA,EAAMlE,EAAAA,oCAAAA,CAAoC,EAC1C,CAAC,CACP,EACAkD,EAAS,IAAI,CACf,OAASiB,EAAuB,CAC9BjB,EAASkB,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRnB,EAAW,EAAK,CAClB,CACF,EAAG,CAAC,CAAC,GAEL,EAAAnB,EAAA,UAAA,KAAsB,CACpBoC,EAAa,CACf,EAAG,CAACA,CAAO,CAAC,EAEZ,IAAMI,GAAA,EAAMvE,EAAAA,YAAAA,CACV,KAAO,IAAyD,CAC9DoD,EAAS,IAAI,EACbE,EAAU,IAAI,EAEd,GAAI,CAIF,OAHAA,EAAU,MAAMkB,EAAK,CAAC,EACtB,MAAML,EAAQ,EAEP,EACT,OAASE,EAAuB,CAG9B,OAFAjB,EAASkB,EAAiBD,CAAY,CAAC,EAEhC,EACT,CACF,EACA,CAACF,CAAO,CACV,EAEMM,GAAA,EAAOtE,EAAAA,QAAAA,KAET4C,EAAU,IAAK,IAAc,CAAE,WAAU,IAAK2B,EAAS,EAAG,EAAE,EAC9D,CAAC3B,CAAS,CACZ,EAEM4B,GAAA,EAAUxE,EAAAA,QAAAA,KACoB,CAChC,CACE,IAAK,QACL,QAAS,CAAE,eACT,EAAA8B,EAAA,KAAA,CAAC,MAAD,CAAK,MAAOI,EAAZ,SAAA,EACE,EAAAJ,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAsE,EAAS,KACA,CAAA,GACZ,EAAAzC,EAAA,KAAA,CAAC7B,EAAAA,WAAD,CAAY,MAAM,eAAe,UAAU,OAAO,QAAQ,UAA1D,SAAA,CACGsE,EAAS,IAAI,IAAEA,EAAS,QAAQ,QAAM,IACtCA,EAAS,WAAW,OAAO,IAClB,CACT,CAAA,CAAA,C,GAEP,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,MACL,QAAS,CAAE,eACT,EAAAzC,EAAA,KAAA,CAAC7B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAArC,SAAA,CACGsE,EAAS,OAAO,IAAEA,EAAS,GAClB,C,GAEd,MAAO,MACP,MAAO,GACT,EACA,CACE,IAAK,SACL,QAAS,CAAE,cACRA,EAAS,OAENA,EAAS,YACX,EAAAzC,EAAA,IAAA,CAAC5B,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,QAAQ,QAAQ,aAAe,CAAA,GAEtD,EAAA4B,EAAA,IAAA,CAAC5B,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,MAAM,QAAQ,aAAe,CAAA,GAJpD,EAAA4B,EAAA,IAAA,CAAC5B,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,MAAM,QAAQ,cAAgB,CAAA,EAMzD,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,cACL,QAAS,CAAE,eACT,EAAA4B,EAAA,KAAA,CAAC,MAAD,CAAK,MAAOI,EAAZ,SAAA,EACE,EAAAJ,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAsE,EAAS,iBAAmB,UAAY,KAC/B,CAAA,GACZ,EAAAzC,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,MAAM,eAAe,UAAU,OAAO,QAAQ,UACvD,SAAAsE,EAAS,YAAY,OAClB,UAAUA,EAAS,YAAY,KAAK,GAAG,IACvC,aACM,CAAA,CACT,C,GAEP,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,YACL,QAAS,CAAE,eACT,EAAAzC,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAE,EAAAA,EAAeoE,EAAS,SAAS,CACxB,CAAA,EAEd,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EAEME,GAAA,EAAUzE,EAAAA,QAAAA,MACoB,CAChC,QAAS,CACP,cACqD,CACrD,CACE,KAAM,KACN,YAAqBqD,EAASqB,EAAcH,EAAU,MAAM,CAAC,CAC/D,EACA,CACE,KAAM,QACN,YAAqBlB,EAASqB,EAAcH,EAAU,SAAS,CAAC,CAClE,EACA,CACE,KAAM,OACN,YAAqB,CACnBH,EAAS,SACPO,EACEJ,EACA,MAAA,EAAMnE,EAAAA,4BAAAA,CAA4BmE,EAAS,EAAE,CAC/C,CACF,CACF,CACF,EACA,CACE,KAAM,OACN,YAAqB,CACnBZ,EAAc,EAAE,EAChBE,EAAgB,EAAK,EACrBJ,EAAYc,CAAQ,CACtB,CACF,EACA,CACE,KAAMA,EAAS,OAAS,KAAO,KAC/B,YAAqB,CACnBH,EAAS,UACP,MAAA,EAAM/D,EAAAA,iCAAAA,CACJkE,EAAS,GACT,CAACA,EAAS,MACZ,EAEO,IAAIA,EAAS,OAAS,KAAO,KAAK,GAAGA,EAAS,MAAM,IAC5D,CACH,CACF,EACA,CACE,KAAM,OACN,YAAqB,EACnB,EAAKjE,EAAAA,kCAAAA,CAAkCiE,EAAS,EAAE,CAAC,CAChD,KAAM,GAAkBR,EAAU,CAAE,WAAU,SAAQ,CAAC,CAAC,CAAC,CACzD,MAAO,GACNd,EAASkB,EAAiBD,CAAY,CAAC,CACzC,CACJ,CACF,CACF,EACA,QAAS,iBACT,MAAO,GACT,GACA,CAACE,CAAG,CACN,EAEA,eAAeQ,GAAiC,CAC9C,GAAI,CAACxB,EACH,OAGFG,EAAU,EAAI,EAEd,IAAMsB,EAAQ,MAAMT,EAAI,SAAY,CAClC,IAAMU,EAAa1B,EAAM,WAAW,IAAK,IAAe,CACtD,YAAa2B,EAAU,YAAY,KAAK,GAAK,KAC7C,IAAKA,EAAU,IAAI,KAAK,EACxB,MAAOA,EAAU,MAAM,KAAK,EAC5B,SAAUA,EAAU,SACpB,KAAMA,EAAU,IAClB,EAAE,EACIC,EAAU5B,EAAM,QACnB,OAAQ,GAAW6B,EAAO,KAAK,KAAK,CAAC,CAAC,CACtC,IAAK,IAAY,CAAE,KAAMA,EAAO,KAAK,KAAK,EAAG,MAAOA,EAAO,KAAM,EAAE,EAChEC,EAAY9B,EAAM,UAAU,KAAK,EAAI,OAAOA,EAAM,SAAS,EAAI,KAiCrE,OA/BIA,EAAM,OAAS,QAAUA,EAAM,YACjC,MAAA,EAAM7C,EAAAA,8BAAAA,CAA8B,CAClC,WAAY6C,EAAM,WAClB,YAAaA,EAAM,YACnB,QACEA,EAAM,gBAAkB+B,EAAgB/B,CAAK,EAAI4B,EAAU,KAC7D,GAAI5B,EAAM,WACV,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,aACA,YACA,IAAKA,EAAM,GACb,CAAC,EAEM,OAAOA,EAAM,MAAM,MAG5B,MAAA,EAAM5C,EAAAA,8BAAAA,CAA8B,CAClC,WAAY4C,EAAM,WAClB,YAAaA,EAAM,YACnB,UACA,IAAKA,EAAM,IACX,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,aACA,cAAeA,EAAM,eAAiB,KACtC,YACA,IAAKA,EAAM,IACX,QAAS,OAAOA,EAAM,OAAO,CAC/B,CAAC,EAEM,OAAOA,EAAM,MAAM,IAAIA,EAAM,QAAQ,aAC9C,CAAC,EAEDG,EAAU,EAAK,EAEXsB,GACFxB,EAAS,IAAI,CAEjB,CAEA,eAAe+B,GAA8B,CAC3C,GAAI,CAAC5B,EACH,OAGF,IAAMe,EAAWf,EAYb,MAXeY,EAAI,UACrB,MAAA,EAAM3D,EAAAA,oCAAAA,CACJ8D,EAAS,GACTX,EAAe,KAAOF,CACxB,EAEOE,EACH,OAAOW,EAAS,MAAM,mBACtB,OAAOA,EAAS,MAAM,qBAC3B,IAGCd,EAAY,IAAI,EAChBE,EAAc,EAAE,EAEpB,CAEA,IAAM0B,EAAU,EAAQ3C,GAAY,QAEpC,OACE,EAAAZ,EAAA,KAAA,CAAApB,EAAAA,SAAA,CAAA,SAAA,EACE,EAAAoB,EAAA,IAAA,CAACnB,EAAAA,WAAD,CAAA,UACE,EAAAmB,EAAA,IAAA,CAAClB,EAAAA,QAAD,CACE,YAAY,+CACZ,MAAM,aAEN,UAAA,EAAAkB,EAAA,IAAA,CAACjB,EAAAA,OAAD,CACE,SAAU,CAACwE,EACX,KAAMvE,EAAAA,SACN,SAAS,UACT,YAAqBuC,EAASb,CAAW,EACzC,QAAQ,eACT,SAAA,MAEO,CAAA,CACK,CAAA,CACL,CAAA,GAEZ,EAAAV,EAAA,IAAA,CAACf,EAAAA,aAAD,CAAA,UACE,EAAAe,EAAA,IAAA,CAACd,EAAAA,QAAD,CAAA,UACE,EAAAc,EAAA,KAAA,CAAC,MAAD,CAAK,MAAOI,EAAZ,SAAA,CACGc,GACC,EAAAlB,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,OACpC,SAAA+C,CACS,CAAA,EACV,KACHE,GACC,EAAApB,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,OACtC,SAAAiD,CACS,CAAA,EACV,KACHR,GAAc,CAAC2C,GACd,EAAAvD,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,OAAO,SAAA,gGAIpC,CAAA,EACV,KACHoF,GACC,EAAAvD,EAAA,KAAA,CAAC7B,EAAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,UAAzC,SAAA,CAAmD,WACxCyC,GAAY,mBAAmB,KAAK,GAAG,CACtC,CACV,CAAA,EAAA,MACJ,EAAAZ,EAAA,IAAA,CAACb,EAAAA,MAAD,CACW,UACA,UACT,WAAYqD,EACZ,UAAA,GACS,SACV,CAAA,CACE,CACE,CAAA,CAAA,CAAA,CACG,CAAA,EAEblB,GACC,EAAAtB,EAAA,IAAA,CAACwD,EAAD,CACS,QACP,aAAsBjC,EAAS,IAAI,EACnC,SAAUA,EACV,cAAuB,KAAKuB,EAAgB,EACpC,QACT,CAAA,EACC,MAEJ,EAAA9C,EAAA,IAAA,CAACZ,EAAAA,MAAD,CACE,WAAW,KACX,mBAAoB,CAAE,SAAU,CAAC0C,GAAgB,CAACF,CAAW,EAC7D,YAAaE,EAAe,OAAS,OACrC,UAAU,WACV,aAAsBH,EAAY,IAAI,EACtC,YAAqBA,EAAY,IAAI,EACrC,cAAuB,KAAK2B,EAAa,EACzC,KAAM,EAAQ5B,EACd,gBAAA,GACA,gBAAA,GACA,eAAe,gCACf,MAAO,UAAUA,GAAU,OAAS,KAEpC,UAAA,EAAA1B,EAAA,KAAA,CAAC,MAAD,CAAK,MAAOI,EAAZ,SAAA,EACE,EAAAJ,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,OAAO,KAAK,sBAC9B,UAAA,EAAAW,EAAA,IAAA,CAACV,EAAAA,OAAD,CACE,QAASwC,EACT,SAAW,GACTC,EAAgB0B,EAAM,OAAO,OAAO,CAEvC,CAAA,CACW,CAAA,EACb3B,EAAe,MACd,EAAA9B,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,MAAM,KAAK,oBAAoB,SAAA,GACjD,UAAA,EAAAW,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,SAAW,GACTsC,EAAc4B,EAAM,OAAO,KAAK,EAElC,MAAO7B,EACP,WAAY,CAAE,aAAc,cAAe,EAC3C,QAAQ,UACT,CAAA,CACW,CAAA,CAEb,C,EACA,CAAA,GAEP,EAAA5B,EAAA,IAAA,CAACZ,EAAAA,MAAD,CACE,YAAY,KACZ,UAAU,WACV,YAAqB6C,EAAU,IAAI,EACnC,cAAuBA,EAAU,IAAI,EACrC,KAAM,EAAQD,EACd,gBAAA,GACA,gBAAA,GACA,KAAK,OACL,eAAe,yBACf,MAAO,QAAQA,GAAQ,SAAS,OAAS,KAEzC,UAAA,EAAAhC,EAAA,IAAA,CAACb,EAAAA,MAAD,CACE,QAASuE,EACT,YAAa1B,GAAQ,SAAW,CAAC,EAAA,CAAG,IAAK,IAAqB,CAC5D,QACA,IAAK2B,EAAM,EACb,EAAE,EACF,UAAA,EACD,CAAA,CACI,CAAA,CACP,CAAA,CAAA,CAEN,CAEA,IAAMD,EAAyC,CAC7C,CACE,IAAK,YACL,QAAS,CAAE,YACT,EAAA1D,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAE,EAAAA,EAAesF,EAAM,SAAS,CACrB,CAAA,EAEd,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,SACL,QAAS,CAAE,YACT,EAAA3D,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAsC,EAAoBkD,EAAM,OACjB,CAAA,EAEd,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,gBACL,QAAS,CAAE,YACT,EAAA3D,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAwF,EAAM,cAAc,KAAK,GAAG,GAAK,GACxB,CAAA,EAEd,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,QACL,QAAS,CAAE,YACT,EAAA3D,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAwF,EAAM,eAAiB,IACd,CAAA,EAEd,MAAO,MACP,MAAO,GACT,CACF,EAEA,SAASH,EAAmB,CAC1B,QACA,WACA,WACA,YACA,UAOe,CACf,IAAMI,EAAUtC,EAAM,OAAS,OAGzBuC,EAAgBR,EAAgB/B,CAAK,EACrCwC,EAAiBxC,EAAM,gBAAkBuC,EACzCE,EAAU,GACdC,EAAS,CAAE,GAAG1C,EAAO,GAAG2C,CAAM,CAAC,EAC3BC,GACJ,EACA,IAEAH,EAAO,CACL,WAAYzC,EAAM,WAAW,KAAK,EAAW,IAC3C6C,IAAYC,EAAQ,CAAE,GAAGnB,EAAW,GAAGgB,CAAM,EAAIhB,CACnD,CACF,CAAC,EACGoB,GAAgB,EAAe,IACnCN,EAAO,CACL,QAASzC,EAAM,QAAQ,KAAK,EAAQ,IAClC6C,IAAYC,EAAQ,CAAE,GAAGjB,EAAQ,GAAGc,CAAM,EAAId,CAChD,CACF,CAAC,EACGmB,EACH,GACA,GACCP,EAAO,EAAGQ,GAAQd,EAAM,OAAO,KAAM,CAAC,EAE1C,OACE,EAAAzD,EAAA,IAAA,CAACZ,EAAAA,MAAD,CACE,WAAW,KACX,YAAawE,EAAU,KAAO,KAC9B,QAASpC,EACT,UAAU,WACA,WACV,QAASgD,EACE,YACX,KAAA,GACA,gBAAA,GACA,gBAAA,GACA,KAAK,OACL,eACEZ,EACI,sCACAtC,EAAM,OAAS,UACb,+BACA,oBAER,MACEsC,EACI,QAAQtC,EAAM,QACdA,EAAM,OAAS,UACb,SAASA,EAAM,MACf,gBAGR,UAAA,EAAAtB,EAAA,KAAA,CAAC,MAAD,CAAK,MAAOI,EAAZ,SAAA,EACE,EAAAJ,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,MAAM,KAAK,cAAc,SAAA,GAC3C,UAAA,EAAAW,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,GAAK+B,EAAM,OAAS,SAAW,CAAC,EAAI,CAAE,SAAU,EAAc,EAC9D,SAAUgD,EAAK,KAAK,EACpB,YAAY,sBACZ,MAAOhD,EAAM,IACb,WAAY,CAAE,aAAc,KAAM,EAClC,QAAQ,MACT,CAAA,CACW,CAAA,GACd,EAAAtB,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,KAAK,KAAK,kBAAkB,SAAA,GAC9C,UAAA,EAAAW,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,GAAKqE,EAAU,CAAE,SAAU,EAAc,EAAI,CAAC,EAC9C,WAAY,CAAE,aAAc,MAAO,UAAW,SAAU,EACxD,SAAUU,EAAK,SAAS,EACxB,MAAOhD,EAAM,QACb,QAAQ,MACT,CAAA,CACW,CAAA,GACd,EAAAtB,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,KAAK,KAAK,gBAAgB,SAAA,GAC5C,UAAA,EAAAW,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,SAAU+E,EAAK,OAAO,EACtB,YAAY,cACZ,MAAOhD,EAAM,MACb,WAAY,CAAE,aAAc,KAAM,EAClC,QAAQ,MACT,CAAA,CACW,CAAA,GACd,EAAAtB,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,KAAK,KAAK,sBAC5B,UAAA,EAAAW,EAAA,IAAA,CAACR,EAAAA,SAAD,CACE,SAAU8E,EAAK,aAAa,EAC5B,KAAM,EACN,MAAOhD,EAAM,WACd,CAAA,CACW,CAAA,GACd,EAAAtB,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,MAAM,KAAK,cAAc,SAAA,GAC3C,UAAA,EAAAW,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,SAAU+E,EAAK,KAAK,EACpB,YAAY,WACZ,MAAOhD,EAAM,IACb,WAAY,CAAE,aAAc,KAAM,EAClC,QAAQ,MACT,CAAA,CACW,CAAA,GACd,EAAAtB,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,SAAS,KAAK,iBAAiB,SAAA,GACjD,UAAA,EAAAW,EAAA,IAAA,CAACP,EAAAA,OAAD,CACE,UAAW,GACX,SAAW,GACTsE,EAAO,CAAE,OAAQU,GAAQ,IAAM,MAAO,CAAC,EAEzC,QAAS,CAAC,GAAGlE,CAAc,EAC3B,MACEA,EAAe,KAAM,GAAWkE,EAAO,KAAOnD,EAAM,MAAM,GAC1D,IAEH,CAAA,CACW,CAAA,GACd,EAAAtB,EAAA,IAAA,CAACX,EAAAA,EAAD,CACE,SAAS,2BACT,MAAM,SACN,KAAK,kBAEL,UAAA,EAAAW,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,WAAY,CAAE,aAAc,MAAO,UAAW,SAAU,EACxD,SAAU+E,EAAK,WAAW,EAC1B,MAAOhD,EAAM,UACb,QAAQ,MACT,CAAA,CACW,CAAA,GACd,EAAAtB,EAAA,IAAA,CAACX,EAAAA,EAAD,CAAc,MAAM,QAAQ,KAAK,qBAC/B,UAAA,EAAAW,EAAA,IAAA,CAACV,EAAAA,OAAD,CACE,QAASgC,EAAM,WACf,SAAW,GACTyC,EAAO,CAAE,WAAYN,EAAM,OAAO,OAAQ,CAAC,CAE9C,CAAA,CACW,CAAA,EACbG,EAAU,MACT,EAAA5D,EAAA,IAAA,CAACX,EAAAA,EAAD,CACE,SAAS,wCACT,MAAM,OACN,KAAK,wBAEL,UAAA,EAAAW,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,SAAU+E,EAAK,eAAe,EAC9B,YAAY,aACZ,MAAOhD,EAAM,cACb,WAAY,CAAE,aAAc,cAAe,EAC3C,QAAQ,UACT,CAAA,CACW,CAAA,GAGhB,EAAAtB,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,QAAQ,0BAA0B,SAAA,SAAmB,CAAA,EAChEyF,GACC,EAAA5D,EAAA,IAAA,CAACX,EAAAA,EAAD,CACE,SACEwE,EACI,8CACA,wCAEN,MAAM,aACN,KAAK,yBAEL,UAAA,EAAA7D,EAAA,IAAA,CAACV,EAAAA,OAAD,CACE,QAASwE,EACT,SAAUD,EACV,SAAW,GACTE,EAAO,CAAE,eAAgBN,EAAM,OAAO,OAAQ,CAAC,CAElD,CAAA,CACW,CAAA,EACZ,KACHK,EACGxC,EAAM,QAAQ,KAAK,EAAQ,KACzB,EAAAtB,EAAA,KAAA,CAAC,MAAD,CAAiB,MAAOM,EAAxB,SAAA,EACE,EAAAN,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,SAAW,GACT8E,EAAaD,EAAO,CAAE,KAAMX,EAAM,OAAO,KAAM,CAAC,EAElD,YAAY,sBACZ,WAAY,CAAE,aAAc,KAAM,EAClC,MAAON,EAAO,KACd,QAAQ,MACT,CAAA,GACD,EAAAnD,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,SAAW,GACT8E,EAAaD,EAAO,CAAE,MAAOX,EAAM,OAAO,KAAM,CAAC,EAEnD,YAAY,IACZ,MAAON,EAAO,MACd,WAAY,CAAE,aAAc,cAAe,EAC3C,QAAQ,UACT,CAAA,GACD,EAAAnD,EAAA,IAAA,CAACjB,EAAAA,OAAD,CACE,KAAMW,EAAAA,UACN,SAAS,YACT,YACEqE,EAAO,CACL,QAASzC,EAAM,QAAQ,QACpB,EAAS,IAAY6C,IAAYC,CACpC,CACF,CAAC,EAEH,QAAQ,wBACT,SAAA,WAEO,CAAA,CACL,CAjCK,EAAAA,CAiCL,CACN,EACD,KACHN,GACC,EAAA9D,EAAA,IAAA,CAAC,MAAD,CAAA,UACE,EAAAA,EAAA,IAAA,CAACjB,EAAAA,OAAD,CACE,KAAMC,EAAAA,SACN,SAAS,UACT,YACE+E,EAAO,CAAE,QAAS,CAAC,GAAGzC,EAAM,QAAS,CAAE,KAAM,GAAI,MAAO,EAAG,CAAC,CAAE,CAAC,EAEjE,QAAQ,cACT,SAAA,WAEO,CAAA,CACL,CAAA,EACH,MAEJ,EAAAtB,EAAA,IAAA,CAAC7B,EAAAA,WAAD,CAAY,QAAQ,0BAA0B,SAAA,IAAc,CAAA,EAC3DmD,EAAM,WAAW,KAAK,EAAW,KAChC,EAAAtB,EAAA,KAAA,CAAC,MAAD,CAAiB,MAAOK,EAAxB,SAAA,EACE,EAAAL,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,GAAKqE,EAAU,CAAE,SAAU,EAAc,EAAI,CAAC,EAC9C,SAAW,GACTM,EAAgBE,EAAO,CAAE,IAAKX,EAAM,OAAO,KAAM,CAAC,EAEpD,YAAY,MACZ,WAAY,CAAE,aAAc,KAAM,EAClC,MAAOR,EAAU,IACjB,QAAQ,MACT,CAAA,GACD,EAAAjD,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,SAAW,GACT2E,EAAgBE,EAAO,CAAE,MAAOX,EAAM,OAAO,KAAM,CAAC,EAEtD,YAAY,OACZ,WAAY,CAAE,aAAc,KAAM,EAClC,MAAOR,EAAU,MACjB,QAAQ,MACT,CAAA,GACD,EAAAjD,EAAA,IAAA,CAACP,EAAAA,OAAD,CACE,UAAW,GACX,SAAUmE,EACV,SAAW,GACTM,EAAgBE,EAAO,CACrB,KAAMM,EAAkBD,GAAQ,IAAM,IAAI,CAC5C,CAAC,EAEH,QAAS,CAAC,GAAGjE,CAAsB,EACnC,MACEA,EAAuB,KACpB,GAAWiE,EAAO,KAAOxB,EAAU,IACtC,GAAK,IAER,CAAA,GACD,EAAAjD,EAAA,IAAA,CAACV,EAAAA,OAAD,CACE,QAAS2D,EAAU,SACnB,SAAUW,EACV,MAAM,KACN,SAAW,GACTM,EAAgBE,EAAO,CAAE,SAAUX,EAAM,OAAO,OAAQ,CAAC,CAE5D,CAAA,GACD,EAAAzD,EAAA,IAAA,CAACjB,EAAAA,OAAD,CACE,SAAU6E,EACV,KAAMlE,EAAAA,UACN,SAAS,YACT,YACEqE,EAAO,CACL,WAAYzC,EAAM,WAAW,QAC1B,EAAY,IAAY6C,IAAYC,CACvC,CACF,CAAC,EAEH,QAAQ,wBACT,SAAA,MAEO,CAAA,CACL,CA1DK,EAAAA,CA0DL,CACN,EACAR,EAAU,MACT,EAAA5D,EAAA,IAAA,CAAC,MAAD,CAAA,UACE,EAAAA,EAAA,IAAA,CAACjB,EAAAA,OAAD,CACE,KAAMC,EAAAA,SACN,SAAS,UACT,YACE+E,EAAO,CACL,WAAY,CACV,GAAGzC,EAAM,WACT,CACE,YAAa,GACb,IAAK,GACL,MAAO,GACP,SAAU,GACV,KAAM,QACR,CACF,CACF,CAAC,EAEH,QAAQ,cACT,SAAA,MAEO,CAAA,CACL,CAAA,CAEJ,C,EACA,CAAA,CAEX,CAEA,SAASsB,EACP,EACA,EACe,CACf,MAAO,CACL,WAAYH,EAAS,WACrB,YAAaA,EAAS,aAAe,GACrC,WAAYkC,IAAS,OAASlC,EAAS,GAAK,KAC5C,QAAS,CAAC,EACV,IAAKA,EAAS,IACd,MAAOA,EAAS,MAChB,OAAQA,EAAS,OACjB,OACA,YAAaA,EAAS,IACtB,WAAYA,EAAS,WAAW,IAAK,IAAe,CAClD,YAAaQ,EAAU,aAAe,GACtC,IAAKA,EAAU,IACf,MAAOA,EAAU,MACjB,SAAUA,EAAU,SACpB,KAAMA,EAAU,IAClB,EAAE,EAEF,eAAgB0B,IAAS,UACzB,cAAe,GACf,UAAWlC,EAAS,UAAY,OAAOA,EAAS,SAAS,EAAI,GAC7D,IAAKA,EAAS,IACd,QAAS,OACPkC,IAAS,UAAYlC,EAAS,QAAU,EAAIA,EAAS,OACvD,CACF,CACF,CAEA,SAASI,EACP,EACA,EACQ,CACR,GAAI+B,EAAO,GACT,MAAO,WAAWnC,EAAS,MAAM,WAAWmC,EAAO,QAAU,GAAG,GAGlE,MAAU,MACR,WAAWnC,EAAS,MAAM,GAAGmC,EAAO,OAAS,WAAWA,EAAO,SAAW,GAAG,GAAGA,EAAO,WAAa,OAAO,GAAGA,EAAO,YAAc,IAAIA,EAAO,cAAgB,IAChK,CACF,CAEA,SAASvB,EAAgB,EAA+B,CACtD,GAAI/B,EAAM,OAAS,OACjB,MAAO,GAGT,IAAMuD,EAAU,GAAwB,CACtC,GAAI,CACF,OAAO,IAAI,IAAIC,EAAI,KAAK,CAAC,CAAC,CAAC,MAC7B,MAAQ,CACN,OAAOA,EAAI,KAAK,CAClB,CACF,EAEA,OAAOD,EAAOvD,EAAM,GAAG,IAAMuD,EAAOvD,EAAM,WAAW,CACvD,CAEA,SAASoD,EAAkB,EAA+C,CACxE,OAAOlE,EAAuB,KAAM,GAAWiE,EAAO,KAAOM,CAAE,EAC1DA,EACD,QACN,CAEA,SAAS1C,EAAiB,EAAwB,CAChD,GAAI,EAAEnB,aAAiB,OACrB,MAAO,SAGT,IAAM8D,EAAU9D,EAAM,QAkBtB,OAhBI8D,EAAQ,SAAS,kCAAkC,EAC9C,oBAGLA,EAAQ,SAAS,wCAAwC,EACpD,2BAGLA,EAAQ,SAAS,4CAA4C,EACxD,uBAGLA,EAAQ,SAAS,oCAAoC,EAChD,uCAGFA,CACT,C"}
@@ -5,23 +5,23 @@ import { useCallback as n, useEffect as r, useMemo as i, useState as a } from "r
5
5
  import { Badge as o, Button as s, Input as c, Modal as l, PageHeader as u, Section as d, SectionGroup as f, Select as p, Table as m, Textarea as h, Toggle as g, Typography as _ } from "@mezzanine-ui/react";
6
6
  import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
7
7
  import x from "@mezzanine-ui/react/ContentHeader";
8
- import { PlusIcon as S, TrashIcon as C } from "@mezzanine-ui/icons";
9
- import { createWorkflowWebhookEndpoint as w, listWorkflowWebhookEndpointAudits as T, listWorkflowWebhookManagedEndpoints as ee, readWorkflowWebhookEndpointManagement as E, rotateWorkflowWebhookEndpointSecret as te, setWorkflowWebhookEndpointActive as ne, testWorkflowWebhookEndpoint as re, updateWorkflowWebhookEndpoint as ie } from "@rytass/bpm-core-client/template";
8
+ import { createWorkflowWebhookEndpoint as ee, listWorkflowWebhookEndpointAudits as te, listWorkflowWebhookManagedEndpoints as S, readWorkflowWebhookEndpointManagement as C, rotateWorkflowWebhookEndpointSecret as w, setWorkflowWebhookEndpointActive as T, testWorkflowWebhookEndpoint as ne, updateWorkflowWebhookEndpoint as re } from "@rytass/bpm-core-client/template";
9
+ import { PlusIcon as E, TrashIcon as D } from "@mezzanine-ui/icons";
10
10
  // src/views/admin/webhook-endpoints/AdminWebhookEndpointsView.tsx
11
- var D = {
11
+ var O = {
12
12
  display: "grid",
13
13
  gap: "var(--mzn-spacing-gap-base)"
14
- }, O = {
14
+ }, k = {
15
15
  alignItems: "center",
16
16
  display: "grid",
17
17
  gap: "var(--mzn-spacing-gap-base)",
18
18
  gridTemplateColumns: "minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto"
19
- }, k = {
19
+ }, A = {
20
20
  alignItems: "center",
21
21
  display: "grid",
22
22
  gap: "var(--mzn-spacing-gap-base)",
23
23
  gridTemplateColumns: "minmax(0, 1fr) minmax(0, 2fr) auto"
24
- }, A = [
24
+ }, j = [
25
25
  {
26
26
  id: "POST",
27
27
  name: "POST"
@@ -34,7 +34,7 @@ var D = {
34
34
  id: "PATCH",
35
35
  name: "PATCH"
36
36
  }
37
- ], j = [
37
+ ], M = [
38
38
  {
39
39
  id: "string",
40
40
  name: "文字"
@@ -55,14 +55,14 @@ var D = {
55
55
  id: "json",
56
56
  name: "JSON"
57
57
  }
58
- ], M = {
58
+ ], N = {
59
59
  CREATED: "建立",
60
60
  DISABLED: "停用",
61
61
  ENABLED: "啟用",
62
62
  SECRET_ROTATED: "輪替金鑰",
63
63
  TEST_SENT: "測試送出",
64
64
  UPDATED: "更新"
65
- }, ae = {
65
+ }, ie = {
66
66
  deprecated: !1,
67
67
  description: "",
68
68
  endpointId: null,
@@ -79,36 +79,36 @@ var D = {
79
79
  url: "",
80
80
  version: "1"
81
81
  };
82
- function N() {
83
- let [p, h] = a(null), [C, O] = a([]), [k, A] = a(!0), [j, M] = a(null), [N, L] = a(null), [z, B] = a(null), [V, H] = a(!1), [U, W] = a(null), [G, K] = a(""), [q, J] = a(!1), [Y, X] = a(null), Z = n(async () => {
84
- A(!0);
82
+ function P() {
83
+ let [p, h] = a(null), [D, k] = a([]), [A, j] = a(!0), [M, N] = a(null), [P, L] = a(null), [z, B] = a(null), [V, H] = a(!1), [U, W] = a(null), [G, K] = a(""), [q, J] = a(!1), [Y, X] = a(null), Z = n(async () => {
84
+ j(!0);
85
85
  try {
86
- let e = await E();
87
- h(e), O(e.enabled ? await ee() : []), M(null);
86
+ let e = await C();
87
+ h(e), k(e.enabled ? await S() : []), N(null);
88
88
  } catch (e) {
89
- M(R(e));
89
+ N(R(e));
90
90
  } finally {
91
- A(!1);
91
+ j(!1);
92
92
  }
93
93
  }, []);
94
94
  r(() => {
95
95
  Z();
96
96
  }, [Z]);
97
97
  let Q = n(async (e) => {
98
- M(null), L(null);
98
+ N(null), L(null);
99
99
  try {
100
100
  return L(await e()), await Z(), !0;
101
101
  } catch (e) {
102
- return M(R(e)), !1;
102
+ return N(R(e)), !1;
103
103
  }
104
- }, [Z]), ce = i(() => C.map((e) => ({
104
+ }, [Z]), ce = i(() => D.map((e) => ({
105
105
  endpoint: e,
106
106
  key: e.id
107
- })), [C]), le = i(() => [
107
+ })), [D]), le = i(() => [
108
108
  {
109
109
  key: "label",
110
110
  render: ({ endpoint: e }) => /* @__PURE__ */ b("div", {
111
- style: D,
111
+ style: O,
112
112
  children: [/* @__PURE__ */ y(_, {
113
113
  component: "span",
114
114
  variant: "body",
@@ -166,7 +166,7 @@ function N() {
166
166
  {
167
167
  key: "credentials",
168
168
  render: ({ endpoint: e }) => /* @__PURE__ */ b("div", {
169
- style: D,
169
+ style: O,
170
170
  children: [/* @__PURE__ */ y(_, {
171
171
  component: "span",
172
172
  variant: "body",
@@ -195,16 +195,16 @@ function N() {
195
195
  render: ({ endpoint: e }) => [
196
196
  {
197
197
  name: "編輯",
198
- onClick: () => B(P(e, "edit"))
198
+ onClick: () => B(F(e, "edit"))
199
199
  },
200
200
  {
201
201
  name: "建立新版本",
202
- onClick: () => B(P(e, "version"))
202
+ onClick: () => B(F(e, "version"))
203
203
  },
204
204
  {
205
205
  name: "測試送出",
206
206
  onClick: () => {
207
- Q(async () => F(e, await re(e.id)));
207
+ Q(async () => se(e, await ne(e.id)));
208
208
  }
209
209
  },
210
210
  {
@@ -216,16 +216,16 @@ function N() {
216
216
  {
217
217
  name: e.active ? "停用" : "啟用",
218
218
  onClick: () => {
219
- Q(async () => (await ne(e.id, !e.active), `已${e.active ? "停用" : "啟用"}「${e.label}」。`));
219
+ Q(async () => (await T(e.id, !e.active), `已${e.active ? "停用" : "啟用"}「${e.label}」。`));
220
220
  }
221
221
  },
222
222
  {
223
223
  name: "異動紀錄",
224
224
  onClick: () => {
225
- T(e.id).then((t) => X({
225
+ te(e.id).then((t) => X({
226
226
  endpoint: e,
227
227
  records: t
228
- })).catch((e) => M(R(e)));
228
+ })).catch((e) => N(R(e)));
229
229
  }
230
230
  }
231
231
  ],
@@ -246,7 +246,7 @@ function N() {
246
246
  name: e.name.trim(),
247
247
  value: e.value
248
248
  })), n = z.timeoutMs.trim() ? Number(z.timeoutMs) : null;
249
- return z.mode === "edit" && z.endpointId ? (await ie({
249
+ return z.mode === "edit" && z.endpointId ? (await re({
250
250
  deprecated: z.deprecated,
251
251
  description: z.description,
252
252
  headers: z.replaceHeaders || I(z) ? t : null,
@@ -256,7 +256,7 @@ function N() {
256
256
  parameters: e,
257
257
  timeoutMs: n,
258
258
  url: z.url
259
- }), `已更新「${z.label}」。`) : (await w({
259
+ }), `已更新「${z.label}」。`) : (await ee({
260
260
  deprecated: z.deprecated,
261
261
  description: z.description,
262
262
  headers: t,
@@ -275,7 +275,7 @@ function N() {
275
275
  async function fe() {
276
276
  if (!U) return;
277
277
  let e = U;
278
- await Q(async () => (await te(e.id, q ? null : G), q ? `已移除「${e.label}」的簽章金鑰,之後的請求不再簽章。` : `已輪替「${e.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`)) && (W(null), K(""));
278
+ await Q(async () => (await w(e.id, q ? null : G), q ? `已移除「${e.label}」的簽章金鑰,之後的請求不再簽章。` : `已輪替「${e.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`)) && (W(null), K(""));
279
279
  }
280
280
  let $ = !!p?.enabled;
281
281
  return /* @__PURE__ */ b(v, { children: [
@@ -284,25 +284,25 @@ function N() {
284
284
  title: "Webhook 端點",
285
285
  children: /* @__PURE__ */ y(s, {
286
286
  disabled: !$,
287
- icon: S,
287
+ icon: E,
288
288
  iconType: "leading",
289
- onClick: () => B(ae),
289
+ onClick: () => B(ie),
290
290
  variant: "base-primary",
291
291
  children: "新增端點"
292
292
  })
293
293
  }) }),
294
294
  /* @__PURE__ */ y(f, { children: /* @__PURE__ */ y(d, { children: /* @__PURE__ */ b("div", {
295
- style: D,
295
+ style: O,
296
296
  children: [
297
- j ? /* @__PURE__ */ y(_, {
297
+ M ? /* @__PURE__ */ y(_, {
298
298
  color: "text-error",
299
299
  variant: "body",
300
- children: j
300
+ children: M
301
301
  }) : null,
302
- N ? /* @__PURE__ */ y(_, {
302
+ P ? /* @__PURE__ */ y(_, {
303
303
  color: "text-success",
304
304
  variant: "body",
305
- children: N
305
+ children: P
306
306
  }) : null,
307
307
  p && !$ ? /* @__PURE__ */ y(_, {
308
308
  color: "text-warning",
@@ -319,11 +319,11 @@ function N() {
319
319
  columns: le,
320
320
  dataSource: ce,
321
321
  fullWidth: !0,
322
- loading: k
322
+ loading: A
323
323
  })
324
324
  ]
325
325
  }) }) }),
326
- z ? /* @__PURE__ */ y(se, {
326
+ z ? /* @__PURE__ */ y(oe, {
327
327
  draft: z,
328
328
  onCancel: () => B(null),
329
329
  onChange: B,
@@ -344,7 +344,7 @@ function N() {
344
344
  supportingText: "新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。",
345
345
  title: `輪替簽章金鑰:${U?.label ?? ""}`,
346
346
  children: /* @__PURE__ */ b("div", {
347
- style: D,
347
+ style: O,
348
348
  children: [/* @__PURE__ */ y(e, {
349
349
  label: "移除金鑰",
350
350
  name: "removeSigningSecret",
@@ -377,7 +377,7 @@ function N() {
377
377
  supportingText: "只記錄誰在何時變更了哪些欄位,不記錄任何值。",
378
378
  title: `異動紀錄:${Y?.endpoint.label ?? ""}`,
379
379
  children: /* @__PURE__ */ y(m, {
380
- columns: oe,
380
+ columns: ae,
381
381
  dataSource: (Y?.records ?? []).map((e) => ({
382
382
  audit: e,
383
383
  key: e.id
@@ -387,7 +387,7 @@ function N() {
387
387
  })
388
388
  ] });
389
389
  }
390
- var oe = [
390
+ var ae = [
391
391
  {
392
392
  key: "createdAt",
393
393
  render: ({ audit: e }) => /* @__PURE__ */ y(_, {
@@ -403,7 +403,7 @@ var oe = [
403
403
  render: ({ audit: e }) => /* @__PURE__ */ y(_, {
404
404
  component: "span",
405
405
  variant: "body",
406
- children: M[e.action]
406
+ children: N[e.action]
407
407
  }),
408
408
  title: "動作",
409
409
  width: 120
@@ -429,7 +429,7 @@ var oe = [
429
429
  width: 160
430
430
  }
431
431
  ];
432
- function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
432
+ function oe({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
433
433
  let o = t.mode === "edit", u = I(t), d = t.replaceHeaders || u, f = (e) => r({
434
434
  ...t,
435
435
  ...e
@@ -455,7 +455,7 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
455
455
  supportingText: o ? "參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。" : t.mode === "version" ? "新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。" : "URL 需符合伺服器設定的白名單。",
456
456
  title: o ? `編輯端點:${t.label}` : t.mode === "version" ? `建立新版本:${t.key}` : "新增 Webhook 端點",
457
457
  children: /* @__PURE__ */ b("div", {
458
- style: D,
458
+ style: O,
459
459
  children: [
460
460
  /* @__PURE__ */ y(e, {
461
461
  label: "Key",
@@ -525,8 +525,8 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
525
525
  children: /* @__PURE__ */ y(p, {
526
526
  clearable: !1,
527
527
  onChange: (e) => f({ method: e?.id ?? "POST" }),
528
- options: [...A],
529
- value: A.find((e) => e.id === t.method) ?? null
528
+ options: [...j],
529
+ value: j.find((e) => e.id === t.method) ?? null
530
530
  })
531
531
  }),
532
532
  /* @__PURE__ */ y(e, {
@@ -578,7 +578,7 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
578
578
  })
579
579
  }) : null,
580
580
  d ? t.headers.map((e, n) => /* @__PURE__ */ b("div", {
581
- style: k,
581
+ style: A,
582
582
  children: [
583
583
  /* @__PURE__ */ y(c, {
584
584
  onChange: (e) => v(n, { name: e.target.value }),
@@ -595,7 +595,7 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
595
595
  variant: "password"
596
596
  }),
597
597
  /* @__PURE__ */ y(s, {
598
- icon: C,
598
+ icon: D,
599
599
  iconType: "icon-only",
600
600
  onClick: () => f({ headers: t.headers.filter((e, t) => t !== n) }),
601
601
  variant: "destructive-text-link",
@@ -604,7 +604,7 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
604
604
  ]
605
605
  }, n)) : null,
606
606
  d ? /* @__PURE__ */ y("div", { children: /* @__PURE__ */ y(s, {
607
- icon: S,
607
+ icon: E,
608
608
  iconType: "leading",
609
609
  onClick: () => f({ headers: [...t.headers, {
610
610
  name: "",
@@ -618,7 +618,7 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
618
618
  children: "參數"
619
619
  }),
620
620
  t.parameters.map((e, n) => /* @__PURE__ */ b("div", {
621
- style: O,
621
+ style: k,
622
622
  children: [
623
623
  /* @__PURE__ */ y(c, {
624
624
  ...o ? { readonly: !0 } : {},
@@ -639,8 +639,8 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
639
639
  clearable: !1,
640
640
  disabled: o,
641
641
  onChange: (e) => m(n, { type: L(e?.id ?? null) }),
642
- options: [...j],
643
- value: j.find((t) => t.id === e.type) ?? null
642
+ options: [...M],
643
+ value: M.find((t) => t.id === e.type) ?? null
644
644
  }),
645
645
  /* @__PURE__ */ y(g, {
646
646
  checked: e.required,
@@ -650,7 +650,7 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
650
650
  }),
651
651
  /* @__PURE__ */ y(s, {
652
652
  disabled: o,
653
- icon: C,
653
+ icon: D,
654
654
  iconType: "icon-only",
655
655
  onClick: () => f({ parameters: t.parameters.filter((e, t) => t !== n) }),
656
656
  variant: "destructive-text-link",
@@ -659,7 +659,7 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
659
659
  ]
660
660
  }, n)),
661
661
  o ? null : /* @__PURE__ */ y("div", { children: /* @__PURE__ */ y(s, {
662
- icon: S,
662
+ icon: E,
663
663
  iconType: "leading",
664
664
  onClick: () => f({ parameters: [...t.parameters, {
665
665
  description: "",
@@ -675,7 +675,7 @@ function se({ draft: t, onCancel: n, onChange: r, onConfirm: i, saving: a }) {
675
675
  })
676
676
  });
677
677
  }
678
- function P(e, t) {
678
+ function F(e, t) {
679
679
  return {
680
680
  deprecated: e.deprecated,
681
681
  description: e.description ?? "",
@@ -700,7 +700,7 @@ function P(e, t) {
700
700
  version: String(t === "version" ? e.version + 1 : e.version)
701
701
  };
702
702
  }
703
- function F(e, t) {
703
+ function se(e, t) {
704
704
  if (t.ok) return `測試送出成功:「${e.label}」回應 HTTP ${t.status ?? ""}。`;
705
705
  throw Error(`測試送出失敗:「${e.label}」${t.status ? `回應 HTTP ${t.status}` : ""}(${t.errorCode ?? "未知錯誤"})${t.errorDetail ? `:${t.errorDetail}` : ""}`);
706
706
  }
@@ -716,13 +716,13 @@ function I(e) {
716
716
  return t(e.url) !== t(e.originalUrl);
717
717
  }
718
718
  function L(e) {
719
- return j.some((t) => t.id === e) ? e : "string";
719
+ return M.some((t) => t.id === e) ? e : "string";
720
720
  }
721
721
  function R(e) {
722
722
  if (!(e instanceof Error)) return "發生未知錯誤";
723
723
  let t = e.message;
724
724
  return t.includes("WORKFLOW_WEBHOOK_URL_NOT_ALLOWED") ? "URL 不在伺服器允許的白名單內。" : t.includes("WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT") ? "這個 Key 已由程式註冊的端點使用,請換一個。" : t.includes("WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED") ? "參數契約不能修改,請改用「建立新版本」。" : t.includes("WORKFLOW_WEBHOOK_TEST_RATE_LIMITED") ? "測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。" : t;
725
725
  }
726
- export { N as AdminWebhookEndpointsView };
726
+ export { P as AdminWebhookEndpointsView };
727
727
 
728
728
  //# sourceMappingURL=index.js.map