@rytass/bpm-core-react 0.23.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.
- package/CHANGELOG.md +33 -0
- package/README.md +1 -0
- package/dist/chunks/{FormBuilderView-bm8P55hp.cjs → FormBuilderView-Bg9ftYz-.cjs} +2 -2
- package/dist/chunks/{FormBuilderView-bm8P55hp.cjs.map → FormBuilderView-Bg9ftYz-.cjs.map} +1 -1
- package/dist/chunks/{FormBuilderView-D_bN9gzT.js → FormBuilderView-CBvdcg_t.js} +2 -2
- package/dist/chunks/{FormBuilderView-D_bN9gzT.js.map → FormBuilderView-CBvdcg_t.js.map} +1 -1
- package/dist/chunks/FormRendererView-D-p6GDQB.cjs +6 -0
- package/dist/chunks/FormRendererView-D-p6GDQB.cjs.map +1 -0
- package/dist/chunks/FormRendererView-DHXmekC3.js +1319 -0
- package/dist/chunks/FormRendererView-DHXmekC3.js.map +1 -0
- package/dist/chunks/{approval-instance-list-page-Cv5I1YPX.cjs → approval-instance-list-page-BqkG9jiR.cjs} +2 -2
- package/dist/chunks/{approval-instance-list-page-Cv5I1YPX.cjs.map → approval-instance-list-page-BqkG9jiR.cjs.map} +1 -1
- package/dist/chunks/{approval-instance-list-page-BI5fIXc-.js → approval-instance-list-page-CsSpIN4C.js} +2 -2
- package/dist/chunks/{approval-instance-list-page-BI5fIXc-.js.map → approval-instance-list-page-CsSpIN4C.js.map} +1 -1
- package/dist/chunks/{compose-CdKVQfjB.cjs → compose-B43jtdyL.cjs} +2 -2
- package/dist/chunks/{compose-CdKVQfjB.cjs.map → compose-B43jtdyL.cjs.map} +1 -1
- package/dist/chunks/{compose-N9657E5u.js → compose-C7yS6bJm.js} +5 -5
- package/dist/chunks/{compose-N9657E5u.js.map → compose-C7yS6bJm.js.map} +1 -1
- package/dist/chunks/{dashboard-page-BoqNhjT_.js → dashboard-page-DBJCsPya.js} +2 -2
- package/dist/chunks/{dashboard-page-BoqNhjT_.js.map → dashboard-page-DBJCsPya.js.map} +1 -1
- package/dist/chunks/{dashboard-page-D7YJ3udk.cjs → dashboard-page-lqlLELKs.cjs} +2 -2
- package/dist/chunks/{dashboard-page-D7YJ3udk.cjs.map → dashboard-page-lqlLELKs.cjs.map} +1 -1
- package/dist/chunks/{designer-CKwG_vM5.js → designer-B9Ut4xze.js} +1736 -1611
- package/dist/chunks/designer-B9Ut4xze.js.map +1 -0
- package/dist/chunks/designer-eXw7R9ug.cjs +69 -0
- package/dist/chunks/designer-eXw7R9ug.cjs.map +1 -0
- package/dist/chunks/{detail-fW0vJudE.js → detail-BB_uYaoM.js} +7 -6
- package/dist/chunks/detail-BB_uYaoM.js.map +1 -0
- package/dist/chunks/detail-DN8pEzUJ.cjs +5 -0
- package/dist/chunks/detail-DN8pEzUJ.cjs.map +1 -0
- package/dist/chunks/member-profile-resolution-CJlgVdTR.js +44 -0
- package/dist/chunks/member-profile-resolution-CJlgVdTR.js.map +1 -0
- package/dist/chunks/member-profile-resolution-DiH-P-Vh.cjs +2 -0
- package/dist/chunks/member-profile-resolution-DiH-P-Vh.cjs.map +1 -0
- package/dist/chunks/{providers-CQWekD7_.js → providers-D35lBOTd.js} +2 -2
- package/dist/chunks/{providers-CQWekD7_.js.map → providers-D35lBOTd.js.map} +1 -1
- package/dist/chunks/{providers-VUOh6i0i.cjs → providers-Dz4Wqxr6.cjs} +2 -2
- package/dist/chunks/{providers-VUOh6i0i.cjs.map → providers-Dz4Wqxr6.cjs.map} +1 -1
- package/dist/chunks/{routes-config-C1j_vFKo.cjs → routes-config-BWjZDAU3.cjs} +2 -2
- package/dist/chunks/{routes-config-C1j_vFKo.cjs.map → routes-config-BWjZDAU3.cjs.map} +1 -1
- package/dist/chunks/{routes-config-BcNaWJWJ.js → routes-config-DjEOE9eP.js} +3 -2
- package/dist/chunks/{routes-config-BcNaWJWJ.js.map → routes-config-DjEOE9eP.js.map} +1 -1
- package/dist/chunks/users-C_Dtw_sR.cjs +2 -0
- package/dist/chunks/users-C_Dtw_sR.cjs.map +1 -0
- package/dist/chunks/users-wgM3TqU3.js +513 -0
- package/dist/chunks/users-wgM3TqU3.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +4 -4
- package/dist/lib/routes-config.d.cts +2 -0
- package/dist/lib/routes-config.d.ts +2 -0
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.js +2 -2
- package/dist/pages/admin/stuck-instances/index.cjs +2 -0
- package/dist/pages/admin/stuck-instances/index.cjs.map +1 -0
- package/dist/pages/admin/stuck-instances/index.d.cts +4 -0
- package/dist/pages/admin/stuck-instances/index.d.ts +4 -0
- package/dist/pages/admin/stuck-instances/index.js +13 -0
- package/dist/pages/admin/stuck-instances/index.js.map +1 -0
- package/dist/pages/admin/users/index.cjs +1 -1
- package/dist/pages/admin/users/index.js +1 -1
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/templates/compose/index.cjs +1 -1
- package/dist/pages/templates/compose/index.js +1 -1
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.d.cts +1 -0
- package/dist/views/admin/index.d.ts +1 -0
- package/dist/views/admin/index.js +3 -2
- package/dist/views/admin/stuck-instances/AdminStuckInstancesView.d.cts +10 -0
- package/dist/views/admin/stuck-instances/AdminStuckInstancesView.d.ts +10 -0
- package/dist/views/admin/stuck-instances/StuckInstanceCancelModal.d.cts +14 -0
- package/dist/views/admin/stuck-instances/StuckInstanceCancelModal.d.ts +14 -0
- package/dist/views/admin/stuck-instances/index.cjs +2 -0
- package/dist/views/admin/stuck-instances/index.cjs.map +1 -0
- package/dist/views/admin/stuck-instances/index.d.cts +2 -0
- package/dist/views/admin/stuck-instances/index.d.ts +2 -0
- package/dist/views/admin/stuck-instances/index.js +237 -0
- package/dist/views/admin/stuck-instances/index.js.map +1 -0
- package/dist/views/admin/users/index.cjs +1 -1
- package/dist/views/admin/users/index.js +1 -1
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.js +1 -1
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.js +1 -1
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/renderer/index.cjs +1 -1
- package/dist/views/forms/renderer/index.js +1 -1
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.js +1 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.js +4 -4
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.js +1 -1
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.js +1 -1
- package/dist/views/templates/compose/index.cjs +1 -1
- package/dist/views/templates/compose/index.js +1 -1
- package/dist/views/templates/designer/approver-resolver-model.d.cts +31 -0
- package/dist/views/templates/designer/approver-resolver-model.d.ts +31 -0
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/dist/views/templates/designer/node-actor-resolver-options.d.cts +30 -3
- package/dist/views/templates/designer/node-actor-resolver-options.d.ts +30 -3
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.js +1 -1
- package/dist/views/templates/versions/index.cjs +1 -1
- package/dist/views/templates/versions/index.js +1 -1
- package/package.json +23 -3
- package/dist/chunks/FormRendererView-BlQgJOkI.cjs +0 -6
- package/dist/chunks/FormRendererView-BlQgJOkI.cjs.map +0 -1
- package/dist/chunks/FormRendererView-CemHvfAT.js +0 -1359
- package/dist/chunks/FormRendererView-CemHvfAT.js.map +0 -1
- package/dist/chunks/designer-CKwG_vM5.js.map +0 -1
- package/dist/chunks/designer-JPs7EijM.cjs +0 -69
- package/dist/chunks/designer-JPs7EijM.cjs.map +0 -1
- package/dist/chunks/detail-Dqu0K9QM.cjs +0 -5
- package/dist/chunks/detail-Dqu0K9QM.cjs.map +0 -1
- package/dist/chunks/detail-fW0vJudE.js.map +0 -1
- package/dist/chunks/users-BBtiZ9QQ.js +0 -486
- package/dist/chunks/users-BBtiZ9QQ.js.map +0 -1
- package/dist/chunks/users-EqSzDhuj.cjs +0 -2
- 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
|