@rytass/bpm-core-react 0.21.4 → 0.23.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 (91) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/chunks/{FormBuilderView-DbfbLZCI.js → FormBuilderView-D_bN9gzT.js} +675 -614
  3. package/dist/chunks/FormBuilderView-D_bN9gzT.js.map +1 -0
  4. package/dist/chunks/FormBuilderView-bm8P55hp.cjs +4 -0
  5. package/dist/chunks/FormBuilderView-bm8P55hp.cjs.map +1 -0
  6. package/dist/chunks/FormRendererView-BlQgJOkI.cjs +6 -0
  7. package/dist/chunks/FormRendererView-BlQgJOkI.cjs.map +1 -0
  8. package/dist/chunks/{FormRendererView-CAyPXhPq.js → FormRendererView-CemHvfAT.js} +298 -290
  9. package/dist/chunks/FormRendererView-CemHvfAT.js.map +1 -0
  10. package/dist/chunks/compose-CdKVQfjB.cjs +2 -0
  11. package/dist/chunks/compose-CdKVQfjB.cjs.map +1 -0
  12. package/dist/chunks/{compose-U1zs3Yof.js → compose-N9657E5u.js} +161 -147
  13. package/dist/chunks/compose-N9657E5u.js.map +1 -0
  14. package/dist/chunks/{designer-DPG7R_WP.js → designer-CKwG_vM5.js} +1913 -1715
  15. package/dist/chunks/designer-CKwG_vM5.js.map +1 -0
  16. package/dist/chunks/designer-JPs7EijM.cjs +69 -0
  17. package/dist/chunks/designer-JPs7EijM.cjs.map +1 -0
  18. package/dist/chunks/detail-Dqu0K9QM.cjs +5 -0
  19. package/dist/chunks/detail-Dqu0K9QM.cjs.map +1 -0
  20. package/dist/chunks/{detail-CHZDNNM6.js → detail-fW0vJudE.js} +902 -895
  21. package/dist/chunks/detail-fW0vJudE.js.map +1 -0
  22. package/dist/chunks/instance-error-message-BKt07-Bo.js +270 -0
  23. package/dist/chunks/instance-error-message-BKt07-Bo.js.map +1 -0
  24. package/dist/chunks/instance-error-message-BL_X7Af8.cjs +2 -0
  25. package/dist/chunks/instance-error-message-BL_X7Af8.cjs.map +1 -0
  26. package/dist/pages/instances/detail/index.cjs +1 -1
  27. package/dist/pages/instances/detail/index.js +1 -1
  28. package/dist/pages/templates/compose/index.cjs +1 -1
  29. package/dist/pages/templates/compose/index.js +1 -1
  30. package/dist/pages/templates/designer/index.cjs +1 -1
  31. package/dist/pages/templates/designer/index.js +1 -1
  32. package/dist/views/forms/builder/index.cjs +1 -1
  33. package/dist/views/forms/builder/index.js +1 -1
  34. package/dist/views/forms/renderer/FormRendererView.d.cts +26 -1
  35. package/dist/views/forms/renderer/FormRendererView.d.ts +26 -1
  36. package/dist/views/forms/renderer/index.cjs +1 -1
  37. package/dist/views/forms/renderer/index.js +1 -1
  38. package/dist/views/inbox/index.cjs +1 -1
  39. package/dist/views/inbox/index.cjs.map +1 -1
  40. package/dist/views/inbox/index.js +185 -94
  41. package/dist/views/inbox/index.js.map +1 -1
  42. package/dist/views/instances/approver-filled-form.d.cts +56 -20
  43. package/dist/views/instances/approver-filled-form.d.ts +56 -20
  44. package/dist/views/instances/detail/index.cjs +1 -1
  45. package/dist/views/instances/detail/index.js +1 -1
  46. package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +7 -0
  47. package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +7 -0
  48. package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +1 -1
  49. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +1 -1
  50. package/dist/views/instances/new/index.cjs +1 -1
  51. package/dist/views/instances/new/index.js +2 -2
  52. package/dist/views/templates/compose/index.cjs +1 -1
  53. package/dist/views/templates/compose/index.js +1 -1
  54. package/dist/views/templates/compose/steps/ComposeReviewStep.d.cts +3 -1
  55. package/dist/views/templates/compose/steps/ComposeReviewStep.d.ts +3 -1
  56. package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.cts +4 -1
  57. package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +4 -1
  58. package/dist/views/templates/compose/use-template-compose-wizard.d.cts +3 -1
  59. package/dist/views/templates/compose/use-template-compose-wizard.d.ts +3 -1
  60. package/dist/views/templates/designer/TemplateDesignerView.d.cts +10 -1
  61. package/dist/views/templates/designer/TemplateDesignerView.d.ts +10 -1
  62. package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.cts +3 -1
  63. package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.ts +3 -1
  64. package/dist/views/templates/designer/field-access-matrix/field-access-copy.d.cts +3 -2
  65. package/dist/views/templates/designer/field-access-matrix/field-access-copy.d.ts +3 -2
  66. package/dist/views/templates/designer/index.cjs +1 -1
  67. package/dist/views/templates/designer/index.js +1 -1
  68. package/dist/views/templates/designer/launch-mode.d.cts +19 -0
  69. package/dist/views/templates/designer/launch-mode.d.ts +19 -0
  70. package/dist/views/templates/designer/publish-default-value-check.d.cts +36 -0
  71. package/dist/views/templates/designer/publish-default-value-check.d.ts +36 -0
  72. package/package.json +3 -3
  73. package/dist/chunks/FormBuilderView-Bok4Y59D.cjs +0 -4
  74. package/dist/chunks/FormBuilderView-Bok4Y59D.cjs.map +0 -1
  75. package/dist/chunks/FormBuilderView-DbfbLZCI.js.map +0 -1
  76. package/dist/chunks/FormRendererView-CAyPXhPq.js.map +0 -1
  77. package/dist/chunks/FormRendererView-iLlHFIUR.cjs +0 -6
  78. package/dist/chunks/FormRendererView-iLlHFIUR.cjs.map +0 -1
  79. package/dist/chunks/compose-DP1N4twA.cjs +0 -2
  80. package/dist/chunks/compose-DP1N4twA.cjs.map +0 -1
  81. package/dist/chunks/compose-U1zs3Yof.js.map +0 -1
  82. package/dist/chunks/designer-CWL-dCQ_.cjs +0 -69
  83. package/dist/chunks/designer-CWL-dCQ_.cjs.map +0 -1
  84. package/dist/chunks/designer-DPG7R_WP.js.map +0 -1
  85. package/dist/chunks/detail-BUfsSal0.cjs +0 -5
  86. package/dist/chunks/detail-BUfsSal0.cjs.map +0 -1
  87. package/dist/chunks/detail-CHZDNNM6.js.map +0 -1
  88. package/dist/chunks/instance-error-message-BEM4O_Kj.js +0 -208
  89. package/dist/chunks/instance-error-message-BEM4O_Kj.js.map +0 -1
  90. package/dist/chunks/instance-error-message-BpCLCOjp.cjs +0 -2
  91. package/dist/chunks/instance-error-message-BpCLCOjp.cjs.map +0 -1
@@ -4,24 +4,55 @@ import { n as t } from "../../chunks/auth-provider-C2b-5mGt.js";
4
4
  import { i as n, o as r } from "../../chunks/task-decision-3d17ZvZE.js";
5
5
  import { r as i } from "../../chunks/router-adapter-CkxCyzf5.js";
6
6
  import { r as a } from "../../chunks/routes-config-BcNaWJWJ.js";
7
- import { useEffect as o, useMemo as s, useState as c } from "react";
8
- import { Badge as l, Button as u, PageHeader as d, Section as f, SectionGroup as p, Tab as m, TabItem as h, Table as g, Typography as _ } from "@mezzanine-ui/react";
9
- import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
10
- import { listApprovalHistoryTasks as x, listApprovalInstancesPage as S, listInboxTasks as C, listTaskDecisions as w, readApprovalInstance as T, readApprovalInstanceCaseTitle as E } from "@rytass/bpm-core-client/workflow";
11
- import D from "@mezzanine-ui/react/ContentHeader";
12
- import { PlusIcon as O } from "@mezzanine-ui/icons";
7
+ import { useCallback as o, useEffect as s, useMemo as c, useRef as l, useState as u } from "react";
8
+ import { Badge as d, Button as f, PageHeader as p, Section as m, SectionGroup as ee, Tab as te, TabItem as h, Table as g, Typography as _ } from "@mezzanine-ui/react";
9
+ import { Fragment as ne, jsx as v, jsxs as y } from "react/jsx-runtime";
10
+ import { listApprovalHistoryTasksPage as b, listApprovalInstancesPage as x, listInboxTasksPage as S, listTaskDecisions as C, readApprovalInstance as w, readApprovalInstanceCaseTitle as T } from "@rytass/bpm-core-client/workflow";
11
+ import re from "@mezzanine-ui/react/ContentHeader";
12
+ import { PlusIcon as ie } from "@mezzanine-ui/icons";
13
13
  // src/views/inbox/InboxView.tsx
