@rytass/bpm-core-react 0.4.1 → 0.6.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 (148) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +21 -0
  3. package/dist/chunks/FormBuilderView-B_KGPjlp.cjs +3 -0
  4. package/dist/chunks/FormBuilderView-B_KGPjlp.cjs.map +1 -0
  5. package/dist/chunks/FormBuilderView-D8DrQOXD.js +1090 -0
  6. package/dist/chunks/FormBuilderView-D8DrQOXD.js.map +1 -0
  7. package/dist/chunks/{approval-instance-list-page-C5ZKPHdA.cjs → approval-instance-list-page-BMUKxzcz.cjs} +2 -2
  8. package/dist/chunks/{approval-instance-list-page-C5ZKPHdA.cjs.map → approval-instance-list-page-BMUKxzcz.cjs.map} +1 -1
  9. package/dist/chunks/{approval-instance-list-page-BF2r5D2-.js → approval-instance-list-page-YZcGGDD8.js} +2 -2
  10. package/dist/chunks/{approval-instance-list-page-BF2r5D2-.js.map → approval-instance-list-page-YZcGGDD8.js.map} +1 -1
  11. package/dist/chunks/compose-PMrmi-LE.js +451 -0
  12. package/dist/chunks/compose-PMrmi-LE.js.map +1 -0
  13. package/dist/chunks/compose-ziVbRYdo.cjs +2 -0
  14. package/dist/chunks/compose-ziVbRYdo.cjs.map +1 -0
  15. package/dist/chunks/{dashboard-page-Ib8srCMy.js → dashboard-page-DJ9vOPga.js} +2 -2
  16. package/dist/chunks/{dashboard-page-Ib8srCMy.js.map → dashboard-page-DJ9vOPga.js.map} +1 -1
  17. package/dist/chunks/{dashboard-page-CddG1MnK.cjs → dashboard-page-DwHQY6Ki.cjs} +2 -2
  18. package/dist/chunks/{dashboard-page-CddG1MnK.cjs.map → dashboard-page-DwHQY6Ki.cjs.map} +1 -1
  19. package/dist/chunks/designer-DCn6_v4b.cjs +65 -0
  20. package/dist/chunks/designer-DCn6_v4b.cjs.map +1 -0
  21. package/dist/chunks/designer-mOMxJ0Py.js +2576 -0
  22. package/dist/chunks/designer-mOMxJ0Py.js.map +1 -0
  23. package/dist/chunks/detail-Cci9tnoC.cjs +2 -0
  24. package/dist/chunks/detail-Cci9tnoC.cjs.map +1 -0
  25. package/dist/chunks/detail-kyolfdBu.js +1957 -0
  26. package/dist/chunks/detail-kyolfdBu.js.map +1 -0
  27. package/dist/chunks/{routes-config-dxahImVe.js → routes-config-RBYQtUd0.js} +2 -3
  28. package/dist/chunks/routes-config-RBYQtUd0.js.map +1 -0
  29. package/dist/chunks/routes-config-fDVHmvXi.cjs +2 -0
  30. package/dist/chunks/routes-config-fDVHmvXi.cjs.map +1 -0
  31. package/dist/index.cjs +1 -1
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.js +268 -128
  34. package/dist/index.js.map +1 -1
  35. package/dist/lib/routes-config.d.ts +6 -4
  36. package/dist/next/index.cjs +1 -1
  37. package/dist/next/index.js +1 -1
  38. package/dist/next/workflow-chat-route.cjs +19 -0
  39. package/dist/next/workflow-chat-route.cjs.map +1 -0
  40. package/dist/next/workflow-chat-route.d.ts +17 -0
  41. package/dist/next/workflow-chat-route.js +31 -0
  42. package/dist/next/workflow-chat-route.js.map +1 -0
  43. package/dist/pages/instances/detail/index.cjs +1 -1
  44. package/dist/pages/instances/detail/index.js +1 -1
  45. package/dist/pages/templates/compose/index.cjs +2 -0
  46. package/dist/pages/templates/compose/index.cjs.map +1 -0
  47. package/dist/pages/templates/compose/index.d.ts +13 -0
  48. package/dist/pages/templates/compose/index.js +14 -0
  49. package/dist/pages/templates/compose/index.js.map +1 -0
  50. package/dist/pages/templates/designer/index.cjs +1 -1
  51. package/dist/pages/templates/designer/index.cjs.map +1 -1
  52. package/dist/pages/templates/designer/index.js +7 -2
  53. package/dist/pages/templates/designer/index.js.map +1 -1
  54. package/dist/pages/templates/index.cjs +1 -1
  55. package/dist/pages/templates/index.cjs.map +1 -1
  56. package/dist/pages/templates/index.js +3 -3
  57. package/dist/pages/templates/index.js.map +1 -1
  58. package/dist/views/cc/index.cjs +1 -1
  59. package/dist/views/cc/index.js +1 -1
  60. package/dist/views/dashboard/index.cjs +1 -1
  61. package/dist/views/dashboard/index.js +1 -1
  62. package/dist/views/forms/builder/FormBuilderView.d.ts +13 -4
  63. package/dist/views/forms/builder/index.cjs +1 -1
  64. package/dist/views/forms/builder/index.js +1 -1
  65. package/dist/views/forms/builder/json-code-editor.d.ts +1 -1
  66. package/dist/views/inbox/index.cjs +1 -1
  67. package/dist/views/inbox/index.js +1 -1
  68. package/dist/views/instances/detail/InstanceDetailView.d.ts +11 -1
  69. package/dist/views/instances/detail/index.cjs +1 -1
  70. package/dist/views/instances/detail/index.d.ts +5 -0
  71. package/dist/views/instances/detail/index.js +2 -2
  72. package/dist/views/instances/detail/sections/InstanceAttachmentsSection.d.ts +15 -0
  73. package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +33 -0
  74. package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +29 -0
  75. package/dist/views/instances/detail/sections/InstanceSignaturesSection.d.ts +14 -0
  76. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +51 -0
  77. package/dist/views/instances/detail/sections/container-helpers.d.ts +9 -0
  78. package/dist/views/instances/detail/sections/shared.d.ts +103 -0
  79. package/dist/views/instances/new/index.cjs +1 -1
  80. package/dist/views/instances/new/index.js +1 -1
  81. package/dist/views/search/index.cjs +1 -1
  82. package/dist/views/search/index.js +1 -1
  83. package/dist/views/sent/index.cjs +1 -1
  84. package/dist/views/sent/index.js +1 -1
  85. package/dist/views/templates/TemplatesView.d.ts +5 -0
  86. package/dist/views/templates/compose/TemplateComposeWizardView.d.ts +8 -0
  87. package/dist/views/templates/compose/index.cjs +1 -0
  88. package/dist/views/templates/compose/index.d.ts +2 -0
  89. package/dist/views/templates/compose/index.js +2 -0
  90. package/dist/views/templates/compose/steps/ComposeFormStep.d.ts +15 -0
  91. package/dist/views/templates/compose/steps/ComposeReviewStep.d.ts +12 -0
  92. package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +11 -0
  93. package/dist/views/templates/compose/use-template-compose-wizard.d.ts +46 -0
  94. package/dist/views/templates/designer/TemplateDesignerView.d.ts +60 -2
  95. package/dist/views/templates/designer/chrome-workflow-chat.d.ts +12 -0
  96. package/dist/views/templates/designer/index.cjs +1 -51
  97. package/dist/views/templates/designer/index.js +2 -2272
  98. package/dist/views/templates/designer/use-workflow-chat.d.ts +21 -0
  99. package/dist/views/templates/designer/use-workflow-designer-controller.d.ts +41 -0
  100. package/dist/views/templates/designer/workflow-chat-drawer.d.ts +16 -0
  101. package/dist/views/templates/index.cjs +2 -1
  102. package/dist/views/templates/index.cjs.map +1 -0
  103. package/dist/views/templates/index.js +265 -4
  104. package/dist/views/templates/index.js.map +1 -0
  105. package/dist/views/templates/versions/index.cjs +1 -1
  106. package/dist/views/templates/versions/index.cjs.map +1 -1
  107. package/dist/views/templates/versions/index.js +38 -42
  108. package/dist/views/templates/versions/index.js.map +1 -1
  109. package/package.json +22 -19
  110. package/dist/chunks/builder-BLVnnpnP.js +0 -1300
  111. package/dist/chunks/builder-BLVnnpnP.js.map +0 -1
  112. package/dist/chunks/builder-DVE9zIKH.cjs +0 -3
  113. package/dist/chunks/builder-DVE9zIKH.cjs.map +0 -1
  114. package/dist/chunks/detail-Dcr5mM8g.cjs +0 -2
  115. package/dist/chunks/detail-Dcr5mM8g.cjs.map +0 -1
  116. package/dist/chunks/detail-u9DdLhDW.js +0 -1518
  117. package/dist/chunks/detail-u9DdLhDW.js.map +0 -1
  118. package/dist/chunks/form-name-modal-C3OEvkCV.js +0 -64
  119. package/dist/chunks/form-name-modal-C3OEvkCV.js.map +0 -1
  120. package/dist/chunks/form-name-modal-uZCHbtRH.cjs +0 -2
  121. package/dist/chunks/form-name-modal-uZCHbtRH.cjs.map +0 -1
  122. package/dist/chunks/routes-config-2aKbWq2H.cjs +0 -2
  123. package/dist/chunks/routes-config-2aKbWq2H.cjs.map +0 -1
  124. package/dist/chunks/routes-config-dxahImVe.js.map +0 -1
  125. package/dist/chunks/templates-D44FSB46.js +0 -380
  126. package/dist/chunks/templates-D44FSB46.js.map +0 -1
  127. package/dist/chunks/templates-w96t83N-.cjs +0 -2
  128. package/dist/chunks/templates-w96t83N-.cjs.map +0 -1
  129. package/dist/pages/forms/builder/index.cjs +0 -2
  130. package/dist/pages/forms/builder/index.cjs.map +0 -1
  131. package/dist/pages/forms/builder/index.d.ts +0 -21
  132. package/dist/pages/forms/builder/index.js +0 -15
  133. package/dist/pages/forms/builder/index.js.map +0 -1
  134. package/dist/pages/forms/index.cjs +0 -2
  135. package/dist/pages/forms/index.cjs.map +0 -1
  136. package/dist/pages/forms/index.d.ts +0 -17
  137. package/dist/pages/forms/index.js +0 -14
  138. package/dist/pages/forms/index.js.map +0 -1
  139. package/dist/views/forms/FormsView.d.ts +0 -2
  140. package/dist/views/forms/form-name-modal.d.ts +0 -12
  141. package/dist/views/forms/index.cjs +0 -2
  142. package/dist/views/forms/index.cjs.map +0 -1
  143. package/dist/views/forms/index.d.ts +0 -2
  144. package/dist/views/forms/index.js +0 -186
  145. package/dist/views/forms/index.js.map +0 -1
  146. package/dist/views/templates/designer/index.cjs.map +0 -1
  147. package/dist/views/templates/designer/index.js.map +0 -1
  148. package/dist/views/templates/template-name-modal.d.ts +0 -22
