@rytass/bpm-core-react 0.22.0 → 0.24.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 (166) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +1 -0
  3. package/dist/chunks/FormBuilderView-Bg9ftYz-.cjs +4 -0
  4. package/dist/chunks/FormBuilderView-Bg9ftYz-.cjs.map +1 -0
  5. package/dist/chunks/{FormBuilderView-DbfbLZCI.js → FormBuilderView-CBvdcg_t.js} +675 -614
  6. package/dist/chunks/FormBuilderView-CBvdcg_t.js.map +1 -0
  7. package/dist/chunks/FormRendererView-D-p6GDQB.cjs +6 -0
  8. package/dist/chunks/FormRendererView-D-p6GDQB.cjs.map +1 -0
  9. package/dist/chunks/FormRendererView-DHXmekC3.js +1319 -0
  10. package/dist/chunks/FormRendererView-DHXmekC3.js.map +1 -0
  11. package/dist/chunks/{approval-instance-list-page-Cv5I1YPX.cjs → approval-instance-list-page-BqkG9jiR.cjs} +2 -2
  12. package/dist/chunks/{approval-instance-list-page-Cv5I1YPX.cjs.map → approval-instance-list-page-BqkG9jiR.cjs.map} +1 -1
  13. package/dist/chunks/{approval-instance-list-page-BI5fIXc-.js → approval-instance-list-page-CsSpIN4C.js} +2 -2
  14. package/dist/chunks/{approval-instance-list-page-BI5fIXc-.js.map → approval-instance-list-page-CsSpIN4C.js.map} +1 -1
  15. package/dist/chunks/compose-B43jtdyL.cjs +2 -0
  16. package/dist/chunks/compose-B43jtdyL.cjs.map +1 -0
  17. package/dist/chunks/{compose-U1zs3Yof.js → compose-C7yS6bJm.js} +162 -148
  18. package/dist/chunks/compose-C7yS6bJm.js.map +1 -0
  19. package/dist/chunks/{dashboard-page-BoqNhjT_.js → dashboard-page-DBJCsPya.js} +2 -2
  20. package/dist/chunks/{dashboard-page-BoqNhjT_.js.map → dashboard-page-DBJCsPya.js.map} +1 -1
  21. package/dist/chunks/{dashboard-page-D7YJ3udk.cjs → dashboard-page-lqlLELKs.cjs} +2 -2
  22. package/dist/chunks/{dashboard-page-D7YJ3udk.cjs.map → dashboard-page-lqlLELKs.cjs.map} +1 -1
  23. package/dist/chunks/{designer-DPG7R_WP.js → designer-B9Ut4xze.js} +1786 -1463
  24. package/dist/chunks/designer-B9Ut4xze.js.map +1 -0
  25. package/dist/chunks/designer-eXw7R9ug.cjs +69 -0
  26. package/dist/chunks/designer-eXw7R9ug.cjs.map +1 -0
  27. package/dist/chunks/{detail-CHZDNNM6.js → detail-BB_uYaoM.js} +904 -896
  28. package/dist/chunks/detail-BB_uYaoM.js.map +1 -0
  29. package/dist/chunks/detail-DN8pEzUJ.cjs +5 -0
  30. package/dist/chunks/detail-DN8pEzUJ.cjs.map +1 -0
  31. package/dist/chunks/instance-error-message-BKt07-Bo.js +270 -0
  32. package/dist/chunks/instance-error-message-BKt07-Bo.js.map +1 -0
  33. package/dist/chunks/instance-error-message-BL_X7Af8.cjs +2 -0
  34. package/dist/chunks/instance-error-message-BL_X7Af8.cjs.map +1 -0
  35. package/dist/chunks/member-profile-resolution-CJlgVdTR.js +44 -0
  36. package/dist/chunks/member-profile-resolution-CJlgVdTR.js.map +1 -0
  37. package/dist/chunks/member-profile-resolution-DiH-P-Vh.cjs +2 -0
  38. package/dist/chunks/member-profile-resolution-DiH-P-Vh.cjs.map +1 -0
  39. package/dist/chunks/{providers-CQWekD7_.js → providers-D35lBOTd.js} +2 -2
  40. package/dist/chunks/{providers-CQWekD7_.js.map → providers-D35lBOTd.js.map} +1 -1
  41. package/dist/chunks/{providers-VUOh6i0i.cjs → providers-Dz4Wqxr6.cjs} +2 -2
  42. package/dist/chunks/{providers-VUOh6i0i.cjs.map → providers-Dz4Wqxr6.cjs.map} +1 -1
  43. package/dist/chunks/{routes-config-C1j_vFKo.cjs → routes-config-BWjZDAU3.cjs} +2 -2
  44. package/dist/chunks/{routes-config-C1j_vFKo.cjs.map → routes-config-BWjZDAU3.cjs.map} +1 -1
  45. package/dist/chunks/{routes-config-BcNaWJWJ.js → routes-config-DjEOE9eP.js} +3 -2
  46. package/dist/chunks/{routes-config-BcNaWJWJ.js.map → routes-config-DjEOE9eP.js.map} +1 -1
  47. package/dist/chunks/users-C_Dtw_sR.cjs +2 -0
  48. package/dist/chunks/users-C_Dtw_sR.cjs.map +1 -0
  49. package/dist/chunks/users-wgM3TqU3.js +513 -0
  50. package/dist/chunks/users-wgM3TqU3.js.map +1 -0
  51. package/dist/index.cjs +1 -1
  52. package/dist/index.js +4 -4
  53. package/dist/lib/routes-config.d.cts +2 -0
  54. package/dist/lib/routes-config.d.ts +2 -0
  55. package/dist/next/index.cjs +1 -1
  56. package/dist/next/index.js +2 -2
  57. package/dist/pages/admin/stuck-instances/index.cjs +2 -0
  58. package/dist/pages/admin/stuck-instances/index.cjs.map +1 -0
  59. package/dist/pages/admin/stuck-instances/index.d.cts +4 -0
  60. package/dist/pages/admin/stuck-instances/index.d.ts +4 -0
  61. package/dist/pages/admin/stuck-instances/index.js +13 -0
  62. package/dist/pages/admin/stuck-instances/index.js.map +1 -0
  63. package/dist/pages/admin/users/index.cjs +1 -1
  64. package/dist/pages/admin/users/index.js +1 -1
  65. package/dist/pages/instances/detail/index.cjs +1 -1
  66. package/dist/pages/instances/detail/index.js +1 -1
  67. package/dist/pages/templates/compose/index.cjs +1 -1
  68. package/dist/pages/templates/compose/index.js +1 -1
  69. package/dist/pages/templates/designer/index.cjs +1 -1
  70. package/dist/pages/templates/designer/index.js +1 -1
  71. package/dist/views/admin/index.cjs +1 -1
  72. package/dist/views/admin/index.d.cts +1 -0
  73. package/dist/views/admin/index.d.ts +1 -0
  74. package/dist/views/admin/index.js +3 -2
  75. package/dist/views/admin/stuck-instances/AdminStuckInstancesView.d.cts +10 -0
  76. package/dist/views/admin/stuck-instances/AdminStuckInstancesView.d.ts +10 -0
  77. package/dist/views/admin/stuck-instances/StuckInstanceCancelModal.d.cts +14 -0
  78. package/dist/views/admin/stuck-instances/StuckInstanceCancelModal.d.ts +14 -0
  79. package/dist/views/admin/stuck-instances/index.cjs +2 -0
  80. package/dist/views/admin/stuck-instances/index.cjs.map +1 -0
  81. package/dist/views/admin/stuck-instances/index.d.cts +2 -0
  82. package/dist/views/admin/stuck-instances/index.d.ts +2 -0
  83. package/dist/views/admin/stuck-instances/index.js +237 -0
  84. package/dist/views/admin/stuck-instances/index.js.map +1 -0
  85. package/dist/views/admin/users/index.cjs +1 -1
  86. package/dist/views/admin/users/index.js +1 -1
  87. package/dist/views/cc/index.cjs +1 -1
  88. package/dist/views/cc/index.js +1 -1
  89. package/dist/views/dashboard/index.cjs +1 -1
  90. package/dist/views/dashboard/index.js +1 -1
  91. package/dist/views/forms/builder/index.cjs +1 -1
  92. package/dist/views/forms/builder/index.js +1 -1
  93. package/dist/views/forms/renderer/FormRendererView.d.cts +26 -1
  94. package/dist/views/forms/renderer/FormRendererView.d.ts +26 -1
  95. package/dist/views/forms/renderer/index.cjs +1 -1
  96. package/dist/views/forms/renderer/index.js +1 -1
  97. package/dist/views/inbox/index.cjs +1 -1
  98. package/dist/views/inbox/index.js +1 -1
  99. package/dist/views/instances/approver-filled-form.d.cts +56 -20
  100. package/dist/views/instances/approver-filled-form.d.ts +56 -20
  101. package/dist/views/instances/detail/index.cjs +1 -1
  102. package/dist/views/instances/detail/index.js +1 -1
  103. package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +7 -0
  104. package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +7 -0
  105. package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +1 -1
  106. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +1 -1
  107. package/dist/views/instances/new/index.cjs +1 -1
  108. package/dist/views/instances/new/index.js +5 -5
  109. package/dist/views/instances/new/index.js.map +1 -1
  110. package/dist/views/search/index.cjs +1 -1
  111. package/dist/views/search/index.js +1 -1
  112. package/dist/views/sent/index.cjs +1 -1
  113. package/dist/views/sent/index.js +1 -1
  114. package/dist/views/templates/compose/index.cjs +1 -1
  115. package/dist/views/templates/compose/index.js +1 -1
  116. package/dist/views/templates/compose/steps/ComposeReviewStep.d.cts +3 -1
  117. package/dist/views/templates/compose/steps/ComposeReviewStep.d.ts +3 -1
  118. package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.cts +4 -1
  119. package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +4 -1
  120. package/dist/views/templates/compose/use-template-compose-wizard.d.cts +3 -1
  121. package/dist/views/templates/compose/use-template-compose-wizard.d.ts +3 -1
  122. package/dist/views/templates/designer/TemplateDesignerView.d.cts +10 -1
  123. package/dist/views/templates/designer/TemplateDesignerView.d.ts +10 -1
  124. package/dist/views/templates/designer/approver-resolver-model.d.cts +31 -0
  125. package/dist/views/templates/designer/approver-resolver-model.d.ts +31 -0
  126. package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.cts +3 -1
  127. package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.ts +3 -1
  128. package/dist/views/templates/designer/field-access-matrix/field-access-copy.d.cts +3 -2
  129. package/dist/views/templates/designer/field-access-matrix/field-access-copy.d.ts +3 -2
  130. package/dist/views/templates/designer/index.cjs +1 -1
  131. package/dist/views/templates/designer/index.js +1 -1
  132. package/dist/views/templates/designer/launch-mode.d.cts +19 -0
  133. package/dist/views/templates/designer/launch-mode.d.ts +19 -0
  134. package/dist/views/templates/designer/node-actor-resolver-options.d.cts +30 -3
  135. package/dist/views/templates/designer/node-actor-resolver-options.d.ts +30 -3
  136. package/dist/views/templates/designer/publish-default-value-check.d.cts +36 -0
  137. package/dist/views/templates/designer/publish-default-value-check.d.ts +36 -0
  138. package/dist/views/templates/index.cjs +1 -1
  139. package/dist/views/templates/index.js +1 -1
  140. package/dist/views/templates/versions/index.cjs +1 -1
  141. package/dist/views/templates/versions/index.js +1 -1
  142. package/package.json +23 -3
  143. package/dist/chunks/FormBuilderView-Bok4Y59D.cjs +0 -4
  144. package/dist/chunks/FormBuilderView-Bok4Y59D.cjs.map +0 -1
  145. package/dist/chunks/FormBuilderView-DbfbLZCI.js.map +0 -1
  146. package/dist/chunks/FormRendererView-CAyPXhPq.js +0 -1351
  147. package/dist/chunks/FormRendererView-CAyPXhPq.js.map +0 -1
  148. package/dist/chunks/FormRendererView-iLlHFIUR.cjs +0 -6
  149. package/dist/chunks/FormRendererView-iLlHFIUR.cjs.map +0 -1
  150. package/dist/chunks/compose-DP1N4twA.cjs +0 -2
  151. package/dist/chunks/compose-DP1N4twA.cjs.map +0 -1
  152. package/dist/chunks/compose-U1zs3Yof.js.map +0 -1
  153. package/dist/chunks/designer-CWL-dCQ_.cjs +0 -69
  154. package/dist/chunks/designer-CWL-dCQ_.cjs.map +0 -1
  155. package/dist/chunks/designer-DPG7R_WP.js.map +0 -1
  156. package/dist/chunks/detail-BUfsSal0.cjs +0 -5
  157. package/dist/chunks/detail-BUfsSal0.cjs.map +0 -1
  158. package/dist/chunks/detail-CHZDNNM6.js.map +0 -1
  159. package/dist/chunks/instance-error-message-BEM4O_Kj.js +0 -208
  160. package/dist/chunks/instance-error-message-BEM4O_Kj.js.map +0 -1
  161. package/dist/chunks/instance-error-message-BpCLCOjp.cjs +0 -2
  162. package/dist/chunks/instance-error-message-BpCLCOjp.cjs.map +0 -1
  163. package/dist/chunks/users-BBtiZ9QQ.js +0 -486
  164. package/dist/chunks/users-BBtiZ9QQ.js.map +0 -1
  165. package/dist/chunks/users-EqSzDhuj.cjs +0 -2
  166. package/dist/chunks/users-EqSzDhuj.cjs.map +0 -1