14
- var k = 100, A = {
14
+ var E = 100, ae = {
15
15
  display: "grid",
16
16
  gap: "var(--mzn-spacing-gap-base)",
17
17
  marginBottom: "var(--mzn-spacing-padding-vertical-spacious)"
18
+ }, D = [
19
+ 10,
20
+ 20,
21
+ 50
22
+ ], O = {
23
+ page: 1,
24
+ pageSize: 20
18
25
  };
19
- function j() {
20
- let n = i(), r = a(), { member: S } = t(), w = S?.memberId ?? null, [T, E] = c("pending"), [k, j] = c(null), [P, L] = c([]), [R, z] = c(!0), [B, H] = c([]), [W, K] = c([]), [q, J] = c(!1);
21
- o(() => {
22
- w && ie();
23
- }, [w]);
24
- let Y = s(() => [
26
+ function k() {
27
+ let n = i(), r = a(), { member: o } = t(), l = o?.memberId ?? null, [x, C] = u("pending"), [w, T] = u(null), [E, D] = u(O), [k, F] = u(O), [L, R] = u(O), z = A(l, {
28
+ enabled: !0,
29
+ paging: E,
30
+ setPaging: D
31
+ }, T, async (e, t) => j(await S({
32
+ assigneeMemberId: e,
33
+ ...t
34
+ }), oe)), B = A(l, {
35
+ enabled: !0,
36
+ paging: k,
37
+ setPaging: F
38
+ }, T, async (e, t) => j(await b({
39
+ assigneeMemberId: e,
40
+ instanceState: "RUNNING",
41
+ ...t
42
+ }), (t) => I(t, e))), H = A(l, {
43
+ enabled: x === "history",
44
+ paging: L,
45
+ setPaging: R
46
+ }, T, async (e, t) => j(await b({
47
+ assigneeMemberId: e,
48
+ ...t
49
+ }), (t) => I(t, e))), [W, K] = u([]), [q, J] = u(!1);
50
+ s(() => {
51
+ l ? P(l).then((e) => {
52
+ K(e?.rows ?? []), J(e?.truncated ?? !1);
53
+ }, (e) => T(X(e))) : (K([]), J(!1));
54
+ }, [l]);
55
+ let Y = c(() => [
25
56
  {
26
57
  dataIndex: "caseTitle",
27
58
  key: "caseTitle",
@@ -42,7 +73,7 @@ function j() {
42
73
  },
43
74
  {
44
75
  key: "fill",
45
- render: (e) => e.hasFillableFields ? /* @__PURE__ */ y(l, {
76
+ render: (e) => e.hasFillableFields ? /* @__PURE__ */ v(d, {
46
77
  size: "sub",
47
78
  text: "需補填",
48
79
  variant: "dot-warning"
@@ -52,7 +83,7 @@ function j() {
52
83
  },
53
84
  {
54
85
  key: "slaDueAt",
55
- render: (e) => /* @__PURE__ */ y(_, {
86
+ render: (e) => /* @__PURE__ */ v(_, {
56
87
  color: e.slaStatusColor,
57
88
  component: "span",
58
89
  variant: "body",
@@ -63,7 +94,7 @@ function j() {
63
94
  },
64
95
  {
65
96
  key: "createdAt",
66
- render: (t) => /* @__PURE__ */ y(_, {
97
+ render: (t) => /* @__PURE__ */ v(_, {
67
98
  component: "span",
68
99
  variant: "body",
69
100
  children: e(t.createdAt)
@@ -71,35 +102,35 @@ function j() {
71
102
  title: "建立時間",
72
103
  width: 220
73
104
  }
74
- ], []), ee = s(() => ({
105
+ ], []), se = c(() => ({
75
106
  render: (e) => [{
76
107
  name: "處理",
77
108
  onClick: () => n.push(r.caseDetail(e.instanceId))
78
109
  }],
79
110
  variant: "base-secondary",
80
111
  width: 88
81
- }), [n, r]), te = s(() => [{
112
+ }), [n, r]), ce = c(() => [{
82
113
  dataIndex: "caseTitle",
83
114
  key: "caseTitle",
84
115
  title: "案件",
85
116
  width: 280
86
117
  }, {
87
118
  key: "startedAt",
88
- render: (t) => /* @__PURE__ */ y(_, {
119
+ render: (t) => /* @__PURE__ */ v(_, {
89
120
  component: "span",
90
121
  variant: "body",
91
122
  children: e(t.startedAt)
92
123
  }),
93
124
  title: "發起時間",
94
125
  width: 220
95
- }], []), ne = s(() => ({
126
+ }], []), le = c(() => ({
96
127
  render: (e) => [{
97
128
  name: "重新送出",
98
129
  onClick: () => n.push(r.caseDetail(e.id))
99
130
  }],
100
131
  variant: "base-secondary",
101
132
  width: 120
102
- }), [n, r]), Z = s(() => [
133
+ }), [n, r]), Z = c(() => [
103
134
  {
104
135
  dataIndex: "caseTitle",
105
136
  key: "caseTitle",
@@ -114,7 +145,7 @@ function j() {
114
145
  },
115
146
  {
116
147
  key: "decisionLabel",
117
- render: (e) => /* @__PURE__ */ y(_, {
148
+ render: (e) => /* @__PURE__ */ v(_, {
118
149
  color: V(e.decisionAction),
119
150
  component: "span",
120
151
  variant: "body",
@@ -125,7 +156,7 @@ function j() {
125
156
  },
126
157
  {
127
158
  key: "decisionComment",
128
- render: (e) => /* @__PURE__ */ y(_, {
159
+ render: (e) => /* @__PURE__ */ v(_, {
129
160
  component: "span",
130
161
  variant: "body",
131
162
  children: e.decisionCommentText
@@ -135,7 +166,7 @@ function j() {
135
166
  },
136
167
  {
137
168
  key: "instanceStateLabel",
138
- render: (e) => /* @__PURE__ */ y(_, {
169
+ render: (e) => /* @__PURE__ */ v(_, {
139
170
  color: U(e.instanceState),
140
171
  component: "span",
141
172
  variant: "body",
@@ -146,7 +177,7 @@ function j() {
146
177
  },
147
178
  {
148
179
  key: "decidedAt",
149
- render: (e) => /* @__PURE__ */ y(_, {
180
+ render: (e) => /* @__PURE__ */ v(_, {
150
181
  component: "span",
151
182
  variant: "body",
152
183
  children: G(e.decidedAt)
@@ -154,143 +185,203 @@ function j() {
154
185
  title: "簽核時間",
155
186
  width: 220
156
187
  }
157
- ], []), Q = s(() => ({
188
+ ], []), Q = c(() => ({
158
189
  render: (e) => [{
159
190
  name: "查看",
160
191
  onClick: () => n.push(r.caseDetail(e.instanceId))
161
192
  }],
162
193
  variant: "base-secondary",
163
194
  width: 88
164
- }), [n, r]), $ = s(() => P.filter((e) => e.instanceState === "RUNNING"), [P]);
165
- function re(e) {
166
- E(e === "history" || e === "pending" || e === "tracking" ? e : "pending");
195
+ }), [n, r]);
196
+ function $(e) {
197
+ C(e === "history" || e === "pending" || e === "tracking" ? e : "pending");
167
198
  }
168
- async function ie() {
169
- z(!0), j(null);
170
- try {
171
- if (!w) {
172
- H([]), L([]), K([]), J(!1);
173
- return;
174
- }
175
- let [e, t, n] = await Promise.all([
176
- C(w),
177
- x(w),
178
- N(w)
179
- ]), [r, i] = await Promise.all([F(e), I(t, w)]);
180
- H(r), L(i), K(n?.rows ?? []), J(n?.truncated ?? !1);
181
- } catch (e) {
182
- j(X(e));
183
- } finally {
184
- z(!1);
185
- }
186
- }
187
- return /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y(d, { children: /* @__PURE__ */ y(D, {
188
- description: `目前以 ${S?.name ?? w ?? "目前登入會員"} 查詢待處理與歷史簽核任務。`,
199
+ return /* @__PURE__ */ y(ne, { children: [/* @__PURE__ */ v(p, { children: /* @__PURE__ */ v(re, {
200
+ description: `目前以 ${o?.name ?? l ?? "目前登入會員"} 查詢待處理與歷史簽核任務。`,
189
201
  title: "我的待簽",
190
- children: /* @__PURE__ */ y(u, {
191
- icon: O,
202
+ children: /* @__PURE__ */ v(f, {
203
+ icon: ie,
192
204
  iconType: "leading",
193
205
  onClick: () => n.push(r.caseNew()),
194
206
  variant: "base-primary",
195
207
  children: "發起簽核"
196
208
  })
197
- }) }), /* @__PURE__ */ y(p, { children: /* @__PURE__ */ b(f, { children: [
198
- k ? /* @__PURE__ */ y(_, {
209
+ }) }), /* @__PURE__ */ v(ee, { children: /* @__PURE__ */ y(m, { children: [
210
+ w ? /* @__PURE__ */ v(_, {
199
211
  color: "text-error",
200
212
  variant: "body",
201
- children: k
213
+ children: w
202
214
  }) : null,
203
- /* @__PURE__ */ b(m, {
204
- activeKey: T,
205
- onChange: re,
215
+ /* @__PURE__ */ y(te, {
216
+ activeKey: x,
217
+ onChange: $,
206
218
  size: "sub",
207
219
  children: [
208
- /* @__PURE__ */ y(h, {
209
- badgeCount: R ? void 0 : B.length,
220
+ /* @__PURE__ */ v(h, {
221
+ badgeCount: z.loading ? void 0 : z.total,
210
222
  children: "待簽核"
211
223
  }, "pending"),
212
- /* @__PURE__ */ y(h, {
213
- badgeCount: R ? void 0 : $.length,
224
+ /* @__PURE__ */ v(h, {
225
+ badgeCount: B.loading ? void 0 : B.total,
214
226
  children: "已處理未結束"
215
227
  }, "tracking"),
216
- /* @__PURE__ */ y(h, { children: "歷史簽核記錄" }, "history")
228
+ /* @__PURE__ */ v(h, { children: "歷史簽核記錄" }, "history")
217
229
  ]
218
230
  }),
219
- T === "pending" && (W.length > 0 || q) ? /* @__PURE__ */ b("div", {
231
+ x === "pending" && (W.length > 0 || q) ? /* @__PURE__ */ y("div", {
220
232
  "data-returned-instances": "",
221
- style: A,
233
+ style: ae,
222
234
  children: [
223
- W.length > 0 ? /* @__PURE__ */ y(_, {
235
+ W.length > 0 ? /* @__PURE__ */ v(_, {
224
236
  component: "h2",
225
237
  variant: "label-primary",
226
238
  children: "被退回待重送"
227
239
  }) : null,
228
- /* @__PURE__ */ y(_, {
240
+ /* @__PURE__ */ v(_, {
229
241
  color: "text-neutral",
230
242
  variant: "caption",
231
- children: M(W.length > 0, q)
243
+ children: N(W.length > 0, q)
232
244
  }),
233
- W.length > 0 ? /* @__PURE__ */ y(g, {
234
- actions: ne,
235
- columns: te,
245
+ W.length > 0 ? /* @__PURE__ */ v(g, {
246
+ actions: le,
247
+ columns: ce,
236
248
  dataSource: [...W],
237
249
  fullWidth: !0
238
250
  }) : null
239
251
  ]
240
252
  }) : null,
241
- T === "pending" ? /* @__PURE__ */ y(g, {
242
- actions: ee,
253
+ x === "pending" ? /* @__PURE__ */ v(g, {
254
+ actions: se,
243
255
  columns: Y,
244
- dataSource: B,
256
+ dataSource: [...z.rows],
245
257
  fullWidth: !0,
246
- loading: R
258
+ loading: z.loading,
259
+ pagination: M(E, z.total, D)
247
260
  }) : null,
248
- T === "tracking" ? /* @__PURE__ */ y(g, {
261
+ x === "tracking" ? /* @__PURE__ */ v(g, {
249
262
  actions: Q,
250
263
  columns: Z,
251
- dataSource: $,
264
+ dataSource: [...B.rows],
252
265
  fullWidth: !0,
253
- loading: R
266
+ loading: B.loading,
267
+ pagination: M(k, B.total, F)
254
268
  }) : null,
255
- T === "history" ? /* @__PURE__ */ y(g, {
269
+ x === "history" ? /* @__PURE__ */ v(g, {
256
270
  actions: Q,
257
271
  columns: Z,
258
- dataSource: P,
272
+ dataSource: [...H.rows],
259
273
  fullWidth: !0,
260
- loading: R
274
+ loading: H.loading,
275
+ pagination: M(L, H.total, R)
261
276
  }) : null
262
277
  ] }) })] });
263
278
  }
264
- function M(e, t) {
265
- return e ? t ? "你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。" : "你發起的案件被退回,請修改後重新送出。" : `前 ${k} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`;
279
+ function A(e, { enabled: t, paging: n, setPaging: r }, i, a) {
280
+ let [c, d] = u({
281
+ loading: !0,
282
+ rows: [],
283
+ total: 0
284
+ }), f = l(0), p = l(a);
285
+ p.current = a;
286
+ let m = o(async () => {
287
+ let t = f.current + 1;
288
+ if (f.current = t, !e) d({
289
+ loading: !1,
290
+ rows: [],
291
+ total: 0
292
+ });
293
+ else {
294
+ d((e) => ({
295
+ ...e,
296
+ loading: !0
297
+ }));
298
+ try {
299
+ let i = await p.current(e, n);
300
+ if (f.current !== t) return;
301
+ let a = Math.max(1, Math.ceil(i.total / n.pageSize));
302
+ if (!i.rows.length && n.page > a) {
303
+ r({
304
+ ...n,
305
+ page: a
306
+ });
307
+ return;
308
+ }
309
+ d({
310
+ loading: !1,
311
+ ...i
312
+ });
313
+ } catch (e) {
314
+ f.current === t && (i(X(e)), d((e) => ({
315
+ ...e,
316
+ loading: !1
317
+ })));
318
+ }
319
+ }
320
+ }, [
321
+ e,
322
+ i,
323
+ n,
324
+ r
325
+ ]);
326
+ return s(() => {
327
+ t && m();
328
+ }, [t, m]), c;
329
+ }
330
+ async function j(e, t) {
331
+ return {
332
+ rows: await t(e.tasks),
333
+ total: e.totalCount
334
+ };
335
+ }
336
+ function M(e, t, n) {
337
+ return {
338
+ current: e.page,
339
+ onChange: (t) => n({
340
+ ...e,
341
+ page: t
342
+ }),
343
+ onChangePageSize: (e) => n({
344
+ page: 1,
345
+ pageSize: e
346
+ }),
347
+ pageSize: e.pageSize,
348
+ pageSizeLabel: "每頁筆數",
349
+ pageSizeOptions: D,
350
+ renderResultSummary: (e, t, n) => `顯示 ${e}-${t} 筆,共 ${n} 筆`,
351
+ showPageSizeOptions: !0,
352
+ total: t
353
+ };
354
+ }
355
+ function N(e, t) {
356
+ return e ? t ? "你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。" : "你發起的案件被退回,請修改後重新送出。" : `前 ${E} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`;
266
357
  }
267
- async function N(e) {
358
+ async function P(e) {
268
359
  try {
269
- let t = await S({
360
+ let t = await x({
270
361
  page: 1,
271
- pageSize: k,
362
+ pageSize: E,
272
363
  searchText: null,
273
364
  state: "RETURNED",
274
365
  templateId: null,
275
366
  view: "SENT"
276
367
  });
277
368
  return {
278
- rows: P(t.instances, e),
369
+ rows: F(t.instances, e),
279
370
  truncated: t.totalCount > t.instances.length
280
371
  };
281
372
  } catch {
282
373
  return null;
283
374
  }
284
375
  }
285
- function P(e, t) {
376
+ function F(e, t) {
286
377
  return e.filter((e) => e.initiatorMemberId === t).map((e) => ({
287
- caseTitle: E(e),
378
+ caseTitle: T(e),
288
379
  id: e.id,
289
380
  key: e.id,
290
381
  startedAt: e.startedAt
291
382
  }));
292
383
  }
293
- async function F(e) {
384
+ async function oe(e) {
294
385
  let t = await L(e);
295
386
  return e.map((e, n) => ({
296
387
  ...e,
@@ -303,7 +394,7 @@ async function F(e) {
303
394
  }));
304
395
  }
305
396
  async function I(e, t) {
306
- let [n, i] = await Promise.all([Promise.all(e.map((e) => w(e.id))), L(e)]);
397
+ let [n, i] = await Promise.all([Promise.all(e.map((e) => C(e.id))), L(e)]);
307
398
  return e.map((e, a) => {
308
399
  let o = n[a] ?? [], s = z(o, t), c = i[a] ?? null;
309
400
  return {
@@ -324,14 +415,14 @@ async function I(e, t) {
324
415
  async function L(e) {
325
416
  return Promise.all(e.map(async (e) => {
326
417
  try {
327
- return (await T(e.instanceId)).instance;
418
+ return (await w(e.instanceId)).instance;
328
419
  } catch {
329
420
  return null;
330
421
  }
331
422
  }));
332
423
  }
333
424
  function R(e, t) {
334
- return t ? E(t) : e.instanceId;
425
+ return t ? T(t) : e.instanceId;
335
426
  }
336
427
  function z(e, t) {
337
428
  return n(e.filter((e) => e.decidedByMemberId === t));
@@ -372,6 +463,6 @@ function Y(e) {
372
463
  function X(e) {
373
464
  return e instanceof Error ? e.message : "發生未知錯誤";
374
465
  }
375
- export { j as InboxView };
466
+ export { k as InboxView };
376
467
 
377
468
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_Fragment","formatDateTime","useAuth","readLatestTaskDecision","readTaskNodeText","useRouterAdapter","useBPMRoutes","Fragment$1","ContentHeader","RETURNED_INSTANCE_PAGE_SIZE","RETURNED_SECTION_STYLE","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","useState","error","setError","historyRows","setHistoryRows","loading","setLoading","pendingRows","setPendingRows","returnedRows","setReturnedRows","returnedTruncated","setReturnedTruncated","refreshTasks","pendingColumns","useMemo","record","Badge","Typography","pendingTableActions","returnedColumns","returnedTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","trackingRows","row","handleTabChange","activeKey","nextPendingTasks","nextHistoryTasks","returned","listInboxTasks","listApprovalHistoryTasks","readReturnedInstances","nextPendingRows","nextHistoryRows","readInboxTaskRows","readApprovalHistoryRows","requestError","readErrorMessage","PageHeader","Button","PlusIcon","SectionGroup","Section","Tab","TabItem","readReturnedSectionHint","Table","hasRows","truncated","page","listApprovalInstancesPage","readReturnedInstanceRows","instances","instance","readApprovalInstanceCaseTitle","readTaskInstances","tasks","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","listTaskDecisions","decisions","decision","readLatestOwnTaskDecision","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","readApprovalInstance","action","state","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport {\n type CSSProperties,\n type Key,\n ReactElement,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n ApprovalInstanceRecord,\n type ApprovalInstancesPageResult,\n listApprovalHistoryTasks,\n listApprovalInstancesPage,\n listInboxTasks,\n listTaskDecisions,\n readApprovalInstance,\n readApprovalInstanceCaseTitle,\n TaskDecisionRecord,\n TaskRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useAuth } from '../../lib/auth-provider';\nimport { readTaskNodeText } from '../../lib/task-node-label';\nimport { readLatestTaskDecision } from '../../lib/task-decision';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\n\ntype InboxTabKey = 'history' | 'pending' | 'tracking';\n\ntype InboxTaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n key: string;\n nodeText: string;\n slaStatusColor: 'text-error' | 'text-neutral' | 'text-success';\n slaStatusText: string;\n statusLabel: string;\n }\n>;\n\ntype ReturnedInstanceRow = Readonly<{\n caseTitle: string;\n id: string;\n key: string;\n startedAt: string | null;\n}>;\n\n/** The server caps a page at 100; more than that is left to 我發起的. */\nconst RETURNED_INSTANCE_PAGE_SIZE = 100;\n\nconst RETURNED_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n marginBottom: 'var(--mzn-spacing-padding-vertical-spacious)',\n};\n\ntype ApprovalHistoryRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n decisionAction: TaskDecisionRecord['action'] | null;\n decisionComment: string | null;\n decisionCommentText: string;\n decisionLabel: string;\n decidedAt: string | null;\n instanceState: ApprovalInstanceRecord['state'] | null;\n instanceStateLabel: string;\n key: string;\n nodeText: string;\n }\n>;\n\n\n/**\n * Framework-agnostic view for the BPM \"我的待簽\" inbox. Mechanical port of\n * `apps/client/src/app/inbox/page.tsx` — renders pending tasks, tracking,\n * and history tabs.\n */\nexport function InboxView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activeTab, setActiveTab] = useState<InboxTabKey>('pending');\n const [error, setError] = useState<string | null>(null);\n const [historyRows, setHistoryRows] = useState<ApprovalHistoryRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [pendingRows, setPendingRows] = useState<InboxTaskRow[]>([]);\n const [returnedRows, setReturnedRows] = useState<\n readonly ReturnedInstanceRow[]\n >([]);\n const [returnedTruncated, setReturnedTruncated] = useState(false);\n\n useEffect((): void => {\n if (!currentMemberId) {\n return;\n }\n\n void refreshTasks();\n }, [currentMemberId]);\n\n const pendingColumns = useMemo(\n (): TableColumn<InboxTaskRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'fill',\n // Approving one of these needs the case page, where the fill is entered.\n render: (record: InboxTaskRow): ReactElement | null =>\n record.hasFillableFields ? (\n <Badge size=\"sub\" text=\"需補填\" variant=\"dot-warning\" />\n ) : null,\n title: '補填',\n width: 120,\n },\n {\n key: 'slaDueAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography\n color={record.slaStatusColor}\n component=\"span\"\n variant=\"body\"\n >\n {record.slaStatusText}\n </Typography>\n ),\n title: 'SLA',\n width: 180,\n },\n {\n key: 'createdAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.createdAt)}\n </Typography>\n ),\n title: '建立時間',\n width: 220,\n },\n ],\n [],\n );\n const pendingTableActions = useMemo(\n (): TableActions<InboxTaskRow> => ({\n render: (record): ReturnType<TableActions<InboxTaskRow>['render']> => [\n {\n name: '處理',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const returnedColumns = useMemo(\n (): TableColumn<ReturnedInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n {\n key: 'startedAt',\n render: (record: ReturnedInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n ],\n [],\n );\n const returnedTableActions = useMemo(\n (): TableActions<ReturnedInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ReturnedInstanceRow>['render']> => [\n {\n name: '重新送出',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 120,\n }),\n [router, routes],\n );\n const historyColumns = useMemo(\n (): TableColumn<ApprovalHistoryRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n key: 'decisionLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readTaskDecisionColor(record.decisionAction)}\n component=\"span\"\n variant=\"body\"\n >\n {record.decisionLabel}\n </Typography>\n ),\n title: '決議',\n width: 120,\n },\n {\n key: 'decisionComment',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.decisionCommentText}\n </Typography>\n ),\n title: '意見',\n width: 240,\n },\n {\n key: 'instanceStateLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.instanceState)}\n component=\"span\"\n variant=\"body\"\n >\n {record.instanceStateLabel}\n </Typography>\n ),\n title: '流程狀態',\n width: 140,\n },\n {\n key: 'decidedAt',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatHistoryDateTime(record.decidedAt)}\n </Typography>\n ),\n title: '簽核時間',\n width: 220,\n },\n ],\n [],\n );\n const historyTableActions = useMemo(\n (): TableActions<ApprovalHistoryRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalHistoryRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const trackingRows = useMemo(\n (): ApprovalHistoryRow[] =>\n historyRows.filter((row) => row.instanceState === 'RUNNING'),\n [historyRows],\n );\n\n function handleTabChange(activeKey: Key): void {\n if (\n activeKey === 'history' ||\n activeKey === 'pending' ||\n activeKey === 'tracking'\n ) {\n setActiveTab(activeKey);\n return;\n }\n\n setActiveTab('pending');\n }\n\n async function refreshTasks(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n if (!currentMemberId) {\n setPendingRows([]);\n setHistoryRows([]);\n setReturnedRows([]);\n setReturnedTruncated(false);\n return;\n }\n\n const [nextPendingTasks, nextHistoryTasks, returned] =\n await Promise.all([\n listInboxTasks(currentMemberId),\n listApprovalHistoryTasks(currentMemberId),\n readReturnedInstances(currentMemberId),\n ]);\n const [nextPendingRows, nextHistoryRows] = await Promise.all([\n readInboxTaskRows(nextPendingTasks),\n readApprovalHistoryRows(nextHistoryTasks, currentMemberId),\n ]);\n\n setPendingRows(nextPendingRows);\n setHistoryRows(nextHistoryRows);\n setReturnedRows(returned?.rows ?? []);\n setReturnedTruncated(returned?.truncated ?? false);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={`目前以 ${member?.name ?? currentMemberId ?? '目前登入會員'} 查詢待處理與歷史簽核任務。`}\n title=\"我的待簽\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.caseNew())}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab activeKey={activeTab} onChange={handleTabChange} size=\"sub\">\n <TabItem\n badgeCount={loading ? undefined : pendingRows.length}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={loading ? undefined : trackingRows.length}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {/* A truncated page with none of the member's own cases still\n points to 我發起的: theirs may sit past the first page. */}\n {activeTab === 'pending' &&\n (returnedRows.length > 0 || returnedTruncated) ? (\n <div data-returned-instances=\"\" style={RETURNED_SECTION_STYLE}>\n {/* Without rows there is nothing here to resubmit, only the\n pointer to 我發起的. */}\n {returnedRows.length > 0 ? (\n <Typography component=\"h2\" variant=\"label-primary\">\n 被退回待重送\n </Typography>\n ) : null}\n <Typography color=\"text-neutral\" variant=\"caption\">\n {readReturnedSectionHint(\n returnedRows.length > 0,\n returnedTruncated,\n )}\n </Typography>\n {returnedRows.length > 0 ? (\n <Table\n actions={returnedTableActions}\n columns={returnedColumns}\n dataSource={[...returnedRows]}\n fullWidth\n />\n ) : null}\n </div>\n ) : null}\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={pendingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={trackingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={historyRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction readReturnedSectionHint(\n hasRows: boolean,\n truncated: boolean,\n): string {\n if (!hasRows) {\n return `前 ${RETURNED_INSTANCE_PAGE_SIZE} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`;\n }\n\n return truncated\n ? '你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。'\n : '你發起的案件被退回,請修改後重新送出。';\n}\n\n/**\n * Returned cases are a side list: a failure here, in the request or in reading\n * its rows, hides that section instead of taking the pending and history tasks\n * down with it.\n */\nasync function readReturnedInstances(\n currentMemberId: string,\n): Promise<Readonly<{\n rows: readonly ReturnedInstanceRow[];\n truncated: boolean;\n}> | null> {\n try {\n // SENT also lists cases filed on someone else's behalf; only the\n // initiator may resubmit, so those are filtered out here.\n const page: ApprovalInstancesPageResult = await listApprovalInstancesPage({\n page: 1,\n pageSize: RETURNED_INSTANCE_PAGE_SIZE,\n searchText: null,\n state: 'RETURNED',\n templateId: null,\n view: 'SENT',\n });\n\n return {\n rows: readReturnedInstanceRows(page.instances, currentMemberId),\n // The total includes cases filed for someone else, so compare it with\n // what this page fetched rather than with the rows kept.\n truncated: page.totalCount > page.instances.length,\n };\n } catch {\n return null;\n }\n}\n\nfunction readReturnedInstanceRows(\n instances: readonly ApprovalInstanceRecord[],\n currentMemberId: string,\n): readonly ReturnedInstanceRow[] {\n return instances\n .filter(\n (instance): boolean => instance.initiatorMemberId === currentMemberId,\n )\n .map(\n (instance): ReturnedInstanceRow => ({\n caseTitle: readApprovalInstanceCaseTitle(instance),\n id: instance.id,\n key: instance.id,\n startedAt: instance.startedAt,\n }),\n );\n}\n\nasync function readInboxTaskRows(\n tasks: readonly TaskRecord[],\n): Promise<InboxTaskRow[]> {\n const instances = await readTaskInstances(tasks);\n\n return tasks.map(\n (task, index): InboxTaskRow => ({\n ...task,\n caseTitle: readTaskCaseTitle(task, instances[index] ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n slaStatusColor: readSlaStatusColor(task.slaDueAt),\n slaStatusText: readSlaStatusText(task.slaDueAt),\n statusLabel: readTaskStatusLabel(task.status),\n }),\n );\n}\n\nasync function readApprovalHistoryRows(\n tasks: readonly TaskRecord[],\n currentMemberId: string,\n): Promise<ApprovalHistoryRow[]> {\n const [decisionLists, instances] = await Promise.all([\n Promise.all(tasks.map((task) => listTaskDecisions(task.id))),\n readTaskInstances(tasks),\n ]);\n\n return tasks.map((task, index): ApprovalHistoryRow => {\n const decisions = decisionLists[index] ?? [];\n const decision = readLatestOwnTaskDecision(decisions, currentMemberId);\n const instance = instances[index] ?? null;\n\n return {\n ...task,\n caseTitle: readTaskCaseTitle(task, instance),\n decisionAction: decision?.action ?? null,\n decisionComment: decision?.comment ?? null,\n decisionCommentText: readDecisionCommentText(decision?.comment ?? null),\n decisionLabel: readTaskDecisionLabel(decision?.action ?? null),\n // completedAt is when the last signer finished, so it can stand in only\n // when the task has no decisions at all.\n decidedAt:\n decision?.decidedAt ??\n (decisions.length === 0 ? task.completedAt : null),\n instanceState: instance?.state ?? null,\n instanceStateLabel: readInstanceStateLabel(instance?.state ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n };\n });\n}\n\nasync function readTaskInstances(\n tasks: readonly TaskRecord[],\n): Promise<readonly (ApprovalInstanceRecord | null)[]> {\n return Promise.all(\n tasks.map(async (task): Promise<ApprovalInstanceRecord | null> => {\n try {\n return (await readApprovalInstance(task.instanceId)).instance;\n } catch {\n return null;\n }\n }),\n );\n}\n\nfunction readTaskCaseTitle(\n task: TaskRecord,\n instance: ApprovalInstanceRecord | null,\n): string {\n return instance ? readApprovalInstanceCaseTitle(instance) : task.instanceId;\n}\n\n// A sequential or countersign task holds decisions from several signers, so\n// the newest one on the task can be somebody else's. A delegate is the one\n// recorded as deciding, and a principal never gets the delegated task in this\n// list.\nfunction readLatestOwnTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n currentMemberId: string,\n): TaskDecisionRecord | null {\n return readLatestTaskDecision(\n decisions.filter(\n (decision): boolean => decision.decidedByMemberId === currentMemberId,\n ),\n );\n}\n\nfunction readTaskDecisionLabel(\n action: TaskDecisionRecord['action'] | null,\n): string {\n if (action === 'APPROVED') {\n return '同意';\n }\n\n if (action === 'REJECTED') {\n return '拒絕';\n }\n\n if (action === 'RETURNED') {\n return '退回';\n }\n\n if (action === 'TRANSFERRED') {\n return '轉派';\n }\n\n return '未記錄';\n}\n\nfunction readTaskDecisionColor(\n action: TaskDecisionRecord['action'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (action === 'APPROVED') {\n return 'text-success';\n }\n\n if (action === 'REJECTED' || action === 'RETURNED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readInstanceStateLabel(\n state: ApprovalInstanceRecord['state'] | null,\n): string {\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n if (state === 'APPROVED') {\n return '已通過';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n return '-';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceRecord['state'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') {\n return 'text-success';\n }\n\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readDecisionCommentText(comment: string | null): string {\n const trimmedComment = comment?.trim() ?? '';\n\n return trimmedComment || '-';\n}\n\nfunction formatHistoryDateTime(value: string | null): string {\n return formatDateTime(value);\n}\n\nfunction readSlaStatusText(value: string | null): string {\n if (!value) {\n return '-';\n }\n\n const dueAt = new Date(value).getTime();\n const now = Date.now();\n const diffMs = Math.abs(dueAt - now);\n const label = formatDuration(diffMs);\n\n return dueAt < now ? `已逾期 ${label}` : `剩餘 ${label}`;\n}\n\nfunction readSlaStatusColor(\n value: string | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (!value) {\n return 'text-neutral';\n }\n\n return new Date(value).getTime() < Date.now() ? 'text-error' : 'text-success';\n}\n\nfunction formatDuration(value: number): string {\n const totalMinutes = Math.max(1, Math.ceil(value / 60_000));\n const days = Math.floor(totalMinutes / 1440);\n const hours = Math.floor((totalMinutes % 1440) / 60);\n const minutes = totalMinutes % 60;\n\n if (days > 0) {\n return `${days}天 ${hours}小時`;\n }\n\n if (hours > 0) {\n return `${hours}小時 ${minutes}分鐘`;\n }\n\n return `${minutes}分鐘`;\n}\n\nfunction readTaskStatusLabel(status: TaskRecord['status']): string {\n if (status === 'PENDING') {\n return '待處理';\n }\n\n if (status === 'IN_PROGRESS') {\n return '處理中';\n }\n\n if (status === 'COMPLETED') {\n return '已完成';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n if (status === 'CANCELLED') {\n return '已取消';\n }\n\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["_Fragment","formatDateTime","useAuth","readLatestTaskDecision","readTaskNodeText","useRouterAdapter","useBPMRoutes","Fragment$1","ContentHeader","RETURNED_INSTANCE_PAGE_SIZE","RETURNED_SECTION_STYLE","PAGE_SIZE_OPTIONS","FIRST_PAGE","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","useState","error","setError","pendingPaging","setPendingPaging","trackingPaging","setTrackingPaging","historyPaging","setHistoryPaging","pending","useTabPage","readRows","listInboxTasksPage","memberId","paging","readInboxTaskRows","tracking","listApprovalHistoryTasksPage","readApprovalHistoryRows","tasks","history","returnedRows","setReturnedRows","returnedTruncated","setReturnedTruncated","readReturnedInstances","returned","readErrorMessage","requestError","pendingColumns","useMemo","record","Badge","Typography","pendingTableActions","returnedColumns","returnedTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","handleTabChange","activeKey","PageHeader","Button","PlusIcon","SectionGroup","Section","Tab","TabItem","readReturnedSectionHint","Table","readTablePagination","state","setState","latestRequestRef","useRef","loadRef","load","refresh","useCallback","request","previous","loaded","lastPage","onError","setPaging","useEffect","enabled","toRows","page","from","to","count","hasRows","truncated","listApprovalInstancesPage","readReturnedInstanceRows","instances","instance","readApprovalInstanceCaseTitle","readTaskInstances","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","listTaskDecisions","decisions","decision","readLatestOwnTaskDecision","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","readApprovalInstance","action","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport {\n type CSSProperties,\n type Key,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n ApprovalInstanceRecord,\n type ApprovalInstancesPageResult,\n listApprovalHistoryTasksPage,\n listApprovalInstancesPage,\n listInboxTasksPage,\n type MemberTaskPage,\n listTaskDecisions,\n readApprovalInstance,\n readApprovalInstanceCaseTitle,\n TaskDecisionRecord,\n TaskRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useAuth } from '../../lib/auth-provider';\nimport { readTaskNodeText } from '../../lib/task-node-label';\nimport { readLatestTaskDecision } from '../../lib/task-decision';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\n\ntype InboxTabKey = 'history' | 'pending' | 'tracking';\n\ntype InboxTaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n key: string;\n nodeText: string;\n slaStatusColor: 'text-error' | 'text-neutral' | 'text-success';\n slaStatusText: string;\n statusLabel: string;\n }\n>;\n\ntype ReturnedInstanceRow = Readonly<{\n caseTitle: string;\n id: string;\n key: string;\n startedAt: string | null;\n}>;\n\n/** The server caps a page at 100; more than that is left to 我發起的. */\nconst RETURNED_INSTANCE_PAGE_SIZE = 100;\n\nconst RETURNED_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n marginBottom: 'var(--mzn-spacing-padding-vertical-spacious)',\n};\n\ntype ApprovalHistoryRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n decisionAction: TaskDecisionRecord['action'] | null;\n decisionComment: string | null;\n decisionCommentText: string;\n decisionLabel: string;\n decidedAt: string | null;\n instanceState: ApprovalInstanceRecord['state'] | null;\n instanceStateLabel: string;\n key: string;\n nodeText: string;\n }\n>;\n\ntype TabPaging = Readonly<{ page: number; pageSize: number }>;\n\ntype TabPage<TRow> = Readonly<{\n loading: boolean;\n rows: readonly TRow[];\n total: number;\n}>;\n\nconst PAGE_SIZE_OPTIONS = [10, 20, 50];\n\nconst FIRST_PAGE: TabPaging = { page: 1, pageSize: 20 };\n\n/**\n * Framework-agnostic view for the BPM \"我的待簽\" inbox. Mechanical port of\n * `apps/client/src/app/inbox/page.tsx` — renders pending tasks, tracking,\n * and history tabs.\n */\nexport function InboxView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activeTab, setActiveTab] = useState<InboxTabKey>('pending');\n const [error, setError] = useState<string | null>(null);\n const [pendingPaging, setPendingPaging] = useState<TabPaging>(FIRST_PAGE);\n const [trackingPaging, setTrackingPaging] =\n useState<TabPaging>(FIRST_PAGE);\n const [historyPaging, setHistoryPaging] = useState<TabPaging>(FIRST_PAGE);\n const pending = useTabPage<InboxTaskRow>(\n currentMemberId,\n { enabled: true, paging: pendingPaging, setPaging: setPendingPaging },\n setError,\n async (memberId, paging) => {\n const page = await listInboxTasksPage({\n assigneeMemberId: memberId,\n ...paging,\n });\n\n return readRows(page, readInboxTaskRows);\n },\n );\n // Tasks of instances still under way: the same history, narrowed on the\n // server so the badge and the pages count every such task, not one page.\n const tracking = useTabPage<ApprovalHistoryRow>(\n currentMemberId,\n { enabled: true, paging: trackingPaging, setPaging: setTrackingPaging },\n setError,\n async (memberId, paging) => {\n const page = await listApprovalHistoryTasksPage({\n assigneeMemberId: memberId,\n instanceState: 'RUNNING',\n ...paging,\n });\n\n return readRows(page, (tasks) => readApprovalHistoryRows(tasks, memberId));\n },\n );\n // History has no badge, so it is read only once its tab is opened.\n const history = useTabPage<ApprovalHistoryRow>(\n currentMemberId,\n {\n enabled: activeTab === 'history',\n paging: historyPaging,\n setPaging: setHistoryPaging,\n },\n setError,\n async (memberId, paging) => {\n const page = await listApprovalHistoryTasksPage({\n assigneeMemberId: memberId,\n ...paging,\n });\n\n return readRows(page, (tasks) => readApprovalHistoryRows(tasks, memberId));\n },\n );\n const [returnedRows, setReturnedRows] = useState<\n readonly ReturnedInstanceRow[]\n >([]);\n const [returnedTruncated, setReturnedTruncated] = useState(false);\n\n useEffect((): void => {\n if (!currentMemberId) {\n setReturnedRows([]);\n setReturnedTruncated(false);\n\n return;\n }\n\n void readReturnedInstances(currentMemberId).then(\n (returned): void => {\n setReturnedRows(returned?.rows ?? []);\n setReturnedTruncated(returned?.truncated ?? false);\n },\n (requestError: unknown): void => setError(readErrorMessage(requestError)),\n );\n }, [currentMemberId]);\n\n const pendingColumns = useMemo(\n (): TableColumn<InboxTaskRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'fill',\n // Approving one of these needs the case page, where the fill is entered.\n render: (record: InboxTaskRow): ReactElement | null =>\n record.hasFillableFields ? (\n <Badge size=\"sub\" text=\"需補填\" variant=\"dot-warning\" />\n ) : null,\n title: '補填',\n width: 120,\n },\n {\n key: 'slaDueAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography\n color={record.slaStatusColor}\n component=\"span\"\n variant=\"body\"\n >\n {record.slaStatusText}\n </Typography>\n ),\n title: 'SLA',\n width: 180,\n },\n {\n key: 'createdAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.createdAt)}\n </Typography>\n ),\n title: '建立時間',\n width: 220,\n },\n ],\n [],\n );\n const pendingTableActions = useMemo(\n (): TableActions<InboxTaskRow> => ({\n render: (record): ReturnType<TableActions<InboxTaskRow>['render']> => [\n {\n name: '處理',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const returnedColumns = useMemo(\n (): TableColumn<ReturnedInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n {\n key: 'startedAt',\n render: (record: ReturnedInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n ],\n [],\n );\n const returnedTableActions = useMemo(\n (): TableActions<ReturnedInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ReturnedInstanceRow>['render']> => [\n {\n name: '重新送出',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 120,\n }),\n [router, routes],\n );\n const historyColumns = useMemo(\n (): TableColumn<ApprovalHistoryRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n key: 'decisionLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readTaskDecisionColor(record.decisionAction)}\n component=\"span\"\n variant=\"body\"\n >\n {record.decisionLabel}\n </Typography>\n ),\n title: '決議',\n width: 120,\n },\n {\n key: 'decisionComment',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.decisionCommentText}\n </Typography>\n ),\n title: '意見',\n width: 240,\n },\n {\n key: 'instanceStateLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.instanceState)}\n component=\"span\"\n variant=\"body\"\n >\n {record.instanceStateLabel}\n </Typography>\n ),\n title: '流程狀態',\n width: 140,\n },\n {\n key: 'decidedAt',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatHistoryDateTime(record.decidedAt)}\n </Typography>\n ),\n title: '簽核時間',\n width: 220,\n },\n ],\n [],\n );\n const historyTableActions = useMemo(\n (): TableActions<ApprovalHistoryRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalHistoryRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n\n function handleTabChange(activeKey: Key): void {\n if (\n activeKey === 'history' ||\n activeKey === 'pending' ||\n activeKey === 'tracking'\n ) {\n setActiveTab(activeKey);\n return;\n }\n\n setActiveTab('pending');\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={`目前以 ${member?.name ?? currentMemberId ?? '目前登入會員'} 查詢待處理與歷史簽核任務。`}\n title=\"我的待簽\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.caseNew())}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab activeKey={activeTab} onChange={handleTabChange} size=\"sub\">\n <TabItem\n badgeCount={pending.loading ? undefined : pending.total}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={tracking.loading ? undefined : tracking.total}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {/* A truncated page with none of the member's own cases still\n points to 我發起的: theirs may sit past the first page. */}\n {activeTab === 'pending' &&\n (returnedRows.length > 0 || returnedTruncated) ? (\n <div data-returned-instances=\"\" style={RETURNED_SECTION_STYLE}>\n {/* Without rows there is nothing here to resubmit, only the\n pointer to 我發起的. */}\n {returnedRows.length > 0 ? (\n <Typography component=\"h2\" variant=\"label-primary\">\n 被退回待重送\n </Typography>\n ) : null}\n <Typography color=\"text-neutral\" variant=\"caption\">\n {readReturnedSectionHint(\n returnedRows.length > 0,\n returnedTruncated,\n )}\n </Typography>\n {returnedRows.length > 0 ? (\n <Table\n actions={returnedTableActions}\n columns={returnedColumns}\n dataSource={[...returnedRows]}\n fullWidth\n />\n ) : null}\n </div>\n ) : null}\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={[...pending.rows]}\n fullWidth\n loading={pending.loading}\n pagination={readTablePagination(\n pendingPaging,\n pending.total,\n setPendingPaging,\n )}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={[...tracking.rows]}\n fullWidth\n loading={tracking.loading}\n pagination={readTablePagination(\n trackingPaging,\n tracking.total,\n setTrackingPaging,\n )}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={[...history.rows]}\n fullWidth\n loading={history.loading}\n pagination={readTablePagination(\n historyPaging,\n history.total,\n setHistoryPaging,\n )}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n/**\n * One tab's rows for the current member and paging. Only the latest request\n * may write, so paging quickly cannot let an earlier page's late answer\n * replace the one asked for last. Nothing is read while `enabled` is false.\n * A page past the end (the list shrank since it was chosen) moves to the last\n * page instead of showing an empty table.\n */\nfunction useTabPage<TRow>(\n memberId: string | null,\n {\n enabled,\n paging,\n setPaging,\n }: Readonly<{\n enabled: boolean;\n paging: TabPaging;\n setPaging: (paging: TabPaging) => void;\n }>,\n onError: (message: string | null) => void,\n load: (\n memberId: string,\n paging: TabPaging,\n ) => Promise<Readonly<{ rows: readonly TRow[]; total: number }>>,\n): TabPage<TRow> {\n const [state, setState] = useState<TabPage<TRow>>({\n loading: true,\n rows: [],\n total: 0,\n });\n const latestRequestRef = useRef(0);\n const loadRef = useRef(load);\n\n loadRef.current = load;\n\n const refresh = useCallback(async (): Promise<void> => {\n const request = latestRequestRef.current + 1;\n\n latestRequestRef.current = request;\n\n if (!memberId) {\n setState({ loading: false, rows: [], total: 0 });\n\n return;\n }\n\n setState((previous) => ({ ...previous, loading: true }));\n\n try {\n const loaded = await loadRef.current(memberId, paging);\n\n if (latestRequestRef.current !== request) {\n return;\n }\n\n const lastPage = Math.max(1, Math.ceil(loaded.total / paging.pageSize));\n\n if (!loaded.rows.length && paging.page > lastPage) {\n setPaging({ ...paging, page: lastPage });\n\n return;\n }\n\n setState({ loading: false, ...loaded });\n } catch (requestError: unknown) {\n if (latestRequestRef.current === request) {\n onError(readErrorMessage(requestError));\n setState((previous) => ({ ...previous, loading: false }));\n }\n }\n }, [memberId, onError, paging, setPaging]);\n\n useEffect((): void => {\n if (enabled) {\n void refresh();\n }\n }, [enabled, refresh]);\n\n return state;\n}\n\nasync function readRows<TRow>(\n page: MemberTaskPage,\n toRows: (tasks: readonly TaskRecord[]) => Promise<TRow[]>,\n): Promise<Readonly<{ rows: readonly TRow[]; total: number }>> {\n return { rows: await toRows(page.tasks), total: page.totalCount };\n}\n\nfunction readTablePagination(\n paging: TabPaging,\n total: number,\n setPaging: (paging: TabPaging) => void,\n): Readonly<{\n current: number;\n onChange: (page: number) => void;\n onChangePageSize: (pageSize: number) => void;\n pageSize: number;\n pageSizeLabel: string;\n pageSizeOptions: number[];\n renderResultSummary: (from: number, to: number, total: number) => string;\n showPageSizeOptions: boolean;\n total: number;\n}> {\n return {\n current: paging.page,\n onChange: (page: number): void => setPaging({ ...paging, page }),\n onChangePageSize: (pageSize: number): void =>\n setPaging({ page: 1, pageSize }),\n pageSize: paging.pageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: PAGE_SIZE_OPTIONS,\n renderResultSummary: (from: number, to: number, count: number): string =>\n `顯示 ${from}-${to} 筆,共 ${count} 筆`,\n showPageSizeOptions: true,\n total,\n };\n}\n\nfunction readReturnedSectionHint(\n hasRows: boolean,\n truncated: boolean,\n): string {\n if (!hasRows) {\n return `前 ${RETURNED_INSTANCE_PAGE_SIZE} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`;\n }\n\n return truncated\n ? '你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。'\n : '你發起的案件被退回,請修改後重新送出。';\n}\n\n/**\n * Returned cases are a side list: a failure here, in the request or in reading\n * its rows, hides that section instead of taking the pending and history tasks\n * down with it.\n */\nasync function readReturnedInstances(\n currentMemberId: string,\n): Promise<Readonly<{\n rows: readonly ReturnedInstanceRow[];\n truncated: boolean;\n}> | null> {\n try {\n // SENT also lists cases filed on someone else's behalf; only the\n // initiator may resubmit, so those are filtered out here.\n const page: ApprovalInstancesPageResult = await listApprovalInstancesPage({\n page: 1,\n pageSize: RETURNED_INSTANCE_PAGE_SIZE,\n searchText: null,\n state: 'RETURNED',\n templateId: null,\n view: 'SENT',\n });\n\n return {\n rows: readReturnedInstanceRows(page.instances, currentMemberId),\n // The total includes cases filed for someone else, so compare it with\n // what this page fetched rather than with the rows kept.\n truncated: page.totalCount > page.instances.length,\n };\n } catch {\n return null;\n }\n}\n\nfunction readReturnedInstanceRows(\n instances: readonly ApprovalInstanceRecord[],\n currentMemberId: string,\n): readonly ReturnedInstanceRow[] {\n return instances\n .filter(\n (instance): boolean => instance.initiatorMemberId === currentMemberId,\n )\n .map(\n (instance): ReturnedInstanceRow => ({\n caseTitle: readApprovalInstanceCaseTitle(instance),\n id: instance.id,\n key: instance.id,\n startedAt: instance.startedAt,\n }),\n );\n}\n\nasync function readInboxTaskRows(\n tasks: readonly TaskRecord[],\n): Promise<InboxTaskRow[]> {\n const instances = await readTaskInstances(tasks);\n\n return tasks.map(\n (task, index): InboxTaskRow => ({\n ...task,\n caseTitle: readTaskCaseTitle(task, instances[index] ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n slaStatusColor: readSlaStatusColor(task.slaDueAt),\n slaStatusText: readSlaStatusText(task.slaDueAt),\n statusLabel: readTaskStatusLabel(task.status),\n }),\n );\n}\n\nasync function readApprovalHistoryRows(\n tasks: readonly TaskRecord[],\n currentMemberId: string,\n): Promise<ApprovalHistoryRow[]> {\n const [decisionLists, instances] = await Promise.all([\n Promise.all(tasks.map((task) => listTaskDecisions(task.id))),\n readTaskInstances(tasks),\n ]);\n\n return tasks.map((task, index): ApprovalHistoryRow => {\n const decisions = decisionLists[index] ?? [];\n const decision = readLatestOwnTaskDecision(decisions, currentMemberId);\n const instance = instances[index] ?? null;\n\n return {\n ...task,\n caseTitle: readTaskCaseTitle(task, instance),\n decisionAction: decision?.action ?? null,\n decisionComment: decision?.comment ?? null,\n decisionCommentText: readDecisionCommentText(decision?.comment ?? null),\n decisionLabel: readTaskDecisionLabel(decision?.action ?? null),\n // completedAt is when the last signer finished, so it can stand in only\n // when the task has no decisions at all.\n decidedAt:\n decision?.decidedAt ??\n (decisions.length === 0 ? task.completedAt : null),\n instanceState: instance?.state ?? null,\n instanceStateLabel: readInstanceStateLabel(instance?.state ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n };\n });\n}\n\nasync function readTaskInstances(\n tasks: readonly TaskRecord[],\n): Promise<readonly (ApprovalInstanceRecord | null)[]> {\n return Promise.all(\n tasks.map(async (task): Promise<ApprovalInstanceRecord | null> => {\n try {\n return (await readApprovalInstance(task.instanceId)).instance;\n } catch {\n return null;\n }\n }),\n );\n}\n\nfunction readTaskCaseTitle(\n task: TaskRecord,\n instance: ApprovalInstanceRecord | null,\n): string {\n return instance ? readApprovalInstanceCaseTitle(instance) : task.instanceId;\n}\n\n// A sequential or countersign task holds decisions from several signers, so\n// the newest one on the task can be somebody else's. A delegate is the one\n// recorded as deciding, and a principal never gets the delegated task in this\n// list.\nfunction readLatestOwnTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n currentMemberId: string,\n): TaskDecisionRecord | null {\n return readLatestTaskDecision(\n decisions.filter(\n (decision): boolean => decision.decidedByMemberId === currentMemberId,\n ),\n );\n}\n\nfunction readTaskDecisionLabel(\n action: TaskDecisionRecord['action'] | null,\n): string {\n if (action === 'APPROVED') {\n return '同意';\n }\n\n if (action === 'REJECTED') {\n return '拒絕';\n }\n\n if (action === 'RETURNED') {\n return '退回';\n }\n\n if (action === 'TRANSFERRED') {\n return '轉派';\n }\n\n return '未記錄';\n}\n\nfunction readTaskDecisionColor(\n action: TaskDecisionRecord['action'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (action === 'APPROVED') {\n return 'text-success';\n }\n\n if (action === 'REJECTED' || action === 'RETURNED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readInstanceStateLabel(\n state: ApprovalInstanceRecord['state'] | null,\n): string {\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n if (state === 'APPROVED') {\n return '已通過';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n return '-';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceRecord['state'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') {\n return 'text-success';\n }\n\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readDecisionCommentText(comment: string | null): string {\n const trimmedComment = comment?.trim() ?? '';\n\n return trimmedComment || '-';\n}\n\nfunction formatHistoryDateTime(value: string | null): string {\n return formatDateTime(value);\n}\n\nfunction readSlaStatusText(value: string | null): string {\n if (!value) {\n return '-';\n }\n\n const dueAt = new Date(value).getTime();\n const now = Date.now();\n const diffMs = Math.abs(dueAt - now);\n const label = formatDuration(diffMs);\n\n return dueAt < now ? `已逾期 ${label}` : `剩餘 ${label}`;\n}\n\nfunction readSlaStatusColor(\n value: string | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (!value) {\n return 'text-neutral';\n }\n\n return new Date(value).getTime() < Date.now() ? 'text-error' : 'text-success';\n}\n\nfunction formatDuration(value: number): string {\n const totalMinutes = Math.max(1, Math.ceil(value / 60_000));\n const days = Math.floor(totalMinutes / 1440);\n const hours = Math.floor((totalMinutes % 1440) / 60);\n const minutes = totalMinutes % 60;\n\n if (days > 0) {\n return `${days}天 ${hours}小時`;\n }\n\n if (hours > 0) {\n return `${hours}小時 ${minutes}分鐘`;\n }\n\n return `${minutes}分鐘`;\n}\n\nfunction readTaskStatusLabel(status: TaskRecord['status']): string {\n if (status === 'PENDING') {\n return '待處理';\n }\n\n if (status === 'IN_PROGRESS') {\n return '處理中';\n }\n\n if (status === 'COMPLETED') {\n return '已完成';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n if (status === 'CANCELLED') {\n return '已取消';\n }\n\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":";;;;;;;;;;;;;AAoEA,IAAMS,IAA8B,KAE9BC,KAAwC;CAC5C,SAAS;CACT,KAAK;CACL,cAAc;AAChB,GA0BMC,IAAoB;CAAC;CAAI;CAAI;AAAE,GAE/BC,IAAwB;CAAE,MAAM;CAAG,UAAU;AAAG;AAOtD,SAAgBC,IAA0B;CACxC,IAAMC,IAAST,EAAiB,GAC1BU,IAAST,EAAa,GACtB,EAAE,cAAWJ,EAAQ,GACrBc,IAAkBC,GAAQ,YAAY,MACtC,CAACC,GAAWC,KAAgBC,EAAsB,SAAS,GAC3D,CAACC,GAAOC,KAAYF,EAAwB,IAAI,GAChD,CAACG,GAAeC,KAAoBJ,EAAoBR,CAAU,GAClE,CAACa,GAAgBC,KACrBN,EAAoBR,CAAU,GAC1B,CAACe,GAAeC,KAAoBR,EAAoBR,CAAU,GAClEiB,IAAUC,EACdd,GACA;EAAE,SAAS;EAAM,QAAQO;EAAe,WAAWC;CAAiB,GACpEF,GACA,OAAO,GAAU,MAMRS,EAAS,MALGC,EAAmB;EACpC,kBAAkBC;EAClB,GAAGC;CACL,CAAC,GAEqBC,EAAiB,CAE3C,GAGMC,IAAWN,EACfd,GACA;EAAE,SAAS;EAAM,QAAQS;EAAgB,WAAWC;CAAkB,GACtEJ,GACA,OAAO,GAAU,MAORS,EAAS,MANGM,EAA6B;EAC9C,kBAAkBJ;EAClB,eAAe;EACf,GAAGC;CACL,CAAC,IAEsB,MAAUI,EAAwBC,GAAON,CAAQ,CAAC,CAE7E,GAEMO,IAAUV,EACdd,GACA;EACE,SAASE,MAAc;EACvB,QAAQS;EACR,WAAWC;CACb,GACAN,GACA,OAAO,GAAU,MAMRS,EAAS,MALGM,EAA6B;EAC9C,kBAAkBJ;EAClB,GAAGC;CACL,CAAC,IAEsB,MAAUI,EAAwBC,GAAON,CAAQ,CAAC,CAE7E,GACM,CAACQ,GAAcC,KAAmBtB,EAEtC,CAAC,CAAC,GACE,CAACuB,GAAmBC,KAAwBxB,EAAS,EAAK;CAEhE,QAAsB;EACpB,AAAKJ,IAOL6B,EAA2B7B,CAAe,CAAC,CAAC,MACzC,MAAmB;GAElB,AADA0B,EAAgBI,GAAU,QAAQ,CAAC,CAAC,GACpCF,EAAqBE,GAAU,aAAa,EAAK;EACnD,IACC,MAAgCxB,EAASyB,EAAiBC,CAAY,CAAC,CAC1E,KAZEN,EAAgB,CAAC,CAAC,GAClBE,EAAqB,EAAK;CAY9B,GAAG,CAAC5B,CAAe,CAAC;CAEpB,IAAMiC,IAAiBC,QACc;EACjC;GAAE,WAAW;GAAa,KAAK;GAAa,OAAO;GAAM,OAAO;EAAI;EACpE;GAAE,WAAW;GAAY,KAAK;GAAY,OAAO;GAAM,OAAO;EAAI;EAClE;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GAEL,SAAS,MACPC,EAAO,oBACL,kBAACC,GAAD;IAAO,MAAK;IAAM,MAAK;IAAM,SAAQ;GAAe,CAAA,IAClD;GACN,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAACC,GAAD;IACE,OAAOF,EAAO;IACd,WAAU;IACV,SAAQ;IAEP,UAAAA,EAAO;GACE,CAAA;GAEd,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAACE,GAAD;IAAY,WAAU;IAAO,SAAQ;IAClC,UAAApD,EAAekD,EAAO,SAAS;GACtB,CAAA;GAEd,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH,GACMG,KAAsBJ,SACS;EACjC,SAAS,MAA6D,CACpE;GACE,MAAM;GACN,eAAqBpC,EAAO,KAAKC,EAAO,WAAWoC,EAAO,UAAU,CAAC;EACvE,CACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAACrC,GAAQC,CAAM,CACjB,GACMwC,KAAkBL,QACoB,CACxC;EAAE,WAAW;EAAa,KAAK;EAAa,OAAO;EAAM,OAAO;CAAI,GACpE;EACE,KAAK;EACL,SAAS,MACP,kBAACG,GAAD;GAAY,WAAU;GAAO,SAAQ;GAClC,UAAApD,EAAekD,EAAO,SAAS;EACtB,CAAA;EAEd,OAAO;EACP,OAAO;CACT,CACF,GACA,CAAC,CACH,GACMK,KAAuBN,SACe;EACxC,SACE,MAC4D,CAC5D;GACE,MAAM;GACN,eAAqBpC,EAAO,KAAKC,EAAO,WAAWoC,EAAO,EAAE,CAAC;EAC/D,CACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAACrC,GAAQC,CAAM,CACjB,GACM0C,IAAiBP,QACoB;EACvC;GAAE,WAAW;GAAa,KAAK;GAAa,OAAO;GAAM,OAAO;EAAI;EACpE;GAAE,WAAW;GAAY,KAAK;GAAY,OAAO;GAAM,OAAO;EAAI;EAClE;GACE,KAAK;GACL,SAAS,MACP,kBAACG,GAAD;IACE,OAAOK,EAAsBP,EAAO,cAAc;IAClD,WAAU;IACV,SAAQ;IAEP,UAAAA,EAAO;GACE,CAAA;GAEd,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAACE,GAAD;IAAY,WAAU;IAAO,SAAQ;IAClC,UAAAF,EAAO;GACE,CAAA;GAEd,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAACE,GAAD;IACE,OAAOM,EAAuBR,EAAO,aAAa;IAClD,WAAU;IACV,SAAQ;IAEP,UAAAA,EAAO;GACE,CAAA;GAEd,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAACE,GAAD;IAAY,WAAU;IAAO,SAAQ;IAClC,UAAAO,EAAsBT,EAAO,SAAS;GAC7B,CAAA;GAEd,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH,GACMU,IAAsBX,SACe;EACvC,SACE,MAC2D,CAC3D;GACE,MAAM;GACN,eAAqBpC,EAAO,KAAKC,EAAO,WAAWoC,EAAO,UAAU,CAAC;EACvE,CACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAACrC,GAAQC,CAAM,CACjB;CAEA,SAAS+C,EAAgB,GAAsB;EAC7C,AAKE3C,EAJA4C,MAAc,aACdA,MAAc,aACdA,MAAc,aAEDA,IAIF,SAFb;CAGF;CAEA,OACE,kBAAA/D,IAAA,EAAA,UAAA,CACI,kBAACgE,GAAD,EAAA,UACE,kBAACxD,IAAD;EACE,aAAa,OAAOS,GAAQ,QAAQD,KAAmB,SAAS;EAChE,OAAM;EAEN,UAAA,kBAACiD,GAAD;GACE,MAAMC;GACN,UAAS;GACT,eAAqBpD,EAAO,KAAKC,EAAO,QAAQ,CAAC;GACjD,SAAQ;GACT,UAAA;EAEO,CAAA;CACK,CAAA,EACL,CAAA,GAEZ,kBAACoD,IAAD,EAAA,UACE,kBAACC,GAAD,EAAA,UAAA;EACG/C,IACC,kBAACgC,GAAD;GAAY,OAAM;GAAa,SAAQ;GACpC,UAAAhC;EACS,CAAA,IACV;EACJ,kBAACgD,IAAD;GAAK,WAAWnD;GAAW,UAAU4C;GAAiB,MAAK;GAA3D,UAAA;IACE,kBAACQ,GAAD;KACE,YAAYzC,EAAQ,UAAU,KAAA,IAAYA,EAAQ;KAEnD,UAAA;IAEQ,GAHH,SAGG;IACT,kBAACyC,GAAD;KACE,YAAYlC,EAAS,UAAU,KAAA,IAAYA,EAAS;KAErD,UAAA;IAEQ,GAHH,UAGG;IACT,kBAACkC,GAAD,EAAA,UAAuB,SAAe,GAAzB,SAAyB;GACnC;;EAIJpD,MAAc,cACduB,EAAa,SAAS,KAAKE,KAC1B,kBAAC,OAAD;GAAK,2BAAwB;GAAG,OAAOjC;GAAvC,UAAA;IAGG+B,EAAa,SAAS,IACrB,kBAACY,GAAD;KAAY,WAAU;KAAK,SAAQ;KAAgB,UAAA;IAEvC,CAAA,IACV;IACJ,kBAACA,GAAD;KAAY,OAAM;KAAe,SAAQ;KACtC,UAAAkB,EACC9B,EAAa,SAAS,GACtBE,CACF;IACU,CAAA;IACXF,EAAa,SAAS,IACrB,kBAAC+B,GAAD;KACE,SAAShB;KACT,SAASD;KACT,YAAY,CAAC,GAAGd,CAAY;KAC5B,WAAA;IACD,CAAA,IACC;GACD;EACH,CAAA,IAAA;EACHvB,MAAc,YACb,kBAACsD,GAAD;GACE,SAASlB;GACT,SAASL;GACT,YAAY,CAAC,GAAGpB,EAAQ,IAAI;GAC5B,WAAA;GACA,SAASA,EAAQ;GACjB,YAAY4C,EACVlD,GACAM,EAAQ,OACRL,CACF;EACD,CAAA,IACC;EACHN,MAAc,aACb,kBAACsD,GAAD;GACE,SAASX;GACT,SAASJ;GACT,YAAY,CAAC,GAAGrB,EAAS,IAAI;GAC7B,WAAA;GACA,SAASA,EAAS;GAClB,YAAYqC,EACVhD,GACAW,EAAS,OACTV,CACF;EACD,CAAA,IACC;EACHR,MAAc,YACb,kBAACsD,GAAD;GACE,SAASX;GACT,SAASJ;GACT,YAAY,CAAC,GAAGjB,EAAQ,IAAI;GAC5B,WAAA;GACA,SAASA,EAAQ;GACjB,YAAYiC,EACV9C,GACAa,EAAQ,OACRZ,CACF;EACD,CAAA,IACC;CACG,EAAA,CAAA,EACG,CAAA,CACd,EAAA,CAAA;AAER;AASA,SAASE,EACP,GACA,EACE,YACA,WACA,gBAMF,GACA,GAIe;CACf,IAAM,CAAC4C,GAAOC,KAAYvD,EAAwB;EAChD,SAAS;EACT,MAAM,CAAC;EACP,OAAO;CACT,CAAC,GACKwD,IAAmBC,EAAO,CAAC,GAC3BC,IAAUD,EAAOE,CAAI;CAE3B,EAAQ,UAAUA;CAElB,IAAMC,IAAUC,EAAY,YAA2B;EACrD,IAAMC,IAAUN,EAAiB,UAAU;EAI3C,IAFA,EAAiB,UAAUM,GAEvB,CAACjD,GACH,EAAS;GAAE,SAAS;GAAO,MAAM,CAAC;GAAG,OAAO;EAAE,CAAC;OAKjD;MAAU,OAAc;IAAE,GAAGkD;IAAU,SAAS;GAAK,EAAE;GAEvD,IAAI;IACF,IAAMC,IAAS,MAAMN,EAAQ,QAAQ7C,GAAUC,CAAM;IAErD,IAAI0C,EAAiB,YAAYM,GAC/B;IAGF,IAAMG,IAAW,KAAK,IAAI,GAAG,KAAK,KAAKD,EAAO,QAAQlD,EAAO,QAAQ,CAAC;IAEtE,IAAI,CAACkD,EAAO,KAAK,UAAUlD,EAAO,OAAOmD,GAAU;KACjD,EAAU;MAAE,GAAGnD;MAAQ,MAAMmD;KAAS,CAAC;KAEvC;IACF;IAEA,EAAS;KAAE,SAAS;KAAO,GAAGD;IAAO,CAAC;GACxC,SAASpC,GAAuB;IAC9B,AAAI4B,EAAiB,YAAYM,MAC/BI,EAAQvC,EAAiBC,CAAY,CAAC,GACtC2B,GAAU,OAAc;KAAE,GAAGQ;KAAU,SAAS;IAAM,EAAE;GAE5D;EAvBuD;CAwBzD,GAAG;EAAClD;EAAUqD;EAASpD;EAAQqD;CAAS,CAAC;CAQzC,OANAC,QAAsB;EACpB,AAAIC,KACFT,EAAa;CAEjB,GAAG,CAACS,GAAST,CAAO,CAAC,GAEdN;AACT;AAEA,eAAe3C,EACb,GACA,GAC6D;CAC7D,OAAO;EAAE,MAAM,MAAM2D,EAAOC,EAAK,KAAK;EAAG,OAAOA,EAAK;CAAW;AAClE;AAEA,SAASlB,EACP,GACA,GACA,GAWC;CACD,OAAO;EACL,SAASvC,EAAO;EAChB,WAAW,MAAuBqD,EAAU;GAAE,GAAGrD;GAAQ;EAAK,CAAC;EAC/D,mBAAmB,MACjBqD,EAAU;GAAE,MAAM;GAAG;EAAS,CAAC;EACjC,UAAUrD,EAAO;EACjB,eAAe;EACf,iBAAiBvB;EACjB,sBAAsB,GAAc,GAAY,MAC9C,MAAMiF,EAAK,GAAGC,EAAG,OAAOC,EAAM;EAChC,qBAAqB;EACrB;CACF;AACF;AAEA,SAASvB,EACP,GACA,GACQ;CAKR,OAJKwB,IAIEC,IACH,gDACA,wBALK,KAAKvF,EAA4B;AAM5C;AAOA,eAAeoC,EACb,GAIS;CACT,IAAI;EAGF,IAAM8C,IAAoC,MAAMM,EAA0B;GACxE,MAAM;GACN,UAAUxF;GACV,YAAY;GACZ,OAAO;GACP,YAAY;GACZ,MAAM;EACR,CAAC;EAED,OAAO;GACL,MAAMyF,EAAyBP,EAAK,WAAW3E,CAAe;GAG9D,WAAW2E,EAAK,aAAaA,EAAK,UAAU;EAC9C;CACF,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAASO,EACP,GACA,GACgC;CAChC,OAAOC,EACJ,QACE,MAAsBC,EAAS,sBAAsBpF,CACxD,CAAC,CACA,KACE,OAAmC;EAClC,WAAWqF,EAA8BD,CAAQ;EACjD,IAAIA,EAAS;EACb,KAAKA,EAAS;EACd,WAAWA,EAAS;CACtB,EACF;AACJ;AAEA,eAAejE,GACb,GACyB;CACzB,IAAMgE,IAAY,MAAMG,EAAkB/D,CAAK;CAE/C,OAAOA,EAAM,KACV,GAAM,OAAyB;EAC9B,GAAGgE;EACH,WAAWC,EAAkBD,GAAMJ,EAAUM,MAAU,IAAI;EAC3D,KAAKF,EAAK;EACV,UAAUnG,EAAiBmG,CAAI;EAC/B,gBAAgBG,EAAmBH,EAAK,QAAQ;EAChD,eAAeI,EAAkBJ,EAAK,QAAQ;EAC9C,aAAaK,EAAoBL,EAAK,MAAM;CAC9C,EACF;AACF;AAEA,eAAejE,EACb,GACA,GAC+B;CAC/B,IAAM,CAACuE,GAAeV,KAAa,MAAM,QAAQ,IAAI,CACnD,QAAQ,IAAI5D,EAAM,KAAK,MAASuE,EAAkBP,EAAK,EAAE,CAAC,CAAC,GAC3DD,EAAkB/D,CAAK,CACzB,CAAC;CAED,OAAOA,EAAM,KAAK,GAAM,MAA8B;EACpD,IAAMwE,IAAYF,EAAcJ,MAAU,CAAC,GACrCO,IAAWC,EAA0BF,GAAW/F,CAAe,GAC/DoF,IAAWD,EAAUM,MAAU;EAErC,OAAO;GACL,GAAGF;GACH,WAAWC,EAAkBD,GAAMH,CAAQ;GAC3C,gBAAgBY,GAAU,UAAU;GACpC,iBAAiBA,GAAU,WAAW;GACtC,qBAAqBE,EAAwBF,GAAU,WAAW,IAAI;GACtE,eAAeG,EAAsBH,GAAU,UAAU,IAAI;GAG7D,WACEA,GAAU,cACTD,EAAU,WAAW,IAAIR,EAAK,cAAc;GAC/C,eAAeH,GAAU,SAAS;GAClC,oBAAoBgB,EAAuBhB,GAAU,SAAS,IAAI;GAClE,KAAKG,EAAK;GACV,UAAUnG,EAAiBmG,CAAI;EACjC;CACF,CAAC;AACH;AAEA,eAAeD,EACb,GACqD;CACrD,OAAO,QAAQ,IACb/D,EAAM,IAAI,OAAO,MAAiD;EAChE,IAAI;GACF,QAAQ,MAAM8E,EAAqBd,EAAK,UAAU,EAAA,CAAG;EACvD,QAAQ;GACN,OAAO;EACT;CACF,CAAC,CACH;AACF;AAEA,SAASC,EACP,GACA,GACQ;CACR,OAAOJ,IAAWC,EAA8BD,CAAQ,IAAIG,EAAK;AACnE;AAMA,SAASU,EACP,GACA,GAC2B;CAC3B,OAAO9G,EACL4G,EAAU,QACP,MAAsBC,EAAS,sBAAsBhG,CACxD,CACF;AACF;AAEA,SAASmG,EACP,GACQ;CAiBR,OAhBIG,MAAW,aACN,OAGLA,MAAW,aACN,OAGLA,MAAW,aACN,OAGLA,MAAW,gBACN,OAGF;AACT;AAEA,SAAS5D,EACP,GACgD;CAShD,OARI4D,MAAW,aACN,iBAGLA,MAAW,cAAcA,MAAW,aAC/B,eAGF;AACT;AAEA,SAASF,EACP,GACQ;CA6BR,OA5BI1C,MAAU,YACL,QAGLA,MAAU,aACL,QAGLA,MAAU,aACL,QAGLA,MAAU,aACL,QAGLA,MAAU,cACL,QAGLA,MAAU,YACL,QAGLA,MAAU,UACL,OAGF;AACT;AAEA,SAASf,EACP,GACgD;CAShD,OARIe,MAAU,aACL,iBAGLA,MAAU,cAAcA,MAAU,eAAeA,MAAU,YACtD,eAGF;AACT;AAEA,SAASwC,EAAwB,GAAgC;CAG/D,QAFuBK,GAAS,KAAK,KAAK,OAEjB;AAC3B;AAEA,SAAS3D,EAAsB,GAA8B;CAC3D,OAAO3D,EAAeuH,CAAK;AAC7B;AAEA,SAASb,EAAkB,GAA8B;CACvD,IAAI,CAACa,GACH,OAAO;CAGT,IAAMC,IAAQ,IAAI,KAAKD,CAAK,CAAC,CAAC,QAAQ,GAChCE,IAAM,KAAK,IAAI,GAEfC,IAAQC,EADC,KAAK,IAAIH,IAAQC,CACH,CAAM;CAEnC,OAAOD,IAAQC,IAAM,OAAOC,MAAU,MAAMA;AAC9C;AAEA,SAASjB,EACP,GACgD;CAKhD,OAJKc,IAIE,IAAI,KAAKA,CAAK,CAAC,CAAC,QAAQ,IAAI,KAAK,IAAI,IAAI,eAAe,iBAHtD;AAIX;AAEA,SAASI,EAAe,GAAuB;CAC7C,IAAMC,IAAe,KAAK,IAAI,GAAG,KAAK,KAAKL,IAAQ,GAAM,CAAC,GACpDM,IAAO,KAAK,MAAMD,IAAe,IAAI,GACrCE,IAAQ,KAAK,MAAOF,IAAe,OAAQ,EAAE,GAC7CG,IAAUH,IAAe;CAU/B,OARIC,IAAO,IACF,GAAGA,EAAK,IAAIC,EAAM,MAGvBA,IAAQ,IACH,GAAGA,EAAM,KAAKC,EAAQ,MAGxB,GAAGA,EAAQ;AACpB;AAEA,SAASpB,EAAoB,GAAsC;CAqBjE,OApBIqB,MAAW,YACN,QAGLA,MAAW,gBACN,QAGLA,MAAW,cACN,QAGLA,MAAW,gBACN,QAGLA,MAAW,cACN,QAGFA;AACT;AAEA,SAASlF,EAAiB,GAAwB;CAChD,OAAO1B,aAAiB,QAAQA,EAAM,UAAU;AAClD"}