@rytass/bpm-core-react 0.20.1 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/README.md +1 -1
- package/dist/approval-instance-list-page.css +1 -1
- package/dist/chunks/{FormBuilderView-CFRiw04B.js → FormBuilderView-6KdApi-D.js} +667 -584
- package/dist/chunks/FormBuilderView-6KdApi-D.js.map +1 -0
- package/dist/chunks/FormBuilderView-CGKkuVFi.cjs +4 -0
- package/dist/chunks/FormBuilderView-CGKkuVFi.cjs.map +1 -0
- package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs → FormRendererView-B-xycC9S.cjs} +3 -3
- package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs.map → FormRendererView-B-xycC9S.cjs.map} +1 -1
- package/dist/chunks/{FormRendererView-GfbVWEGa.js → FormRendererView-BcQKUi1A.js} +238 -238
- package/dist/chunks/{FormRendererView-GfbVWEGa.js.map → FormRendererView-BcQKUi1A.js.map} +1 -1
- package/dist/chunks/approval-instance-list-page-BI5fIXc-.js +724 -0
- package/dist/chunks/approval-instance-list-page-BI5fIXc-.js.map +1 -0
- package/dist/chunks/approval-instance-list-page-Cv5I1YPX.cjs +2 -0
- package/dist/chunks/approval-instance-list-page-Cv5I1YPX.cjs.map +1 -0
- package/dist/chunks/{categories-DQUtVEiV.cjs → categories-CyyqG6wG.cjs} +2 -2
- package/dist/chunks/{categories-DQUtVEiV.cjs.map → categories-CyyqG6wG.cjs.map} +1 -1
- package/dist/chunks/{categories-BAdxjNSA.js → categories-f7E-RJEc.js} +9 -9
- package/dist/chunks/{categories-BAdxjNSA.js.map → categories-f7E-RJEc.js.map} +1 -1
- package/dist/chunks/{compose-egQlRjuZ.js → compose-DFuLPmOA.js} +5 -5
- package/dist/chunks/{compose-egQlRjuZ.js.map → compose-DFuLPmOA.js.map} +1 -1
- package/dist/chunks/compose-DK3ocWwG.cjs +2 -0
- package/dist/chunks/compose-DK3ocWwG.cjs.map +1 -0
- package/dist/chunks/{delegations-CVmtpkRn.cjs → delegations-ClRCwD1I.cjs} +2 -2
- package/dist/chunks/{delegations-CVmtpkRn.cjs.map → delegations-ClRCwD1I.cjs.map} +1 -1
- package/dist/chunks/{delegations-9-yvWWws.js → delegations-CqND-Qtz.js} +5 -5
- package/dist/chunks/{delegations-9-yvWWws.js.map → delegations-CqND-Qtz.js.map} +1 -1
- package/dist/chunks/{delegations-CrfjsH94.cjs → delegations-D43VDSz1.cjs} +2 -2
- package/dist/chunks/{delegations-CrfjsH94.cjs.map → delegations-D43VDSz1.cjs.map} +1 -1
- package/dist/chunks/{delegations-CxnNvTCc.js → delegations-zisffLwk.js} +5 -5
- package/dist/chunks/{delegations-CxnNvTCc.js.map → delegations-zisffLwk.js.map} +1 -1
- package/dist/chunks/designer-CAUWEKJ4.cjs +69 -0
- package/dist/chunks/designer-CAUWEKJ4.cjs.map +1 -0
- package/dist/chunks/{designer-CZDlQ9Nf.js → designer-CCy5EbOe.js} +2380 -1786
- package/dist/chunks/designer-CCy5EbOe.js.map +1 -0
- package/dist/chunks/detail-C5KrUC7s.cjs +5 -0
- package/dist/chunks/detail-C5KrUC7s.cjs.map +1 -0
- package/dist/chunks/{detail-ByZV1XaI.js → detail-Dnc4PPWO.js} +804 -777
- package/dist/chunks/detail-Dnc4PPWO.js.map +1 -0
- package/dist/chunks/instance-error-message-BEM4O_Kj.js +208 -0
- package/dist/chunks/instance-error-message-BEM4O_Kj.js.map +1 -0
- package/dist/chunks/instance-error-message-BpCLCOjp.cjs +2 -0
- package/dist/chunks/instance-error-message-BpCLCOjp.cjs.map +1 -0
- package/dist/chunks/organization-time-zone-provider-B7CXQril.cjs +2 -0
- package/dist/chunks/organization-time-zone-provider-B7CXQril.cjs.map +1 -0
- package/dist/chunks/organization-time-zone-provider-DNL8yo4-.js +42 -0
- package/dist/chunks/organization-time-zone-provider-DNL8yo4-.js.map +1 -0
- package/dist/chunks/{providers-BbCs23sk.js → providers-CQWekD7_.js} +197 -196
- package/dist/chunks/providers-CQWekD7_.js.map +1 -0
- package/dist/chunks/providers-VUOh6i0i.cjs +2 -0
- package/dist/chunks/providers-VUOh6i0i.cjs.map +1 -0
- package/dist/components/approval-instance-field-filter-controls.d.cts +12 -0
- package/dist/components/approval-instance-field-filter-controls.d.ts +12 -0
- package/dist/components/approval-instance-field-filters.d.cts +86 -0
- package/dist/components/approval-instance-field-filters.d.ts +86 -0
- package/dist/components/approval-instance-list-page.d.cts +4 -0
- package/dist/components/approval-instance-list-page.d.ts +4 -0
- package/dist/components/notification-drawer-options.d.cts +18 -0
- package/dist/components/notification-drawer-options.d.ts +18 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +23 -23
- package/dist/index.js.map +1 -1
- package/dist/lib/organization-time-zone-provider.d.cts +20 -0
- package/dist/lib/organization-time-zone-provider.d.ts +20 -0
- package/dist/lib/organization-time-zone.d.cts +8 -0
- package/dist/lib/organization-time-zone.d.ts +8 -0
- package/dist/lib/providers.d.cts +10 -1
- package/dist/lib/providers.d.ts +10 -1
- package/dist/next/BPMNextProviders.d.cts +8 -1
- package/dist/next/BPMNextProviders.d.ts +8 -1
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +12 -11
- package/dist/next/index.js.map +1 -1
- package/dist/next/workflow-chat-route.cjs +2 -2
- package/dist/next/workflow-chat-route.cjs.map +1 -1
- package/dist/next/workflow-chat-route.js +13 -13
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.js +1 -1
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.js +1 -1
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/templates/categories/index.cjs +1 -1
- package/dist/pages/templates/categories/index.js +1 -1
- package/dist/pages/templates/compose/index.cjs +1 -1
- package/dist/pages/templates/compose/index.js +1 -1
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.js +1 -1
- package/dist/views/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +1 -1
- package/dist/views/admin/webhook-endpoints/index.cjs +1 -1
- package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
- package/dist/views/admin/webhook-endpoints/index.js +60 -60
- package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.js +1 -1
- package/dist/views/delegations/index.cjs +1 -1
- package/dist/views/delegations/index.js +1 -1
- package/dist/views/forms/builder/FormBuilderView.d.cts +8 -1
- package/dist/views/forms/builder/FormBuilderView.d.ts +8 -1
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/renderer/index.cjs +1 -1
- package/dist/views/forms/renderer/index.js +1 -1
- package/dist/views/instances/approver-filled-form.d.cts +8 -5
- package/dist/views/instances/approver-filled-form.d.ts +8 -5
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +2 -1
- package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +2 -1
- package/dist/views/instances/detail/sections/shared.d.cts +0 -1
- package/dist/views/instances/detail/sections/shared.d.ts +0 -1
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.cjs.map +1 -1
- package/dist/views/instances/new/index.js +8 -8
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.js +1 -1
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.js +1 -1
- package/dist/views/templates/categories/index.cjs +1 -1
- package/dist/views/templates/categories/index.js +1 -1
- package/dist/views/templates/compose/index.cjs +1 -1
- package/dist/views/templates/compose/index.js +1 -1
- package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.cts +2 -0
- package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.ts +2 -0
- package/dist/views/templates/designer/approver-resolver-model.d.cts +105 -1
- package/dist/views/templates/designer/approver-resolver-model.d.ts +105 -1
- package/dist/views/templates/designer/dynamic-form-resolver-options.d.cts +5 -0
- package/dist/views/templates/designer/dynamic-form-resolver-options.d.ts +5 -0
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/dist/views/templates/designer/node-actor-resolver-options.d.cts +44 -1
- package/dist/views/templates/designer/node-actor-resolver-options.d.ts +44 -1
- package/dist/views/templates/designer/notify-recipient-options.d.cts +81 -0
- package/dist/views/templates/designer/notify-recipient-options.d.ts +81 -0
- package/dist/views/templates/designer/position-level-options.d.cts +3 -1
- package/dist/views/templates/designer/position-level-options.d.ts +3 -1
- package/dist/views/templates/designer/position-scope.d.cts +51 -0
- package/dist/views/templates/designer/position-scope.d.ts +51 -0
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.cjs.map +1 -1
- package/dist/views/templates/index.js +7 -7
- package/package.json +3 -3
- package/dist/chunks/FormBuilderView-CFRiw04B.js.map +0 -1
- package/dist/chunks/FormBuilderView-CpUgbSbt.cjs +0 -3
- package/dist/chunks/FormBuilderView-CpUgbSbt.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-BnI4t5mD.js +0 -279
- package/dist/chunks/approval-instance-list-page-BnI4t5mD.js.map +0 -1
- package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs +0 -2
- package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs.map +0 -1
- package/dist/chunks/compose-Bb5bUVFd.cjs +0 -2
- package/dist/chunks/compose-Bb5bUVFd.cjs.map +0 -1
- package/dist/chunks/designer-CX9bhYJS.cjs +0 -69
- package/dist/chunks/designer-CX9bhYJS.cjs.map +0 -1
- package/dist/chunks/designer-CZDlQ9Nf.js.map +0 -1
- package/dist/chunks/detail-ByZV1XaI.js.map +0 -1
- package/dist/chunks/detail-ChseSF55.cjs +0 -5
- package/dist/chunks/detail-ChseSF55.cjs.map +0 -1
- package/dist/chunks/instance-error-message-DTARGbGo.cjs +0 -2
- package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +0 -1
- package/dist/chunks/instance-error-message-q6gy5evy.js +0 -120
- package/dist/chunks/instance-error-message-q6gy5evy.js.map +0 -1
- package/dist/chunks/language-provider-Bdnx3Gxl.cjs +0 -2
- package/dist/chunks/language-provider-Bdnx3Gxl.cjs.map +0 -1
- package/dist/chunks/language-provider-phkWOapf.js +0 -17
- package/dist/chunks/language-provider-phkWOapf.js.map +0 -1
- package/dist/chunks/providers-BbCs23sk.js.map +0 -1
- package/dist/chunks/providers-D_KAgOOu.cjs +0 -2
- package/dist/chunks/providers-D_KAgOOu.cjs.map +0 -1
|
@@ -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 {
|
|
9
|
-
import {
|
|
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
|
|
11
|
+
var O = {
|
|
12
12
|
display: "grid",
|
|
13
13
|
gap: "var(--mzn-spacing-gap-base)"
|
|
14
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
],
|
|
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
|
-
],
|
|
58
|
+
], N = {
|
|
59
59
|
CREATED: "建立",
|
|
60
60
|
DISABLED: "停用",
|
|
61
61
|
ENABLED: "啟用",
|
|
62
62
|
SECRET_ROTATED: "輪替金鑰",
|
|
63
63
|
TEST_SENT: "測試送出",
|
|
64
64
|
UPDATED: "更新"
|
|
65
|
-
},
|
|
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
|
|
83
|
-
let [p, h] = a(null), [
|
|
84
|
-
|
|
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
|
|
87
|
-
h(e),
|
|
86
|
+
let e = await C();
|
|
87
|
+
h(e), k(e.enabled ? await S() : []), N(null);
|
|
88
88
|
} catch (e) {
|
|
89
|
-
|
|
89
|
+
N(R(e));
|
|
90
90
|
} finally {
|
|
91
|
-
|
|
91
|
+
j(!1);
|
|
92
92
|
}
|
|
93
93
|
}, []);
|
|
94
94
|
r(() => {
|
|
95
95
|
Z();
|
|
96
96
|
}, [Z]);
|
|
97
97
|
let Q = n(async (e) => {
|
|
98
|
-
|
|
98
|
+
N(null), L(null);
|
|
99
99
|
try {
|
|
100
100
|
return L(await e()), await Z(), !0;
|
|
101
101
|
} catch (e) {
|
|
102
|
-
return
|
|
102
|
+
return N(R(e)), !1;
|
|
103
103
|
}
|
|
104
|
-
}, [Z]), ce = i(() =>
|
|
104
|
+
}, [Z]), ce = i(() => D.map((e) => ({
|
|
105
105
|
endpoint: e,
|
|
106
106
|
key: e.id
|
|
107
|
-
})), [
|
|
107
|
+
})), [D]), le = i(() => [
|
|
108
108
|
{
|
|
109
109
|
key: "label",
|
|
110
110
|
render: ({ endpoint: e }) => /* @__PURE__ */ b("div", {
|
|
111
|
-
style:
|
|
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:
|
|
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(
|
|
198
|
+
onClick: () => B(F(e, "edit"))
|
|
199
199
|
},
|
|
200
200
|
{
|
|
201
201
|
name: "建立新版本",
|
|
202
|
-
onClick: () => B(
|
|
202
|
+
onClick: () => B(F(e, "version"))
|
|
203
203
|
},
|
|
204
204
|
{
|
|
205
205
|
name: "測試送出",
|
|
206
206
|
onClick: () => {
|
|
207
|
-
Q(async () =>
|
|
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
|
|
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
|
-
|
|
225
|
+
te(e.id).then((t) => X({
|
|
226
226
|
endpoint: e,
|
|
227
227
|
records: t
|
|
228
|
-
})).catch((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
|
|
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
|
|
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
|
|
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:
|
|
287
|
+
icon: E,
|
|
288
288
|
iconType: "leading",
|
|
289
|
-
onClick: () => B(
|
|
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:
|
|
295
|
+
style: O,
|
|
296
296
|
children: [
|
|
297
|
-
|
|
297
|
+
M ? /* @__PURE__ */ y(_, {
|
|
298
298
|
color: "text-error",
|
|
299
299
|
variant: "body",
|
|
300
|
-
children:
|
|
300
|
+
children: M
|
|
301
301
|
}) : null,
|
|
302
|
-
|
|
302
|
+
P ? /* @__PURE__ */ y(_, {
|
|
303
303
|
color: "text-success",
|
|
304
304
|
variant: "body",
|
|
305
|
-
children:
|
|
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:
|
|
322
|
+
loading: A
|
|
323
323
|
})
|
|
324
324
|
]
|
|
325
325
|
}) }) }),
|
|
326
|
-
z ? /* @__PURE__ */ y(
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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: [...
|
|
529
|
-
value:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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: [...
|
|
643
|
-
value:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
726
|
+
export { P as AdminWebhookEndpointsView };
|
|
727
727
|
|
|
728
728
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_Fragment","BPMFormField","Fragment$1","ContentHeader","STACK_STYLE","ROW_STYLE","HEADER_ROW_STYLE","METHOD_OPTIONS","PARAMETER_TYPE_OPTIONS","AUDIT_ACTION_LABELS","EMPTY_DRAFT","AdminWebhookEndpointsView","management","setManagement","useState","endpoints","setEndpoints","loading","setLoading","error","setError","notice","setNotice","draft","setDraft","saving","setSaving","rotating","setRotating","nextSecret","setNextSecret","removeSecret","setRemoveSecret","audits","setAudits","refresh","useCallback","nextManagement","readWorkflowWebhookEndpointManagement","listWorkflowWebhookManagedEndpoints","requestError","readErrorMessage","run","work","rows","useMemo","endpoint","columns","Typography","Badge","formatDateTime","actions","readEditDraft","readTestNotice","testWorkflowWebhookEndpoint","setWorkflowWebhookEndpointActive","handleSaveDraft","saved","parameters","parameter","headers","header","timeoutMs","updateWorkflowWebhookEndpoint","isOriginChanged","createWorkflowWebhookEndpoint","handleRotate","rotateWorkflowWebhookEndpointSecret","enabled","PageHeader","Button","PlusIcon","SectionGroup","Section","Table","EndpointDraftModal","Modal","Toggle","event","Input","AUDIT_COLUMNS","audit","editing","originChanged","replaceHeaders","update","onChange","patch","updateParameter","current","index","updateHeader","text","field","onCancel","Textarea","Select","option","TrashIcon","readParameterType","mode","result","origin","url","id","message"],"sources":["../../../../src/views/admin/webhook-endpoints/AdminWebhookEndpointsView.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon, TrashIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { NotifyWebhookParameterType } from '@rytass/bpm-core-shared/workflow';\nimport {\n WorkflowWebhookEndpointAuditRecord,\n WorkflowWebhookEndpointManagementRecord,\n WorkflowWebhookEndpointTestResultRecord,\n WorkflowWebhookManagedEndpointRecord,\n createWorkflowWebhookEndpoint,\n listWorkflowWebhookEndpointAudits,\n listWorkflowWebhookManagedEndpoints,\n readWorkflowWebhookEndpointManagement,\n rotateWorkflowWebhookEndpointSecret,\n setWorkflowWebhookEndpointActive,\n testWorkflowWebhookEndpoint,\n updateWorkflowWebhookEndpoint,\n} from '@rytass/bpm-core-client/template';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype SelectOption = Readonly<{ id: string; name: string }>;\n\ntype EndpointRow = Readonly<\n Record<string, unknown> & {\n endpoint: WorkflowWebhookManagedEndpointRecord;\n key: string;\n }\n>;\n\ntype AuditRow = Readonly<\n Record<string, unknown> & {\n audit: WorkflowWebhookEndpointAuditRecord;\n key: string;\n }\n>;\n\ntype ParameterDraft = Readonly<{\n description: string;\n key: string;\n label: string;\n required: boolean;\n type: NotifyWebhookParameterType;\n}>;\n\ntype HeaderDraft = Readonly<{ name: string; value: string }>;\n\n/**\n * `mode` decides what can change: a new endpoint (or a new version of one)\n * sets everything; editing keeps the parameter contract and only replaces\n * headers when asked to.\n */\ntype EndpointDraft = Readonly<{\n deprecated: boolean;\n description: string;\n endpointId: string | null;\n headers: readonly HeaderDraft[];\n key: string;\n label: string;\n method: string;\n mode: 'create' | 'edit' | 'version';\n /** The stored URL when editing, to spot a move to another host. */\n originalUrl: string;\n parameters: readonly ParameterDraft[];\n replaceHeaders: boolean;\n signingSecret: string;\n timeoutMs: string;\n url: string;\n version: string;\n}>;\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n};\n\nconst ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto',\n};\n\nconst HEADER_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 2fr) auto',\n};\n\nconst METHOD_OPTIONS: readonly SelectOption[] = [\n { id: 'POST', name: 'POST' },\n { id: 'PUT', name: 'PUT' },\n { id: 'PATCH', name: 'PATCH' },\n];\n\nconst PARAMETER_TYPE_OPTIONS: readonly SelectOption[] = [\n { id: 'string', name: '文字' },\n { id: 'number', name: '數字' },\n { id: 'boolean', name: '是/否' },\n { id: 'stringArray', name: '文字清單' },\n { id: 'json', name: 'JSON' },\n];\n\nconst AUDIT_ACTION_LABELS: Readonly<\n Record<WorkflowWebhookEndpointAuditRecord['action'], string>\n> = {\n CREATED: '建立',\n DISABLED: '停用',\n ENABLED: '啟用',\n SECRET_ROTATED: '輪替金鑰',\n TEST_SENT: '測試送出',\n UPDATED: '更新',\n};\n\nconst EMPTY_DRAFT: EndpointDraft = {\n deprecated: false,\n description: '',\n endpointId: null,\n headers: [],\n key: '',\n label: '',\n method: 'POST',\n mode: 'create',\n originalUrl: '',\n parameters: [],\n replaceHeaders: true,\n signingSecret: '',\n timeoutMs: '',\n url: '',\n version: '1',\n};\n\n/**\n * Back-office management of database webhook endpoints (ADR 18 §3.13):\n * create, edit, disable, rotate the signing secret, test-send and read the\n * change history. Header values and secrets are entered here and never shown\n * again. Administrator-only on the server.\n */\nexport function AdminWebhookEndpointsView(): ReactElement {\n const [management, setManagement] =\n useState<WorkflowWebhookEndpointManagementRecord | null>(null);\n const [endpoints, setEndpoints] = useState<\n readonly WorkflowWebhookManagedEndpointRecord[]\n >([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n const [draft, setDraft] = useState<EndpointDraft | null>(null);\n const [saving, setSaving] = useState(false);\n const [rotating, setRotating] =\n useState<WorkflowWebhookManagedEndpointRecord | null>(null);\n const [nextSecret, setNextSecret] = useState('');\n const [removeSecret, setRemoveSecret] = useState(false);\n const [audits, setAudits] = useState<{\n readonly endpoint: WorkflowWebhookManagedEndpointRecord;\n readonly records: readonly WorkflowWebhookEndpointAuditRecord[];\n } | null>(null);\n\n const refresh = useCallback(async (): Promise<void> => {\n setLoading(true);\n\n try {\n const nextManagement = await readWorkflowWebhookEndpointManagement();\n\n setManagement(nextManagement);\n setEndpoints(\n nextManagement.enabled\n ? await listWorkflowWebhookManagedEndpoints()\n : [],\n );\n setError(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect((): void => {\n void refresh();\n }, [refresh]);\n\n const run = useCallback(\n async (work: () => Promise<string | null>): Promise<boolean> => {\n setError(null);\n setNotice(null);\n\n try {\n setNotice(await work());\n await refresh();\n\n return true;\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n\n return false;\n }\n },\n [refresh],\n );\n\n const rows = useMemo(\n (): EndpointRow[] =>\n endpoints.map((endpoint) => ({ endpoint, key: endpoint.id })),\n [endpoints],\n );\n\n const columns = useMemo(\n (): TableColumn<EndpointRow>[] => [\n {\n key: 'label',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.label}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.key}@{endpoint.version} · 參數{' '}\n {endpoint.parameters.length} 個\n </Typography>\n </div>\n ),\n title: '端點',\n width: 240,\n },\n {\n key: 'url',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {endpoint.method} {endpoint.url}\n </Typography>\n ),\n title: 'URL',\n width: 320,\n },\n {\n key: 'status',\n render: ({ endpoint }: EndpointRow): ReactElement =>\n !endpoint.active ? (\n <Badge size=\"sub\" text=\"已停用\" variant=\"dot-inactive\" />\n ) : endpoint.deprecated ? (\n <Badge size=\"sub\" text=\"不建議使用\" variant=\"dot-warning\" />\n ) : (\n <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'credentials',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.hasSigningSecret ? '已設定簽章金鑰' : '未簽章'}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.headerNames.length\n ? `Header:${endpoint.headerNames.join('、')}`\n : '沒有自訂 header'}\n </Typography>\n </div>\n ),\n title: '憑證',\n width: 200,\n },\n {\n key: 'updatedAt',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(endpoint.updatedAt)}\n </Typography>\n ),\n title: '更新時間',\n width: 180,\n },\n ],\n [],\n );\n\n const actions = useMemo(\n (): TableActions<EndpointRow> => ({\n render: ({\n endpoint,\n }): ReturnType<TableActions<EndpointRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'edit')),\n },\n {\n name: '建立新版本',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'version')),\n },\n {\n name: '測試送出',\n onClick: (): void => {\n void run(async () =>\n readTestNotice(\n endpoint,\n await testWorkflowWebhookEndpoint(endpoint.id),\n ),\n );\n },\n },\n {\n name: '輪替金鑰',\n onClick: (): void => {\n setNextSecret('');\n setRemoveSecret(false);\n setRotating(endpoint);\n },\n },\n {\n name: endpoint.active ? '停用' : '啟用',\n onClick: (): void => {\n void run(async () => {\n await setWorkflowWebhookEndpointActive(\n endpoint.id,\n !endpoint.active,\n );\n\n return `已${endpoint.active ? '停用' : '啟用'}「${endpoint.label}」。`;\n });\n },\n },\n {\n name: '異動紀錄',\n onClick: (): void => {\n void listWorkflowWebhookEndpointAudits(endpoint.id)\n .then((records): void => setAudits({ endpoint, records }))\n .catch((requestError: unknown): void =>\n setError(readErrorMessage(requestError)),\n );\n },\n },\n ],\n variant: 'base-secondary',\n width: 180,\n }),\n [run],\n );\n\n async function handleSaveDraft(): Promise<void> {\n if (!draft) {\n return;\n }\n\n setSaving(true);\n\n const saved = await run(async () => {\n const parameters = draft.parameters.map((parameter) => ({\n description: parameter.description.trim() || null,\n key: parameter.key.trim(),\n label: parameter.label.trim(),\n required: parameter.required,\n type: parameter.type,\n }));\n const headers = draft.headers\n .filter((header) => header.name.trim())\n .map((header) => ({ name: header.name.trim(), value: header.value }));\n const timeoutMs = draft.timeoutMs.trim() ? Number(draft.timeoutMs) : null;\n\n if (draft.mode === 'edit' && draft.endpointId) {\n await updateWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers:\n draft.replaceHeaders || isOriginChanged(draft) ? headers : null,\n id: draft.endpointId,\n label: draft.label,\n method: draft.method,\n parameters,\n timeoutMs,\n url: draft.url,\n });\n\n return `已更新「${draft.label}」。`;\n }\n\n await createWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers,\n key: draft.key,\n label: draft.label,\n method: draft.method,\n parameters,\n signingSecret: draft.signingSecret || null,\n timeoutMs,\n url: draft.url,\n version: Number(draft.version),\n });\n\n return `已建立「${draft.label}」v${draft.version},設計器現在可以選用。`;\n });\n\n setSaving(false);\n\n if (saved) {\n setDraft(null);\n }\n }\n\n async function handleRotate(): Promise<void> {\n if (!rotating) {\n return;\n }\n\n const endpoint = rotating;\n const done = await run(async () => {\n await rotateWorkflowWebhookEndpointSecret(\n endpoint.id,\n removeSecret ? null : nextSecret,\n );\n\n return removeSecret\n ? `已移除「${endpoint.label}」的簽章金鑰,之後的請求不再簽章。`\n : `已輪替「${endpoint.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`;\n });\n\n if (done) {\n setRotating(null);\n setNextSecret('');\n }\n }\n\n const enabled = Boolean(management?.enabled);\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"維護知會節點可呼叫的外部系統端點。Header 值與簽章金鑰加密保存,儲存後不會再顯示。\"\n title=\"Webhook 端點\"\n >\n <Button\n disabled={!enabled}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setDraft(EMPTY_DRAFT)}\n variant=\"base-primary\"\n >\n 新增端點\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={STACK_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {notice ? (\n <Typography color=\"text-success\" variant=\"body\">\n {notice}\n </Typography>\n ) : null}\n {management && !enabled ? (\n <Typography color=\"text-warning\" variant=\"body\">\n 此伺服器未啟用後台維護的 Webhook 端點:需要設定\n workflowWebhookTargetSources 含 DATABASE、URL\n 白名單與加密金鑰。程式註冊的端點不受影響。\n </Typography>\n ) : null}\n {enabled ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 允許的 URL:{management?.allowedUrlPatterns.join('、')}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </div>\n </Section>\n </SectionGroup>\n\n {draft ? (\n <EndpointDraftModal\n draft={draft}\n onCancel={(): void => setDraft(null)}\n onChange={setDraft}\n onConfirm={(): void => void handleSaveDraft()}\n saving={saving}\n />\n ) : null}\n\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !removeSecret && !nextSecret }}\n confirmText={removeSecret ? '移除金鑰' : '輪替金鑰'}\n modalType=\"standard\"\n onCancel={(): void => setRotating(null)}\n onClose={(): void => setRotating(null)}\n onConfirm={(): void => void handleRotate()}\n open={Boolean(rotating)}\n showModalFooter\n showModalHeader\n supportingText=\"新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。\"\n title={`輪替簽章金鑰:${rotating?.label ?? ''}`}\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"移除金鑰\" name=\"removeSigningSecret\">\n <Toggle\n checked={removeSecret}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setRemoveSecret(event.target.checked)\n }\n />\n </BPMFormField>\n {removeSecret ? null : (\n <BPMFormField label=\"新金鑰\" name=\"nextSigningSecret\" required>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setNextSecret(event.target.value)\n }\n value={nextSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n </div>\n </Modal>\n\n <Modal\n confirmText=\"關閉\"\n modalType=\"standard\"\n onClose={(): void => setAudits(null)}\n onConfirm={(): void => setAudits(null)}\n open={Boolean(audits)}\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText=\"只記錄誰在何時變更了哪些欄位,不記錄任何值。\"\n title={`異動紀錄:${audits?.endpoint.label ?? ''}`}\n >\n <Table\n columns={AUDIT_COLUMNS}\n dataSource={(audits?.records ?? []).map((audit): AuditRow => ({\n audit,\n key: audit.id,\n }))}\n fullWidth\n />\n </Modal>\n </>\n );\n}\n\nconst AUDIT_COLUMNS: TableColumn<AuditRow>[] = [\n {\n key: 'createdAt',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(audit.createdAt)}\n </Typography>\n ),\n title: '時間',\n width: 180,\n },\n {\n key: 'action',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {AUDIT_ACTION_LABELS[audit.action]}\n </Typography>\n ),\n title: '動作',\n width: 120,\n },\n {\n key: 'changedFields',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.changedFields.join('、') || '—'}\n </Typography>\n ),\n title: '欄位',\n width: 280,\n },\n {\n key: 'actor',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.actorMemberId ?? '系統'}\n </Typography>\n ),\n title: '操作者',\n width: 160,\n },\n];\n\nfunction EndpointDraftModal({\n draft,\n onCancel,\n onChange,\n onConfirm,\n saving,\n}: {\n readonly draft: EndpointDraft;\n readonly onCancel: () => void;\n readonly onChange: (draft: EndpointDraft) => void;\n readonly onConfirm: () => void;\n readonly saving: boolean;\n}): ReactElement {\n const editing = draft.mode === 'edit';\n // Stored header values must not follow the URL to another host, so a new\n // host always means entering the headers again.\n const originChanged = isOriginChanged(draft);\n const replaceHeaders = draft.replaceHeaders || originChanged;\n const update = (patch: Partial<EndpointDraft>): void =>\n onChange({ ...draft, ...patch });\n const updateParameter = (\n index: number,\n patch: Partial<ParameterDraft>,\n ): void =>\n update({\n parameters: draft.parameters.map((parameter, current) =>\n current === index ? { ...parameter, ...patch } : parameter,\n ),\n });\n const updateHeader = (index: number, patch: Partial<HeaderDraft>): void =>\n update({\n headers: draft.headers.map((header, current) =>\n current === index ? { ...header, ...patch } : header,\n ),\n });\n const text =\n (field: keyof EndpointDraft) =>\n (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void =>\n update({ [field]: event.target.value });\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmText={editing ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onCancel}\n onClose={onCancel}\n onConfirm={onConfirm}\n open\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText={\n editing\n ? '參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。'\n : draft.mode === 'version'\n ? '新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。'\n : 'URL 需符合伺服器設定的白名單。'\n }\n title={\n editing\n ? `編輯端點:${draft.label}`\n : draft.mode === 'version'\n ? `建立新版本:${draft.key}`\n : '新增 Webhook 端點'\n }\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"Key\" name=\"endpointKey\" required>\n <Input\n {...(draft.mode === 'create' ? {} : { readonly: true as const })}\n onChange={text('key')}\n placeholder=\"例如 crm.lead-created\"\n value={draft.key}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"版本\" name=\"endpointVersion\" required>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('version')}\n value={draft.version}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"名稱\" name=\"endpointLabel\" required>\n <Input\n onChange={text('label')}\n placeholder=\"例如 CRM 建立名單\"\n value={draft.label}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"說明\" name=\"endpointDescription\">\n <Textarea\n onChange={text('description')}\n rows={2}\n value={draft.description}\n />\n </BPMFormField>\n <BPMFormField label=\"URL\" name=\"endpointUrl\" required>\n <Input\n onChange={text('url')}\n placeholder=\"https://\"\n value={draft.url}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"Method\" name=\"endpointMethod\" required>\n <Select\n clearable={false}\n onChange={(option): void =>\n update({ method: option?.id ?? 'POST' })\n }\n options={[...METHOD_OPTIONS]}\n value={\n METHOD_OPTIONS.find((option) => option.id === draft.method) ??\n null\n }\n />\n </BPMFormField>\n <BPMFormField\n hintText=\"留空使用預設 10 秒,上限 30000 毫秒。\"\n label=\"逾時(毫秒)\"\n name=\"endpointTimeout\"\n >\n <Input\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('timeoutMs')}\n value={draft.timeoutMs}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"不建議使用\" name=\"endpointDeprecated\">\n <Toggle\n checked={draft.deprecated}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ deprecated: event.target.checked })\n }\n />\n </BPMFormField>\n {editing ? null : (\n <BPMFormField\n hintText=\"選填;設定後 BPM 以 HMAC-SHA256 簽章,儲存後不會再顯示。\"\n label=\"簽章金鑰\"\n name=\"endpointSigningSecret\"\n >\n <Input\n onChange={text('signingSecret')}\n placeholder=\"選填,儲存後不再顯示\"\n value={draft.signingSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n\n <Typography variant=\"label-primary-highlight\">Headers</Typography>\n {editing ? (\n <BPMFormField\n hintText={\n originChanged\n ? 'URL 已改到其他主機,必須重新輸入 header(留空代表不帶任何 header)。'\n : '現有 header 的值不會顯示;開啟後以下列內容取代全部 header。'\n }\n label=\"取代 headers\"\n name=\"endpointReplaceHeaders\"\n >\n <Toggle\n checked={replaceHeaders}\n disabled={originChanged}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ replaceHeaders: event.target.checked })\n }\n />\n </BPMFormField>\n ) : null}\n {replaceHeaders\n ? draft.headers.map((header, index): ReactElement => (\n <div key={index} style={HEADER_ROW_STYLE}>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { name: event.target.value })\n }\n placeholder=\"名稱,例如 Authorization\"\n inputProps={{ autoComplete: 'off' }}\n value={header.name}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { value: event.target.value })\n }\n placeholder=\"值\"\n value={header.value}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n <Button\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n headers: draft.headers.filter(\n (_header, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除 header\n </Button>\n </div>\n ))\n : null}\n {replaceHeaders ? (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({ headers: [...draft.headers, { name: '', value: '' }] })\n }\n variant=\"base-dashed\"\n >\n 新增 header\n </Button>\n </div>\n ) : null}\n\n <Typography variant=\"label-primary-highlight\">參數</Typography>\n {draft.parameters.map((parameter, index): ReactElement => (\n <div key={index} style={ROW_STYLE}>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { key: event.target.value })\n }\n placeholder=\"參數鍵\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.key}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { label: event.target.value })\n }\n placeholder=\"顯示名稱\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.label}\n variant=\"base\"\n />\n <Select\n clearable={false}\n disabled={editing}\n onChange={(option): void =>\n updateParameter(index, {\n type: readParameterType(option?.id ?? null),\n })\n }\n options={[...PARAMETER_TYPE_OPTIONS]}\n value={\n PARAMETER_TYPE_OPTIONS.find(\n (option) => option.id === parameter.type,\n ) ?? null\n }\n />\n <Toggle\n checked={parameter.required}\n disabled={editing}\n label=\"必填\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { required: event.target.checked })\n }\n />\n <Button\n disabled={editing}\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n parameters: draft.parameters.filter(\n (_parameter, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除參數\n </Button>\n </div>\n ))}\n {editing ? null : (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({\n parameters: [\n ...draft.parameters,\n {\n description: '',\n key: '',\n label: '',\n required: false,\n type: 'string',\n },\n ],\n })\n }\n variant=\"base-dashed\"\n >\n 新增參數\n </Button>\n </div>\n )}\n </div>\n </Modal>\n );\n}\n\nfunction readEditDraft(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n mode: 'edit' | 'version',\n): EndpointDraft {\n return {\n deprecated: endpoint.deprecated,\n description: endpoint.description ?? '',\n endpointId: mode === 'edit' ? endpoint.id : null,\n headers: [],\n key: endpoint.key,\n label: endpoint.label,\n method: endpoint.method,\n mode,\n originalUrl: endpoint.url,\n parameters: endpoint.parameters.map((parameter) => ({\n description: parameter.description ?? '',\n key: parameter.key,\n label: parameter.label,\n required: parameter.required,\n type: parameter.type,\n })),\n // A new version starts without credentials: they are not readable.\n replaceHeaders: mode === 'version',\n signingSecret: '',\n timeoutMs: endpoint.timeoutMs ? String(endpoint.timeoutMs) : '',\n url: endpoint.url,\n version: String(\n mode === 'version' ? endpoint.version + 1 : endpoint.version,\n ),\n };\n}\n\nfunction readTestNotice(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n result: WorkflowWebhookEndpointTestResultRecord,\n): string {\n if (result.ok) {\n return `測試送出成功:「${endpoint.label}」回應 HTTP ${result.status ?? ''}。`;\n }\n\n throw new Error(\n `測試送出失敗:「${endpoint.label}」${result.status ? `回應 HTTP ${result.status}` : ''}(${result.errorCode ?? '未知錯誤'})${result.errorDetail ? `:${result.errorDetail}` : ''}`,\n );\n}\n\nfunction isOriginChanged(draft: EndpointDraft): boolean {\n if (draft.mode !== 'edit') {\n return false;\n }\n\n const origin = (url: string): string => {\n try {\n return new URL(url.trim()).origin;\n } catch {\n return url.trim();\n }\n };\n\n return origin(draft.url) !== origin(draft.originalUrl);\n}\n\nfunction readParameterType(id: string | null): NotifyWebhookParameterType {\n return PARAMETER_TYPE_OPTIONS.some((option) => option.id === id)\n ? (id as NotifyWebhookParameterType)\n : 'string';\n}\n\nfunction readErrorMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return '發生未知錯誤';\n }\n\n const message = error.message;\n\n if (message.includes('WORKFLOW_WEBHOOK_URL_NOT_ALLOWED')) {\n return 'URL 不在伺服器允許的白名單內。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT')) {\n return '這個 Key 已由程式註冊的端點使用,請換一個。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED')) {\n return '參數契約不能修改,請改用「建立新版本」。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_TEST_RATE_LIMITED')) {\n return '測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。';\n }\n\n return message;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","BPMFormField","Fragment$1","ContentHeader","STACK_STYLE","ROW_STYLE","HEADER_ROW_STYLE","METHOD_OPTIONS","PARAMETER_TYPE_OPTIONS","AUDIT_ACTION_LABELS","EMPTY_DRAFT","AdminWebhookEndpointsView","management","setManagement","useState","endpoints","setEndpoints","loading","setLoading","error","setError","notice","setNotice","draft","setDraft","saving","setSaving","rotating","setRotating","nextSecret","setNextSecret","removeSecret","setRemoveSecret","audits","setAudits","refresh","useCallback","nextManagement","readWorkflowWebhookEndpointManagement","listWorkflowWebhookManagedEndpoints","requestError","readErrorMessage","run","work","rows","useMemo","endpoint","columns","Typography","Badge","formatDateTime","actions","readEditDraft","readTestNotice","testWorkflowWebhookEndpoint","setWorkflowWebhookEndpointActive","handleSaveDraft","saved","parameters","parameter","headers","header","timeoutMs","updateWorkflowWebhookEndpoint","isOriginChanged","createWorkflowWebhookEndpoint","handleRotate","rotateWorkflowWebhookEndpointSecret","enabled","PageHeader","Button","PlusIcon","SectionGroup","Section","Table","EndpointDraftModal","Modal","Toggle","event","Input","AUDIT_COLUMNS","audit","editing","originChanged","replaceHeaders","update","onChange","patch","updateParameter","current","index","updateHeader","text","field","onCancel","Textarea","Select","option","TrashIcon","readParameterType","mode","result","origin","url","id","message"],"sources":["../../../../src/views/admin/webhook-endpoints/AdminWebhookEndpointsView.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon, TrashIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { NotifyWebhookParameterType } from '@rytass/bpm-core-shared/workflow';\nimport {\n WorkflowWebhookEndpointAuditRecord,\n WorkflowWebhookEndpointManagementRecord,\n WorkflowWebhookEndpointTestResultRecord,\n WorkflowWebhookManagedEndpointRecord,\n createWorkflowWebhookEndpoint,\n listWorkflowWebhookEndpointAudits,\n listWorkflowWebhookManagedEndpoints,\n readWorkflowWebhookEndpointManagement,\n rotateWorkflowWebhookEndpointSecret,\n setWorkflowWebhookEndpointActive,\n testWorkflowWebhookEndpoint,\n updateWorkflowWebhookEndpoint,\n} from '@rytass/bpm-core-client/template';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype SelectOption = Readonly<{ id: string; name: string }>;\n\ntype EndpointRow = Readonly<\n Record<string, unknown> & {\n endpoint: WorkflowWebhookManagedEndpointRecord;\n key: string;\n }\n>;\n\ntype AuditRow = Readonly<\n Record<string, unknown> & {\n audit: WorkflowWebhookEndpointAuditRecord;\n key: string;\n }\n>;\n\ntype ParameterDraft = Readonly<{\n description: string;\n key: string;\n label: string;\n required: boolean;\n type: NotifyWebhookParameterType;\n}>;\n\ntype HeaderDraft = Readonly<{ name: string; value: string }>;\n\n/**\n * `mode` decides what can change: a new endpoint (or a new version of one)\n * sets everything; editing keeps the parameter contract and only replaces\n * headers when asked to.\n */\ntype EndpointDraft = Readonly<{\n deprecated: boolean;\n description: string;\n endpointId: string | null;\n headers: readonly HeaderDraft[];\n key: string;\n label: string;\n method: string;\n mode: 'create' | 'edit' | 'version';\n /** The stored URL when editing, to spot a move to another host. */\n originalUrl: string;\n parameters: readonly ParameterDraft[];\n replaceHeaders: boolean;\n signingSecret: string;\n timeoutMs: string;\n url: string;\n version: string;\n}>;\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n};\n\nconst ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto',\n};\n\nconst HEADER_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 2fr) auto',\n};\n\nconst METHOD_OPTIONS: readonly SelectOption[] = [\n { id: 'POST', name: 'POST' },\n { id: 'PUT', name: 'PUT' },\n { id: 'PATCH', name: 'PATCH' },\n];\n\nconst PARAMETER_TYPE_OPTIONS: readonly SelectOption[] = [\n { id: 'string', name: '文字' },\n { id: 'number', name: '數字' },\n { id: 'boolean', name: '是/否' },\n { id: 'stringArray', name: '文字清單' },\n { id: 'json', name: 'JSON' },\n];\n\nconst AUDIT_ACTION_LABELS: Readonly<\n Record<WorkflowWebhookEndpointAuditRecord['action'], string>\n> = {\n CREATED: '建立',\n DISABLED: '停用',\n ENABLED: '啟用',\n SECRET_ROTATED: '輪替金鑰',\n TEST_SENT: '測試送出',\n UPDATED: '更新',\n};\n\nconst EMPTY_DRAFT: EndpointDraft = {\n deprecated: false,\n description: '',\n endpointId: null,\n headers: [],\n key: '',\n label: '',\n method: 'POST',\n mode: 'create',\n originalUrl: '',\n parameters: [],\n replaceHeaders: true,\n signingSecret: '',\n timeoutMs: '',\n url: '',\n version: '1',\n};\n\n/**\n * Back-office management of database webhook endpoints (ADR 18 §3.13):\n * create, edit, disable, rotate the signing secret, test-send and read the\n * change history. Header values and secrets are entered here and never shown\n * again. Administrator-only on the server.\n */\nexport function AdminWebhookEndpointsView(): ReactElement {\n const [management, setManagement] =\n useState<WorkflowWebhookEndpointManagementRecord | null>(null);\n const [endpoints, setEndpoints] = useState<\n readonly WorkflowWebhookManagedEndpointRecord[]\n >([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n const [draft, setDraft] = useState<EndpointDraft | null>(null);\n const [saving, setSaving] = useState(false);\n const [rotating, setRotating] =\n useState<WorkflowWebhookManagedEndpointRecord | null>(null);\n const [nextSecret, setNextSecret] = useState('');\n const [removeSecret, setRemoveSecret] = useState(false);\n const [audits, setAudits] = useState<{\n readonly endpoint: WorkflowWebhookManagedEndpointRecord;\n readonly records: readonly WorkflowWebhookEndpointAuditRecord[];\n } | null>(null);\n\n const refresh = useCallback(async (): Promise<void> => {\n setLoading(true);\n\n try {\n const nextManagement = await readWorkflowWebhookEndpointManagement();\n\n setManagement(nextManagement);\n setEndpoints(\n nextManagement.enabled\n ? await listWorkflowWebhookManagedEndpoints()\n : [],\n );\n setError(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect((): void => {\n void refresh();\n }, [refresh]);\n\n const run = useCallback(\n async (work: () => Promise<string | null>): Promise<boolean> => {\n setError(null);\n setNotice(null);\n\n try {\n setNotice(await work());\n await refresh();\n\n return true;\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n\n return false;\n }\n },\n [refresh],\n );\n\n const rows = useMemo(\n (): EndpointRow[] =>\n endpoints.map((endpoint) => ({ endpoint, key: endpoint.id })),\n [endpoints],\n );\n\n const columns = useMemo(\n (): TableColumn<EndpointRow>[] => [\n {\n key: 'label',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.label}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.key}@{endpoint.version} · 參數{' '}\n {endpoint.parameters.length} 個\n </Typography>\n </div>\n ),\n title: '端點',\n width: 240,\n },\n {\n key: 'url',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {endpoint.method} {endpoint.url}\n </Typography>\n ),\n title: 'URL',\n width: 320,\n },\n {\n key: 'status',\n render: ({ endpoint }: EndpointRow): ReactElement =>\n !endpoint.active ? (\n <Badge size=\"sub\" text=\"已停用\" variant=\"dot-inactive\" />\n ) : endpoint.deprecated ? (\n <Badge size=\"sub\" text=\"不建議使用\" variant=\"dot-warning\" />\n ) : (\n <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'credentials',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.hasSigningSecret ? '已設定簽章金鑰' : '未簽章'}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.headerNames.length\n ? `Header:${endpoint.headerNames.join('、')}`\n : '沒有自訂 header'}\n </Typography>\n </div>\n ),\n title: '憑證',\n width: 200,\n },\n {\n key: 'updatedAt',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(endpoint.updatedAt)}\n </Typography>\n ),\n title: '更新時間',\n width: 180,\n },\n ],\n [],\n );\n\n const actions = useMemo(\n (): TableActions<EndpointRow> => ({\n render: ({\n endpoint,\n }): ReturnType<TableActions<EndpointRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'edit')),\n },\n {\n name: '建立新版本',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'version')),\n },\n {\n name: '測試送出',\n onClick: (): void => {\n void run(async () =>\n readTestNotice(\n endpoint,\n await testWorkflowWebhookEndpoint(endpoint.id),\n ),\n );\n },\n },\n {\n name: '輪替金鑰',\n onClick: (): void => {\n setNextSecret('');\n setRemoveSecret(false);\n setRotating(endpoint);\n },\n },\n {\n name: endpoint.active ? '停用' : '啟用',\n onClick: (): void => {\n void run(async () => {\n await setWorkflowWebhookEndpointActive(\n endpoint.id,\n !endpoint.active,\n );\n\n return `已${endpoint.active ? '停用' : '啟用'}「${endpoint.label}」。`;\n });\n },\n },\n {\n name: '異動紀錄',\n onClick: (): void => {\n void listWorkflowWebhookEndpointAudits(endpoint.id)\n .then((records): void => setAudits({ endpoint, records }))\n .catch((requestError: unknown): void =>\n setError(readErrorMessage(requestError)),\n );\n },\n },\n ],\n variant: 'base-secondary',\n width: 180,\n }),\n [run],\n );\n\n async function handleSaveDraft(): Promise<void> {\n if (!draft) {\n return;\n }\n\n setSaving(true);\n\n const saved = await run(async () => {\n const parameters = draft.parameters.map((parameter) => ({\n description: parameter.description.trim() || null,\n key: parameter.key.trim(),\n label: parameter.label.trim(),\n required: parameter.required,\n type: parameter.type,\n }));\n const headers = draft.headers\n .filter((header) => header.name.trim())\n .map((header) => ({ name: header.name.trim(), value: header.value }));\n const timeoutMs = draft.timeoutMs.trim() ? Number(draft.timeoutMs) : null;\n\n if (draft.mode === 'edit' && draft.endpointId) {\n await updateWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers:\n draft.replaceHeaders || isOriginChanged(draft) ? headers : null,\n id: draft.endpointId,\n label: draft.label,\n method: draft.method,\n parameters,\n timeoutMs,\n url: draft.url,\n });\n\n return `已更新「${draft.label}」。`;\n }\n\n await createWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers,\n key: draft.key,\n label: draft.label,\n method: draft.method,\n parameters,\n signingSecret: draft.signingSecret || null,\n timeoutMs,\n url: draft.url,\n version: Number(draft.version),\n });\n\n return `已建立「${draft.label}」v${draft.version},設計器現在可以選用。`;\n });\n\n setSaving(false);\n\n if (saved) {\n setDraft(null);\n }\n }\n\n async function handleRotate(): Promise<void> {\n if (!rotating) {\n return;\n }\n\n const endpoint = rotating;\n const done = await run(async () => {\n await rotateWorkflowWebhookEndpointSecret(\n endpoint.id,\n removeSecret ? null : nextSecret,\n );\n\n return removeSecret\n ? `已移除「${endpoint.label}」的簽章金鑰,之後的請求不再簽章。`\n : `已輪替「${endpoint.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`;\n });\n\n if (done) {\n setRotating(null);\n setNextSecret('');\n }\n }\n\n const enabled = Boolean(management?.enabled);\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"維護知會節點可呼叫的外部系統端點。Header 值與簽章金鑰加密保存,儲存後不會再顯示。\"\n title=\"Webhook 端點\"\n >\n <Button\n disabled={!enabled}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setDraft(EMPTY_DRAFT)}\n variant=\"base-primary\"\n >\n 新增端點\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={STACK_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {notice ? (\n <Typography color=\"text-success\" variant=\"body\">\n {notice}\n </Typography>\n ) : null}\n {management && !enabled ? (\n <Typography color=\"text-warning\" variant=\"body\">\n 此伺服器未啟用後台維護的 Webhook 端點:需要設定\n workflowWebhookTargetSources 含 DATABASE、URL\n 白名單與加密金鑰。程式註冊的端點不受影響。\n </Typography>\n ) : null}\n {enabled ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 允許的 URL:{management?.allowedUrlPatterns.join('、')}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </div>\n </Section>\n </SectionGroup>\n\n {draft ? (\n <EndpointDraftModal\n draft={draft}\n onCancel={(): void => setDraft(null)}\n onChange={setDraft}\n onConfirm={(): void => void handleSaveDraft()}\n saving={saving}\n />\n ) : null}\n\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !removeSecret && !nextSecret }}\n confirmText={removeSecret ? '移除金鑰' : '輪替金鑰'}\n modalType=\"standard\"\n onCancel={(): void => setRotating(null)}\n onClose={(): void => setRotating(null)}\n onConfirm={(): void => void handleRotate()}\n open={Boolean(rotating)}\n showModalFooter\n showModalHeader\n supportingText=\"新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。\"\n title={`輪替簽章金鑰:${rotating?.label ?? ''}`}\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"移除金鑰\" name=\"removeSigningSecret\">\n <Toggle\n checked={removeSecret}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setRemoveSecret(event.target.checked)\n }\n />\n </BPMFormField>\n {removeSecret ? null : (\n <BPMFormField label=\"新金鑰\" name=\"nextSigningSecret\" required>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setNextSecret(event.target.value)\n }\n value={nextSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n </div>\n </Modal>\n\n <Modal\n confirmText=\"關閉\"\n modalType=\"standard\"\n onClose={(): void => setAudits(null)}\n onConfirm={(): void => setAudits(null)}\n open={Boolean(audits)}\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText=\"只記錄誰在何時變更了哪些欄位,不記錄任何值。\"\n title={`異動紀錄:${audits?.endpoint.label ?? ''}`}\n >\n <Table\n columns={AUDIT_COLUMNS}\n dataSource={(audits?.records ?? []).map((audit): AuditRow => ({\n audit,\n key: audit.id,\n }))}\n fullWidth\n />\n </Modal>\n </>\n );\n}\n\nconst AUDIT_COLUMNS: TableColumn<AuditRow>[] = [\n {\n key: 'createdAt',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(audit.createdAt)}\n </Typography>\n ),\n title: '時間',\n width: 180,\n },\n {\n key: 'action',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {AUDIT_ACTION_LABELS[audit.action]}\n </Typography>\n ),\n title: '動作',\n width: 120,\n },\n {\n key: 'changedFields',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.changedFields.join('、') || '—'}\n </Typography>\n ),\n title: '欄位',\n width: 280,\n },\n {\n key: 'actor',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.actorMemberId ?? '系統'}\n </Typography>\n ),\n title: '操作者',\n width: 160,\n },\n];\n\nfunction EndpointDraftModal({\n draft,\n onCancel,\n onChange,\n onConfirm,\n saving,\n}: {\n readonly draft: EndpointDraft;\n readonly onCancel: () => void;\n readonly onChange: (draft: EndpointDraft) => void;\n readonly onConfirm: () => void;\n readonly saving: boolean;\n}): ReactElement {\n const editing = draft.mode === 'edit';\n // Stored header values must not follow the URL to another host, so a new\n // host always means entering the headers again.\n const originChanged = isOriginChanged(draft);\n const replaceHeaders = draft.replaceHeaders || originChanged;\n const update = (patch: Partial<EndpointDraft>): void =>\n onChange({ ...draft, ...patch });\n const updateParameter = (\n index: number,\n patch: Partial<ParameterDraft>,\n ): void =>\n update({\n parameters: draft.parameters.map((parameter, current) =>\n current === index ? { ...parameter, ...patch } : parameter,\n ),\n });\n const updateHeader = (index: number, patch: Partial<HeaderDraft>): void =>\n update({\n headers: draft.headers.map((header, current) =>\n current === index ? { ...header, ...patch } : header,\n ),\n });\n const text =\n (field: keyof EndpointDraft) =>\n (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void =>\n update({ [field]: event.target.value });\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmText={editing ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onCancel}\n onClose={onCancel}\n onConfirm={onConfirm}\n open\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText={\n editing\n ? '參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。'\n : draft.mode === 'version'\n ? '新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。'\n : 'URL 需符合伺服器設定的白名單。'\n }\n title={\n editing\n ? `編輯端點:${draft.label}`\n : draft.mode === 'version'\n ? `建立新版本:${draft.key}`\n : '新增 Webhook 端點'\n }\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"Key\" name=\"endpointKey\" required>\n <Input\n {...(draft.mode === 'create' ? {} : { readonly: true as const })}\n onChange={text('key')}\n placeholder=\"例如 crm.lead-created\"\n value={draft.key}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"版本\" name=\"endpointVersion\" required>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('version')}\n value={draft.version}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"名稱\" name=\"endpointLabel\" required>\n <Input\n onChange={text('label')}\n placeholder=\"例如 CRM 建立名單\"\n value={draft.label}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"說明\" name=\"endpointDescription\">\n <Textarea\n onChange={text('description')}\n rows={2}\n value={draft.description}\n />\n </BPMFormField>\n <BPMFormField label=\"URL\" name=\"endpointUrl\" required>\n <Input\n onChange={text('url')}\n placeholder=\"https://\"\n value={draft.url}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"Method\" name=\"endpointMethod\" required>\n <Select\n clearable={false}\n onChange={(option): void =>\n update({ method: option?.id ?? 'POST' })\n }\n options={[...METHOD_OPTIONS]}\n value={\n METHOD_OPTIONS.find((option) => option.id === draft.method) ??\n null\n }\n />\n </BPMFormField>\n <BPMFormField\n hintText=\"留空使用預設 10 秒,上限 30000 毫秒。\"\n label=\"逾時(毫秒)\"\n name=\"endpointTimeout\"\n >\n <Input\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('timeoutMs')}\n value={draft.timeoutMs}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"不建議使用\" name=\"endpointDeprecated\">\n <Toggle\n checked={draft.deprecated}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ deprecated: event.target.checked })\n }\n />\n </BPMFormField>\n {editing ? null : (\n <BPMFormField\n hintText=\"選填;設定後 BPM 以 HMAC-SHA256 簽章,儲存後不會再顯示。\"\n label=\"簽章金鑰\"\n name=\"endpointSigningSecret\"\n >\n <Input\n onChange={text('signingSecret')}\n placeholder=\"選填,儲存後不再顯示\"\n value={draft.signingSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n\n <Typography variant=\"label-primary-highlight\">Headers</Typography>\n {editing ? (\n <BPMFormField\n hintText={\n originChanged\n ? 'URL 已改到其他主機,必須重新輸入 header(留空代表不帶任何 header)。'\n : '現有 header 的值不會顯示;開啟後以下列內容取代全部 header。'\n }\n label=\"取代 headers\"\n name=\"endpointReplaceHeaders\"\n >\n <Toggle\n checked={replaceHeaders}\n disabled={originChanged}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ replaceHeaders: event.target.checked })\n }\n />\n </BPMFormField>\n ) : null}\n {replaceHeaders\n ? draft.headers.map((header, index): ReactElement => (\n <div key={index} style={HEADER_ROW_STYLE}>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { name: event.target.value })\n }\n placeholder=\"名稱,例如 Authorization\"\n inputProps={{ autoComplete: 'off' }}\n value={header.name}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { value: event.target.value })\n }\n placeholder=\"值\"\n value={header.value}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n <Button\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n headers: draft.headers.filter(\n (_header, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除 header\n </Button>\n </div>\n ))\n : null}\n {replaceHeaders ? (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({ headers: [...draft.headers, { name: '', value: '' }] })\n }\n variant=\"base-dashed\"\n >\n 新增 header\n </Button>\n </div>\n ) : null}\n\n <Typography variant=\"label-primary-highlight\">參數</Typography>\n {draft.parameters.map((parameter, index): ReactElement => (\n <div key={index} style={ROW_STYLE}>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { key: event.target.value })\n }\n placeholder=\"參數鍵\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.key}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { label: event.target.value })\n }\n placeholder=\"顯示名稱\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.label}\n variant=\"base\"\n />\n <Select\n clearable={false}\n disabled={editing}\n onChange={(option): void =>\n updateParameter(index, {\n type: readParameterType(option?.id ?? null),\n })\n }\n options={[...PARAMETER_TYPE_OPTIONS]}\n value={\n PARAMETER_TYPE_OPTIONS.find(\n (option) => option.id === parameter.type,\n ) ?? null\n }\n />\n <Toggle\n checked={parameter.required}\n disabled={editing}\n label=\"必填\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { required: event.target.checked })\n }\n />\n <Button\n disabled={editing}\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n parameters: draft.parameters.filter(\n (_parameter, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除參數\n </Button>\n </div>\n ))}\n {editing ? null : (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({\n parameters: [\n ...draft.parameters,\n {\n description: '',\n key: '',\n label: '',\n required: false,\n type: 'string',\n },\n ],\n })\n }\n variant=\"base-dashed\"\n >\n 新增參數\n </Button>\n </div>\n )}\n </div>\n </Modal>\n );\n}\n\nfunction readEditDraft(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n mode: 'edit' | 'version',\n): EndpointDraft {\n return {\n deprecated: endpoint.deprecated,\n description: endpoint.description ?? '',\n endpointId: mode === 'edit' ? endpoint.id : null,\n headers: [],\n key: endpoint.key,\n label: endpoint.label,\n method: endpoint.method,\n mode,\n originalUrl: endpoint.url,\n parameters: endpoint.parameters.map((parameter) => ({\n description: parameter.description ?? '',\n key: parameter.key,\n label: parameter.label,\n required: parameter.required,\n type: parameter.type,\n })),\n // A new version starts without credentials: they are not readable.\n replaceHeaders: mode === 'version',\n signingSecret: '',\n timeoutMs: endpoint.timeoutMs ? String(endpoint.timeoutMs) : '',\n url: endpoint.url,\n version: String(\n mode === 'version' ? endpoint.version + 1 : endpoint.version,\n ),\n };\n}\n\nfunction readTestNotice(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n result: WorkflowWebhookEndpointTestResultRecord,\n): string {\n if (result.ok) {\n return `測試送出成功:「${endpoint.label}」回應 HTTP ${result.status ?? ''}。`;\n }\n\n throw new Error(\n `測試送出失敗:「${endpoint.label}」${result.status ? `回應 HTTP ${result.status}` : ''}(${result.errorCode ?? '未知錯誤'})${result.errorDetail ? `:${result.errorDetail}` : ''}`,\n );\n}\n\nfunction isOriginChanged(draft: EndpointDraft): boolean {\n if (draft.mode !== 'edit') {\n return false;\n }\n\n const origin = (url: string): string => {\n try {\n return new URL(url.trim()).origin;\n } catch {\n return url.trim();\n }\n };\n\n return origin(draft.url) !== origin(draft.originalUrl);\n}\n\nfunction readParameterType(id: string | null): NotifyWebhookParameterType {\n return PARAMETER_TYPE_OPTIONS.some((option) => option.id === id)\n ? (id as NotifyWebhookParameterType)\n : 'string';\n}\n\nfunction readErrorMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return '發生未知錯誤';\n }\n\n const message = error.message;\n\n if (message.includes('WORKFLOW_WEBHOOK_URL_NOT_ALLOWED')) {\n return 'URL 不在伺服器允許的白名單內。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT')) {\n return '這個 Key 已由程式註冊的端點使用,請換一個。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED')) {\n return '參數契約不能修改,請改用「建立新版本」。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_TEST_RATE_LIMITED')) {\n return '測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。';\n }\n\n return message;\n}\n"],"mappings":"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"}
|
package/dist/views/cc/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-Cv5I1YPX.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`查看抄送給你的簽核案件。`,emptyMessage:`目前沒有抄送給你的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`抄送給我`,view:`CC`})}exports.CcView=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/views/cc/index.js
CHANGED