@@ -1,380 +0,0 @@
1
- "use client";
2
- import { r as e } from "./router-adapter-DftlFTOd.js";
3
- import { t } from "./format-date-time-CB-LxzqT.js";
4
- import { r as n } from "./routes-config-dxahImVe.js";
5
- import { t as r } from "./bpm-form-field-Cao0rMol.js";
6
- import { n as i } from "./categories-DBPoSrsi.js";
7
- import { useCallback as a, useEffect as o, useMemo as s, useState as c } from "react";
8
- import { Badge as l, Button as u, Filter as d, FilterArea as f, FilterLine as p, FormField as m, Input as h, Modal as g, PageHeader as _, Section as v, SectionGroup as y, Select as b, Tab as x, TabItem as ee, Table as S, Typography as C } from "@mezzanine-ui/react";
9
- import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
10
- import { listLaunchableTemplates as te } from "@rytass/bpm-core-client/workflow";
11
- import ne from "@mezzanine-ui/react/ContentHeader";
12
- import { FormFieldLayout as D } from "@mezzanine-ui/core/form";
13
- import { PlusIcon as re } from "@mezzanine-ui/icons";
14
- import { createApprovalTemplate as O, listApprovalTemplateCategoriesPage as k, listApprovalTemplatesPage as ie } from "@rytass/bpm-core-client/template";
15
- //#region src/views/templates/template-name-modal.tsx
16
- function ae({ confirmText: e, categoryOptions: t, initialName: n, loading: i, onClose: a, onSubmit: s, open: l, title: u }) {
17
- let [d, f] = c(n), [p, m] = c(t[0] ?? j), [_, v] = c(null), y = d.trim();
18
- o(() => {
19
- l && (f(n), m(t[0] ?? j), v(null));
20
- }, [
21
- t,
22
- n,
23
- l
24
- ]);
25
- async function x() {
26
- if (!y) {
27
- v("請輸入模板名稱");
28
- return;
29
- }
30
- try {
31
- await s({
32
- categoryId: p.categoryId,
33
- name: y
34
- });
35
- } catch (e) {
36
- v(A(e));
37
- }
38
- }
39
- return /* @__PURE__ */ E(g, {
40
- cancelText: "取消",
41
- confirmButtonProps: { disabled: !y },
42
- confirmText: e,
43
- loading: i,
44
- modalType: "standard",
45
- onCancel: a,
46
- onClose: a,
47
- onConfirm: () => void x(),
48
- open: l,
49
- showModalFooter: !0,
50
- showModalHeader: !0,
51
- size: "narrow",
52
- title: u,
53
- children: [
54
- /* @__PURE__ */ T(r, {
55
- label: "模板名稱",
56
- name: "templateName",
57
- required: !0,
58
- children: /* @__PURE__ */ T(h, {
59
- autoFocus: !0,
60
- fullWidth: !0,
61
- onChange: (e) => {
62
- f(e.target.value), v(null);
63
- },
64
- placeholder: "例如:費用申請流程",
65
- value: d,
66
- variant: "base"
67
- })
68
- }),
69
- /* @__PURE__ */ T(r, {
70
- label: "分類",
71
- name: "templateCategory",
72
- children: /* @__PURE__ */ T(b, {
73
- clearable: !1,
74
- fullWidth: !0,
75
- onChange: (e) => {
76
- m(M(e, t)), v(null);
77
- },
78
- options: [...t],
79
- placeholder: "選擇分類",
80
- value: p
81
- })
82
- }),
83
- _ ? /* @__PURE__ */ T(C, {
84
- color: "text-error",
85
- variant: "body",
86
- children: _
87
- }) : null
88
- ]
89
- });
90
- }
91
- function A(e) {
92
- return e instanceof Error ? e.message : "發生未知錯誤";
93
- }
94
- var j = {
95
- categoryId: null,
96
- id: "UNCATEGORIZED",
97
- name: "未分類"
98
- };
99
- function M(e, t) {
100
- if (!N(e)) return j;
101
- let n = typeof e.id == "string" ? e.id : null;
102
- return t.find((e) => e.id === n) ?? j;
103
- }
104
- function N(e) {
105
- return typeof e == "object" && !!e;
106
- }
107
- //#endregion
108
- //#region src/views/templates/TemplatesView.tsx
109
- var oe = [
110
- 10,
111
- 20,
112
- 50
113
- ], se = [
114
- {
115
- key: "ALL",
116
- label: "全部"
117
- },
118
- {
119
- key: "PUBLISHED",
120
- label: "已發布"
121
- },
122
- {
123
- key: "DRAFT",
124
- label: "草稿"
125
- }
126
- ], ce = 100;
127
- function P() {
128
- let r = e(), l = n(), [g, A] = c([]), [M, N] = c(F), [P, B] = c([]), [V, pe] = c(/* @__PURE__ */ new Set()), [me, H] = c(!1), [U, W] = c(!1), [G, K] = c(null), [he, q] = c(!0), [J, Y] = c(1), [X, ge] = c(10), [Z, _e] = c(""), [Q, ve] = c("ALL"), [ye, be] = c(0), $ = a(async () => {
129
- q(!0), K(null);
130
- try {
131
- let [e, t, n] = await Promise.all([
132
- ie({
133
- categoryId: M.categoryId,
134
- page: J,
135
- pageSize: X,
136
- searchText: Z,
137
- status: Q === "ALL" ? null : Q
138
- }),
139
- te(),
140
- k({
141
- page: 1,
142
- pageSize: ce,
143
- searchText: "",
144
- status: "ACTIVE"
145
- })
146
- ]);
147
- B([...n.categories.map(I)]), A(e.templates), be(e.totalCount), pe(new Set(t.map((e) => e.id)));
148
- } catch (e) {
149
- K(le(e));
150
- } finally {
151
- q(!1);
152
- }
153
- }, [
154
- M,
155
- J,
156
- X,
157
- Z,
158
- Q
159
- ]);
160
- o(() => {
161
- $();
162
- }, [$]);
163
- let xe = s(() => g.map((e) => ({
164
- ...e,
165
- categoryLabel: z(e),
166
- key: e.id,
167
- status: e.currentVersionId ? "PUBLISHED" : "DRAFT",
168
- updatedAt: t(e.updatedAt)
169
- })), [g]), Se = s(() => [
170
- {
171
- dataIndex: "name",
172
- key: "name",
173
- title: "模板名稱",
174
- width: 220
175
- },
176
- {
177
- key: "status",
178
- render: (e) => /* @__PURE__ */ T(de, { status: e.status }),
179
- title: "狀態",
180
- width: 120
181
- },
182
- {
183
- key: "category",
184
- render: (e) => /* @__PURE__ */ T(fe, { record: e }),
185
- title: "分類",
186
- width: 160
187
- },
188
- {
189
- dataIndex: "updatedAt",
190
- key: "updatedAt",
191
- title: "更新時間",
192
- width: 220
193
- }
194
- ], []), Ce = s(() => ({
195
- render: (e) => [
196
- {
197
- disabled: (e) => !V.has(e.id),
198
- name: "發起",
199
- onClick: () => r.push(l.caseNew(e.id)),
200
- variant: "base-primary"
201
- },
202
- {
203
- name: "設計",
204
- onClick: () => r.push(l.templateDesigner(e.id))
205
- },
206
- {
207
- name: "版本",
208
- onClick: () => r.push(l.templateVersions(e.id))
209
- }
210
- ],
211
- variant: "base-secondary",
212
- width: 192
213
- }), [V, r]);
214
- async function we({ categoryId: e, name: t }) {
215
- W(!0), K(null);
216
- try {
217
- let n = await O({
218
- categoryId: e,
219
- name: t
220
- });
221
- H(!1), r.push(l.templateDesigner(n));
222
- } finally {
223
- W(!1);
224
- }
225
- }
226
- return /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ E(w, { children: [/* @__PURE__ */ T(_, { children: /* @__PURE__ */ T(ne, {
227
- description: "建立流程模板、維護草稿與發布版本。",
228
- title: "簽核模板",
229
- children: /* @__PURE__ */ T(u, {
230
- disabled: U,
231
- icon: re,
232
- iconType: "leading",
233
- onClick: () => H(!0),
234
- variant: "base-primary",
235
- children: "建立模板"
236
- })
237
- }) }), /* @__PURE__ */ T(y, { children: /* @__PURE__ */ E(v, {
238
- filterArea: /* @__PURE__ */ T(f, {
239
- className: i.templateFilterArea,
240
- size: "sub",
241
- children: /* @__PURE__ */ E(p, { children: [/* @__PURE__ */ T(d, {
242
- span: 3,
243
- children: /* @__PURE__ */ T(m, {
244
- fullWidth: !0,
245
- layout: D.VERTICAL,
246
- name: "templateSearchText",
247
- children: /* @__PURE__ */ T(h, {
248
- fullWidth: !0,
249
- onChange: (e) => {
250
- _e(e.target.value), Y(1);
251
- },
252
- placeholder: "關鍵字:搜尋模板名稱、分類或描述",
253
- size: "sub",
254
- value: Z,
255
- variant: "base"
256
- })
257
- })
258
- }), /* @__PURE__ */ T(d, {
259
- span: 2,
260
- children: /* @__PURE__ */ T(m, {
261
- fullWidth: !0,
262
- layout: D.VERTICAL,
263
- name: "templateCategoryFilter",
264
- children: /* @__PURE__ */ T(b, {
265
- clearable: !1,
266
- fullWidth: !0,
267
- onChange: (e) => {
268
- N(L(e, P)), Y(1);
269
- },
270
- options: [F, ...P],
271
- placeholder: "分類",
272
- renderValue: (e) => `分類:${R(e)}`,
273
- size: "sub",
274
- value: M
275
- })
276
- })
277
- })] })
278
- }),
279
- tab: /* @__PURE__ */ T(x, {
280
- activeKey: Q,
281
- onChange: (e) => {
282
- ve(ue(e)), Y(1);
283
- },
284
- children: se.map((e) => /* @__PURE__ */ T(ee, { children: e.label }, e.key))
285
- }),
286
- children: [G ? /* @__PURE__ */ T(C, {
287
- color: "text-error",
288
- variant: "body",
289
- children: G
290
- }) : null, /* @__PURE__ */ T(S, {
291
- actions: Ce,
292
- columns: Se,
293
- dataSource: xe,
294
- fullWidth: !0,
295
- loading: he,
296
- pagination: {
297
- current: J,
298
- onChange: (e) => {
299
- Y(e);
300
- },
301
- onChangePageSize: (e) => {
302
- Y(1), ge(e);
303
- },
304
- pageSize: X,
305
- pageSizeLabel: "每頁筆數",
306
- pageSizeOptions: oe,
307
- renderResultSummary: (e, t, n) => `顯示 ${e}-${t} 筆,共 ${n} 筆`,
308
- showPageSizeOptions: !0,
309
- total: ye
310
- }
311
- })]
312
- }) })] }), /* @__PURE__ */ T(ae, {
313
- categoryOptions: [j, ...P],
314
- confirmText: "建立",
315
- initialName: "",
316
- loading: U,
317
- onClose: () => H(!1),
318
- onSubmit: we,
319
- open: me,
320
- title: "建立簽核模板"
321
- })] });
322
- }
323
- function le(e) {
324
- return e instanceof Error ? e.message : "發生未知錯誤";
325
- }
326
- function ue(e) {
327
- return e === "PUBLISHED" || e === "DRAFT" ? e : "ALL";
328
- }
329
- function de({ status: e }) {
330
- return e === "PUBLISHED" ? /* @__PURE__ */ T(l, {
331
- size: "sub",
332
- text: "已發布",
333
- variant: "dot-success"
334
- }) : /* @__PURE__ */ T(l, {
335
- size: "sub",
336
- text: "草稿",
337
- variant: "dot-inactive"
338
- });
339
- }
340
- function fe({ record: e }) {
341
- return e.categoryDetail?.isActive === !1 ? /* @__PURE__ */ T(l, {
342
- size: "sub",
343
- text: `${e.categoryLabel}(停用)`,
344
- variant: "dot-inactive"
345
- }) : /* @__PURE__ */ T(C, {
346
- component: "span",
347
- variant: "body",
348
- children: e.categoryLabel
349
- });
350
- }
351
- var F = {
352
- categoryId: null,
353
- id: "ALL_CATEGORIES",
354
- name: "全部分類"
355
- };
356
- function I(e) {
357
- return {
358
- categoryId: e.id,
359
- id: e.id,
360
- name: e.name
361
- };
362
- }
363
- function L(e, t) {
364
- if (!B(e)) return F;
365
- let n = typeof e.id == "string" ? e.id : null;
366
- return n === F.id ? F : t.find((e) => e.id === n) ?? F;
367
- }
368
- function R(e) {
369
- return Array.isArray(e) || !B(e) ? F.name : typeof e.name == "string" ? e.name : F.name;
370
- }
371
- function z(e) {
372
- return e.categoryDetail?.name ?? e.category ?? "未分類";
373
- }
374
- function B(e) {
375
- return typeof e == "object" && !!e;
376
- }
377
- //#endregion
378
- export { P as t };
379
-
380
- //# sourceMappingURL=templates-D44FSB46.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"templates-D44FSB46.js","names":[],"sources":["../../src/views/templates/template-name-modal.tsx","../../src/views/templates/TemplatesView.tsx"],"sourcesContent":["'use client';\n\nimport { ChangeEvent, ReactElement, useEffect, useState } from 'react';\nimport { Input, Modal, Select, Typography } from '@mezzanine-ui/react';\nimport { BPMFormField } from '../../components/bpm-form-field';\n\nexport interface TemplateCategoryOption {\n readonly categoryId: string | null;\n readonly id: string;\n readonly name: string;\n}\n\ninterface TemplateNameModalProps {\n readonly confirmText: string;\n readonly categoryOptions: readonly TemplateCategoryOption[];\n readonly initialName: string;\n readonly loading: boolean;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly categoryId: string | null;\n readonly name: string;\n }) => Promise<void>;\n readonly open: boolean;\n readonly title: string;\n}\n\nexport function TemplateNameModal({\n confirmText,\n categoryOptions,\n initialName,\n loading,\n onClose,\n onSubmit,\n open,\n title,\n}: TemplateNameModalProps): ReactElement {\n const [name, setName] = useState(initialName);\n const [category, setCategory] = useState<TemplateCategoryOption>(\n categoryOptions[0] ?? UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n );\n const [error, setError] = useState<string | null>(null);\n const trimmedName = name.trim();\n\n useEffect((): void => {\n if (!open) {\n return;\n }\n\n setName(initialName);\n setCategory(categoryOptions[0] ?? UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION);\n setError(null);\n }, [categoryOptions, initialName, open]);\n\n async function handleConfirm(): Promise<void> {\n if (!trimmedName) {\n setError('請輸入模板名稱');\n return;\n }\n\n try {\n await onSubmit({ categoryId: category.categoryId, name: trimmedName });\n } catch (submitError: unknown) {\n setError(readErrorMessage(submitError));\n }\n }\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !trimmedName }}\n confirmText={confirmText}\n loading={loading}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void => void handleConfirm()}\n open={open}\n showModalFooter\n showModalHeader\n size=\"narrow\"\n title={title}\n >\n <BPMFormField label=\"模板名稱\" name=\"templateName\" required>\n <Input\n autoFocus\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void => {\n setName(event.target.value);\n setError(null);\n }}\n placeholder=\"例如:費用申請流程\"\n value={name}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"分類\" name=\"templateCategory\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategory(readCategoryOption(option, categoryOptions));\n setError(null);\n }}\n options={[...categoryOptions]}\n placeholder=\"選擇分類\"\n value={category}\n />\n </BPMFormField>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n </Modal>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nexport const UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'UNCATEGORIZED',\n name: '未分類',\n};\n\nfunction readCategoryOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION\n );\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n","'use client';\n\nimport type { ChangeEvent, Key, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport styles from './templates.module.scss';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\nimport {\n TemplateCategoryOption,\n TemplateNameModal,\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n} from './template-name-modal';\nimport {\n ApprovalTemplateListStatus,\n ApprovalTemplateRecord,\n ApprovalTemplateCategoryRecord,\n createApprovalTemplate,\n listApprovalTemplateCategoriesPage,\n listApprovalTemplatesPage,\n} from '@rytass/bpm-core-client/template';\nimport { listLaunchableTemplates } from '@rytass/bpm-core-client/workflow';\n\nconst TEMPLATE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst TEMPLATE_STATUS_TABS: readonly {\n readonly key: TemplateStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'PUBLISHED', label: '已發布' },\n { key: 'DRAFT', label: '草稿' },\n];\n\nconst TEMPLATE_CATEGORY_PAGE_SIZE = 100;\n\ntype TemplateStatusTabKey = 'ALL' | ApprovalTemplateListStatus;\n\ntype TemplateRow = Readonly<\n Record<string, unknown> &\n ApprovalTemplateRecord & {\n categoryLabel: string;\n key: string;\n status: ApprovalTemplateListStatus;\n }\n>;\n\n\nexport function TemplatesView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [templates, setTemplates] = useState<readonly ApprovalTemplateRecord[]>(\n [],\n );\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategoryOption>(\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n );\n const [categoryOptions, setCategoryOptions] = useState<\n readonly TemplateCategoryOption[]\n >([]);\n const [launchableTemplateIds, setLaunchableTemplateIds] = useState<\n ReadonlySet<string>\n >(new Set());\n const [createModalOpen, setCreateModalOpen] = useState(false);\n const [creating, setCreating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [templatePage, setTemplatePage] = useState(1);\n const [templatePageSize, setTemplatePageSize] = useState(10);\n const [templateSearchText, setTemplateSearchText] = useState('');\n const [templateStatus, setTemplateStatus] =\n useState<TemplateStatusTabKey>('ALL');\n const [templateTotalCount, setTemplateTotalCount] = useState(0);\n\n const refreshTemplates = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const [\n templatePageResult,\n nextLaunchableTemplates,\n activeCategoryPageResult,\n ] = await Promise.all([\n listApprovalTemplatesPage({\n categoryId: categoryFilter.categoryId,\n page: templatePage,\n pageSize: templatePageSize,\n searchText: templateSearchText,\n status: templateStatus === 'ALL' ? null : templateStatus,\n }),\n listLaunchableTemplates(),\n listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: TEMPLATE_CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n }),\n ]);\n\n setCategoryOptions([\n ...activeCategoryPageResult.categories.map(readCategoryOption),\n ]);\n setTemplates(templatePageResult.templates);\n setTemplateTotalCount(templatePageResult.totalCount);\n setLaunchableTemplateIds(\n new Set(nextLaunchableTemplates.map((template) => template.id)),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [\n categoryFilter,\n templatePage,\n templatePageSize,\n templateSearchText,\n templateStatus,\n ]);\n\n useEffect((): void => {\n void refreshTemplates();\n }, [refreshTemplates]);\n\n const rows = useMemo(\n (): TemplateRow[] =>\n templates.map((template) => ({\n ...template,\n categoryLabel: readTemplateCategoryLabel(template),\n key: template.id,\n status: template.currentVersionId ? 'PUBLISHED' : 'DRAFT',\n updatedAt: formatDateTime(template.updatedAt),\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<TemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 220 },\n {\n key: 'status',\n render: (record: TemplateRow): ReactElement => (\n <TemplateStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'category',\n render: (record: TemplateRow): ReactElement => (\n <TemplateCategoryLabel record={record} />\n ),\n title: '分類',\n width: 160,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<TemplateRow> => ({\n render: (record): ReturnType<TableActions<TemplateRow>['render']> => [\n {\n disabled: (template): boolean =>\n !launchableTemplateIds.has(template.id),\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n {\n name: '設計',\n onClick: (): void => router.push(routes.templateDesigner(record.id)),\n },\n {\n name: '版本',\n onClick: (): void => router.push(routes.templateVersions(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 192,\n }),\n [launchableTemplateIds, router],\n );\n\n async function handleCreateTemplate({\n categoryId,\n name,\n }: {\n readonly categoryId: string | null;\n readonly name: string;\n }): Promise<void> {\n setCreating(true);\n setError(null);\n\n try {\n const templateId = await createApprovalTemplate({ categoryId, name });\n setCreateModalOpen(false);\n router.push(routes.templateDesigner(templateId));\n } finally {\n setCreating(false);\n }\n }\n\n return (\n <>\n <>\n <PageHeader>\n <ContentHeader\n description=\"建立流程模板、維護草稿與發布版本。\"\n title=\"簽核模板\"\n >\n <Button\n disabled={creating}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setCreateModalOpen(true)}\n variant=\"base-primary\"\n >\n 建立模板\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.templateFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setTemplateSearchText(event.target.value);\n setTemplatePage(1);\n }}\n placeholder=\"關鍵字:搜尋模板名稱、分類或描述\"\n size=\"sub\"\n value={templateSearchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateCategoryFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategoryFilter(\n readCategoryFilterOption(option, categoryOptions),\n );\n setTemplatePage(1);\n }}\n options={[\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n ...categoryOptions,\n ]}\n placeholder=\"分類\"\n renderValue={(value): string =>\n `分類:${readTemplateCategoryFilterLabel(value)}`\n }\n size=\"sub\"\n value={categoryFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={templateStatus}\n onChange={(activeKey): void => {\n setTemplateStatus(readTemplateStatusTabKey(activeKey));\n setTemplatePage(1);\n }}\n >\n {TEMPLATE_STATUS_TABS.map((statusTab) => (\n <TabItem key={statusTab.key}>{statusTab.label}</TabItem>\n ))}\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n pagination={{\n current: templatePage,\n onChange: (page): void => {\n setTemplatePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setTemplatePage(1);\n setTemplatePageSize(pageSize);\n },\n pageSize: templatePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: TEMPLATE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: templateTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n\n <TemplateNameModal\n categoryOptions={[\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n ...categoryOptions,\n ]}\n confirmText=\"建立\"\n initialName=\"\"\n loading={creating}\n onClose={(): void => setCreateModalOpen(false)}\n onSubmit={handleCreateTemplate}\n open={createModalOpen}\n title=\"建立簽核模板\"\n />\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nfunction readTemplateStatusTabKey(activeKey: Key): TemplateStatusTabKey {\n if (activeKey === 'PUBLISHED' || activeKey === 'DRAFT') {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction TemplateStatusBadge({\n status,\n}: {\n readonly status: ApprovalTemplateListStatus;\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateCategoryLabel({\n record,\n}: {\n readonly record: TemplateRow;\n}): ReactElement {\n if (record.categoryDetail?.isActive === false) {\n return (\n <Badge\n size=\"sub\"\n text={`${record.categoryLabel}(停用)`}\n variant=\"dot-inactive\"\n />\n );\n }\n\n return (\n <Typography component=\"span\" variant=\"body\">\n {record.categoryLabel}\n </Typography>\n );\n}\n\nconst UNCATEGORIZED_TEMPLATE_FILTER_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'ALL_CATEGORIES',\n name: '全部分類',\n};\n\nfunction readCategoryOption(\n category: ApprovalTemplateCategoryRecord,\n): TemplateCategoryOption {\n return {\n categoryId: category.id,\n id: category.id,\n name: category.name,\n };\n}\n\nfunction readCategoryFilterOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n if (id === UNCATEGORIZED_TEMPLATE_FILTER_OPTION.id) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION\n );\n}\n\nfunction readTemplateCategoryFilterLabel(value: unknown): string {\n if (Array.isArray(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n return typeof value.name === 'string'\n ? value.name\n : UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n}\n\nfunction readTemplateCategoryLabel(template: ApprovalTemplateRecord): string {\n return template.categoryDetail?.name ?? template.category ?? '未分類';\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":";;;;;;;;;;;;;;;AA0BA,SAAgB,GAAkB,EAChC,gBACA,oBACA,gBACA,YACA,YACA,aACA,SACA,YACuC;CACvC,IAAM,CAAC,GAAM,KAAW,EAAS,CAAW,GACtC,CAAC,GAAU,KAAe,EAC9B,EAAgB,MAAM,CACxB,GACM,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,IAAc,EAAK,KAAK;CAE9B,QAAsB;EACf,MAIL,EAAQ,CAAW,GACnB,EAAY,EAAgB,MAAM,CAAsC,GACxE,EAAS,IAAI;CACf,GAAG;EAAC;EAAiB;EAAa;CAAI,CAAC;CAEvC,eAAe,IAA+B;EAC5C,IAAI,CAAC,GAAa;GAChB,EAAS,SAAS;GAClB;EACF;EAEA,IAAI;GACF,MAAM,EAAS;IAAE,YAAY,EAAS;IAAY,MAAM;GAAY,CAAC;EACvE,SAAS,GAAsB;GAC7B,EAAS,EAAiB,CAAW,CAAC;EACxC;CACF;CAEA,OACE,kBAAC,GAAD;EACE,YAAW;EACX,oBAAoB,EAAE,UAAU,CAAC,EAAY;EAChC;EACJ;EACT,WAAU;EACV,UAAU;EACD;EACT,iBAAuB,KAAK,EAAc;EACpC;EACN,iBAAA;EACA,iBAAA;EACA,MAAK;EACE;YAbT;GAeE,kBAAC,GAAD;IAAc,OAAM;IAAO,MAAK;IAAe,UAAA;cAC7C,kBAAC,GAAD;KACE,WAAA;KACA,WAAA;KACA,WAAW,MAA+C;MAExD,AADA,EAAQ,EAAM,OAAO,KAAK,GAC1B,EAAS,IAAI;KACf;KACA,aAAY;KACZ,OAAO;KACP,SAAQ;IACT,CAAA;GACW,CAAA;GACd,kBAAC,GAAD;IAAc,OAAM;IAAK,MAAK;cAC5B,kBAAC,GAAD;KACE,WAAW;KACX,WAAA;KACA,WAAW,MAAiB;MAE1B,AADA,EAAY,EAAmB,GAAQ,CAAe,CAAC,GACvD,EAAS,IAAI;KACf;KACA,SAAS,CAAC,GAAG,CAAe;KAC5B,aAAY;KACZ,OAAO;IACR,CAAA;GACW,CAAA;GACb,IACC,kBAAC,GAAD;IAAY,OAAM;IAAa,SAAQ;cACpC;GACS,CAAA,IACV;EACC;;AAEX;AAEA,SAAS,EAAiB,GAAwB;CAChD,OAAO,aAAiB,QAAQ,EAAM,UAAU;AAClD;AAEA,IAAa,IAAiE;CAC5E,YAAY;CACZ,IAAI;CACJ,MAAM;AACR;AAEA,SAAS,EACP,GACA,GACwB;CACxB,IAAI,CAAC,EAAS,CAAK,GACjB,OAAO;CAGT,IAAM,IAAK,OAAO,EAAM,MAAO,WAAW,EAAM,KAAK;CAErD,OACE,EAAQ,MAAM,MAAW,EAAO,OAAO,CAAE,KACzC;AAEJ;AAEA,SAAS,EAAS,GAA4D;CAC5E,OAAO,OAAO,KAAU,cAAY;AACtC;;;ACrGA,IAAM,KAA6B;CAAC;CAAI;CAAI;AAAE,GACxC,KAGA;CACJ;EAAE,KAAK;EAAO,OAAO;CAAK;CAC1B;EAAE,KAAK;EAAa,OAAO;CAAM;CACjC;EAAE,KAAK;EAAS,OAAO;CAAK;AAC9B,GAEM,KAA8B;AAcpC,SAAgB,IAA8B;CAC5C,IAAM,IAAS,EAAiB,GAC1B,IAAS,EAAa,GACtB,CAAC,GAAW,KAAgB,EAChC,CAAC,CACH,GACM,CAAC,GAAgB,KAAqB,EAC1C,CACF,GACM,CAAC,GAAiB,KAAsB,EAE5C,CAAC,CAAC,GACE,CAAC,GAAuB,MAA4B,kBAExD,IAAI,IAAI,CAAC,GACL,CAAC,IAAiB,KAAsB,EAAS,EAAK,GACtD,CAAC,GAAU,KAAe,EAAS,EAAK,GACxC,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,IAAS,KAAc,EAAS,EAAI,GACrC,CAAC,GAAc,KAAmB,EAAS,CAAC,GAC5C,CAAC,GAAkB,MAAuB,EAAS,EAAE,GACrD,CAAC,GAAoB,MAAyB,EAAS,EAAE,GACzD,CAAC,GAAgB,MACrB,EAA+B,KAAK,GAChC,CAAC,IAAoB,MAAyB,EAAS,CAAC,GAExD,IAAmB,EAAY,YAA2B;EAE9D,AADA,EAAW,EAAI,GACf,EAAS,IAAI;EAEb,IAAI;GACF,IAAM,CACJ,GACA,GACA,KACE,MAAM,QAAQ,IAAI;IACpB,GAA0B;KACxB,YAAY,EAAe;KAC3B,MAAM;KACN,UAAU;KACV,YAAY;KACZ,QAAQ,MAAmB,QAAQ,OAAO;IAC5C,CAAC;IACD,GAAwB;IACxB,EAAmC;KACjC,MAAM;KACN,UAAU;KACV,YAAY;KACZ,QAAQ;IACV,CAAC;GACH,CAAC;GAOD,AALA,EAAmB,CACjB,GAAG,EAAyB,WAAW,IAAI,CAAkB,CAC/D,CAAC,GACD,EAAa,EAAmB,SAAS,GACzC,GAAsB,EAAmB,UAAU,GACnD,GACE,IAAI,IAAI,EAAwB,KAAK,MAAa,EAAS,EAAE,CAAC,CAChE;EACF,SAAS,GAAuB;GAC9B,EAAS,GAAiB,CAAY,CAAC;EACzC,UAAU;GACR,EAAW,EAAK;EAClB;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,QAAsB;EACpB,EAAsB;CACxB,GAAG,CAAC,CAAgB,CAAC;CAErB,IAAM,KAAO,QAET,EAAU,KAAK,OAAc;EAC3B,GAAG;EACH,eAAe,EAA0B,CAAQ;EACjD,KAAK,EAAS;EACd,QAAQ,EAAS,mBAAmB,cAAc;EAClD,WAAW,EAAe,EAAS,SAAS;CAC9C,EAAE,GACJ,CAAC,CAAS,CACZ,GACM,KAAU,QACoB;EAChC;GAAE,WAAW;GAAQ,KAAK;GAAQ,OAAO;GAAQ,OAAO;EAAI;EAC5D;GACE,KAAK;GACL,SAAS,MACP,kBAAC,IAAD,EAAqB,QAAQ,EAAO,OAAS,CAAA;GAE/C,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAAC,IAAD,EAA+B,UAAS,CAAA;GAE1C,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH,GACM,KAAe,SACe;EAChC,SAAS,MAA4D;GACnE;IACE,WAAW,MACT,CAAC,EAAsB,IAAI,EAAS,EAAE;IACxC,MAAM;IACN,eACE,EAAO,KAAK,EAAO,QAAQ,EAAO,EAAE,CAAC;IACvC,SAAS;GACX;GACA;IACE,MAAM;IACN,eAAqB,EAAO,KAAK,EAAO,iBAAiB,EAAO,EAAE,CAAC;GACrE;GACA;IACE,MAAM;IACN,eAAqB,EAAO,KAAK,EAAO,iBAAiB,EAAO,EAAE,CAAC;GACrE;EACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAAC,GAAuB,CAAM,CAChC;CAEA,eAAe,GAAqB,EAClC,eACA,WAIgB;EAEhB,AADA,EAAY,EAAI,GAChB,EAAS,IAAI;EAEb,IAAI;GACF,IAAM,IAAa,MAAM,EAAuB;IAAE;IAAY;GAAK,CAAC;GAEpE,AADA,EAAmB,EAAK,GACxB,EAAO,KAAK,EAAO,iBAAiB,CAAU,CAAC;EACjD,UAAU;GACR,EAAY,EAAK;EACnB;CACF;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAA,GAAA,EAAA,UAAA,CACI,kBAAC,GAAD,EAAA,UACE,kBAAC,IAAD;EACE,aAAY;EACZ,OAAM;YAEN,kBAAC,GAAD;GACE,UAAU;GACV,MAAM;GACN,UAAS;GACT,eAAqB,EAAmB,EAAI;GAC5C,SAAQ;aACT;EAEO,CAAA;CACK,CAAA,EACL,CAAA,GAEZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;EACE,YACE,kBAAC,GAAD;GAAY,WAAW,EAAO;GAAoB,MAAK;aACrD,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;IAAQ,MAAM;cACZ,kBAAC,GAAD;KACE,WAAA;KACA,QAAQ,EAAgB;KACxB,MAAK;eAEL,kBAAC,GAAD;MACE,WAAA;MACA,WACE,MACS;OAET,AADA,GAAsB,EAAM,OAAO,KAAK,GACxC,EAAgB,CAAC;MACnB;MACA,aAAY;MACZ,MAAK;MACL,OAAO;MACP,SAAQ;KACT,CAAA;IACQ,CAAA;GACL,CAAA,GACR,kBAAC,GAAD;IAAQ,MAAM;cACZ,kBAAC,GAAD;KACE,WAAA;KACA,QAAQ,EAAgB;KACxB,MAAK;eAEL,kBAAC,GAAD;MACE,WAAW;MACX,WAAA;MACA,WAAW,MAAiB;OAI1B,AAHA,EACE,EAAyB,GAAQ,CAAe,CAClD,GACA,EAAgB,CAAC;MACnB;MACA,SAAS,CACP,GACA,GAAG,CACL;MACA,aAAY;MACZ,cAAc,MACZ,MAAM,EAAgC,CAAK;MAE7C,MAAK;MACL,OAAO;KACR,CAAA;IACQ,CAAA;GACL,CAAA,CACE,EAAA,CAAA;EACF,CAAA;EAEd,KACE,kBAAC,GAAD;GACE,WAAW;GACX,WAAW,MAAoB;IAE7B,AADA,GAAkB,GAAyB,CAAS,CAAC,GACrD,EAAgB,CAAC;GACnB;aAEC,GAAqB,KAAK,MACzB,kBAAC,IAAD,EAAA,UAA8B,EAAU,MAAe,GAAzC,EAAU,GAA+B,CACxD;EACE,CAAA;YAnET,CAsEG,IACC,kBAAC,GAAD;GAAY,OAAM;GAAa,SAAQ;aACpC;EACS,CAAA,IACV,MACJ,kBAAC,GAAD;GACE,SAAS;GACA;GACT,YAAY;GACZ,WAAA;GACS;GACT,YAAY;IACV,SAAS;IACT,WAAW,MAAe;KACxB,EAAgB,CAAI;IACtB;IACA,mBAAmB,MAAmB;KAEpC,AADA,EAAgB,CAAC,GACjB,GAAoB,CAAQ;IAC9B;IACA,UAAU;IACV,eAAe;IACf,iBAAiB;IACjB,sBAAsB,GAAM,GAAI,MAC9B,MAAM,EAAK,GAAG,EAAG,OAAO,EAAM;IAChC,qBAAqB;IACrB,OAAO;GACT;EACD,CAAA,CACM;IACG,CAAA,CACd,EAAA,CAAA,GAEJ,kBAAC,IAAD;EACE,iBAAiB,CACf,GACA,GAAG,CACL;EACA,aAAY;EACZ,aAAY;EACZ,SAAS;EACT,eAAqB,EAAmB,EAAK;EAC7C,UAAU;EACV,MAAM;EACN,OAAM;CACP,CAAA,CACD,EAAA,CAAA;AAEN;AAEA,SAAS,GAAiB,GAAwB;CAChD,OAAO,aAAiB,QAAQ,EAAM,UAAU;AAClD;AAEA,SAAS,GAAyB,GAAsC;CAKtE,OAJI,MAAc,eAAe,MAAc,UACtC,IAGF;AACT;AAEA,SAAS,GAAoB,EAC3B,aAGe;CAKf,OAJI,MAAW,cACN,kBAAC,GAAD;EAAO,MAAK;EAAM,MAAK;EAAM,SAAQ;CAAe,CAAA,IAGtD,kBAAC,GAAD;EAAO,MAAK;EAAM,MAAK;EAAK,SAAQ;CAAgB,CAAA;AAC7D;AAEA,SAAS,GAAsB,EAC7B,aAGe;CAWf,OAVI,EAAO,gBAAgB,aAAa,KAEpC,kBAAC,GAAD;EACE,MAAK;EACL,MAAM,GAAG,EAAO,cAAc;EAC9B,SAAQ;CACT,CAAA,IAKH,kBAAC,GAAD;EAAY,WAAU;EAAO,SAAQ;YAClC,EAAO;CACE,CAAA;AAEhB;AAEA,IAAM,IAA+D;CACnE,YAAY;CACZ,IAAI;CACJ,MAAM;AACR;AAEA,SAAS,EACP,GACwB;CACxB,OAAO;EACL,YAAY,EAAS;EACrB,IAAI,EAAS;EACb,MAAM,EAAS;CACjB;AACF;AAEA,SAAS,EACP,GACA,GACwB;CACxB,IAAI,CAAC,EAAS,CAAK,GACjB,OAAO;CAGT,IAAM,IAAK,OAAO,EAAM,MAAO,WAAW,EAAM,KAAK;CAMrD,OAJI,MAAO,EAAqC,KACvC,IAIP,EAAQ,MAAM,MAAW,EAAO,OAAO,CAAE,KACzC;AAEJ;AAEA,SAAS,EAAgC,GAAwB;CAS/D,OARI,MAAM,QAAQ,CAAK,KAInB,CAAC,EAAS,CAAK,IACV,EAAqC,OAGvC,OAAO,EAAM,QAAS,WACzB,EAAM,OACN,EAAqC;AAC3C;AAEA,SAAS,EAA0B,GAA0C;CAC3E,OAAO,EAAS,gBAAgB,QAAQ,EAAS,YAAY;AAC/D;AAEA,SAAS,EAAS,GAA4D;CAC5E,OAAO,OAAO,KAAU,cAAY;AACtC"}
@@ -1,2 +0,0 @@
1
- "use client";const e=require("./chunk-CMqjfN_6.cjs"),t=require("./router-adapter--gYs13E8.cjs"),n=require("./format-date-time-XxBzF0F5.cjs"),r=require("./routes-config-2aKbWq2H.cjs"),i=require("./bpm-form-field-Bc6k4ZEO.cjs"),a=require("./categories-B6QZKZRt.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@rytass/bpm-core-client/workflow"),u=require("@mezzanine-ui/react/ContentHeader");u=e.t(u,1);let d=require("@mezzanine-ui/core/form"),f=require("@mezzanine-ui/icons"),p=require("@rytass/bpm-core-client/template");function m({confirmText:e,categoryOptions:t,initialName:n,loading:r,onClose:a,onSubmit:l,open:u,title:d}){let[f,p]=(0,o.useState)(n),[m,v]=(0,o.useState)(t[0]??g),[y,b]=(0,o.useState)(null),x=f.trim();(0,o.useEffect)(()=>{u&&(p(n),v(t[0]??g),b(null))},[t,n,u]);async function S(){if(!x){b(`請輸入模板名稱`);return}try{await l({categoryId:m.categoryId,name:x})}catch(e){b(h(e))}}return(0,c.jsxs)(s.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!x},confirmText:e,loading:r,modalType:`standard`,onCancel:a,onClose:a,onConfirm:()=>void S(),open:u,showModalFooter:!0,showModalHeader:!0,size:`narrow`,title:d,children:[(0,c.jsx)(i.t,{label:`模板名稱`,name:`templateName`,required:!0,children:(0,c.jsx)(s.Input,{autoFocus:!0,fullWidth:!0,onChange:e=>{p(e.target.value),b(null)},placeholder:`例如:費用申請流程`,value:f,variant:`base`})}),(0,c.jsx)(i.t,{label:`分類`,name:`templateCategory`,children:(0,c.jsx)(s.Select,{clearable:!1,fullWidth:!0,onChange:e=>{v(_(e,t)),b(null)},options:[...t],placeholder:`選擇分類`,value:m})}),y?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:y}):null]})}function h(e){return e instanceof Error?e.message:`發生未知錯誤`}var g={categoryId:null,id:`UNCATEGORIZED`,name:`未分類`};function _(e,t){if(!v(e))return g;let n=typeof e.id==`string`?e.id:null;return t.find(e=>e.id===n)??g}function v(e){return typeof e==`object`&&!!e}var y=[10,20,50],b=[{key:`ALL`,label:`全部`},{key:`PUBLISHED`,label:`已發布`},{key:`DRAFT`,label:`草稿`}],x=100;function S(){let e=t.r(),i=r.r(),[h,_]=(0,o.useState)([]),[v,S]=(0,o.useState)(E),[j,M]=(0,o.useState)([]),[N,P]=(0,o.useState)(new Set),[F,I]=(0,o.useState)(!1),[L,R]=(0,o.useState)(!1),[z,B]=(0,o.useState)(null),[V,H]=(0,o.useState)(!0),[U,W]=(0,o.useState)(1),[G,K]=(0,o.useState)(10),[q,J]=(0,o.useState)(``),[Y,X]=(0,o.useState)(`ALL`),[Z,Q]=(0,o.useState)(0),$=(0,o.useCallback)(async()=>{H(!0),B(null);try{let[e,t,n]=await Promise.all([(0,p.listApprovalTemplatesPage)({categoryId:v.categoryId,page:U,pageSize:G,searchText:q,status:Y===`ALL`?null:Y}),(0,l.listLaunchableTemplates)(),(0,p.listApprovalTemplateCategoriesPage)({page:1,pageSize:x,searchText:``,status:`ACTIVE`})]);M([...n.categories.map(D)]),_(e.templates),Q(e.totalCount),P(new Set(t.map(e=>e.id)))}catch(e){B(ee(e))}finally{H(!1)}},[v,U,G,q,Y]);(0,o.useEffect)(()=>{$()},[$]);let te=(0,o.useMemo)(()=>h.map(e=>({...e,categoryLabel:A(e),key:e.id,status:e.currentVersionId?`PUBLISHED`:`DRAFT`,updatedAt:n.t(e.updatedAt)})),[h]),ne=(0,o.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`模板名稱`,width:220},{key:`status`,render:e=>(0,c.jsx)(w,{status:e.status}),title:`狀態`,width:120},{key:`category`,render:e=>(0,c.jsx)(T,{record:e}),title:`分類`,width:160},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:220}],[]),re=(0,o.useMemo)(()=>({render:t=>[{disabled:e=>!N.has(e.id),name:`發起`,onClick:()=>e.push(i.caseNew(t.id)),variant:`base-primary`},{name:`設計`,onClick:()=>e.push(i.templateDesigner(t.id))},{name:`版本`,onClick:()=>e.push(i.templateVersions(t.id))}],variant:`base-secondary`,width:192}),[N,e]);async function ie({categoryId:t,name:n}){R(!0),B(null);try{let r=await(0,p.createApprovalTemplate)({categoryId:t,name:n});I(!1),e.push(i.templateDesigner(r))}finally{R(!1)}}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(u.default,{description:`建立流程模板、維護草稿與發布版本。`,title:`簽核模板`,children:(0,c.jsx)(s.Button,{disabled:L,icon:f.PlusIcon,iconType:`leading`,onClick:()=>I(!0),variant:`base-primary`,children:`建立模板`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{filterArea:(0,c.jsx)(s.FilterArea,{className:a.n.templateFilterArea,size:`sub`,children:(0,c.jsxs)(s.FilterLine,{children:[(0,c.jsx)(s.Filter,{span:3,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:d.FormFieldLayout.VERTICAL,name:`templateSearchText`,children:(0,c.jsx)(s.Input,{fullWidth:!0,onChange:e=>{J(e.target.value),W(1)},placeholder:`關鍵字:搜尋模板名稱、分類或描述`,size:`sub`,value:q,variant:`base`})})}),(0,c.jsx)(s.Filter,{span:2,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:d.FormFieldLayout.VERTICAL,name:`templateCategoryFilter`,children:(0,c.jsx)(s.Select,{clearable:!1,fullWidth:!0,onChange:e=>{S(O(e,j)),W(1)},options:[E,...j],placeholder:`分類`,renderValue:e=>`分類:${k(e)}`,size:`sub`,value:v})})})]})}),tab:(0,c.jsx)(s.Tab,{activeKey:Y,onChange:e=>{X(C(e)),W(1)},children:b.map(e=>(0,c.jsx)(s.TabItem,{children:e.label},e.key))}),children:[z?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:z}):null,(0,c.jsx)(s.Table,{actions:re,columns:ne,dataSource:te,fullWidth:!0,loading:V,pagination:{current:U,onChange:e=>{W(e)},onChangePageSize:e=>{W(1),K(e)},pageSize:G,pageSizeLabel:`每頁筆數`,pageSizeOptions:y,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:Z}})]})})]}),(0,c.jsx)(m,{categoryOptions:[g,...j],confirmText:`建立`,initialName:``,loading:L,onClose:()=>I(!1),onSubmit:ie,open:F,title:`建立簽核模板`})]})}function ee(e){return e instanceof Error?e.message:`發生未知錯誤`}function C(e){return e===`PUBLISHED`||e===`DRAFT`?e:`ALL`}function w({status:e}){return e===`PUBLISHED`?(0,c.jsx)(s.Badge,{size:`sub`,text:`已發布`,variant:`dot-success`}):(0,c.jsx)(s.Badge,{size:`sub`,text:`草稿`,variant:`dot-inactive`})}function T({record:e}){return e.categoryDetail?.isActive===!1?(0,c.jsx)(s.Badge,{size:`sub`,text:`${e.categoryLabel}(停用)`,variant:`dot-inactive`}):(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.categoryLabel})}var E={categoryId:null,id:`ALL_CATEGORIES`,name:`全部分類`};function D(e){return{categoryId:e.id,id:e.id,name:e.name}}function O(e,t){if(!j(e))return E;let n=typeof e.id==`string`?e.id:null;return n===E.id?E:t.find(e=>e.id===n)??E}function k(e){return Array.isArray(e)||!j(e)?E.name:typeof e.name==`string`?e.name:E.name}function A(e){return e.categoryDetail?.name??e.category??`未分類`}function j(e){return typeof e==`object`&&!!e}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return S}});
2
- //# sourceMappingURL=templates-w96t83N-.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"templates-w96t83N-.cjs","names":[],"sources":["../../src/views/templates/template-name-modal.tsx","../../src/views/templates/TemplatesView.tsx"],"sourcesContent":["'use client';\n\nimport { ChangeEvent, ReactElement, useEffect, useState } from 'react';\nimport { Input, Modal, Select, Typography } from '@mezzanine-ui/react';\nimport { BPMFormField } from '../../components/bpm-form-field';\n\nexport interface TemplateCategoryOption {\n readonly categoryId: string | null;\n readonly id: string;\n readonly name: string;\n}\n\ninterface TemplateNameModalProps {\n readonly confirmText: string;\n readonly categoryOptions: readonly TemplateCategoryOption[];\n readonly initialName: string;\n readonly loading: boolean;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly categoryId: string | null;\n readonly name: string;\n }) => Promise<void>;\n readonly open: boolean;\n readonly title: string;\n}\n\nexport function TemplateNameModal({\n confirmText,\n categoryOptions,\n initialName,\n loading,\n onClose,\n onSubmit,\n open,\n title,\n}: TemplateNameModalProps): ReactElement {\n const [name, setName] = useState(initialName);\n const [category, setCategory] = useState<TemplateCategoryOption>(\n categoryOptions[0] ?? UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n );\n const [error, setError] = useState<string | null>(null);\n const trimmedName = name.trim();\n\n useEffect((): void => {\n if (!open) {\n return;\n }\n\n setName(initialName);\n setCategory(categoryOptions[0] ?? UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION);\n setError(null);\n }, [categoryOptions, initialName, open]);\n\n async function handleConfirm(): Promise<void> {\n if (!trimmedName) {\n setError('請輸入模板名稱');\n return;\n }\n\n try {\n await onSubmit({ categoryId: category.categoryId, name: trimmedName });\n } catch (submitError: unknown) {\n setError(readErrorMessage(submitError));\n }\n }\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !trimmedName }}\n confirmText={confirmText}\n loading={loading}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void => void handleConfirm()}\n open={open}\n showModalFooter\n showModalHeader\n size=\"narrow\"\n title={title}\n >\n <BPMFormField label=\"模板名稱\" name=\"templateName\" required>\n <Input\n autoFocus\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void => {\n setName(event.target.value);\n setError(null);\n }}\n placeholder=\"例如:費用申請流程\"\n value={name}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"分類\" name=\"templateCategory\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategory(readCategoryOption(option, categoryOptions));\n setError(null);\n }}\n options={[...categoryOptions]}\n placeholder=\"選擇分類\"\n value={category}\n />\n </BPMFormField>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n </Modal>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nexport const UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'UNCATEGORIZED',\n name: '未分類',\n};\n\nfunction readCategoryOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION\n );\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n","'use client';\n\nimport type { ChangeEvent, Key, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport styles from './templates.module.scss';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\nimport {\n TemplateCategoryOption,\n TemplateNameModal,\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n} from './template-name-modal';\nimport {\n ApprovalTemplateListStatus,\n ApprovalTemplateRecord,\n ApprovalTemplateCategoryRecord,\n createApprovalTemplate,\n listApprovalTemplateCategoriesPage,\n listApprovalTemplatesPage,\n} from '@rytass/bpm-core-client/template';\nimport { listLaunchableTemplates } from '@rytass/bpm-core-client/workflow';\n\nconst TEMPLATE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst TEMPLATE_STATUS_TABS: readonly {\n readonly key: TemplateStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'PUBLISHED', label: '已發布' },\n { key: 'DRAFT', label: '草稿' },\n];\n\nconst TEMPLATE_CATEGORY_PAGE_SIZE = 100;\n\ntype TemplateStatusTabKey = 'ALL' | ApprovalTemplateListStatus;\n\ntype TemplateRow = Readonly<\n Record<string, unknown> &\n ApprovalTemplateRecord & {\n categoryLabel: string;\n key: string;\n status: ApprovalTemplateListStatus;\n }\n>;\n\n\nexport function TemplatesView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [templates, setTemplates] = useState<readonly ApprovalTemplateRecord[]>(\n [],\n );\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategoryOption>(\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n );\n const [categoryOptions, setCategoryOptions] = useState<\n readonly TemplateCategoryOption[]\n >([]);\n const [launchableTemplateIds, setLaunchableTemplateIds] = useState<\n ReadonlySet<string>\n >(new Set());\n const [createModalOpen, setCreateModalOpen] = useState(false);\n const [creating, setCreating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [templatePage, setTemplatePage] = useState(1);\n const [templatePageSize, setTemplatePageSize] = useState(10);\n const [templateSearchText, setTemplateSearchText] = useState('');\n const [templateStatus, setTemplateStatus] =\n useState<TemplateStatusTabKey>('ALL');\n const [templateTotalCount, setTemplateTotalCount] = useState(0);\n\n const refreshTemplates = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const [\n templatePageResult,\n nextLaunchableTemplates,\n activeCategoryPageResult,\n ] = await Promise.all([\n listApprovalTemplatesPage({\n categoryId: categoryFilter.categoryId,\n page: templatePage,\n pageSize: templatePageSize,\n searchText: templateSearchText,\n status: templateStatus === 'ALL' ? null : templateStatus,\n }),\n listLaunchableTemplates(),\n listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: TEMPLATE_CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n }),\n ]);\n\n setCategoryOptions([\n ...activeCategoryPageResult.categories.map(readCategoryOption),\n ]);\n setTemplates(templatePageResult.templates);\n setTemplateTotalCount(templatePageResult.totalCount);\n setLaunchableTemplateIds(\n new Set(nextLaunchableTemplates.map((template) => template.id)),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [\n categoryFilter,\n templatePage,\n templatePageSize,\n templateSearchText,\n templateStatus,\n ]);\n\n useEffect((): void => {\n void refreshTemplates();\n }, [refreshTemplates]);\n\n const rows = useMemo(\n (): TemplateRow[] =>\n templates.map((template) => ({\n ...template,\n categoryLabel: readTemplateCategoryLabel(template),\n key: template.id,\n status: template.currentVersionId ? 'PUBLISHED' : 'DRAFT',\n updatedAt: formatDateTime(template.updatedAt),\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<TemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 220 },\n {\n key: 'status',\n render: (record: TemplateRow): ReactElement => (\n <TemplateStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'category',\n render: (record: TemplateRow): ReactElement => (\n <TemplateCategoryLabel record={record} />\n ),\n title: '分類',\n width: 160,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<TemplateRow> => ({\n render: (record): ReturnType<TableActions<TemplateRow>['render']> => [\n {\n disabled: (template): boolean =>\n !launchableTemplateIds.has(template.id),\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n {\n name: '設計',\n onClick: (): void => router.push(routes.templateDesigner(record.id)),\n },\n {\n name: '版本',\n onClick: (): void => router.push(routes.templateVersions(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 192,\n }),\n [launchableTemplateIds, router],\n );\n\n async function handleCreateTemplate({\n categoryId,\n name,\n }: {\n readonly categoryId: string | null;\n readonly name: string;\n }): Promise<void> {\n setCreating(true);\n setError(null);\n\n try {\n const templateId = await createApprovalTemplate({ categoryId, name });\n setCreateModalOpen(false);\n router.push(routes.templateDesigner(templateId));\n } finally {\n setCreating(false);\n }\n }\n\n return (\n <>\n <>\n <PageHeader>\n <ContentHeader\n description=\"建立流程模板、維護草稿與發布版本。\"\n title=\"簽核模板\"\n >\n <Button\n disabled={creating}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setCreateModalOpen(true)}\n variant=\"base-primary\"\n >\n 建立模板\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.templateFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setTemplateSearchText(event.target.value);\n setTemplatePage(1);\n }}\n placeholder=\"關鍵字:搜尋模板名稱、分類或描述\"\n size=\"sub\"\n value={templateSearchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateCategoryFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategoryFilter(\n readCategoryFilterOption(option, categoryOptions),\n );\n setTemplatePage(1);\n }}\n options={[\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n ...categoryOptions,\n ]}\n placeholder=\"分類\"\n renderValue={(value): string =>\n `分類:${readTemplateCategoryFilterLabel(value)}`\n }\n size=\"sub\"\n value={categoryFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={templateStatus}\n onChange={(activeKey): void => {\n setTemplateStatus(readTemplateStatusTabKey(activeKey));\n setTemplatePage(1);\n }}\n >\n {TEMPLATE_STATUS_TABS.map((statusTab) => (\n <TabItem key={statusTab.key}>{statusTab.label}</TabItem>\n ))}\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n pagination={{\n current: templatePage,\n onChange: (page): void => {\n setTemplatePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setTemplatePage(1);\n setTemplatePageSize(pageSize);\n },\n pageSize: templatePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: TEMPLATE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: templateTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n\n <TemplateNameModal\n categoryOptions={[\n UNCATEGORIZED_TEMPLATE_CATEGORY_OPTION,\n ...categoryOptions,\n ]}\n confirmText=\"建立\"\n initialName=\"\"\n loading={creating}\n onClose={(): void => setCreateModalOpen(false)}\n onSubmit={handleCreateTemplate}\n open={createModalOpen}\n title=\"建立簽核模板\"\n />\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nfunction readTemplateStatusTabKey(activeKey: Key): TemplateStatusTabKey {\n if (activeKey === 'PUBLISHED' || activeKey === 'DRAFT') {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction TemplateStatusBadge({\n status,\n}: {\n readonly status: ApprovalTemplateListStatus;\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateCategoryLabel({\n record,\n}: {\n readonly record: TemplateRow;\n}): ReactElement {\n if (record.categoryDetail?.isActive === false) {\n return (\n <Badge\n size=\"sub\"\n text={`${record.categoryLabel}(停用)`}\n variant=\"dot-inactive\"\n />\n );\n }\n\n return (\n <Typography component=\"span\" variant=\"body\">\n {record.categoryLabel}\n </Typography>\n );\n}\n\nconst UNCATEGORIZED_TEMPLATE_FILTER_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'ALL_CATEGORIES',\n name: '全部分類',\n};\n\nfunction readCategoryOption(\n category: ApprovalTemplateCategoryRecord,\n): TemplateCategoryOption {\n return {\n categoryId: category.id,\n id: category.id,\n name: category.name,\n };\n}\n\nfunction readCategoryFilterOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n if (id === UNCATEGORIZED_TEMPLATE_FILTER_OPTION.id) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION\n );\n}\n\nfunction readTemplateCategoryFilterLabel(value: unknown): string {\n if (Array.isArray(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n return typeof value.name === 'string'\n ? value.name\n : UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n}\n\nfunction readTemplateCategoryLabel(template: ApprovalTemplateRecord): string {\n return template.categoryDetail?.name ?? template.category ?? '未分類';\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/builder-DVE9zIKH.cjs");let t=require("react/jsx-runtime");var n={title:`表單編輯器 | BPM Admin`,description:`編輯 BPM 表單欄位、版本與預覽。`};async function r({params:n}){let{id:r}=await n;return(0,t.jsx)(e.t,{formId:r})}exports.default=r,exports.metadata=n;
2
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../../../../src/pages/forms/builder/index.tsx"],"sourcesContent":["import type { Metadata } from 'next';\nimport type { ReactElement } from 'react';\nimport { FormBuilderView } from '../../../views/forms/builder';\n\n/**\n * Next.js metadata for the BPM form builder page. Consumers re-export this\n * alongside the default page component.\n */\nexport const metadata: Metadata = {\n title: '表單編輯器 | BPM Admin',\n description: '編輯 BPM 表單欄位、版本與預覽。',\n};\n\n/**\n * Drop-in Next.js App Router page for the BPM form builder screen.\n *\n * Consumer usage in `app/forms/[id]/builder/page.tsx`:\n *\n * ```ts\n * export { default, metadata } from '@rytass/bpm-core-react/pages/forms/builder';\n * ```\n */\nexport default async function FormBuilderPage({\n params,\n}: {\n readonly params: Promise<{ readonly id: string }>;\n}): Promise<ReactElement> {\n const { id } = await params;\n return <FormBuilderView formId={id} />;\n}\n"],"mappings":"0LAQA,IAAa,EAAqB,CAChC,MAAO,oBACP,YAAa,oBACf,EAWA,eAA8B,EAAgB,CAC5C,UAGwB,CACxB,GAAM,CAAE,MAAO,MAAM,EACrB,OAAO,EAAA,EAAA,KAAC,EAAA,EAAD,CAAiB,OAAQ,CAAK,CAAA,CACvC"}
@@ -1,21 +0,0 @@
1
- import { Metadata } from 'next';
2
- import { ReactElement } from 'react';
3
- /**
4
- * Next.js metadata for the BPM form builder page. Consumers re-export this
5
- * alongside the default page component.
6
- */
7
- export declare const metadata: Metadata;
8
- /**
9
- * Drop-in Next.js App Router page for the BPM form builder screen.
10
- *
11
- * Consumer usage in `app/forms/[id]/builder/page.tsx`:
12
- *
13
- * ```ts
14
- * export { default, metadata } from '@rytass/bpm-core-react/pages/forms/builder';
15
- * ```
16
- */
17
- export default function FormBuilderPage({ params, }: {
18
- readonly params: Promise<{
19
- readonly id: string;
20
- }>;
21
- }): Promise<ReactElement>;
@@ -1,15 +0,0 @@
1
- import { t as e } from "../../../chunks/builder-BLVnnpnP.js";
2
- import { jsx as t } from "react/jsx-runtime";
3
- //#region src/pages/forms/builder/index.tsx
4
- var n = {
5
- title: "表單編輯器 | BPM Admin",
6
- description: "編輯 BPM 表單欄位、版本與預覽。"
7
- };
8
- async function r({ params: n }) {
9
- let { id: r } = await n;
10
- return /* @__PURE__ */ t(e, { formId: r });
11
- }
12
- //#endregion
13
- export { r as default, n as metadata };
14
-
15
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/pages/forms/builder/index.tsx"],"sourcesContent":["import type { Metadata } from 'next';\nimport type { ReactElement } from 'react';\nimport { FormBuilderView } from '../../../views/forms/builder';\n\n/**\n * Next.js metadata for the BPM form builder page. Consumers re-export this\n * alongside the default page component.\n */\nexport const metadata: Metadata = {\n title: '表單編輯器 | BPM Admin',\n description: '編輯 BPM 表單欄位、版本與預覽。',\n};\n\n/**\n * Drop-in Next.js App Router page for the BPM form builder screen.\n *\n * Consumer usage in `app/forms/[id]/builder/page.tsx`:\n *\n * ```ts\n * export { default, metadata } from '@rytass/bpm-core-react/pages/forms/builder';\n * ```\n */\nexport default async function FormBuilderPage({\n params,\n}: {\n readonly params: Promise<{ readonly id: string }>;\n}): Promise<ReactElement> {\n const { id } = await params;\n return <FormBuilderView formId={id} />;\n}\n"],"mappings":";;;AAQA,IAAa,IAAqB;CAChC,OAAO;CACP,aAAa;AACf;AAWA,eAA8B,EAAgB,EAC5C,aAGwB;CACxB,IAAM,EAAE,UAAO,MAAM;CACrB,OAAO,kBAAC,GAAD,EAAiB,QAAQ,EAAK,CAAA;AACvC"}
@@ -1,2 +0,0 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../views/forms/index.cjs");let t=require("react/jsx-runtime");var n={title:`表單管理 | BPM Admin`,description:`建立、編輯與管理 BPM 表單定義版本。`};function r(){return(0,t.jsx)(e.FormsView,{})}exports.default=r,exports.metadata=n;
2
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/pages/forms/index.tsx"],"sourcesContent":["import type { Metadata } from 'next';\nimport type { ReactElement } from 'react';\nimport { FormsView } from '../../views/forms';\n\n/**\n * Next.js metadata for the BPM forms list page. Consumers re-export this\n * alongside the default page component.\n */\nexport const metadata: Metadata = {\n title: '表單管理 | BPM Admin',\n description: '建立、編輯與管理 BPM 表單定義版本。',\n};\n\n/**\n * Drop-in Next.js App Router page for the BPM forms list screen.\n *\n * Consumer usage in `app/forms/page.tsx`:\n *\n * ```ts\n * export { default, metadata } from '@rytass/bpm-core-react/pages/forms';\n * ```\n */\nexport default function FormsPage(): ReactElement {\n return <FormsView />;\n}\n"],"mappings":"iLAQA,IAAa,EAAqB,CAChC,MAAO,mBACP,YAAa,sBACf,EAWA,SAAwB,GAA0B,CAChD,OAAO,EAAA,EAAA,KAAC,EAAA,UAAD,CAAY,CAAA,CACrB"}
@@ -1,17 +0,0 @@
1
- import { Metadata } from 'next';
2
- import { ReactElement } from 'react';
3
- /**
4
- * Next.js metadata for the BPM forms list page. Consumers re-export this
5
- * alongside the default page component.
6
- */
7
- export declare const metadata: Metadata;
8
- /**
9
- * Drop-in Next.js App Router page for the BPM forms list screen.
10
- *
11
- * Consumer usage in `app/forms/page.tsx`:
12
- *
13
- * ```ts
14
- * export { default, metadata } from '@rytass/bpm-core-react/pages/forms';
15
- * ```
16
- */
17
- export default function FormsPage(): ReactElement;
@@ -1,14 +0,0 @@
1
- import { FormsView as e } from "../../views/forms/index.js";
2
- import { jsx as t } from "react/jsx-runtime";
3
- //#region src/pages/forms/index.tsx
4
- var n = {
5
- title: "表單管理 | BPM Admin",
6
- description: "建立、編輯與管理 BPM 表單定義版本。"
7
- };
8
- function r() {
9
- return /* @__PURE__ */ t(e, {});
10
- }
11
- //#endregion
12
- export { r as default, n as metadata };
13
-
14
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/pages/forms/index.tsx"],"sourcesContent":["import type { Metadata } from 'next';\nimport type { ReactElement } from 'react';\nimport { FormsView } from '../../views/forms';\n\n/**\n * Next.js metadata for the BPM forms list page. Consumers re-export this\n * alongside the default page component.\n */\nexport const metadata: Metadata = {\n title: '表單管理 | BPM Admin',\n description: '建立、編輯與管理 BPM 表單定義版本。',\n};\n\n/**\n * Drop-in Next.js App Router page for the BPM forms list screen.\n *\n * Consumer usage in `app/forms/page.tsx`:\n *\n * ```ts\n * export { default, metadata } from '@rytass/bpm-core-react/pages/forms';\n * ```\n */\nexport default function FormsPage(): ReactElement {\n return <FormsView />;\n}\n"],"mappings":";;;AAQA,IAAa,IAAqB;CAChC,OAAO;CACP,aAAa;AACf;AAWA,SAAwB,IAA0B;CAChD,OAAO,kBAAC,GAAD,CAAY,CAAA;AACrB"}
@@ -1,2 +0,0 @@
1
- import { ReactElement } from 'react';
2
- export declare function FormsView(): ReactElement;
@@ -1,12 +0,0 @@
1
- import { ReactElement } from 'react';
2
- interface FormNameModalProps {
3
- readonly confirmText: string;
4
- readonly initialName: string;
5
- readonly loading: boolean;
6
- readonly onClose: () => void;
7
- readonly onSubmit: (name: string) => Promise<void>;
8
- readonly open: boolean;
9
- readonly title: string;
10
- }
11
- export declare function FormNameModal({ confirmText, initialName, loading, onClose, onSubmit, open, title, }: FormNameModalProps): ReactElement;
12
- export {};