@rytass/bpm-core-react 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/dist/chunks/{app-navigation-BRRFCkxZ.cjs → app-navigation-C_mbz7jx.cjs} +2 -2
- package/dist/chunks/app-navigation-C_mbz7jx.cjs.map +1 -0
- package/dist/chunks/{app-navigation-rxhpHCch.js → app-navigation-uwbNEw9P.js} +65 -65
- package/dist/chunks/app-navigation-uwbNEw9P.js.map +1 -0
- package/dist/chunks/approval-instance-list-page-Mo6wpDPb.cjs +2 -0
- package/dist/chunks/approval-instance-list-page-Mo6wpDPb.cjs.map +1 -0
- package/dist/chunks/approval-instance-list-page-nmzMrj0b.js +281 -0
- package/dist/chunks/approval-instance-list-page-nmzMrj0b.js.map +1 -0
- package/dist/chunks/builder-DPhAH381.cjs +3 -0
- package/dist/chunks/builder-DPhAH381.cjs.map +1 -0
- package/dist/chunks/{builder-Du_0apkh.js → builder-DqZskyXC.js} +333 -330
- package/dist/chunks/builder-DqZskyXC.js.map +1 -0
- package/dist/chunks/categories-DEijUOnw.cjs +2 -0
- package/dist/chunks/categories-DEijUOnw.cjs.map +1 -0
- package/dist/chunks/{categories-DG4k7S8V.js → categories-DTEl182t.js} +129 -126
- package/dist/chunks/categories-DTEl182t.js.map +1 -0
- package/dist/chunks/{dashboard-page-DcDiWQp2.cjs → dashboard-page-DCmuB0Rw.cjs} +2 -2
- package/dist/chunks/dashboard-page-DCmuB0Rw.cjs.map +1 -0
- package/dist/chunks/dashboard-page-Dx5PeEeN.js +117 -0
- package/dist/chunks/dashboard-page-Dx5PeEeN.js.map +1 -0
- package/dist/chunks/delegations-C-ZrwzvU.js +572 -0
- package/dist/chunks/delegations-C-ZrwzvU.js.map +1 -0
- package/dist/chunks/delegations-C5PzZ5Kn.js +645 -0
- package/dist/chunks/delegations-C5PzZ5Kn.js.map +1 -0
- package/dist/chunks/delegations-DOGDvybX.cjs +2 -0
- package/dist/chunks/delegations-DOGDvybX.cjs.map +1 -0
- package/dist/chunks/delegations-DkDBWOQ7.cjs +2 -0
- package/dist/chunks/delegations-DkDBWOQ7.cjs.map +1 -0
- package/dist/chunks/detail-B2gcOPkd.cjs +2 -0
- package/dist/chunks/detail-B2gcOPkd.cjs.map +1 -0
- package/dist/chunks/{detail-DilI0PPe.js → detail-CfFyU5zC.js} +667 -664
- package/dist/chunks/detail-CfFyU5zC.js.map +1 -0
- package/dist/chunks/{format-date-time-hKLVMxq4.cjs → format-date-time-isOa3e9q.cjs} +2 -2
- package/dist/chunks/{format-date-time-hKLVMxq4.cjs.map → format-date-time-isOa3e9q.cjs.map} +1 -1
- package/dist/chunks/notifications-CPQ-nVar.cjs +2 -0
- package/dist/chunks/notifications-CPQ-nVar.cjs.map +1 -0
- package/dist/chunks/notifications-DweexUVy.js +197 -0
- package/dist/chunks/notifications-DweexUVy.js.map +1 -0
- package/dist/chunks/orgs-DgZ0DQ3-.cjs +2 -0
- package/dist/chunks/orgs-DgZ0DQ3-.cjs.map +1 -0
- package/dist/chunks/{orgs-c29y74w2.js → orgs-xrdhb3hS.js} +668 -665
- package/dist/chunks/orgs-xrdhb3hS.js.map +1 -0
- package/dist/chunks/templates-PK_VYvcy.js +383 -0
- package/dist/chunks/templates-PK_VYvcy.js.map +1 -0
- package/dist/chunks/{templates-Cd0WFheA.cjs → templates-x1OJZmsG.cjs} +2 -2
- package/dist/chunks/templates-x1OJZmsG.cjs.map +1 -0
- package/dist/chunks/users-CY4-NK3j.js +218 -0
- package/dist/chunks/users-CY4-NK3j.js.map +1 -0
- package/dist/chunks/users-DHnu_056.cjs +2 -0
- package/dist/chunks/users-DHnu_056.cjs.map +1 -0
- package/dist/components/app-navigation.d.ts +17 -10
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/notification-drawer-provider.d.ts +1 -1
- package/dist/lib/notification-unread-provider.d.ts +1 -1
- package/dist/lib/providers.d.ts +1 -1
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.js +1 -1
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.js +1 -1
- package/dist/pages/admin/users/index.cjs +1 -1
- package/dist/pages/admin/users/index.js +1 -1
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.js +1 -1
- package/dist/pages/forms/builder/index.cjs +1 -1
- package/dist/pages/forms/builder/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/settings/notifications/index.cjs +1 -1
- package/dist/pages/settings/notifications/index.js +1 -1
- package/dist/pages/templates/categories/index.cjs +1 -1
- package/dist/pages/templates/categories/index.js +1 -1
- package/dist/pages/templates/index.cjs +1 -1
- package/dist/pages/templates/index.js +1 -1
- package/dist/views/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +3 -3
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -1
- 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/delegations/index.cjs +1 -1
- package/dist/views/delegations/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/index.cjs +1 -1
- package/dist/views/forms/index.cjs.map +1 -1
- package/dist/views/forms/index.js +93 -90
- package/dist/views/forms/index.js.map +1 -1
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.cjs.map +1 -1
- package/dist/views/inbox/index.js +127 -124
- package/dist/views/inbox/index.js.map +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.cjs.map +1 -1
- package/dist/views/instances/new/index.js +120 -114
- 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/settings/index.cjs +1 -1
- package/dist/views/settings/index.js +1 -1
- package/dist/views/settings/notifications/index.cjs +1 -1
- package/dist/views/settings/notifications/index.js +1 -1
- package/dist/views/templates/categories/index.cjs +1 -1
- package/dist/views/templates/categories/index.js +1 -1
- package/dist/views/templates/designer/index.cjs +2 -2
- package/dist/views/templates/designer/index.cjs.map +1 -1
- package/dist/views/templates/designer/index.js +573 -570
- package/dist/views/templates/designer/index.js.map +1 -1
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.js +2 -2
- package/dist/views/templates/versions/index.cjs +1 -1
- package/dist/views/templates/versions/index.cjs.map +1 -1
- package/dist/views/templates/versions/index.js +50 -47
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/app-navigation-BRRFCkxZ.cjs.map +0 -1
- package/dist/chunks/app-navigation-rxhpHCch.js.map +0 -1
- package/dist/chunks/approval-instance-list-page-2vUWc5-c.cjs +0 -2
- package/dist/chunks/approval-instance-list-page-2vUWc5-c.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-BgE4vQw8.js +0 -278
- package/dist/chunks/approval-instance-list-page-BgE4vQw8.js.map +0 -1
- package/dist/chunks/builder-B8X-m6C5.cjs +0 -3
- package/dist/chunks/builder-B8X-m6C5.cjs.map +0 -1
- package/dist/chunks/builder-Du_0apkh.js.map +0 -1
- package/dist/chunks/categories-DG4k7S8V.js.map +0 -1
- package/dist/chunks/categories-DshBQG33.cjs +0 -2
- package/dist/chunks/categories-DshBQG33.cjs.map +0 -1
- package/dist/chunks/dashboard-page-CTBwpu_D.js +0 -114
- package/dist/chunks/dashboard-page-CTBwpu_D.js.map +0 -1
- package/dist/chunks/dashboard-page-DcDiWQp2.cjs.map +0 -1
- package/dist/chunks/delegations-BAZQbElH.js +0 -642
- package/dist/chunks/delegations-BAZQbElH.js.map +0 -1
- package/dist/chunks/delegations-DzrckrPp.js +0 -569
- package/dist/chunks/delegations-DzrckrPp.js.map +0 -1
- package/dist/chunks/delegations-Z8hTajLj.cjs +0 -2
- package/dist/chunks/delegations-Z8hTajLj.cjs.map +0 -1
- package/dist/chunks/delegations-hb9JoVZe.cjs +0 -2
- package/dist/chunks/delegations-hb9JoVZe.cjs.map +0 -1
- package/dist/chunks/detail-DilI0PPe.js.map +0 -1
- package/dist/chunks/detail-DuRg3Y7b.cjs +0 -2
- package/dist/chunks/detail-DuRg3Y7b.cjs.map +0 -1
- package/dist/chunks/notifications-B2Lk3grg.js +0 -194
- package/dist/chunks/notifications-B2Lk3grg.js.map +0 -1
- package/dist/chunks/notifications-C8ADhnxF.cjs +0 -2
- package/dist/chunks/notifications-C8ADhnxF.cjs.map +0 -1
- package/dist/chunks/orgs-CGv3VNDR.cjs +0 -2
- package/dist/chunks/orgs-CGv3VNDR.cjs.map +0 -1
- package/dist/chunks/orgs-c29y74w2.js.map +0 -1
- package/dist/chunks/templates-Cd0WFheA.cjs.map +0 -1
- package/dist/chunks/templates-Dn9QHFSy.js +0 -380
- package/dist/chunks/templates-Dn9QHFSy.js.map +0 -1
- package/dist/chunks/users-B-trMu0E.cjs +0 -2
- package/dist/chunks/users-B-trMu0E.cjs.map +0 -1
- package/dist/chunks/users-itVXXRj7.js +0 -215
- package/dist/chunks/users-itVXXRj7.js.map +0 -1
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { t as e } from "./format-date-time-CB-LxzqT.js";
|
|
3
|
-
import { t } from "./app-navigation-
|
|
3
|
+
import { t } from "./app-navigation-uwbNEw9P.js";
|
|
4
4
|
import { t as n } from "./bpm-form-field-Cao0rMol.js";
|
|
5
5
|
import { useCallback as r, useEffect as i, useMemo as a, useState as o } from "react";
|
|
6
|
-
import { Badge as s, Button as c, Filter as l, FilterArea as u, FilterLine as d, FormField as f, Input as p,
|
|
6
|
+
import { Badge as s, Button as c, Filter as l, FilterArea as u, FilterLine as d, FormField as f, Input as p, Modal as m, PageHeader as h, Section as g, SectionGroup as _, Tab as ee, TabItem as te, Table as ne, Textarea as v, Typography as y } from "@mezzanine-ui/react";
|
|
7
7
|
import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
|
|
8
8
|
import { PlusIcon as C } from "@mezzanine-ui/icons";
|
|
9
9
|
import w from "@mezzanine-ui/react/ContentHeader";
|
|
10
|
-
import { FormFieldLayout as
|
|
11
|
-
import { createApprovalTemplateCategory as
|
|
12
|
-
import '../categories.css';var
|
|
10
|
+
import { FormFieldLayout as re } from "@mezzanine-ui/core/form";
|
|
11
|
+
import { createApprovalTemplateCategory as ie, deleteApprovalTemplateCategory as ae, listApprovalTemplateCategoriesPage as oe, updateApprovalTemplateCategory as T } from "@rytass/bpm-core-client/template";
|
|
12
|
+
import '../categories.css';var E = {
|
|
13
13
|
templateFilterArea: "bpm_templateFilterArea_nUL-R",
|
|
14
14
|
templateModalFields: "bpm_templateModalFields_hUxWp"
|
|
15
|
-
},
|
|
15
|
+
}, D = [
|
|
16
16
|
10,
|
|
17
17
|
20,
|
|
18
18
|
50
|
|
19
|
-
],
|
|
19
|
+
], O = [
|
|
20
20
|
{
|
|
21
21
|
key: "ALL",
|
|
22
22
|
label: "全部"
|
|
@@ -30,36 +30,36 @@ import '../categories.css';var A = {
|
|
|
30
30
|
label: "停用"
|
|
31
31
|
}
|
|
32
32
|
];
|
|
33
|
-
function
|
|
34
|
-
let [s, v] = o([]), [
|
|
35
|
-
q(!0),
|
|
33
|
+
function k({ activeHref: n = "/templates/categories" } = {}) {
|
|
34
|
+
let [s, v] = o([]), [k, F] = o(1), [I, L] = o(10), [R, z] = o("ALL"), [B, V] = o(0), [H, U] = o(null), [W, G] = o(null), [K, q] = o(!0), [J, Y] = o(null), [X, Z] = o(!1), [Q, se] = o(""), $ = r(async () => {
|
|
35
|
+
q(!0), G(null);
|
|
36
36
|
try {
|
|
37
|
-
let e = await
|
|
38
|
-
page:
|
|
39
|
-
pageSize:
|
|
37
|
+
let e = await oe({
|
|
38
|
+
page: k,
|
|
39
|
+
pageSize: I,
|
|
40
40
|
searchText: Q,
|
|
41
|
-
status:
|
|
41
|
+
status: N(R)
|
|
42
42
|
});
|
|
43
|
-
v(e.categories),
|
|
43
|
+
v(e.categories), V(e.totalCount);
|
|
44
44
|
} catch (e) {
|
|
45
|
-
|
|
45
|
+
G(P(e));
|
|
46
46
|
} finally {
|
|
47
47
|
q(!1);
|
|
48
48
|
}
|
|
49
49
|
}, [
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
k,
|
|
51
|
+
I,
|
|
52
|
+
R,
|
|
53
53
|
Q
|
|
54
54
|
]);
|
|
55
55
|
i(() => {
|
|
56
56
|
$();
|
|
57
57
|
}, [$]);
|
|
58
|
-
let
|
|
58
|
+
let ce = a(() => s.map((t) => ({
|
|
59
59
|
...t,
|
|
60
60
|
key: t.id,
|
|
61
61
|
updatedAtLabel: e(t.updatedAt)
|
|
62
|
-
})), [s]),
|
|
62
|
+
})), [s]), le = a(() => [
|
|
63
63
|
{
|
|
64
64
|
dataIndex: "name",
|
|
65
65
|
key: "name",
|
|
@@ -68,7 +68,7 @@ function N({ activeHref: n = "/templates/categories" } = {}) {
|
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
key: "status",
|
|
71
|
-
render: (e) => /* @__PURE__ */ x(
|
|
71
|
+
render: (e) => /* @__PURE__ */ x(j, { isActive: e.isActive }),
|
|
72
72
|
title: "狀態",
|
|
73
73
|
width: 120
|
|
74
74
|
},
|
|
@@ -95,23 +95,23 @@ function N({ activeHref: n = "/templates/categories" } = {}) {
|
|
|
95
95
|
width: 220
|
|
96
96
|
}
|
|
97
97
|
], []);
|
|
98
|
-
async function
|
|
99
|
-
Z(!0),
|
|
98
|
+
async function ue(e) {
|
|
99
|
+
Z(!0), G(null);
|
|
100
100
|
try {
|
|
101
|
-
J?.type === "EDIT" && J.record ? await
|
|
101
|
+
J?.type === "EDIT" && J.record ? await T({
|
|
102
102
|
...e,
|
|
103
103
|
id: J.record.id
|
|
104
|
-
}) : await
|
|
104
|
+
}) : await ie(e), Y(null), await $();
|
|
105
105
|
} catch (e) {
|
|
106
|
-
throw
|
|
106
|
+
throw G(P(e)), e;
|
|
107
107
|
} finally {
|
|
108
108
|
Z(!1);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
async function
|
|
112
|
-
Z(!0),
|
|
111
|
+
async function de(e) {
|
|
112
|
+
Z(!0), G(null);
|
|
113
113
|
try {
|
|
114
|
-
await
|
|
114
|
+
await T({
|
|
115
115
|
description: e.description,
|
|
116
116
|
id: e.id,
|
|
117
117
|
isActive: !e.isActive,
|
|
@@ -119,24 +119,24 @@ function N({ activeHref: n = "/templates/categories" } = {}) {
|
|
|
119
119
|
sortOrder: e.sortOrder
|
|
120
120
|
}), await $();
|
|
121
121
|
} catch (e) {
|
|
122
|
-
|
|
122
|
+
G(P(e));
|
|
123
123
|
} finally {
|
|
124
124
|
Z(!1);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
-
async function
|
|
128
|
-
if (
|
|
129
|
-
Z(!0),
|
|
127
|
+
async function fe() {
|
|
128
|
+
if (H) {
|
|
129
|
+
Z(!0), G(null);
|
|
130
130
|
try {
|
|
131
|
-
await
|
|
131
|
+
await ae(H.id), U(null), await $();
|
|
132
132
|
} catch (e) {
|
|
133
|
-
|
|
133
|
+
G(P(e));
|
|
134
134
|
} finally {
|
|
135
135
|
Z(!1);
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
let
|
|
139
|
+
let pe = a(() => ({
|
|
140
140
|
render: (e) => [
|
|
141
141
|
{
|
|
142
142
|
name: "編輯",
|
|
@@ -147,12 +147,12 @@ function N({ activeHref: n = "/templates/categories" } = {}) {
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
name: e.isActive ? "停用" : "啟用",
|
|
150
|
-
onClick: () => void
|
|
150
|
+
onClick: () => void de(e),
|
|
151
151
|
variant: e.isActive ? "destructive-secondary" : "base-secondary"
|
|
152
152
|
},
|
|
153
153
|
{
|
|
154
154
|
name: "刪除",
|
|
155
|
-
onClick: () =>
|
|
155
|
+
onClick: () => U({
|
|
156
156
|
id: e.id,
|
|
157
157
|
name: e.name
|
|
158
158
|
}),
|
|
@@ -163,93 +163,96 @@ function N({ activeHref: n = "/templates/categories" } = {}) {
|
|
|
163
163
|
width: 192
|
|
164
164
|
}), [$]);
|
|
165
165
|
return /* @__PURE__ */ S(b, { children: [
|
|
166
|
-
/* @__PURE__ */ S(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
children: /* @__PURE__ */ x(
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
name: "categorySearchText",
|
|
189
|
-
children: /* @__PURE__ */ x(p, {
|
|
166
|
+
/* @__PURE__ */ S(t, {
|
|
167
|
+
activeHref: n,
|
|
168
|
+
children: [/* @__PURE__ */ x(h, { children: /* @__PURE__ */ x(w, {
|
|
169
|
+
description: "維護簽核模板分類,供模板建立、篩選與列表標示使用。",
|
|
170
|
+
title: "簽核模板分類",
|
|
171
|
+
children: /* @__PURE__ */ x(c, {
|
|
172
|
+
icon: C,
|
|
173
|
+
iconType: "leading",
|
|
174
|
+
onClick: () => Y({
|
|
175
|
+
record: null,
|
|
176
|
+
type: "CREATE"
|
|
177
|
+
}),
|
|
178
|
+
variant: "base-primary",
|
|
179
|
+
children: "建立分類"
|
|
180
|
+
})
|
|
181
|
+
}) }), /* @__PURE__ */ x(_, { children: /* @__PURE__ */ S(g, {
|
|
182
|
+
filterArea: /* @__PURE__ */ x(u, {
|
|
183
|
+
className: E.templateFilterArea,
|
|
184
|
+
size: "sub",
|
|
185
|
+
children: /* @__PURE__ */ x(d, { children: /* @__PURE__ */ x(l, {
|
|
186
|
+
span: 3,
|
|
187
|
+
children: /* @__PURE__ */ x(f, {
|
|
190
188
|
fullWidth: !0,
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
189
|
+
layout: re.VERTICAL,
|
|
190
|
+
name: "categorySearchText",
|
|
191
|
+
children: /* @__PURE__ */ x(p, {
|
|
192
|
+
fullWidth: !0,
|
|
193
|
+
onChange: (e) => {
|
|
194
|
+
se(e.target.value), F(1);
|
|
195
|
+
},
|
|
196
|
+
placeholder: "關鍵字:搜尋分類名稱或說明",
|
|
197
|
+
size: "sub",
|
|
198
|
+
value: Q,
|
|
199
|
+
variant: "base"
|
|
200
|
+
})
|
|
198
201
|
})
|
|
199
|
-
})
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
activeKey: z,
|
|
204
|
-
onChange: (e) => {
|
|
205
|
-
B(oe(e)), I(1);
|
|
206
|
-
},
|
|
207
|
-
children: M.map((e) => /* @__PURE__ */ x(ne, { children: e.label }, e.key))
|
|
208
|
-
}),
|
|
209
|
-
children: [G ? /* @__PURE__ */ x(y, {
|
|
210
|
-
color: "text-error",
|
|
211
|
-
variant: "body",
|
|
212
|
-
children: G
|
|
213
|
-
}) : null, /* @__PURE__ */ x(re, {
|
|
214
|
-
actions: me,
|
|
215
|
-
columns: ue,
|
|
216
|
-
dataSource: le,
|
|
217
|
-
fullWidth: !0,
|
|
218
|
-
loading: se || X,
|
|
219
|
-
pagination: {
|
|
220
|
-
current: N,
|
|
202
|
+
}) })
|
|
203
|
+
}),
|
|
204
|
+
tab: /* @__PURE__ */ x(ee, {
|
|
205
|
+
activeKey: R,
|
|
221
206
|
onChange: (e) => {
|
|
222
|
-
|
|
223
|
-
},
|
|
224
|
-
onChangePageSize: (e) => {
|
|
225
|
-
I(1), R(e);
|
|
207
|
+
z(M(e)), F(1);
|
|
226
208
|
},
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
209
|
+
children: O.map((e) => /* @__PURE__ */ x(te, { children: e.label }, e.key))
|
|
210
|
+
}),
|
|
211
|
+
children: [W ? /* @__PURE__ */ x(y, {
|
|
212
|
+
color: "text-error",
|
|
213
|
+
variant: "body",
|
|
214
|
+
children: W
|
|
215
|
+
}) : null, /* @__PURE__ */ x(ne, {
|
|
216
|
+
actions: pe,
|
|
217
|
+
columns: le,
|
|
218
|
+
dataSource: ce,
|
|
219
|
+
fullWidth: !0,
|
|
220
|
+
loading: K || X,
|
|
221
|
+
pagination: {
|
|
222
|
+
current: k,
|
|
223
|
+
onChange: (e) => {
|
|
224
|
+
F(e);
|
|
225
|
+
},
|
|
226
|
+
onChangePageSize: (e) => {
|
|
227
|
+
F(1), L(e);
|
|
228
|
+
},
|
|
229
|
+
pageSize: I,
|
|
230
|
+
pageSizeLabel: "每頁筆數",
|
|
231
|
+
pageSizeOptions: D,
|
|
232
|
+
renderResultSummary: (e, t, n) => `顯示 ${e}-${t} 筆,共 ${n} 筆`,
|
|
233
|
+
showPageSizeOptions: !0,
|
|
234
|
+
total: B
|
|
235
|
+
}
|
|
236
|
+
})]
|
|
237
|
+
}) })]
|
|
238
|
+
}),
|
|
239
|
+
/* @__PURE__ */ x(A, {
|
|
237
240
|
loading: X,
|
|
238
241
|
modal: J,
|
|
239
242
|
onClose: () => Y(null),
|
|
240
|
-
onSubmit:
|
|
243
|
+
onSubmit: ue
|
|
241
244
|
}),
|
|
242
|
-
/* @__PURE__ */ x(
|
|
245
|
+
/* @__PURE__ */ x(m, {
|
|
243
246
|
cancelText: "取消",
|
|
244
247
|
confirmButtonProps: { variant: "destructive-primary" },
|
|
245
248
|
confirmText: "刪除",
|
|
246
249
|
loading: X,
|
|
247
250
|
modalStatusType: "error",
|
|
248
251
|
modalType: "standard",
|
|
249
|
-
onCancel: () =>
|
|
250
|
-
onClose: () =>
|
|
251
|
-
onConfirm: () => void
|
|
252
|
-
open: !!
|
|
252
|
+
onCancel: () => U(null),
|
|
253
|
+
onClose: () => U(null),
|
|
254
|
+
onConfirm: () => void fe(),
|
|
255
|
+
open: !!H,
|
|
253
256
|
showModalFooter: !0,
|
|
254
257
|
showModalHeader: !0,
|
|
255
258
|
size: "regular",
|
|
@@ -260,20 +263,20 @@ function N({ activeHref: n = "/templates/categories" } = {}) {
|
|
|
260
263
|
variant: "body",
|
|
261
264
|
children: [
|
|
262
265
|
"確定要刪除「",
|
|
263
|
-
|
|
266
|
+
H?.name ?? "",
|
|
264
267
|
"」嗎?"
|
|
265
268
|
]
|
|
266
269
|
})
|
|
267
270
|
})
|
|
268
271
|
] });
|
|
269
272
|
}
|
|
270
|
-
function
|
|
271
|
-
let [s, c] = o(""), [l, u] = o(null), [d, f] = o(""), [
|
|
273
|
+
function A({ loading: e, modal: t, onClose: r, onSubmit: a }) {
|
|
274
|
+
let [s, c] = o(""), [l, u] = o(null), [d, f] = o(""), [h, g] = o("0");
|
|
272
275
|
i(() => {
|
|
273
276
|
t && (c(t.record?.description ?? ""), u(null), f(t.record?.name ?? ""), g(String(t.record?.sortOrder ?? 0)));
|
|
274
277
|
}, [t]);
|
|
275
278
|
async function _() {
|
|
276
|
-
let e = d.trim(), n = Number(
|
|
279
|
+
let e = d.trim(), n = Number(h);
|
|
277
280
|
if (!e) {
|
|
278
281
|
u("請輸入分類名稱");
|
|
279
282
|
return;
|
|
@@ -290,10 +293,10 @@ function ie({ loading: e, modal: t, onClose: r, onSubmit: a }) {
|
|
|
290
293
|
sortOrder: n
|
|
291
294
|
});
|
|
292
295
|
} catch (e) {
|
|
293
|
-
u(
|
|
296
|
+
u(P(e));
|
|
294
297
|
}
|
|
295
298
|
}
|
|
296
|
-
return /* @__PURE__ */ S(
|
|
299
|
+
return /* @__PURE__ */ S(m, {
|
|
297
300
|
cancelText: "取消",
|
|
298
301
|
confirmButtonProps: { disabled: !d.trim() },
|
|
299
302
|
confirmText: t?.type === "EDIT" ? "儲存" : "建立",
|
|
@@ -308,7 +311,7 @@ function ie({ loading: e, modal: t, onClose: r, onSubmit: a }) {
|
|
|
308
311
|
size: "regular",
|
|
309
312
|
title: t?.type === "EDIT" ? "編輯分類" : "建立分類",
|
|
310
313
|
children: [/* @__PURE__ */ S("div", {
|
|
311
|
-
className:
|
|
314
|
+
className: E.templateModalFields,
|
|
312
315
|
children: [
|
|
313
316
|
/* @__PURE__ */ x(n, {
|
|
314
317
|
label: "分類名稱",
|
|
@@ -334,7 +337,7 @@ function ie({ loading: e, modal: t, onClose: r, onSubmit: a }) {
|
|
|
334
337
|
g(e.target.value), u(null);
|
|
335
338
|
},
|
|
336
339
|
placeholder: "0",
|
|
337
|
-
value:
|
|
340
|
+
value: h,
|
|
338
341
|
variant: "base"
|
|
339
342
|
})
|
|
340
343
|
}),
|
|
@@ -357,7 +360,7 @@ function ie({ loading: e, modal: t, onClose: r, onSubmit: a }) {
|
|
|
357
360
|
}) : null]
|
|
358
361
|
});
|
|
359
362
|
}
|
|
360
|
-
function
|
|
363
|
+
function j({ isActive: e }) {
|
|
361
364
|
return e ? /* @__PURE__ */ x(s, {
|
|
362
365
|
size: "sub",
|
|
363
366
|
text: "啟用",
|
|
@@ -368,16 +371,16 @@ function ae({ isActive: e }) {
|
|
|
368
371
|
variant: "dot-inactive"
|
|
369
372
|
});
|
|
370
373
|
}
|
|
371
|
-
function
|
|
374
|
+
function M(e) {
|
|
372
375
|
return e === "ACTIVE" || e === "INACTIVE" ? e : "ALL";
|
|
373
376
|
}
|
|
374
|
-
function
|
|
377
|
+
function N(e) {
|
|
375
378
|
return e;
|
|
376
379
|
}
|
|
377
|
-
function
|
|
380
|
+
function P(e) {
|
|
378
381
|
return e instanceof Error ? e.message : "發生未知錯誤";
|
|
379
382
|
}
|
|
380
383
|
//#endregion
|
|
381
|
-
export {
|
|
384
|
+
export { E as n, k as t };
|
|
382
385
|
|
|
383
|
-
//# sourceMappingURL=categories-
|
|
386
|
+
//# sourceMappingURL=categories-DTEl182t.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"categories-DTEl182t.js","names":[],"sources":["../../src/views/templates/templates.module.scss","../../src/views/templates/categories/TemplateCategoriesView.tsx"],"sourcesContent":[".templateFilterArea {\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-form-field__label-area) {\n display: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n}\n\n.templateModalFields {\n display: grid;\n gap: 16px;\n}\n","'use client';\n\nimport type { ChangeEvent, Key, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Tab,\n TabItem,\n Table,\n Textarea,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { AppLayout } from '../../../components/app-navigation';\nimport {\n ApprovalTemplateCategoryRecord,\n ApprovalTemplateCategoryStatus,\n createApprovalTemplateCategory,\n deleteApprovalTemplateCategory,\n listApprovalTemplateCategoriesPage,\n updateApprovalTemplateCategory,\n} from '@rytass/bpm-core-client/template';\nimport styles from '../templates.module.scss';\n\nconst CATEGORY_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst CATEGORY_STATUS_TABS: readonly {\n readonly key: CategoryStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'ACTIVE', label: '啟用' },\n { key: 'INACTIVE', label: '停用' },\n];\ntype CategoryStatusTabKey = 'ACTIVE' | 'ALL' | 'INACTIVE';\n\ntype CategoryRow = Readonly<\n Record<string, unknown> &\n ApprovalTemplateCategoryRecord & {\n key: string;\n updatedAtLabel: string;\n }\n>;\n\ntype CategoryModalState = Readonly<{\n record: ApprovalTemplateCategoryRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype DeleteConfirmationState = Readonly<{\n id: string;\n name: string;\n}>;\n\nexport interface TemplateCategoriesViewProps {\n readonly activeHref?: string;\n}\n\nexport function TemplateCategoriesView({\n activeHref = '/templates/categories',\n}: TemplateCategoriesViewProps = {}): ReactElement {\n const [categories, setCategories] = useState<\n readonly ApprovalTemplateCategoryRecord[]\n >([]);\n const [categoryPage, setCategoryPage] = useState(1);\n const [categoryPageSize, setCategoryPageSize] = useState(10);\n const [categoryStatus, setCategoryStatus] =\n useState<CategoryStatusTabKey>('ALL');\n const [categoryTotalCount, setCategoryTotalCount] = useState(0);\n const [deleteConfirmation, setDeleteConfirmation] =\n useState<DeleteConfirmationState | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [modalState, setModalState] = useState<CategoryModalState | null>(null);\n const [saving, setSaving] = useState(false);\n const [searchText, setSearchText] = useState('');\n\n const refreshCategories = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const categoryPageResult = await listApprovalTemplateCategoriesPage({\n page: categoryPage,\n pageSize: categoryPageSize,\n searchText,\n status: readCategoryStatus(categoryStatus),\n });\n\n setCategories(categoryPageResult.categories);\n setCategoryTotalCount(categoryPageResult.totalCount);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [categoryPage, categoryPageSize, categoryStatus, searchText]);\n\n useEffect((): void => {\n void refreshCategories();\n }, [refreshCategories]);\n\n const rows = useMemo(\n (): CategoryRow[] =>\n categories.map((category) => ({\n ...category,\n key: category.id,\n updatedAtLabel: formatDateTime(category.updatedAt),\n })),\n [categories],\n );\n\n const columns = useMemo(\n (): TableColumn<CategoryRow>[] => [\n { dataIndex: 'name', key: 'name', title: '分類名稱', width: 180 },\n {\n key: 'status',\n render: (record: CategoryRow): ReactElement => (\n <CategoryStatusBadge isActive={record.isActive} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n dataIndex: 'sortOrder',\n key: 'sortOrder',\n title: '排序',\n width: 100,\n },\n {\n key: 'description',\n render: (record: CategoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.description || '無'}\n </Typography>\n ),\n title: '說明',\n width: 260,\n },\n {\n dataIndex: 'updatedAtLabel',\n key: 'updatedAtLabel',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n\n async function handleSaveCategory(input: CategoryFormInput): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n if (modalState?.type === 'EDIT' && modalState.record) {\n await updateApprovalTemplateCategory({\n ...input,\n id: modalState.record.id,\n });\n } else {\n await createApprovalTemplateCategory(input);\n }\n\n setModalState(null);\n await refreshCategories();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n throw requestError;\n } finally {\n setSaving(false);\n }\n }\n\n async function handleToggleCategory(\n record: ApprovalTemplateCategoryRecord,\n ): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await updateApprovalTemplateCategory({\n description: record.description,\n id: record.id,\n isActive: !record.isActive,\n name: record.name,\n sortOrder: record.sortOrder,\n });\n await refreshCategories();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n async function handleConfirmDelete(): Promise<void> {\n if (!deleteConfirmation) {\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await deleteApprovalTemplateCategory(deleteConfirmation.id);\n setDeleteConfirmation(null);\n await refreshCategories();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n const tableActions = useMemo(\n (): TableActions<CategoryRow> => ({\n render: (record): ReturnType<TableActions<CategoryRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setModalState({ record, type: 'EDIT' }),\n },\n {\n name: record.isActive ? '停用' : '啟用',\n onClick: (): void => void handleToggleCategory(record),\n variant: record.isActive ? 'destructive-secondary' : 'base-secondary',\n },\n {\n name: '刪除',\n onClick: (): void =>\n setDeleteConfirmation({ id: record.id, name: record.name }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 192,\n }),\n [refreshCategories],\n );\n\n return (\n <>\n <AppLayout activeHref={activeHref}>\n <PageHeader>\n <ContentHeader\n description=\"維護簽核模板分類,供模板建立、篩選與列表標示使用。\"\n title=\"簽核模板分類\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n setModalState({ record: null, type: 'CREATE' })\n }\n variant=\"base-primary\"\n >\n 建立分類\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.templateFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"categorySearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setSearchText(event.target.value);\n setCategoryPage(1);\n }}\n placeholder=\"關鍵字:搜尋分類名稱或說明\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={categoryStatus}\n onChange={(activeKey): void => {\n setCategoryStatus(readCategoryStatusTabKey(activeKey));\n setCategoryPage(1);\n }}\n >\n {CATEGORY_STATUS_TABS.map((statusTab) => (\n <TabItem key={statusTab.key}>{statusTab.label}</TabItem>\n ))}\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading || saving}\n pagination={{\n current: categoryPage,\n onChange: (page): void => {\n setCategoryPage(page);\n },\n onChangePageSize: (pageSize): void => {\n setCategoryPage(1);\n setCategoryPageSize(pageSize);\n },\n pageSize: categoryPageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: CATEGORY_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: categoryTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </AppLayout>\n\n <CategoryModal\n loading={saving}\n modal={modalState}\n onClose={(): void => setModalState(null)}\n onSubmit={handleSaveCategory}\n />\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ variant: 'destructive-primary' }}\n confirmText=\"刪除\"\n loading={saving}\n modalStatusType=\"error\"\n modalType=\"standard\"\n onCancel={(): void => setDeleteConfirmation(null)}\n onClose={(): void => setDeleteConfirmation(null)}\n onConfirm={(): void => void handleConfirmDelete()}\n open={Boolean(deleteConfirmation)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"若分類已被模板使用,系統會改為停用分類並保留既有模板關聯。\"\n title=\"刪除分類\"\n >\n <Typography color=\"text-neutral\" variant=\"body\">\n 確定要刪除「{deleteConfirmation?.name ?? ''}」嗎?\n </Typography>\n </Modal>\n </>\n );\n}\n\ninterface CategoryFormInput {\n readonly description: string | null;\n readonly isActive: boolean;\n readonly name: string;\n readonly sortOrder: number;\n}\n\nfunction CategoryModal({\n loading,\n modal,\n onClose,\n onSubmit,\n}: {\n readonly loading: boolean;\n readonly modal: CategoryModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: CategoryFormInput) => Promise<void>;\n}): ReactElement {\n const [description, setDescription] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [name, setName] = useState('');\n const [sortOrder, setSortOrder] = useState('0');\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n setDescription(modal.record?.description ?? '');\n setError(null);\n setName(modal.record?.name ?? '');\n setSortOrder(String(modal.record?.sortOrder ?? 0));\n }, [modal]);\n\n async function handleConfirm(): Promise<void> {\n const trimmedName = name.trim();\n const parsedSortOrder = Number(sortOrder);\n\n if (!trimmedName) {\n setError('請輸入分類名稱');\n return;\n }\n\n if (!Number.isInteger(parsedSortOrder)) {\n setError('排序必須是整數');\n return;\n }\n\n try {\n await onSubmit({\n description: description.trim() || null,\n isActive: modal?.record?.isActive ?? true,\n name: trimmedName,\n sortOrder: parsedSortOrder,\n });\n } catch (submitError: unknown) {\n setError(readErrorMessage(submitError));\n }\n }\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !name.trim() }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={loading}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void => void handleConfirm()}\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯分類' : '建立分類'}\n >\n <div className={styles.templateModalFields}>\n <BPMFormField label=\"分類名稱\" name=\"categoryName\" required>\n <Input\n autoFocus\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void => {\n setName(event.target.value);\n setError(null);\n }}\n placeholder=\"例如:行政管理\"\n value={name}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"排序\" name=\"categorySortOrder\">\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void => {\n setSortOrder(event.target.value);\n setError(null);\n }}\n placeholder=\"0\"\n value={sortOrder}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"說明\" name=\"categoryDescription\">\n <Textarea\n onChange={(event: ChangeEvent<HTMLTextAreaElement>): void => {\n setDescription(event.target.value);\n setError(null);\n }}\n placeholder=\"補充分類用途\"\n value={description}\n />\n </BPMFormField>\n </div>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n </Modal>\n );\n}\n\nfunction CategoryStatusBadge({\n isActive,\n}: {\n readonly isActive: boolean;\n}): ReactElement {\n return isActive ? (\n <Badge size=\"sub\" text=\"啟用\" variant=\"dot-success\" />\n ) : (\n <Badge size=\"sub\" text=\"停用\" variant=\"dot-inactive\" />\n );\n}\n\nfunction readCategoryStatusTabKey(activeKey: Key): CategoryStatusTabKey {\n if (activeKey === 'ACTIVE' || activeKey === 'INACTIVE') {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction readCategoryStatus(\n status: CategoryStatusTabKey,\n): ApprovalTemplateCategoryStatus {\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";require('../dashboard-page.css');const e=require("./app-navigation-
|
|
2
|
-
//# sourceMappingURL=dashboard-page-
|
|
1
|
+
"use client";require('../dashboard-page.css');const e=require("./app-navigation-C_mbz7jx.cjs"),t=require("./auth-provider-BV8Iiwfb.cjs");let n=require("react"),r=require("@mezzanine-ui/react"),i=require("react/jsx-runtime"),a=require("@rytass/bpm-core-client/workflow"),o=require("@mezzanine-ui/icons"),s=require("@mezzanine-ui/react/ContentHeader");s=e.o(s,1);var c={metricCard:`bpm_metricCard_vp2qC`},l={activeInstanceCount:0,completedInstanceCount:0,overdueTaskCount:0,pendingTaskCount:0,rejectedInstanceCount:0,totalInstanceCount:0,unreadNotificationCount:0};function u({activeHref:u}){let p=t.a(),{member:m}=t.n(),h=m?.memberId??null,[g,_]=(0,n.useState)(null),[v,y]=(0,n.useState)(!0),[b,x]=(0,n.useState)(l),S=(0,n.useCallback)(async()=>{if(!h){y(!1);return}y(!0),_(null);try{x(await(0,a.readWorkflowDashboardSummary)({currentMemberId:h,from:null,to:null}))}catch(e){_(f(e))}finally{y(!1)}},[h]);(0,n.useEffect)(()=>{S()},[S]);let C=(0,n.useMemo)(()=>[{caption:`目前需要你處理的任務`,href:`/inbox`,label:`待處理簽核`,value:d(b.pendingTaskCount,v)},{caption:`尚未讀取的站內通知`,href:`/notifications`,label:`未讀通知`,value:d(b.unreadNotificationCount,v)},{caption:`目前仍在流程中的案件`,href:`/search`,label:`進行中案件`,value:d(b.activeInstanceCount,v)},{caption:`已超過 SLA 的待處理任務`,href:`/inbox`,label:`逾時任務`,value:d(b.overdueTaskCount,v)},{caption:`你有權限查看的全部案件`,href:`/search`,label:`案件總數`,value:d(b.totalInstanceCount,v)}],[v,b]);return(0,i.jsxs)(e.t,{activeHref:u,children:[(0,i.jsx)(r.PageHeader,{children:(0,i.jsx)(s.default,{description:`查看待處理簽核、近期通知與你發起的案件進度。`,title:`工作台`,children:(0,i.jsx)(r.Button,{icon:o.PlusIcon,iconType:`leading`,onClick:()=>p.push(`/instances/new`),variant:`base-primary`,children:`發起簽核`})})}),(0,i.jsx)(r.SectionGroup,{children:(0,i.jsxs)(r.Section,{children:[g?(0,i.jsx)(r.Typography,{color:`text-error`,variant:`body`,children:g}):null,(0,i.jsx)(r.CardGroup,{children:C.map(e=>(0,i.jsx)(r.BaseCard,{"aria-label":`前往${e.label}`,className:c.metricCard,description:e.value,onClick:()=>p.push(e.href),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),p.push(e.href))},role:`link`,tabIndex:0,title:e.label,children:(0,i.jsx)(r.Typography,{color:`text-neutral`,variant:`caption`,children:e.caption})},e.label))})]})})]})}function d(e,t){return t?`-`:String(e)}function f(e){return e instanceof Error?e.message:`讀取工作台摘要失敗。`}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return u}});
|
|
2
|
+
//# sourceMappingURL=dashboard-page-DCmuB0Rw.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-page-DCmuB0Rw.cjs","names":[],"sources":["../../src/components/dashboard-page.module.scss","../../src/components/dashboard-page.tsx"],"sourcesContent":[".metricCard {\n color: inherit;\n cursor: pointer;\n text-decoration: none;\n}\n\n.metricCard:hover {\n text-decoration: none;\n}\n","'use client';\n\nimport type { KeyboardEvent, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n BaseCard,\n Button,\n CardGroup,\n PageHeader,\n Section,\n SectionGroup,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport {\n readWorkflowDashboardSummary,\n type WorkflowDashboardSummaryRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { useAuth } from '../lib/auth-provider';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { AppLayout } from './app-navigation';\nimport styles from './dashboard-page.module.scss';\n\nexport interface DashboardPageProps {\n readonly activeHref: string;\n}\n\ninterface Metric {\n readonly caption: string;\n readonly href: string;\n readonly label: string;\n readonly value: string;\n}\n\nconst EMPTY_DASHBOARD_SUMMARY: WorkflowDashboardSummaryRecord = {\n activeInstanceCount: 0,\n completedInstanceCount: 0,\n overdueTaskCount: 0,\n pendingTaskCount: 0,\n rejectedInstanceCount: 0,\n totalInstanceCount: 0,\n unreadNotificationCount: 0,\n};\n\n/**\n * Operator dashboard — shows pending/unread/active counts for the\n * currently-authenticated member. Reads {@link readWorkflowDashboardSummary}\n * and renders five metric tiles that navigate via {@link useRouterAdapter}.\n */\nexport function DashboardPage({ activeHref }: DashboardPageProps): ReactElement {\n const router = useRouterAdapter();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [summary, setSummary] = useState<WorkflowDashboardSummaryRecord>(\n EMPTY_DASHBOARD_SUMMARY,\n );\n\n const refreshSummary = useCallback(async (): Promise<void> => {\n if (!currentMemberId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n setSummary(\n await readWorkflowDashboardSummary({\n currentMemberId,\n from: null,\n to: null,\n }),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [currentMemberId]);\n\n useEffect((): void => {\n void refreshSummary();\n }, [refreshSummary]);\n\n const metrics = useMemo(\n (): readonly Metric[] => [\n {\n caption: '目前需要你處理的任務',\n href: '/inbox',\n label: '待處理簽核',\n value: readMetricValue(summary.pendingTaskCount, loading),\n },\n {\n caption: '尚未讀取的站內通知',\n href: '/notifications',\n label: '未讀通知',\n value: readMetricValue(summary.unreadNotificationCount, loading),\n },\n {\n caption: '目前仍在流程中的案件',\n href: '/search',\n label: '進行中案件',\n value: readMetricValue(summary.activeInstanceCount, loading),\n },\n {\n caption: '已超過 SLA 的待處理任務',\n href: '/inbox',\n label: '逾時任務',\n value: readMetricValue(summary.overdueTaskCount, loading),\n },\n {\n caption: '你有權限查看的全部案件',\n href: '/search',\n label: '案件總數',\n value: readMetricValue(summary.totalInstanceCount, loading),\n },\n ],\n [loading, summary],\n );\n\n return (\n <AppLayout activeHref={activeHref}>\n <PageHeader>\n <ContentHeader\n description=\"查看待處理簽核、近期通知與你發起的案件進度。\"\n title=\"工作台\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push('/instances/new')}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <CardGroup>\n {metrics.map((metric) => (\n <BaseCard\n aria-label={`前往${metric.label}`}\n className={styles.metricCard}\n description={metric.value}\n key={metric.label}\n onClick={(): void => router.push(metric.href)}\n onKeyDown={(event: KeyboardEvent<HTMLElement>): void => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n router.push(metric.href);\n }\n }}\n role=\"link\"\n tabIndex={0}\n title={metric.label}\n >\n <Typography color=\"text-neutral\" variant=\"caption\">\n {metric.caption}\n </Typography>\n </BaseCard>\n ))}\n </CardGroup>\n </Section>\n </SectionGroup>\n </AppLayout>\n );\n}\n\nfunction readMetricValue(value: number, loading: boolean): string {\n return loading ? '-' : String(value);\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取工作台摘要失敗。';\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { a as e, n as t } from "./auth-provider-Bnox5gsx.js";
|
|
3
|
+
import { t as n } from "./app-navigation-uwbNEw9P.js";
|
|
4
|
+
import { useCallback as r, useEffect as i, useMemo as a, useState as o } from "react";
|
|
5
|
+
import { BaseCard as s, Button as c, CardGroup as l, PageHeader as u, Section as d, SectionGroup as f, Typography as p } from "@mezzanine-ui/react";
|
|
6
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
7
|
+
import { readWorkflowDashboardSummary as g } from "@rytass/bpm-core-client/workflow";
|
|
8
|
+
import { PlusIcon as _ } from "@mezzanine-ui/icons";
|
|
9
|
+
import v from "@mezzanine-ui/react/ContentHeader";
|
|
10
|
+
import '../dashboard-page.css';var y = { metricCard: "bpm_metricCard_vp2qC" }, b = {
|
|
11
|
+
activeInstanceCount: 0,
|
|
12
|
+
completedInstanceCount: 0,
|
|
13
|
+
overdueTaskCount: 0,
|
|
14
|
+
pendingTaskCount: 0,
|
|
15
|
+
rejectedInstanceCount: 0,
|
|
16
|
+
totalInstanceCount: 0,
|
|
17
|
+
unreadNotificationCount: 0
|
|
18
|
+
};
|
|
19
|
+
function x({ activeHref: x }) {
|
|
20
|
+
let w = e(), { member: T } = t(), E = T?.memberId ?? null, [D, O] = o(null), [k, A] = o(!0), [j, M] = o(b), N = r(async () => {
|
|
21
|
+
if (!E) {
|
|
22
|
+
A(!1);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
A(!0), O(null);
|
|
26
|
+
try {
|
|
27
|
+
M(await g({
|
|
28
|
+
currentMemberId: E,
|
|
29
|
+
from: null,
|
|
30
|
+
to: null
|
|
31
|
+
}));
|
|
32
|
+
} catch (e) {
|
|
33
|
+
O(C(e));
|
|
34
|
+
} finally {
|
|
35
|
+
A(!1);
|
|
36
|
+
}
|
|
37
|
+
}, [E]);
|
|
38
|
+
i(() => {
|
|
39
|
+
N();
|
|
40
|
+
}, [N]);
|
|
41
|
+
let P = a(() => [
|
|
42
|
+
{
|
|
43
|
+
caption: "目前需要你處理的任務",
|
|
44
|
+
href: "/inbox",
|
|
45
|
+
label: "待處理簽核",
|
|
46
|
+
value: S(j.pendingTaskCount, k)
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
caption: "尚未讀取的站內通知",
|
|
50
|
+
href: "/notifications",
|
|
51
|
+
label: "未讀通知",
|
|
52
|
+
value: S(j.unreadNotificationCount, k)
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
caption: "目前仍在流程中的案件",
|
|
56
|
+
href: "/search",
|
|
57
|
+
label: "進行中案件",
|
|
58
|
+
value: S(j.activeInstanceCount, k)
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
caption: "已超過 SLA 的待處理任務",
|
|
62
|
+
href: "/inbox",
|
|
63
|
+
label: "逾時任務",
|
|
64
|
+
value: S(j.overdueTaskCount, k)
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
caption: "你有權限查看的全部案件",
|
|
68
|
+
href: "/search",
|
|
69
|
+
label: "案件總數",
|
|
70
|
+
value: S(j.totalInstanceCount, k)
|
|
71
|
+
}
|
|
72
|
+
], [k, j]);
|
|
73
|
+
return /* @__PURE__ */ h(n, {
|
|
74
|
+
activeHref: x,
|
|
75
|
+
children: [/* @__PURE__ */ m(u, { children: /* @__PURE__ */ m(v, {
|
|
76
|
+
description: "查看待處理簽核、近期通知與你發起的案件進度。",
|
|
77
|
+
title: "工作台",
|
|
78
|
+
children: /* @__PURE__ */ m(c, {
|
|
79
|
+
icon: _,
|
|
80
|
+
iconType: "leading",
|
|
81
|
+
onClick: () => w.push("/instances/new"),
|
|
82
|
+
variant: "base-primary",
|
|
83
|
+
children: "發起簽核"
|
|
84
|
+
})
|
|
85
|
+
}) }), /* @__PURE__ */ m(f, { children: /* @__PURE__ */ h(d, { children: [D ? /* @__PURE__ */ m(p, {
|
|
86
|
+
color: "text-error",
|
|
87
|
+
variant: "body",
|
|
88
|
+
children: D
|
|
89
|
+
}) : null, /* @__PURE__ */ m(l, { children: P.map((e) => /* @__PURE__ */ m(s, {
|
|
90
|
+
"aria-label": `前往${e.label}`,
|
|
91
|
+
className: y.metricCard,
|
|
92
|
+
description: e.value,
|
|
93
|
+
onClick: () => w.push(e.href),
|
|
94
|
+
onKeyDown: (t) => {
|
|
95
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), w.push(e.href));
|
|
96
|
+
},
|
|
97
|
+
role: "link",
|
|
98
|
+
tabIndex: 0,
|
|
99
|
+
title: e.label,
|
|
100
|
+
children: /* @__PURE__ */ m(p, {
|
|
101
|
+
color: "text-neutral",
|
|
102
|
+
variant: "caption",
|
|
103
|
+
children: e.caption
|
|
104
|
+
})
|
|
105
|
+
}, e.label)) })] }) })]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function S(e, t) {
|
|
109
|
+
return t ? "-" : String(e);
|
|
110
|
+
}
|
|
111
|
+
function C(e) {
|
|
112
|
+
return e instanceof Error ? e.message : "讀取工作台摘要失敗。";
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
export { x as t };
|
|
116
|
+
|
|
117
|
+
//# sourceMappingURL=dashboard-page-Dx5PeEeN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-page-Dx5PeEeN.js","names":[],"sources":["../../src/components/dashboard-page.module.scss","../../src/components/dashboard-page.tsx"],"sourcesContent":[".metricCard {\n color: inherit;\n cursor: pointer;\n text-decoration: none;\n}\n\n.metricCard:hover {\n text-decoration: none;\n}\n","'use client';\n\nimport type { KeyboardEvent, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n BaseCard,\n Button,\n CardGroup,\n PageHeader,\n Section,\n SectionGroup,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport {\n readWorkflowDashboardSummary,\n type WorkflowDashboardSummaryRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { useAuth } from '../lib/auth-provider';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { AppLayout } from './app-navigation';\nimport styles from './dashboard-page.module.scss';\n\nexport interface DashboardPageProps {\n readonly activeHref: string;\n}\n\ninterface Metric {\n readonly caption: string;\n readonly href: string;\n readonly label: string;\n readonly value: string;\n}\n\nconst EMPTY_DASHBOARD_SUMMARY: WorkflowDashboardSummaryRecord = {\n activeInstanceCount: 0,\n completedInstanceCount: 0,\n overdueTaskCount: 0,\n pendingTaskCount: 0,\n rejectedInstanceCount: 0,\n totalInstanceCount: 0,\n unreadNotificationCount: 0,\n};\n\n/**\n * Operator dashboard — shows pending/unread/active counts for the\n * currently-authenticated member. Reads {@link readWorkflowDashboardSummary}\n * and renders five metric tiles that navigate via {@link useRouterAdapter}.\n */\nexport function DashboardPage({ activeHref }: DashboardPageProps): ReactElement {\n const router = useRouterAdapter();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [summary, setSummary] = useState<WorkflowDashboardSummaryRecord>(\n EMPTY_DASHBOARD_SUMMARY,\n );\n\n const refreshSummary = useCallback(async (): Promise<void> => {\n if (!currentMemberId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n setSummary(\n await readWorkflowDashboardSummary({\n currentMemberId,\n from: null,\n to: null,\n }),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [currentMemberId]);\n\n useEffect((): void => {\n void refreshSummary();\n }, [refreshSummary]);\n\n const metrics = useMemo(\n (): readonly Metric[] => [\n {\n caption: '目前需要你處理的任務',\n href: '/inbox',\n label: '待處理簽核',\n value: readMetricValue(summary.pendingTaskCount, loading),\n },\n {\n caption: '尚未讀取的站內通知',\n href: '/notifications',\n label: '未讀通知',\n value: readMetricValue(summary.unreadNotificationCount, loading),\n },\n {\n caption: '目前仍在流程中的案件',\n href: '/search',\n label: '進行中案件',\n value: readMetricValue(summary.activeInstanceCount, loading),\n },\n {\n caption: '已超過 SLA 的待處理任務',\n href: '/inbox',\n label: '逾時任務',\n value: readMetricValue(summary.overdueTaskCount, loading),\n },\n {\n caption: '你有權限查看的全部案件',\n href: '/search',\n label: '案件總數',\n value: readMetricValue(summary.totalInstanceCount, loading),\n },\n ],\n [loading, summary],\n );\n\n return (\n <AppLayout activeHref={activeHref}>\n <PageHeader>\n <ContentHeader\n description=\"查看待處理簽核、近期通知與你發起的案件進度。\"\n title=\"工作台\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push('/instances/new')}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <CardGroup>\n {metrics.map((metric) => (\n <BaseCard\n aria-label={`前往${metric.label}`}\n className={styles.metricCard}\n description={metric.value}\n key={metric.label}\n onClick={(): void => router.push(metric.href)}\n onKeyDown={(event: KeyboardEvent<HTMLElement>): void => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n router.push(metric.href);\n }\n }}\n role=\"link\"\n tabIndex={0}\n title={metric.label}\n >\n <Typography color=\"text-neutral\" variant=\"caption\">\n {metric.caption}\n </Typography>\n </BaseCard>\n ))}\n </CardGroup>\n </Section>\n </SectionGroup>\n </AppLayout>\n );\n}\n\nfunction readMetricValue(value: number, loading: boolean): string {\n return loading ? '-' : String(value);\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取工作台摘要失敗。';\n}\n"],"mappings":";;;;;;;;;gDCmCM,IAA0D;CAC9D,qBAAqB;CACrB,wBAAwB;CACxB,kBAAkB;CAClB,kBAAkB;CAClB,uBAAuB;CACvB,oBAAoB;CACpB,yBAAyB;AAC3B;AAOA,SAAgB,EAAc,EAAE,iBAAgD;CAC9E,IAAM,IAAS,EAAiB,GAC1B,EAAE,cAAW,EAAQ,GACrB,IAAkB,GAAQ,YAAY,MACtC,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAS,KAAc,EAAS,EAAI,GACrC,CAAC,GAAS,KAAc,EAC5B,CACF,GAEM,IAAiB,EAAY,YAA2B;EAC5D,IAAI,CAAC,GAAiB;GACpB,EAAW,EAAK;GAChB;EACF;EAGA,AADA,EAAW,EAAI,GACf,EAAS,IAAI;EAEb,IAAI;GACF,EACE,MAAM,EAA6B;IACjC;IACA,MAAM;IACN,IAAI;GACN,CAAC,CACH;EACF,SAAS,GAAuB;GAC9B,EAAS,EAAiB,CAAY,CAAC;EACzC,UAAU;GACR,EAAW,EAAK;EAClB;CACF,GAAG,CAAC,CAAe,CAAC;CAEpB,QAAsB;EACpB,EAAoB;CACtB,GAAG,CAAC,CAAc,CAAC;CAEnB,IAAM,IAAU,QACW;EACvB;GACE,SAAS;GACT,MAAM;GACN,OAAO;GACP,OAAO,EAAgB,EAAQ,kBAAkB,CAAO;EAC1D;EACA;GACE,SAAS;GACT,MAAM;GACN,OAAO;GACP,OAAO,EAAgB,EAAQ,yBAAyB,CAAO;EACjE;EACA;GACE,SAAS;GACT,MAAM;GACN,OAAO;GACP,OAAO,EAAgB,EAAQ,qBAAqB,CAAO;EAC7D;EACA;GACE,SAAS;GACT,MAAM;GACN,OAAO;GACP,OAAO,EAAgB,EAAQ,kBAAkB,CAAO;EAC1D;EACA;GACE,SAAS;GACT,MAAM;GACN,OAAO;GACP,OAAO,EAAgB,EAAQ,oBAAoB,CAAO;EAC5D;CACF,GACA,CAAC,GAAS,CAAO,CACnB;CAEA,OACE,kBAAC,GAAD;EAAuB;YAAvB,CACI,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;GACE,aAAY;GACZ,OAAM;aAEN,kBAAC,GAAD;IACE,MAAM;IACN,UAAS;IACT,eAAqB,EAAO,KAAK,gBAAgB;IACjD,SAAQ;cACT;GAEO,CAAA;EACK,CAAA,EACL,CAAA,GAEZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA,CACG,IACC,kBAAC,GAAD;GAAY,OAAM;GAAa,SAAQ;aACpC;EACS,CAAA,IACV,MACJ,kBAAC,GAAD,EAAA,UACG,EAAQ,KAAK,MACZ,kBAAC,GAAD;GACE,cAAY,KAAK,EAAO;GACxB,WAAW,EAAO;GAClB,aAAa,EAAO;GAEpB,eAAqB,EAAO,KAAK,EAAO,IAAI;GAC5C,YAAY,MAA4C;IACtD,CAAI,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,eAAe,GACrB,EAAO,KAAK,EAAO,IAAI;GAE3B;GACA,MAAK;GACL,UAAU;GACV,OAAO,EAAO;aAEd,kBAAC,GAAD;IAAY,OAAM;IAAe,SAAQ;cACtC,EAAO;GACE,CAAA;EACJ,GAfH,EAAO,KAeJ,CACX,EACQ,CAAA,CACJ,EAAA,CAAA,EACG,CAAA,CACL;;AAEjB;AAEA,SAAS,EAAgB,GAAe,GAA0B;CAChE,OAAO,IAAU,MAAM,OAAO,CAAK;AACrC;AAEA,SAAS,EAAiB,GAAwB;CAChD,OAAO,aAAiB,QAAQ,EAAM,UAAU;AAClD"}
|