@@ -1,486 +0,0 @@
1
- "use client";
2
- import { t as e } from "./format-member-label-C73FuP-d.js";
3
- import { t } from "./bpm-form-field-9B-Det0u.js";
4
- import { t as n } from "./admin-pickers-DfGxsjpp.js";
5
- import { useCallback as r, useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
6
- import { BaseCard as c, Button as l, Filter as u, FilterArea as d, FilterLine as f, FormField as p, Input as m, Modal as h, PageHeader as g, Section as _, SectionGroup as v, Table as y, Typography as b } from "@mezzanine-ui/react";
7
- import { listMemberDirectoryPage as x, resolveMembers as S } from "@rytass/bpm-core-client";
8
- import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
9
- import { listInactiveMembersWithOpenTasks as E, listMemberOpenTasks as ee, reassignMemberTasks as D } from "@rytass/bpm-core-client/workflow";
10
- import { FormFieldLayout as O } from "@mezzanine-ui/core/form";
11
- import k from "@mezzanine-ui/react/ContentHeader";
12
- import { listMemberships as A, readOrganizationDashboard as j, readResolvedManager as M } from "@rytass/bpm-core-client/organization";
13
- import '../users.css';var N = {
14
- memberFilterArea: "bpm_memberFilterArea_9RB2k",
15
- header: "bpm_header_sIEtg",
16
- detailFields: "bpm_detailFields_TyKNL",
17
- detailSection: "bpm_detailSection_-iLjy",
18
- membershipList: "bpm_membershipList_5n9iq"
19
- };
20
- // src/views/admin/users/MemberTaskReassignModal.tsx
21
- function P({ member: e, onClose: c }) {
22
- let [u, d] = s([]), [f, p] = s(!1), [g, _] = s(null), [v, x] = s(""), [S, C] = s(null), [E, O] = s(null), [k, A] = s(!1), [j, M] = s(null), P = v.trim(), L = `${g?.id ?? ""}|${P}`, R = S !== null && S.inputKey === L, te = S !== null && R && S.results.some((e) => e.outcome === "WOULD_REASSIGN"), z = o(0), B = r(async (e) => {
23
- let t = z.current + 1;
24
- z.current = t, p(!0);
25
- try {
26
- let n = await ee(e);
27
- z.current === t && d(n);
28
- } catch (e) {
29
- z.current === t && M(I(e));
30
- } finally {
31
- z.current === t && p(!1);
32
- }
33
- }, []);
34
- i(() => {
35
- _(null), x(""), C(null), O(null), M(null), e ? (d([]), B(e.memberId)) : (z.current += 1, d([]), p(!1));
36
- }, [e, B]);
37
- let V = a(() => new Map(u.map((e) => [e.taskId, e.instanceTitle])), [u]);
38
- async function H(t) {
39
- if (e && g && P) {
40
- A(!0), M(null);
41
- try {
42
- let n = await D({
43
- dryRun: t,
44
- fromMemberId: e.memberId,
45
- reason: P,
46
- toMemberId: g.id
47
- });
48
- t ? (C({
49
- inputKey: L,
50
- results: n
51
- }), O(null)) : (O({
52
- results: n,
53
- titleById: V
54
- }), C(null), await B(e.memberId));
55
- } catch (e) {
56
- M(I(e));
57
- } finally {
58
- A(!1);
59
- }
60
- }
61
- }
62
- let U = a(() => {
63
- let e = E?.results ?? S?.results ?? [], t = E?.titleById ?? V;
64
- return e.map((e) => ({
65
- instanceTitle: t.get(e.taskId) ?? e.taskId,
66
- key: e.taskId,
67
- message: e.message,
68
- outcomeLabel: F(e.outcome)
69
- }));
70
- }, [
71
- E,
72
- S,
73
- V
74
- ]), W = a(() => [
75
- {
76
- dataIndex: "instanceTitle",
77
- key: "instanceTitle",
78
- title: "案件",
79
- width: 220
80
- },
81
- {
82
- dataIndex: "nodeLabel",
83
- key: "nodeLabel",
84
- title: "節點",
85
- width: 160
86
- },
87
- {
88
- key: "memberRole",
89
- render: (e) => e.memberRole === "ASSIGNEE" ? "指派人" : "會簽候選人",
90
- title: "身分",
91
- width: 120
92
- }
93
- ], []), G = a(() => [
94
- {
95
- dataIndex: "instanceTitle",
96
- key: "instanceTitle",
97
- title: "案件",
98
- width: 220
99
- },
100
- {
101
- dataIndex: "outcomeLabel",
102
- key: "outcomeLabel",
103
- title: "結果",
104
- width: 100
105
- },
106
- {
107
- dataIndex: "message",
108
- key: "message",
109
- title: "說明",
110
- width: 160
111
- }
112
- ], []);
113
- return /* @__PURE__ */ w(h, {
114
- cancelText: "關閉",
115
- confirmButtonProps: { disabled: !te || k },
116
- confirmText: "確認改派",
117
- loading: k,
118
- modalType: "standard",
119
- onCancel: c,
120
- onClose: c,
121
- onConfirm: () => {
122
- H(!1);
123
- },
124
- open: !!e,
125
- showModalFooter: !0,
126
- showModalHeader: !0,
127
- size: "regular",
128
- title: e ? `改派待辦:${e.name}` : "改派待辦",
129
- children: e ? /* @__PURE__ */ T("div", {
130
- className: N.detailFields,
131
- children: [
132
- /* @__PURE__ */ w(b, {
133
- variant: "body",
134
- children: "改派會保留任務編號,但不產生簽核紀錄;原簽核人的待辦會結案為已轉交, 接手人會收到新的待辦通知。"
135
- }),
136
- j ? /* @__PURE__ */ w(b, {
137
- color: "text-error",
138
- variant: "body",
139
- children: j
140
- }) : null,
141
- u.length ? /* @__PURE__ */ w(y, {
142
- columns: W,
143
- dataSource: u.map((e) => ({
144
- ...e,
145
- key: e.taskId
146
- })),
147
- fullWidth: !0,
148
- loading: f
149
- }) : /* @__PURE__ */ w(b, {
150
- color: "text-neutral",
151
- variant: "body",
152
- children: f ? "載入待辦中…" : "此成員目前沒有待簽任務。"
153
- }),
154
- /* @__PURE__ */ w(t, {
155
- label: "接手人",
156
- name: "reassignTarget",
157
- children: /* @__PURE__ */ w(n, {
158
- name: "reassignTarget",
159
- onChange: (e) => {
160
- _(e), C(null), O(null);
161
- },
162
- placeholder: "搜尋接手人姓名或信箱",
163
- value: g
164
- })
165
- }),
166
- /* @__PURE__ */ w(t, {
167
- label: "改派原因",
168
- name: "reassignReason",
169
- children: /* @__PURE__ */ w(m, {
170
- fullWidth: !0,
171
- name: "reassignReason",
172
- onChange: (e) => {
173
- x(e.target.value), C(null), O(null);
174
- },
175
- placeholder: "例如:原簽核人已離職",
176
- value: v
177
- })
178
- }),
179
- /* @__PURE__ */ T("div", {
180
- className: N.membershipList,
181
- children: [/* @__PURE__ */ w(b, {
182
- color: "text-neutral",
183
- variant: "caption",
184
- children: "先按「預覽」確認每筆任務的結果,確認無誤後再按「確認改派」。"
185
- }), /* @__PURE__ */ w("div", { children: /* @__PURE__ */ w(l, {
186
- disabled: k || !g || !P || u.length === 0,
187
- onClick: () => {
188
- H(!0);
189
- },
190
- variant: "base-secondary",
191
- children: "預覽"
192
- }) })]
193
- }),
194
- U.length ? /* @__PURE__ */ w(y, {
195
- columns: G,
196
- dataSource: U,
197
- fullWidth: !0
198
- }) : null
199
- ]
200
- }) : null
201
- });
202
- }
203
- function F(e) {
204
- return e === "WOULD_REASSIGN" ? "會改派" : e === "REASSIGNED" ? "已改派" : "會被拒";
205
- }
206
- function I(e) {
207
- return e instanceof Error ? e.message : "改派待辦失敗。";
208
- }
209
- // src/views/admin/users/AdminUsersView.tsx
210
- var L = [
211
- 10,
212
- 20,
213
- 50
214
- ];
215
- function R() {
216
- let [e, t] = s(null), [n, c] = s([]), [l, h] = s(null), [ee, D] = s(null), [F, I] = s(null), [R, z] = s([]), [B, V] = s(null), [U, W] = s(!0), [G, K] = s(1), [q, ne] = s(10), [re, ie] = s(0), [J, ae] = s([]), [Y, oe] = s([]), [se, ce] = s([]), [le, X] = s(null), [Z, ue] = s(""), de = a(() => new Map(Y.map((e) => [e.id, e])), [Y]), fe = a(() => new Map(se.map((e) => [e.id, e])), [se]), pe = r(async () => {
217
- W(!0), I(null);
218
- try {
219
- let [e, t] = await Promise.all([x({
220
- page: G,
221
- pageSize: q,
222
- searchText: Z
223
- }), j()]);
224
- ae(e.members), ie(e.totalCount), oe(t.orgUnits), ce(t.positions);
225
- } catch (e) {
226
- I(H(e));
227
- } finally {
228
- W(!1);
229
- }
230
- }, [
231
- G,
232
- q,
233
- Z
234
- ]);
235
- i(() => {
236
- pe();
237
- }, [pe]);
238
- let Q = o(0), $ = r(async () => {
239
- let e = Q.current + 1;
240
- Q.current = e;
241
- try {
242
- let t = await E();
243
- Q.current === e && (z(t), V(null));
244
- } catch (t) {
245
- Q.current === e && V(H(t));
246
- }
247
- }, []);
248
- i(() => {
249
- $();
250
- }, [$]);
251
- let me = a(() => R.map((e) => ({
252
- ...e,
253
- key: e.memberId
254
- })), [R]), he = a(() => [
255
- {
256
- dataIndex: "name",
257
- key: "name",
258
- title: "姓名",
259
- width: 160
260
- },
261
- {
262
- dataIndex: "email",
263
- key: "email",
264
- title: "信箱",
265
- width: 260
266
- },
267
- {
268
- dataIndex: "openTaskCount",
269
- key: "openTaskCount",
270
- title: "待簽數",
271
- width: 96
272
- }
273
- ], []), ge = a(() => ({
274
- render: () => [{
275
- name: "改派待辦",
276
- onClick: (e) => {
277
- X({
278
- customFieldsJson: "{}",
279
- email: e.email,
280
- memberId: e.memberId,
281
- name: e.name
282
- });
283
- }
284
- }],
285
- variant: "base-secondary",
286
- width: 112
287
- }), []), _e = a(() => J.map((e) => ({
288
- ...e,
289
- key: e.memberId
290
- })), [J]), ve = r(async (e) => {
291
- t(e), h(null), I(null);
292
- try {
293
- let [t, n] = await Promise.all([A({ memberId: e.memberId }), M(e.memberId)]);
294
- c(t), D(n), h((await S(n.managerMemberId ? [n.managerMemberId] : []))[0] ?? null);
295
- } catch (e) {
296
- I(H(e));
297
- }
298
- }, []), ye = a(() => [{
299
- dataIndex: "name",
300
- key: "name",
301
- title: "姓名",
302
- width: 160
303
- }, {
304
- dataIndex: "email",
305
- key: "email",
306
- title: "信箱",
307
- width: 260
308
- }], []), be = a(() => ({
309
- render: () => [{
310
- name: "檢視",
311
- onClick: (e) => {
312
- ve(e);
313
- }
314
- }, {
315
- name: "改派待辦",
316
- onClick: (e) => {
317
- X(e);
318
- }
319
- }],
320
- variant: "base-secondary",
321
- width: 176
322
- }), [ve]);
323
- function xe() {
324
- t(null), h(null), c([]), D(null);
325
- }
326
- return /* @__PURE__ */ T(C, { children: [
327
- /* @__PURE__ */ w(g, { children: /* @__PURE__ */ w(k, {
328
- description: "會員資料由 host member resolver 提供,BPM 僅維護組織歸屬與主管解析。",
329
- title: "會員對照"
330
- }) }),
331
- /* @__PURE__ */ T(v, { children: [me.length || B ? /* @__PURE__ */ w(_, {
332
- contentHeader: /* @__PURE__ */ w(k, {
333
- description: "這些會員已停用,身上仍有待簽,請改派給在職的人。",
334
- title: "已停用、仍有待簽的會員"
335
- }),
336
- children: /* @__PURE__ */ w("div", {
337
- "data-inactive-members": "",
338
- children: B ? /* @__PURE__ */ w(b, {
339
- color: "text-error",
340
- variant: "body",
341
- children: B
342
- }) : /* @__PURE__ */ w(y, {
343
- actions: ge,
344
- columns: he,
345
- dataSource: me,
346
- fullWidth: !0
347
- })
348
- })
349
- }) : null, /* @__PURE__ */ T(_, {
350
- filterArea: /* @__PURE__ */ w(d, {
351
- className: N.memberFilterArea,
352
- children: /* @__PURE__ */ w(f, { children: /* @__PURE__ */ w(u, {
353
- span: 3,
354
- children: /* @__PURE__ */ w(p, {
355
- fullWidth: !0,
356
- layout: O.VERTICAL,
357
- name: "memberSearchText",
358
- children: /* @__PURE__ */ w(m, {
359
- fullWidth: !0,
360
- onChange: (e) => {
361
- ue(e.target.value), K(1);
362
- },
363
- placeholder: "搜尋姓名或信箱",
364
- size: "sub",
365
- value: Z,
366
- variant: "base"
367
- })
368
- })
369
- }) })
370
- }),
371
- children: [F ? /* @__PURE__ */ w(b, {
372
- color: "text-error",
373
- variant: "body",
374
- children: F
375
- }) : null, /* @__PURE__ */ w(y, {
376
- actions: be,
377
- columns: ye,
378
- dataSource: _e,
379
- fullWidth: !0,
380
- loading: U,
381
- pagination: {
382
- current: G,
383
- onChange: (e) => {
384
- K(e);
385
- },
386
- onChangePageSize: (e) => {
387
- K(1), ne(e);
388
- },
389
- pageSize: q,
390
- pageSizeLabel: "每頁筆數",
391
- pageSizeOptions: L,
392
- renderResultSummary: (e, t, n) => `顯示 ${e}-${t} 筆,共 ${n} 筆`,
393
- showPageSizeOptions: !0,
394
- total: re
395
- }
396
- })]
397
- })] }),
398
- /* @__PURE__ */ w(P, {
399
- member: le,
400
- onClose: () => {
401
- X(null), $();
402
- }
403
- }),
404
- /* @__PURE__ */ w(te, {
405
- managerProfile: l,
406
- member: e,
407
- memberships: n,
408
- onClose: xe,
409
- orgUnitsById: de,
410
- positionsById: fe,
411
- resolvedManager: ee
412
- })
413
- ] });
414
- }
415
- function te({ managerProfile: e, member: t, memberships: n, onClose: r, orgUnitsById: i, positionsById: a, resolvedManager: o }) {
416
- return /* @__PURE__ */ w(h, {
417
- cancelText: "關閉",
418
- confirmText: "關閉",
419
- modalType: "standard",
420
- onCancel: r,
421
- onClose: r,
422
- onConfirm: r,
423
- open: !!t,
424
- showModalFooter: !0,
425
- showModalHeader: !0,
426
- size: "regular",
427
- title: t?.name ?? "會員明細",
428
- children: t ? /* @__PURE__ */ T("div", {
429
- className: N.detailFields,
430
- children: [
431
- /* @__PURE__ */ w(c, {
432
- title: "基本資料",
433
- children: /* @__PURE__ */ w("div", {
434
- className: N.detailSection,
435
- children: /* @__PURE__ */ T(b, {
436
- variant: "body",
437
- children: ["信箱:", t.email?.trim() ? t.email : "未設定"]
438
- })
439
- })
440
- }),
441
- /* @__PURE__ */ w(c, {
442
- title: "BPM 組織歸屬",
443
- children: /* @__PURE__ */ w("div", {
444
- className: N.membershipList,
445
- children: n.length ? n.map((e) => /* @__PURE__ */ T(b, {
446
- variant: "body",
447
- children: [
448
- z(i.get(e.orgUnitId)),
449
- " / ",
450
- e.positionId ? B(a.get(e.positionId)) : "未指定職位",
451
- " / ",
452
- e.isPrimary ? "主要" : "一般"
453
- ]
454
- }, e.id)) : /* @__PURE__ */ w(b, {
455
- color: "text-neutral",
456
- variant: "body",
457
- children: "尚未建立 BPM 組織歸屬"
458
- })
459
- })
460
- }),
461
- /* @__PURE__ */ w(c, {
462
- title: "主管解析",
463
- children: /* @__PURE__ */ w(b, {
464
- variant: "body",
465
- children: o?.managerMemberId ? V(e) : "尚未解析到主管"
466
- })
467
- })
468
- ]
469
- }) : null
470
- });
471
- }
472
- function z(e) {
473
- return e ? `${e.name} · ${e.code}` : "未知組織";
474
- }
475
- function B(e) {
476
- return e ? `${e.name} · ${e.code}` : "未知職位";
477
- }
478
- function V(t) {
479
- return t ? e(t.name, t.email, "dot") : "主管資料尚未載入";
480
- }
481
- function H(e) {
482
- return e instanceof Error ? e.message : "讀取會員資料失敗。";
483
- }
484
- export { R as t };
485
-
486
- //# sourceMappingURL=users-BBtiZ9QQ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"users-BBtiZ9QQ.js","names":["readErrorMessage","styles","_Fragment","styles","formatMemberLabel","MemberPicker","Fragment$1","ContentHeader","users_module_default","MemberTaskReassignModal","tasks","setTasks","useState","tasksLoading","setTasksLoading","target","setTarget","reason","setReason","preview","setPreview","committed","setCommitted","busy","setBusy","error","setError","trimmedReason","inputKey","previewIsCurrent","canConfirm","result","latestRequestRef","useRef","loadTasks","useCallback","request","loaded","listMemberOpenTasks","memberId","requestError","readErrorMessage$1","member","titleById","useMemo","task","runReassignment","outcomes","reassignMemberTasks","dryRun","shownResultRows","shownResults","shownTitleById","readOutcomeLabel","taskColumns","record","resultColumns","Modal","onClose","Typography","Table","BPMFormField","option","Input","event","Button","outcome","MEMBER_PAGE_SIZE_OPTIONS","AdminUsersView","detailMember","setDetailMember","detailMemberships","setDetailMemberships","detailManagerProfile","setDetailManagerProfile","detailResolvedManager","setDetailResolvedManager","inactiveMembers","setInactiveMembers","inactiveMembersError","setInactiveMembersError","loading","setLoading","memberPage","setMemberPage","memberPageSize","setMemberPageSize","memberTotalCount","setMemberTotalCount","members","setMembers","orgUnits","setOrgUnits","positions","setPositions","reassignMember","setReassignMember","searchText","setSearchText","orgUnitsById","orgUnit","positionsById","position","refreshMembers","memberPageResult","organization","listMemberDirectoryPage","readOrganizationDashboard","readErrorMessage","latestInactiveRequestRef","refreshInactiveMembers","listInactiveMembersWithOpenTasks","inactiveMemberRows","inactiveMemberColumns","inactiveMemberActions","rows","openDetail","memberships","resolvedManager","listMemberships","readResolvedManager","resolveMembers","columns","tableActions","closeDetail","PageHeader","SectionGroup","Section","FilterArea","FilterLine","Filter","FormField","FormFieldLayout","page","pageSize","from","to","total","MemberDetailModal","BaseCard","readOrgUnitLabel","membership","readPositionLabel","readMemberLabel","managerProfile"],"sources":["../../src/views/admin/users/MemberTaskReassignModal.tsx","../../src/views/admin/users/AdminUsersView.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChangeEvent,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Button, Input, Modal, Table, Typography } from '@mezzanine-ui/react';\nimport type { TableColumn } from '@mezzanine-ui/core/table';\nimport type { MemberProfileRecord } from '@rytass/bpm-core-client';\nimport {\n listMemberOpenTasks,\n type MemberOpenTaskRecord,\n reassignMemberTasks,\n type TaskReassignmentResultRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { MemberOption, MemberPicker } from '../../../components/admin-pickers';\nimport styles from './users.module.scss';\n\ntype TaskRow = Readonly<\n Record<string, unknown> &\n MemberOpenTaskRecord & {\n key: string;\n }\n>;\n\ntype ResultRow = Readonly<\n Record<string, unknown> & {\n instanceTitle: string;\n key: string;\n message: string | null;\n outcomeLabel: string;\n }\n>;\n\ninterface PreviewState {\n readonly inputKey: string;\n readonly results: readonly TaskReassignmentResultRecord[];\n}\n\n/**\n * A committed run keeps the titles it was started with: the task list reloads\n * right after, and a member whose every task moved no longer lists any of them.\n */\ninterface CommittedState {\n readonly results: readonly TaskReassignmentResultRecord[];\n readonly titleById: ReadonlyMap<string, string>;\n}\n\n/**\n * Administrator reassignment of a member's open tasks. Lists what the member\n * holds, takes a target and a reason, previews every task's outcome (dry run),\n * and only then commits. Confirm stays disabled until the preview matches the\n * current target and reason. Replacing a seat is not a decision: no signature\n * is written, and the task keeps its id.\n */\nexport function MemberTaskReassignModal({\n member,\n onClose,\n}: {\n readonly member: MemberProfileRecord | null;\n readonly onClose: () => void;\n}): ReactElement {\n const [tasks, setTasks] = useState<readonly MemberOpenTaskRecord[]>([]);\n const [tasksLoading, setTasksLoading] = useState(false);\n const [target, setTarget] = useState<MemberOption | null>(null);\n const [reason, setReason] = useState('');\n const [preview, setPreview] = useState<PreviewState | null>(null);\n const [committed, setCommitted] = useState<CommittedState | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const trimmedReason = reason.trim();\n const inputKey = `${target?.id ?? ''}|${trimmedReason}`;\n const previewIsCurrent = preview !== null && preview.inputKey === inputKey;\n const canConfirm =\n preview !== null &&\n previewIsCurrent &&\n preview.results.some((result) => result.outcome === 'WOULD_REASSIGN');\n\n // Only the latest request may write: switching members while an earlier\n // listing is in flight must not let its late answer replace the current one.\n const latestRequestRef = useRef(0);\n\n const loadTasks = useCallback(async (memberId: string): Promise<void> => {\n const request = latestRequestRef.current + 1;\n\n latestRequestRef.current = request;\n setTasksLoading(true);\n\n try {\n const loaded = await listMemberOpenTasks(memberId);\n\n if (latestRequestRef.current === request) {\n setTasks(loaded);\n }\n } catch (requestError: unknown) {\n if (latestRequestRef.current === request) {\n setError(readErrorMessage(requestError));\n }\n } finally {\n if (latestRequestRef.current === request) {\n setTasksLoading(false);\n }\n }\n }, []);\n\n useEffect((): void => {\n setTarget(null);\n setReason('');\n setPreview(null);\n setCommitted(null);\n setError(null);\n\n if (!member) {\n latestRequestRef.current += 1;\n setTasks([]);\n setTasksLoading(false);\n\n return;\n }\n\n setTasks([]);\n void loadTasks(member.memberId);\n }, [member, loadTasks]);\n\n const titleById = useMemo(\n (): ReadonlyMap<string, string> =>\n new Map(tasks.map((task) => [task.taskId, task.instanceTitle])),\n [tasks],\n );\n\n async function runReassignment(dryRun: boolean): Promise<void> {\n if (!member || !target || !trimmedReason) {\n return;\n }\n\n setBusy(true);\n setError(null);\n\n try {\n const outcomes = await reassignMemberTasks({\n dryRun,\n fromMemberId: member.memberId,\n reason: trimmedReason,\n toMemberId: target.id,\n });\n\n if (dryRun) {\n setPreview({ inputKey, results: outcomes });\n setCommitted(null);\n } else {\n setCommitted({ results: outcomes, titleById });\n setPreview(null);\n await loadTasks(member.memberId);\n }\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setBusy(false);\n }\n }\n\n const shownResultRows = useMemo((): ResultRow[] => {\n const shownResults = committed?.results ?? preview?.results ?? [];\n const shownTitleById = committed?.titleById ?? titleById;\n\n return shownResults.map((result) => ({\n instanceTitle: shownTitleById.get(result.taskId) ?? result.taskId,\n key: result.taskId,\n message: result.message,\n outcomeLabel: readOutcomeLabel(result.outcome),\n }));\n }, [committed, preview, titleById]);\n\n const taskColumns = useMemo(\n (): TableColumn<TaskRow>[] => [\n {\n dataIndex: 'instanceTitle',\n key: 'instanceTitle',\n title: '案件',\n width: 220,\n },\n {\n dataIndex: 'nodeLabel',\n key: 'nodeLabel',\n title: '節點',\n width: 160,\n },\n {\n key: 'memberRole',\n render: (record: TaskRow): string =>\n record.memberRole === 'ASSIGNEE' ? '指派人' : '會簽候選人',\n title: '身分',\n width: 120,\n },\n ],\n [],\n );\n const resultColumns = useMemo(\n (): TableColumn<ResultRow>[] => [\n {\n dataIndex: 'instanceTitle',\n key: 'instanceTitle',\n title: '案件',\n width: 220,\n },\n {\n dataIndex: 'outcomeLabel',\n key: 'outcomeLabel',\n title: '結果',\n width: 100,\n },\n {\n dataIndex: 'message',\n key: 'message',\n title: '說明',\n width: 160,\n },\n ],\n [],\n );\n\n return (\n <Modal\n cancelText=\"關閉\"\n confirmButtonProps={{ disabled: !canConfirm || busy }}\n confirmText=\"確認改派\"\n loading={busy}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void => {\n void runReassignment(false);\n }}\n open={Boolean(member)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={member ? `改派待辦:${member.name}` : '改派待辦'}\n >\n {member ? (\n <div className={styles.detailFields}>\n <Typography variant=\"body\">\n 改派會保留任務編號,但不產生簽核紀錄;原簽核人的待辦會結案為已轉交,\n 接手人會收到新的待辦通知。\n </Typography>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {tasks.length ? (\n <Table\n columns={taskColumns}\n dataSource={tasks.map((task): TaskRow => ({\n ...task,\n key: task.taskId,\n }))}\n fullWidth\n loading={tasksLoading}\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n {tasksLoading ? '載入待辦中…' : '此成員目前沒有待簽任務。'}\n </Typography>\n )}\n <BPMFormField label=\"接手人\" name=\"reassignTarget\">\n <MemberPicker\n name=\"reassignTarget\"\n onChange={(option): void => {\n setTarget(option);\n setPreview(null);\n setCommitted(null);\n }}\n placeholder=\"搜尋接手人姓名或信箱\"\n value={target}\n />\n </BPMFormField>\n <BPMFormField label=\"改派原因\" name=\"reassignReason\">\n <Input\n fullWidth\n name=\"reassignReason\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void => {\n setReason(event.target.value);\n setPreview(null);\n setCommitted(null);\n }}\n placeholder=\"例如:原簽核人已離職\"\n value={reason}\n />\n </BPMFormField>\n <div className={styles.membershipList}>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 先按「預覽」確認每筆任務的結果,確認無誤後再按「確認改派」。\n </Typography>\n <div>\n <Button\n disabled={\n busy || !target || !trimmedReason || tasks.length === 0\n }\n onClick={(): void => {\n void runReassignment(true);\n }}\n variant=\"base-secondary\"\n >\n 預覽\n </Button>\n </div>\n </div>\n {shownResultRows.length ? (\n <Table\n columns={resultColumns}\n dataSource={shownResultRows}\n fullWidth\n />\n ) : null}\n </div>\n ) : null}\n </Modal>\n );\n}\n\nfunction readOutcomeLabel(\n outcome: TaskReassignmentResultRecord['outcome'],\n): string {\n if (outcome === 'WOULD_REASSIGN') {\n return '會改派';\n }\n\n if (outcome === 'REASSIGNED') {\n return '已改派';\n }\n\n return '會被拒';\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '改派待辦失敗。';\n}\n","'use client';\n\nimport {\n ChangeEvent,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n BaseCard,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { formatMemberLabel } from '../../../lib/format-member-label';\nimport styles from './users.module.scss';\nimport { MemberTaskReassignModal } from './MemberTaskReassignModal';\nimport {\n listMemberDirectoryPage,\n MemberProfileRecord,\n resolveMembers,\n} from '@rytass/bpm-core-client';\nimport {\n listMemberships,\n MembershipRecord,\n OrgUnitRecord,\n PositionRecord,\n readOrganizationDashboard,\n readResolvedManager,\n ResolvedManagerRecord,\n} from '@rytass/bpm-core-client/organization';\nimport {\n type InactiveMemberWithOpenTasksRecord,\n listInactiveMembersWithOpenTasks,\n} from '@rytass/bpm-core-client/workflow';\n\ntype MemberRow = Readonly<\n Record<string, unknown> &\n MemberProfileRecord & {\n key: string;\n }\n>;\n\ntype InactiveMemberRow = Readonly<\n Record<string, unknown> &\n InactiveMemberWithOpenTasksRecord & {\n key: string;\n }\n>;\n\nconst MEMBER_PAGE_SIZE_OPTIONS = [10, 20, 50];\n\nexport function AdminUsersView(): ReactElement {\n const [detailMember, setDetailMember] = useState<MemberProfileRecord | null>(\n null,\n );\n const [detailMemberships, setDetailMemberships] = useState<\n readonly MembershipRecord[]\n >([]);\n const [detailManagerProfile, setDetailManagerProfile] =\n useState<MemberProfileRecord | null>(null);\n const [detailResolvedManager, setDetailResolvedManager] =\n useState<ResolvedManagerRecord | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [inactiveMembers, setInactiveMembers] = useState<\n readonly InactiveMemberWithOpenTasksRecord[]\n >([]);\n const [inactiveMembersError, setInactiveMembersError] = useState<\n string | null\n >(null);\n const [loading, setLoading] = useState(true);\n const [memberPage, setMemberPage] = useState(1);\n const [memberPageSize, setMemberPageSize] = useState(10);\n const [memberTotalCount, setMemberTotalCount] = useState(0);\n const [members, setMembers] = useState<readonly MemberProfileRecord[]>([]);\n const [orgUnits, setOrgUnits] = useState<readonly OrgUnitRecord[]>([]);\n const [positions, setPositions] = useState<readonly PositionRecord[]>([]);\n const [reassignMember, setReassignMember] =\n useState<MemberProfileRecord | null>(null);\n const [searchText, setSearchText] = useState('');\n\n const orgUnitsById = useMemo(\n (): ReadonlyMap<string, OrgUnitRecord> =>\n new Map(orgUnits.map((orgUnit) => [orgUnit.id, orgUnit])),\n [orgUnits],\n );\n const positionsById = useMemo(\n (): ReadonlyMap<string, PositionRecord> =>\n new Map(positions.map((position) => [position.id, position])),\n [positions],\n );\n\n const refreshMembers = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const [memberPageResult, organization] = await Promise.all([\n listMemberDirectoryPage({\n page: memberPage,\n pageSize: memberPageSize,\n searchText,\n }),\n readOrganizationDashboard(),\n ]);\n\n setMembers(memberPageResult.members);\n setMemberTotalCount(memberPageResult.totalCount);\n setOrgUnits(organization.orgUnits);\n setPositions(organization.positions);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [memberPage, memberPageSize, searchText]);\n\n useEffect((): void => {\n void refreshMembers();\n }, [refreshMembers]);\n\n const latestInactiveRequestRef = useRef(0);\n\n // Loaded on its own so a failure here leaves the member directory usable.\n // Only the latest request may write: a reload started when the reassignment\n // closes must not be overwritten by an earlier one answering late.\n const refreshInactiveMembers = useCallback(async (): Promise<void> => {\n const request = latestInactiveRequestRef.current + 1;\n\n latestInactiveRequestRef.current = request;\n\n try {\n const loaded = await listInactiveMembersWithOpenTasks();\n\n if (latestInactiveRequestRef.current === request) {\n setInactiveMembers(loaded);\n setInactiveMembersError(null);\n }\n } catch (requestError: unknown) {\n if (latestInactiveRequestRef.current === request) {\n setInactiveMembersError(readErrorMessage(requestError));\n }\n }\n }, []);\n\n useEffect((): void => {\n void refreshInactiveMembers();\n }, [refreshInactiveMembers]);\n\n const inactiveMemberRows = useMemo(\n (): InactiveMemberRow[] =>\n inactiveMembers.map(\n (member): InactiveMemberRow => ({ ...member, key: member.memberId }),\n ),\n [inactiveMembers],\n );\n const inactiveMemberColumns = useMemo(\n (): TableColumn<InactiveMemberRow>[] => [\n { dataIndex: 'name', key: 'name', title: '姓名', width: 160 },\n { dataIndex: 'email', key: 'email', title: '信箱', width: 260 },\n {\n dataIndex: 'openTaskCount',\n key: 'openTaskCount',\n title: '待簽數',\n width: 96,\n },\n ],\n [],\n );\n const inactiveMemberActions = useMemo(\n (): TableActions<InactiveMemberRow> => ({\n render: (): ReturnType<TableActions<InactiveMemberRow>['render']> => [\n {\n name: '改派待辦',\n onClick: (record): void => {\n setReassignMember({\n customFieldsJson: '{}',\n email: record.email,\n memberId: record.memberId,\n name: record.name,\n });\n },\n },\n ],\n variant: 'base-secondary',\n width: 112,\n }),\n [],\n );\n\n const rows = useMemo(\n (): MemberRow[] =>\n members.map((member) => ({\n ...member,\n key: member.memberId,\n })),\n [members],\n );\n\n const openDetail = useCallback(\n async (member: MemberProfileRecord): Promise<void> => {\n setDetailMember(member);\n setDetailManagerProfile(null);\n setError(null);\n\n try {\n const [memberships, resolvedManager] = await Promise.all([\n listMemberships({ memberId: member.memberId }),\n readResolvedManager(member.memberId),\n ]);\n\n setDetailMemberships(memberships);\n setDetailResolvedManager(resolvedManager);\n setDetailManagerProfile(\n (\n await resolveMembers(\n resolvedManager.managerMemberId\n ? [resolvedManager.managerMemberId]\n : [],\n )\n )[0] ?? null,\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n }\n },\n [],\n );\n\n const columns = useMemo(\n (): TableColumn<MemberRow>[] => [\n { dataIndex: 'name', key: 'name', title: '姓名', width: 160 },\n { dataIndex: 'email', key: 'email', title: '信箱', width: 260 },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<MemberRow> => ({\n render: (): ReturnType<TableActions<MemberRow>['render']> => [\n {\n name: '檢視',\n onClick: (record): void => {\n void openDetail(record);\n },\n },\n {\n name: '改派待辦',\n onClick: (record): void => {\n setReassignMember(record);\n },\n },\n ],\n variant: 'base-secondary',\n width: 176,\n }),\n [openDetail],\n );\n\n function closeDetail(): void {\n setDetailMember(null);\n setDetailManagerProfile(null);\n setDetailMemberships([]);\n setDetailResolvedManager(null);\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"會員資料由 host member resolver 提供,BPM 僅維護組織歸屬與主管解析。\"\n title=\"會員對照\"\n />\n </PageHeader>\n\n <SectionGroup>\n {inactiveMemberRows.length || inactiveMembersError ? (\n <Section\n contentHeader={\n <ContentHeader\n description=\"這些會員已停用,身上仍有待簽,請改派給在職的人。\"\n title=\"已停用、仍有待簽的會員\"\n />\n }\n >\n <div data-inactive-members=\"\">\n {inactiveMembersError ? (\n <Typography color=\"text-error\" variant=\"body\">\n {inactiveMembersError}\n </Typography>\n ) : (\n <Table\n actions={inactiveMemberActions}\n columns={inactiveMemberColumns}\n dataSource={inactiveMemberRows}\n fullWidth\n />\n )}\n </div>\n </Section>\n ) : null}\n <Section\n filterArea={\n <FilterArea className={styles.memberFilterArea}>\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"memberSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setSearchText(event.target.value);\n setMemberPage(1);\n }}\n placeholder=\"搜尋姓名或信箱\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\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: memberPage,\n onChange: (page): void => {\n setMemberPage(page);\n },\n onChangePageSize: (pageSize): void => {\n setMemberPage(1);\n setMemberPageSize(pageSize);\n },\n pageSize: memberPageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: MEMBER_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: memberTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n\n <MemberTaskReassignModal\n member={reassignMember}\n onClose={(): void => {\n setReassignMember(null);\n // A reassignment may have cleared someone off the list.\n void refreshInactiveMembers();\n }}\n />\n\n <MemberDetailModal\n managerProfile={detailManagerProfile}\n member={detailMember}\n memberships={detailMemberships}\n onClose={closeDetail}\n orgUnitsById={orgUnitsById}\n positionsById={positionsById}\n resolvedManager={detailResolvedManager}\n />\n </>\n );\n}\n\nfunction MemberDetailModal({\n managerProfile,\n member,\n memberships,\n onClose,\n orgUnitsById,\n positionsById,\n resolvedManager,\n}: {\n readonly managerProfile: MemberProfileRecord | null;\n readonly member: MemberProfileRecord | null;\n readonly memberships: readonly MembershipRecord[];\n readonly onClose: () => void;\n readonly orgUnitsById: ReadonlyMap<string, OrgUnitRecord>;\n readonly positionsById: ReadonlyMap<string, PositionRecord>;\n readonly resolvedManager: ResolvedManagerRecord | null;\n}): ReactElement {\n return (\n <Modal\n cancelText=\"關閉\"\n confirmText=\"關閉\"\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={onClose}\n open={Boolean(member)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={member?.name ?? '會員明細'}\n >\n {member ? (\n <div className={styles.detailFields}>\n <BaseCard title=\"基本資料\">\n <div className={styles.detailSection}>\n <Typography variant=\"body\">\n 信箱:{member.email?.trim() ? member.email : '未設定'}\n </Typography>\n </div>\n </BaseCard>\n <BaseCard title=\"BPM 組織歸屬\">\n <div className={styles.membershipList}>\n {memberships.length ? (\n memberships.map((membership) => (\n <Typography key={membership.id} variant=\"body\">\n {readOrgUnitLabel(orgUnitsById.get(membership.orgUnitId))}\n {' / '}\n {membership.positionId\n ? readPositionLabel(\n positionsById.get(membership.positionId),\n )\n : '未指定職位'}\n {' / '}\n {membership.isPrimary ? '主要' : '一般'}\n </Typography>\n ))\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 尚未建立 BPM 組織歸屬\n </Typography>\n )}\n </div>\n </BaseCard>\n <BaseCard title=\"主管解析\">\n <Typography variant=\"body\">\n {resolvedManager?.managerMemberId\n ? readMemberLabel(managerProfile)\n : '尚未解析到主管'}\n </Typography>\n </BaseCard>\n </div>\n ) : null}\n </Modal>\n );\n}\n\nfunction readOrgUnitLabel(orgUnit: OrgUnitRecord | undefined): string {\n return orgUnit ? `${orgUnit.name} · ${orgUnit.code}` : '未知組織';\n}\n\nfunction readPositionLabel(position: PositionRecord | undefined): string {\n return position ? `${position.name} · ${position.code}` : '未知職位';\n}\n\nfunction readMemberLabel(member: MemberProfileRecord | null): string {\n return member\n ? formatMemberLabel(member.name, member.email, 'dot')\n : '主管資料尚未載入';\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取會員資料失敗。';\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use client";require('../users.css');const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./format-member-label-t7ANTF62.cjs"),n=require("./bpm-form-field-Bc6k4ZEO.cjs"),r=require("./admin-pickers-BjbkBpSJ.cjs");let i=require("react"),a=require("@mezzanine-ui/react"),o=require("@rytass/bpm-core-client"),s=require("react/jsx-runtime"),c=require("@rytass/bpm-core-client/workflow"),l=require("@mezzanine-ui/core/form"),u=require("@mezzanine-ui/react/ContentHeader");u=e.t(u,1);let d=require("@rytass/bpm-core-client/organization");var f={memberFilterArea:`bpm_memberFilterArea_9RB2k`,header:`bpm_header_sIEtg`,detailFields:`bpm_detailFields_TyKNL`,detailSection:`bpm_detailSection_-iLjy`,membershipList:`bpm_membershipList_5n9iq`};function p({member:e,onClose:t}){let[o,l]=(0,i.useState)([]),[u,d]=(0,i.useState)(!1),[p,g]=(0,i.useState)(null),[_,v]=(0,i.useState)(``),[y,b]=(0,i.useState)(null),[x,S]=(0,i.useState)(null),[C,w]=(0,i.useState)(!1),[T,E]=(0,i.useState)(null),D=_.trim(),O=`${p?.id??``}|${D}`,k=y!==null&&y.inputKey===O,A=y!==null&&k&&y.results.some(e=>e.outcome===`WOULD_REASSIGN`),j=(0,i.useRef)(0),M=(0,i.useCallback)(async e=>{let t=j.current+1;j.current=t,d(!0);try{let n=await(0,c.listMemberOpenTasks)(e);j.current===t&&l(n)}catch(e){j.current===t&&E(h(e))}finally{j.current===t&&d(!1)}},[]);(0,i.useEffect)(()=>{g(null),v(``),b(null),S(null),E(null),e?(l([]),M(e.memberId)):(j.current+=1,l([]),d(!1))},[e,M]);let N=(0,i.useMemo)(()=>new Map(o.map(e=>[e.taskId,e.instanceTitle])),[o]);async function P(t){if(e&&p&&D){w(!0),E(null);try{let n=await(0,c.reassignMemberTasks)({dryRun:t,fromMemberId:e.memberId,reason:D,toMemberId:p.id});t?(b({inputKey:O,results:n}),S(null)):(S({results:n,titleById:N}),b(null),await M(e.memberId))}catch(e){E(h(e))}finally{w(!1)}}}let F=(0,i.useMemo)(()=>{let e=x?.results??y?.results??[],t=x?.titleById??N;return e.map(e=>({instanceTitle:t.get(e.taskId)??e.taskId,key:e.taskId,message:e.message,outcomeLabel:m(e.outcome)}))},[x,y,N]),I=(0,i.useMemo)(()=>[{dataIndex:`instanceTitle`,key:`instanceTitle`,title:`案件`,width:220},{dataIndex:`nodeLabel`,key:`nodeLabel`,title:`節點`,width:160},{key:`memberRole`,render:e=>e.memberRole===`ASSIGNEE`?`指派人`:`會簽候選人`,title:`身分`,width:120}],[]),L=(0,i.useMemo)(()=>[{dataIndex:`instanceTitle`,key:`instanceTitle`,title:`案件`,width:220},{dataIndex:`outcomeLabel`,key:`outcomeLabel`,title:`結果`,width:100},{dataIndex:`message`,key:`message`,title:`說明`,width:160}],[]);return(0,s.jsx)(a.Modal,{cancelText:`關閉`,confirmButtonProps:{disabled:!A||C},confirmText:`確認改派`,loading:C,modalType:`standard`,onCancel:t,onClose:t,onConfirm:()=>{P(!1)},open:!!e,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:e?`改派待辦:${e.name}`:`改派待辦`,children:e?(0,s.jsxs)(`div`,{className:f.detailFields,children:[(0,s.jsx)(a.Typography,{variant:`body`,children:`改派會保留任務編號,但不產生簽核紀錄;原簽核人的待辦會結案為已轉交, 接手人會收到新的待辦通知。`}),T?(0,s.jsx)(a.Typography,{color:`text-error`,variant:`body`,children:T}):null,o.length?(0,s.jsx)(a.Table,{columns:I,dataSource:o.map(e=>({...e,key:e.taskId})),fullWidth:!0,loading:u}):(0,s.jsx)(a.Typography,{color:`text-neutral`,variant:`body`,children:u?`載入待辦中…`:`此成員目前沒有待簽任務。`}),(0,s.jsx)(n.t,{label:`接手人`,name:`reassignTarget`,children:(0,s.jsx)(r.t,{name:`reassignTarget`,onChange:e=>{g(e),b(null),S(null)},placeholder:`搜尋接手人姓名或信箱`,value:p})}),(0,s.jsx)(n.t,{label:`改派原因`,name:`reassignReason`,children:(0,s.jsx)(a.Input,{fullWidth:!0,name:`reassignReason`,onChange:e=>{v(e.target.value),b(null),S(null)},placeholder:`例如:原簽核人已離職`,value:_})}),(0,s.jsxs)(`div`,{className:f.membershipList,children:[(0,s.jsx)(a.Typography,{color:`text-neutral`,variant:`caption`,children:`先按「預覽」確認每筆任務的結果,確認無誤後再按「確認改派」。`}),(0,s.jsx)(`div`,{children:(0,s.jsx)(a.Button,{disabled:C||!p||!D||o.length===0,onClick:()=>{P(!0)},variant:`base-secondary`,children:`預覽`})})]}),F.length?(0,s.jsx)(a.Table,{columns:L,dataSource:F,fullWidth:!0}):null]}):null})}function m(e){return e===`WOULD_REASSIGN`?`會改派`:e===`REASSIGNED`?`已改派`:`會被拒`}function h(e){return e instanceof Error?e.message:`改派待辦失敗。`}var g=[10,20,50];function _(){let[e,t]=(0,i.useState)(null),[n,r]=(0,i.useState)([]),[m,h]=(0,i.useState)(null),[_,y]=(0,i.useState)(null),[b,x]=(0,i.useState)(null),[C,w]=(0,i.useState)([]),[T,E]=(0,i.useState)(null),[D,O]=(0,i.useState)(!0),[k,A]=(0,i.useState)(1),[j,M]=(0,i.useState)(10),[N,P]=(0,i.useState)(0),[F,I]=(0,i.useState)([]),[L,R]=(0,i.useState)([]),[z,B]=(0,i.useState)([]),[V,H]=(0,i.useState)(null),[U,W]=(0,i.useState)(``),G=(0,i.useMemo)(()=>new Map(L.map(e=>[e.id,e])),[L]),K=(0,i.useMemo)(()=>new Map(z.map(e=>[e.id,e])),[z]),q=(0,i.useCallback)(async()=>{O(!0),x(null);try{let[e,t]=await Promise.all([(0,o.listMemberDirectoryPage)({page:k,pageSize:j,searchText:U}),(0,d.readOrganizationDashboard)()]);I(e.members),P(e.totalCount),R(t.orgUnits),B(t.positions)}catch(e){x(S(e))}finally{O(!1)}},[k,j,U]);(0,i.useEffect)(()=>{q()},[q]);let J=(0,i.useRef)(0),Y=(0,i.useCallback)(async()=>{let e=J.current+1;J.current=e;try{let t=await(0,c.listInactiveMembersWithOpenTasks)();J.current===e&&(w(t),E(null))}catch(t){J.current===e&&E(S(t))}},[]);(0,i.useEffect)(()=>{Y()},[Y]);let X=(0,i.useMemo)(()=>C.map(e=>({...e,key:e.memberId})),[C]),Z=(0,i.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`姓名`,width:160},{dataIndex:`email`,key:`email`,title:`信箱`,width:260},{dataIndex:`openTaskCount`,key:`openTaskCount`,title:`待簽數`,width:96}],[]),Q=(0,i.useMemo)(()=>({render:()=>[{name:`改派待辦`,onClick:e=>{H({customFieldsJson:`{}`,email:e.email,memberId:e.memberId,name:e.name})}}],variant:`base-secondary`,width:112}),[]),ee=(0,i.useMemo)(()=>F.map(e=>({...e,key:e.memberId})),[F]),$=(0,i.useCallback)(async e=>{t(e),h(null),x(null);try{let[t,n]=await Promise.all([(0,d.listMemberships)({memberId:e.memberId}),(0,d.readResolvedManager)(e.memberId)]);r(t),y(n),h((await(0,o.resolveMembers)(n.managerMemberId?[n.managerMemberId]:[]))[0]??null)}catch(e){x(S(e))}},[]),te=(0,i.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`姓名`,width:160},{dataIndex:`email`,key:`email`,title:`信箱`,width:260}],[]),ne=(0,i.useMemo)(()=>({render:()=>[{name:`檢視`,onClick:e=>{$(e)}},{name:`改派待辦`,onClick:e=>{H(e)}}],variant:`base-secondary`,width:176}),[$]);function re(){t(null),h(null),r([]),y(null)}return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(a.PageHeader,{children:(0,s.jsx)(u.default,{description:`會員資料由 host member resolver 提供,BPM 僅維護組織歸屬與主管解析。`,title:`會員對照`})}),(0,s.jsxs)(a.SectionGroup,{children:[X.length||T?(0,s.jsx)(a.Section,{contentHeader:(0,s.jsx)(u.default,{description:`這些會員已停用,身上仍有待簽,請改派給在職的人。`,title:`已停用、仍有待簽的會員`}),children:(0,s.jsx)(`div`,{"data-inactive-members":``,children:T?(0,s.jsx)(a.Typography,{color:`text-error`,variant:`body`,children:T}):(0,s.jsx)(a.Table,{actions:Q,columns:Z,dataSource:X,fullWidth:!0})})}):null,(0,s.jsxs)(a.Section,{filterArea:(0,s.jsx)(a.FilterArea,{className:f.memberFilterArea,children:(0,s.jsx)(a.FilterLine,{children:(0,s.jsx)(a.Filter,{span:3,children:(0,s.jsx)(a.FormField,{fullWidth:!0,layout:l.FormFieldLayout.VERTICAL,name:`memberSearchText`,children:(0,s.jsx)(a.Input,{fullWidth:!0,onChange:e=>{W(e.target.value),A(1)},placeholder:`搜尋姓名或信箱`,size:`sub`,value:U,variant:`base`})})})})}),children:[b?(0,s.jsx)(a.Typography,{color:`text-error`,variant:`body`,children:b}):null,(0,s.jsx)(a.Table,{actions:ne,columns:te,dataSource:ee,fullWidth:!0,loading:D,pagination:{current:k,onChange:e=>{A(e)},onChangePageSize:e=>{A(1),M(e)},pageSize:j,pageSizeLabel:`每頁筆數`,pageSizeOptions:g,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:N}})]})]}),(0,s.jsx)(p,{member:V,onClose:()=>{H(null),Y()}}),(0,s.jsx)(v,{managerProfile:m,member:e,memberships:n,onClose:re,orgUnitsById:G,positionsById:K,resolvedManager:_})]})}function v({managerProfile:e,member:t,memberships:n,onClose:r,orgUnitsById:i,positionsById:o,resolvedManager:c}){return(0,s.jsx)(a.Modal,{cancelText:`關閉`,confirmText:`關閉`,modalType:`standard`,onCancel:r,onClose:r,onConfirm:r,open:!!t,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:t?.name??`會員明細`,children:t?(0,s.jsxs)(`div`,{className:f.detailFields,children:[(0,s.jsx)(a.BaseCard,{title:`基本資料`,children:(0,s.jsx)(`div`,{className:f.detailSection,children:(0,s.jsxs)(a.Typography,{variant:`body`,children:[`信箱:`,t.email?.trim()?t.email:`未設定`]})})}),(0,s.jsx)(a.BaseCard,{title:`BPM 組織歸屬`,children:(0,s.jsx)(`div`,{className:f.membershipList,children:n.length?n.map(e=>(0,s.jsxs)(a.Typography,{variant:`body`,children:[y(i.get(e.orgUnitId)),` / `,e.positionId?b(o.get(e.positionId)):`未指定職位`,` / `,e.isPrimary?`主要`:`一般`]},e.id)):(0,s.jsx)(a.Typography,{color:`text-neutral`,variant:`body`,children:`尚未建立 BPM 組織歸屬`})})}),(0,s.jsx)(a.BaseCard,{title:`主管解析`,children:(0,s.jsx)(a.Typography,{variant:`body`,children:c?.managerMemberId?x(e):`尚未解析到主管`})})]}):null})}function y(e){return e?`${e.name} · ${e.code}`:`未知組織`}function b(e){return e?`${e.name} · ${e.code}`:`未知職位`}function x(e){return e?t.t(e.name,e.email,`dot`):`主管資料尚未載入`}function S(e){return e instanceof Error?e.message:`讀取會員資料失敗。`}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return _}});
2
- //# sourceMappingURL=users-EqSzDhuj.cjs.map