@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.
Files changed (168) hide show
  1. package/README.md +13 -1
  2. package/dist/chunks/{app-navigation-BRRFCkxZ.cjs → app-navigation-C_mbz7jx.cjs} +2 -2
  3. package/dist/chunks/app-navigation-C_mbz7jx.cjs.map +1 -0
  4. package/dist/chunks/{app-navigation-rxhpHCch.js → app-navigation-uwbNEw9P.js} +65 -65
  5. package/dist/chunks/app-navigation-uwbNEw9P.js.map +1 -0
  6. package/dist/chunks/approval-instance-list-page-Mo6wpDPb.cjs +2 -0
  7. package/dist/chunks/approval-instance-list-page-Mo6wpDPb.cjs.map +1 -0
  8. package/dist/chunks/approval-instance-list-page-nmzMrj0b.js +281 -0
  9. package/dist/chunks/approval-instance-list-page-nmzMrj0b.js.map +1 -0
  10. package/dist/chunks/builder-DPhAH381.cjs +3 -0
  11. package/dist/chunks/builder-DPhAH381.cjs.map +1 -0
  12. package/dist/chunks/{builder-Du_0apkh.js → builder-DqZskyXC.js} +333 -330
  13. package/dist/chunks/builder-DqZskyXC.js.map +1 -0
  14. package/dist/chunks/categories-DEijUOnw.cjs +2 -0
  15. package/dist/chunks/categories-DEijUOnw.cjs.map +1 -0
  16. package/dist/chunks/{categories-DG4k7S8V.js → categories-DTEl182t.js} +129 -126
  17. package/dist/chunks/categories-DTEl182t.js.map +1 -0
  18. package/dist/chunks/{dashboard-page-DcDiWQp2.cjs → dashboard-page-DCmuB0Rw.cjs} +2 -2
  19. package/dist/chunks/dashboard-page-DCmuB0Rw.cjs.map +1 -0
  20. package/dist/chunks/dashboard-page-Dx5PeEeN.js +117 -0
  21. package/dist/chunks/dashboard-page-Dx5PeEeN.js.map +1 -0
  22. package/dist/chunks/delegations-C-ZrwzvU.js +572 -0
  23. package/dist/chunks/delegations-C-ZrwzvU.js.map +1 -0
  24. package/dist/chunks/delegations-C5PzZ5Kn.js +645 -0
  25. package/dist/chunks/delegations-C5PzZ5Kn.js.map +1 -0
  26. package/dist/chunks/delegations-DOGDvybX.cjs +2 -0
  27. package/dist/chunks/delegations-DOGDvybX.cjs.map +1 -0
  28. package/dist/chunks/delegations-DkDBWOQ7.cjs +2 -0
  29. package/dist/chunks/delegations-DkDBWOQ7.cjs.map +1 -0
  30. package/dist/chunks/detail-B2gcOPkd.cjs +2 -0
  31. package/dist/chunks/detail-B2gcOPkd.cjs.map +1 -0
  32. package/dist/chunks/{detail-DilI0PPe.js → detail-CfFyU5zC.js} +667 -664
  33. package/dist/chunks/detail-CfFyU5zC.js.map +1 -0
  34. package/dist/chunks/{format-date-time-hKLVMxq4.cjs → format-date-time-isOa3e9q.cjs} +2 -2
  35. package/dist/chunks/{format-date-time-hKLVMxq4.cjs.map → format-date-time-isOa3e9q.cjs.map} +1 -1
  36. package/dist/chunks/notifications-CPQ-nVar.cjs +2 -0
  37. package/dist/chunks/notifications-CPQ-nVar.cjs.map +1 -0
  38. package/dist/chunks/notifications-DweexUVy.js +197 -0
  39. package/dist/chunks/notifications-DweexUVy.js.map +1 -0
  40. package/dist/chunks/orgs-DgZ0DQ3-.cjs +2 -0
  41. package/dist/chunks/orgs-DgZ0DQ3-.cjs.map +1 -0
  42. package/dist/chunks/{orgs-c29y74w2.js → orgs-xrdhb3hS.js} +668 -665
  43. package/dist/chunks/orgs-xrdhb3hS.js.map +1 -0
  44. package/dist/chunks/templates-PK_VYvcy.js +383 -0
  45. package/dist/chunks/templates-PK_VYvcy.js.map +1 -0
  46. package/dist/chunks/{templates-Cd0WFheA.cjs → templates-x1OJZmsG.cjs} +2 -2
  47. package/dist/chunks/templates-x1OJZmsG.cjs.map +1 -0
  48. package/dist/chunks/users-CY4-NK3j.js +218 -0
  49. package/dist/chunks/users-CY4-NK3j.js.map +1 -0
  50. package/dist/chunks/users-DHnu_056.cjs +2 -0
  51. package/dist/chunks/users-DHnu_056.cjs.map +1 -0
  52. package/dist/components/app-navigation.d.ts +17 -10
  53. package/dist/index.cjs +1 -1
  54. package/dist/index.cjs.map +1 -1
  55. package/dist/index.js +4 -4
  56. package/dist/index.js.map +1 -1
  57. package/dist/lib/notification-drawer-provider.d.ts +1 -1
  58. package/dist/lib/notification-unread-provider.d.ts +1 -1
  59. package/dist/lib/providers.d.ts +1 -1
  60. package/dist/pages/admin/delegations/index.cjs +1 -1
  61. package/dist/pages/admin/delegations/index.js +1 -1
  62. package/dist/pages/admin/orgs/index.cjs +1 -1
  63. package/dist/pages/admin/orgs/index.js +1 -1
  64. package/dist/pages/admin/users/index.cjs +1 -1
  65. package/dist/pages/admin/users/index.js +1 -1
  66. package/dist/pages/delegations/index.cjs +1 -1
  67. package/dist/pages/delegations/index.js +1 -1
  68. package/dist/pages/forms/builder/index.cjs +1 -1
  69. package/dist/pages/forms/builder/index.js +1 -1
  70. package/dist/pages/instances/detail/index.cjs +1 -1
  71. package/dist/pages/instances/detail/index.js +1 -1
  72. package/dist/pages/settings/notifications/index.cjs +1 -1
  73. package/dist/pages/settings/notifications/index.js +1 -1
  74. package/dist/pages/templates/categories/index.cjs +1 -1
  75. package/dist/pages/templates/categories/index.js +1 -1
  76. package/dist/pages/templates/index.cjs +1 -1
  77. package/dist/pages/templates/index.js +1 -1
  78. package/dist/views/admin/delegations/index.cjs +1 -1
  79. package/dist/views/admin/delegations/index.js +1 -1
  80. package/dist/views/admin/index.cjs +1 -1
  81. package/dist/views/admin/index.js +3 -3
  82. package/dist/views/admin/orgs/index.cjs +1 -1
  83. package/dist/views/admin/orgs/index.js +1 -1
  84. package/dist/views/admin/users/index.cjs +1 -1
  85. package/dist/views/admin/users/index.js +1 -1
  86. package/dist/views/cc/index.cjs +1 -1
  87. package/dist/views/cc/index.js +1 -1
  88. package/dist/views/dashboard/index.cjs +1 -1
  89. package/dist/views/dashboard/index.js +1 -1
  90. package/dist/views/delegations/index.cjs +1 -1
  91. package/dist/views/delegations/index.js +1 -1
  92. package/dist/views/forms/builder/index.cjs +1 -1
  93. package/dist/views/forms/builder/index.js +1 -1
  94. package/dist/views/forms/index.cjs +1 -1
  95. package/dist/views/forms/index.cjs.map +1 -1
  96. package/dist/views/forms/index.js +93 -90
  97. package/dist/views/forms/index.js.map +1 -1
  98. package/dist/views/inbox/index.cjs +1 -1
  99. package/dist/views/inbox/index.cjs.map +1 -1
  100. package/dist/views/inbox/index.js +127 -124
  101. package/dist/views/inbox/index.js.map +1 -1
  102. package/dist/views/instances/detail/index.cjs +1 -1
  103. package/dist/views/instances/detail/index.js +1 -1
  104. package/dist/views/instances/new/index.cjs +1 -1
  105. package/dist/views/instances/new/index.cjs.map +1 -1
  106. package/dist/views/instances/new/index.js +120 -114
  107. package/dist/views/instances/new/index.js.map +1 -1
  108. package/dist/views/search/index.cjs +1 -1
  109. package/dist/views/search/index.js +1 -1
  110. package/dist/views/sent/index.cjs +1 -1
  111. package/dist/views/sent/index.js +1 -1
  112. package/dist/views/settings/index.cjs +1 -1
  113. package/dist/views/settings/index.js +1 -1
  114. package/dist/views/settings/notifications/index.cjs +1 -1
  115. package/dist/views/settings/notifications/index.js +1 -1
  116. package/dist/views/templates/categories/index.cjs +1 -1
  117. package/dist/views/templates/categories/index.js +1 -1
  118. package/dist/views/templates/designer/index.cjs +2 -2
  119. package/dist/views/templates/designer/index.cjs.map +1 -1
  120. package/dist/views/templates/designer/index.js +573 -570
  121. package/dist/views/templates/designer/index.js.map +1 -1
  122. package/dist/views/templates/index.cjs +1 -1
  123. package/dist/views/templates/index.js +2 -2
  124. package/dist/views/templates/versions/index.cjs +1 -1
  125. package/dist/views/templates/versions/index.cjs.map +1 -1
  126. package/dist/views/templates/versions/index.js +50 -47
  127. package/dist/views/templates/versions/index.js.map +1 -1
  128. package/package.json +1 -1
  129. package/dist/chunks/app-navigation-BRRFCkxZ.cjs.map +0 -1
  130. package/dist/chunks/app-navigation-rxhpHCch.js.map +0 -1
  131. package/dist/chunks/approval-instance-list-page-2vUWc5-c.cjs +0 -2
  132. package/dist/chunks/approval-instance-list-page-2vUWc5-c.cjs.map +0 -1
  133. package/dist/chunks/approval-instance-list-page-BgE4vQw8.js +0 -278
  134. package/dist/chunks/approval-instance-list-page-BgE4vQw8.js.map +0 -1
  135. package/dist/chunks/builder-B8X-m6C5.cjs +0 -3
  136. package/dist/chunks/builder-B8X-m6C5.cjs.map +0 -1
  137. package/dist/chunks/builder-Du_0apkh.js.map +0 -1
  138. package/dist/chunks/categories-DG4k7S8V.js.map +0 -1
  139. package/dist/chunks/categories-DshBQG33.cjs +0 -2
  140. package/dist/chunks/categories-DshBQG33.cjs.map +0 -1
  141. package/dist/chunks/dashboard-page-CTBwpu_D.js +0 -114
  142. package/dist/chunks/dashboard-page-CTBwpu_D.js.map +0 -1
  143. package/dist/chunks/dashboard-page-DcDiWQp2.cjs.map +0 -1
  144. package/dist/chunks/delegations-BAZQbElH.js +0 -642
  145. package/dist/chunks/delegations-BAZQbElH.js.map +0 -1
  146. package/dist/chunks/delegations-DzrckrPp.js +0 -569
  147. package/dist/chunks/delegations-DzrckrPp.js.map +0 -1
  148. package/dist/chunks/delegations-Z8hTajLj.cjs +0 -2
  149. package/dist/chunks/delegations-Z8hTajLj.cjs.map +0 -1
  150. package/dist/chunks/delegations-hb9JoVZe.cjs +0 -2
  151. package/dist/chunks/delegations-hb9JoVZe.cjs.map +0 -1
  152. package/dist/chunks/detail-DilI0PPe.js.map +0 -1
  153. package/dist/chunks/detail-DuRg3Y7b.cjs +0 -2
  154. package/dist/chunks/detail-DuRg3Y7b.cjs.map +0 -1
  155. package/dist/chunks/notifications-B2Lk3grg.js +0 -194
  156. package/dist/chunks/notifications-B2Lk3grg.js.map +0 -1
  157. package/dist/chunks/notifications-C8ADhnxF.cjs +0 -2
  158. package/dist/chunks/notifications-C8ADhnxF.cjs.map +0 -1
  159. package/dist/chunks/orgs-CGv3VNDR.cjs +0 -2
  160. package/dist/chunks/orgs-CGv3VNDR.cjs.map +0 -1
  161. package/dist/chunks/orgs-c29y74w2.js.map +0 -1
  162. package/dist/chunks/templates-Cd0WFheA.cjs.map +0 -1
  163. package/dist/chunks/templates-Dn9QHFSy.js +0 -380
  164. package/dist/chunks/templates-Dn9QHFSy.js.map +0 -1
  165. package/dist/chunks/users-B-trMu0E.cjs +0 -2
  166. package/dist/chunks/users-B-trMu0E.cjs.map +0 -1
  167. package/dist/chunks/users-itVXXRj7.js +0 -215
  168. 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-rxhpHCch.js";
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, Layout as m, Modal as h, PageHeader as g, Section as _, SectionGroup as ee, Tab as te, TabItem as ne, Table as re, Textarea as v, Typography as y } from "@mezzanine-ui/react";
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 T } from "@mezzanine-ui/core/form";
11
- import { createApprovalTemplateCategory as E, deleteApprovalTemplateCategory as D, listApprovalTemplateCategoriesPage as O, updateApprovalTemplateCategory as k } from "@rytass/bpm-core-client/template";
12
- import '../categories.css';var A = {
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
- }, j = [
15
+ }, D = [
16
16
  10,
17
17
  20,
18
18
  50
19
- ], M = [
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 N({ activeHref: n = "/templates/categories" } = {}) {
34
- let [s, v] = o([]), [N, I] = o(1), [L, R] = o(10), [z, B] = o("ALL"), [V, H] = o(0), [U, W] = o(null), [G, K] = o(null), [se, q] = o(!0), [J, Y] = o(null), [X, Z] = o(!1), [Q, ce] = o(""), $ = r(async () => {
35
- q(!0), K(null);
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 O({
38
- page: N,
39
- pageSize: L,
37
+ let e = await oe({
38
+ page: k,
39
+ pageSize: I,
40
40
  searchText: Q,
41
- status: P(z)
41
+ status: N(R)
42
42
  });
43
- v(e.categories), H(e.totalCount);
43
+ v(e.categories), V(e.totalCount);
44
44
  } catch (e) {
45
- K(F(e));
45
+ G(P(e));
46
46
  } finally {
47
47
  q(!1);
48
48
  }
49
49
  }, [
50
- N,
51
- L,
52
- z,
50
+ k,
51
+ I,
52
+ R,
53
53
  Q
54
54
  ]);
55
55
  i(() => {
56
56
  $();
57
57
  }, [$]);
58
- let le = a(() => s.map((t) => ({
58
+ let ce = a(() => s.map((t) => ({
59
59
  ...t,
60
60
  key: t.id,
61
61
  updatedAtLabel: e(t.updatedAt)
62
- })), [s]), ue = a(() => [
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(ae, { isActive: e.isActive }),
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 de(e) {
99
- Z(!0), K(null);
98
+ async function ue(e) {
99
+ Z(!0), G(null);
100
100
  try {
101
- J?.type === "EDIT" && J.record ? await k({
101
+ J?.type === "EDIT" && J.record ? await T({
102
102
  ...e,
103
103
  id: J.record.id
104
- }) : await E(e), Y(null), await $();
104
+ }) : await ie(e), Y(null), await $();
105
105
  } catch (e) {
106
- throw K(F(e)), e;
106
+ throw G(P(e)), e;
107
107
  } finally {
108
108
  Z(!1);
109
109
  }
110
110
  }
111
- async function fe(e) {
112
- Z(!0), K(null);
111
+ async function de(e) {
112
+ Z(!0), G(null);
113
113
  try {
114
- await k({
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
- K(F(e));
122
+ G(P(e));
123
123
  } finally {
124
124
  Z(!1);
125
125
  }
126
126
  }
127
- async function pe() {
128
- if (U) {
129
- Z(!0), K(null);
127
+ async function fe() {
128
+ if (H) {
129
+ Z(!0), G(null);
130
130
  try {
131
- await D(U.id), W(null), await $();
131
+ await ae(H.id), U(null), await $();
132
132
  } catch (e) {
133
- K(F(e));
133
+ G(P(e));
134
134
  } finally {
135
135
  Z(!1);
136
136
  }
137
137
  }
138
138
  }
139
- let me = a(() => ({
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 fe(e),
150
+ onClick: () => void de(e),
151
151
  variant: e.isActive ? "destructive-secondary" : "base-secondary"
152
152
  },
153
153
  {
154
154
  name: "刪除",
155
- onClick: () => W({
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(m, { children: [/* @__PURE__ */ x(t, { activeHref: n }), /* @__PURE__ */ S(m.Main, { children: [/* @__PURE__ */ x(g, { children: /* @__PURE__ */ x(w, {
167
- description: "維護簽核模板分類,供模板建立、篩選與列表標示使用。",
168
- title: "簽核模板分類",
169
- children: /* @__PURE__ */ x(c, {
170
- icon: C,
171
- iconType: "leading",
172
- onClick: () => Y({
173
- record: null,
174
- type: "CREATE"
175
- }),
176
- variant: "base-primary",
177
- children: "建立分類"
178
- })
179
- }) }), /* @__PURE__ */ x(ee, { children: /* @__PURE__ */ S(_, {
180
- filterArea: /* @__PURE__ */ x(u, {
181
- className: A.templateFilterArea,
182
- size: "sub",
183
- children: /* @__PURE__ */ x(d, { children: /* @__PURE__ */ x(l, {
184
- span: 3,
185
- children: /* @__PURE__ */ x(f, {
186
- fullWidth: !0,
187
- layout: T.VERTICAL,
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
- onChange: (e) => {
192
- ce(e.target.value), I(1);
193
- },
194
- placeholder: "關鍵字:搜尋分類名稱或說明",
195
- size: "sub",
196
- value: Q,
197
- variant: "base"
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
- tab: /* @__PURE__ */ x(te, {
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
- I(e);
223
- },
224
- onChangePageSize: (e) => {
225
- I(1), R(e);
207
+ z(M(e)), F(1);
226
208
  },
227
- pageSize: L,
228
- pageSizeLabel: "每頁筆數",
229
- pageSizeOptions: j,
230
- renderResultSummary: (e, t, n) => `顯示 ${e}-${t} 筆,共 ${n} 筆`,
231
- showPageSizeOptions: !0,
232
- total: V
233
- }
234
- })]
235
- }) })] })] }),
236
- /* @__PURE__ */ x(ie, {
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: de
243
+ onSubmit: ue
241
244
  }),
242
- /* @__PURE__ */ x(h, {
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: () => W(null),
250
- onClose: () => W(null),
251
- onConfirm: () => void pe(),
252
- open: !!U,
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
- U?.name ?? "",
266
+ H?.name ?? "",
264
267
  "」嗎?"
265
268
  ]
266
269
  })
267
270
  })
268
271
  ] });
269
272
  }
270
- function ie({ loading: e, modal: t, onClose: r, onSubmit: a }) {
271
- let [s, c] = o(""), [l, u] = o(null), [d, f] = o(""), [m, g] = o("0");
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(m);
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(F(e));
296
+ u(P(e));
294
297
  }
295
298
  }
296
- return /* @__PURE__ */ S(h, {
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: A.templateModalFields,
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: m,
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 ae({ isActive: e }) {
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 oe(e) {
374
+ function M(e) {
372
375
  return e === "ACTIVE" || e === "INACTIVE" ? e : "ALL";
373
376
  }
374
- function P(e) {
377
+ function N(e) {
375
378
  return e;
376
379
  }
377
- function F(e) {
380
+ function P(e) {
378
381
  return e instanceof Error ? e.message : "發生未知錯誤";
379
382
  }
380
383
  //#endregion
381
- export { A as n, N as t };
384
+ export { E as n, k as t };
382
385
 
383
- //# sourceMappingURL=categories-DG4k7S8V.js.map
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":";;;;;;;;;;;;;;GCuCM,IAA6B;CAAC;CAAI;CAAI;AAAE,GACxC,IAGA;CACJ;EAAE,KAAK;EAAO,OAAO;CAAK;CAC1B;EAAE,KAAK;EAAU,OAAO;CAAK;CAC7B;EAAE,KAAK;EAAY,OAAO;CAAK;AACjC;AAyBA,SAAgB,EAAuB,EACrC,gBAAa,4BACkB,CAAC,GAAiB;CACjD,IAAM,CAAC,GAAY,KAAiB,EAElC,CAAC,CAAC,GACE,CAAC,GAAc,KAAmB,EAAS,CAAC,GAC5C,CAAC,GAAkB,KAAuB,EAAS,EAAE,GACrD,CAAC,GAAgB,KACrB,EAA+B,KAAK,GAChC,CAAC,GAAoB,KAAyB,EAAS,CAAC,GACxD,CAAC,GAAoB,KACzB,EAAyC,IAAI,GACzC,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAS,KAAc,EAAS,EAAI,GACrC,CAAC,GAAY,KAAiB,EAAoC,IAAI,GACtE,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,CAAC,GAAY,MAAiB,EAAS,EAAE,GAEzC,IAAoB,EAAY,YAA2B;EAE/D,AADA,EAAW,EAAI,GACf,EAAS,IAAI;EAEb,IAAI;GACF,IAAM,IAAqB,MAAM,GAAmC;IAClE,MAAM;IACN,UAAU;IACV;IACA,QAAQ,EAAmB,CAAc;GAC3C,CAAC;GAGD,AADA,EAAc,EAAmB,UAAU,GAC3C,EAAsB,EAAmB,UAAU;EACrD,SAAS,GAAuB;GAC9B,EAAS,EAAiB,CAAY,CAAC;EACzC,UAAU;GACR,EAAW,EAAK;EAClB;CACF,GAAG;EAAC;EAAc;EAAkB;EAAgB;CAAU,CAAC;CAE/D,QAAsB;EACpB,EAAuB;CACzB,GAAG,CAAC,CAAiB,CAAC;CAEtB,IAAM,KAAO,QAET,EAAW,KAAK,OAAc;EAC5B,GAAG;EACH,KAAK,EAAS;EACd,gBAAgB,EAAe,EAAS,SAAS;CACnD,EAAE,GACJ,CAAC,CAAU,CACb,GAEM,KAAU,QACoB;EAChC;GAAE,WAAW;GAAQ,KAAK;GAAQ,OAAO;GAAQ,OAAO;EAAI;EAC5D;GACE,KAAK;GACL,SAAS,MACP,kBAAC,GAAD,EAAqB,UAAU,EAAO,SAAW,CAAA;GAEnD,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAAC,GAAD;IAAY,WAAU;IAAO,SAAQ;cAClC,EAAO,eAAe;GACb,CAAA;GAEd,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH;CAEA,eAAe,GAAmB,GAAyC;EAEzE,AADA,EAAU,EAAI,GACd,EAAS,IAAI;EAEb,IAAI;GAWF,AAVI,GAAY,SAAS,UAAU,EAAW,SAC5C,MAAM,EAA+B;IACnC,GAAG;IACH,IAAI,EAAW,OAAO;GACxB,CAAC,IAED,MAAM,GAA+B,CAAK,GAG5C,EAAc,IAAI,GAClB,MAAM,EAAkB;EAC1B,SAAS,GAAuB;GAE9B,MADA,EAAS,EAAiB,CAAY,CAAC,GACjC;EACR,UAAU;GACR,EAAU,EAAK;EACjB;CACF;CAEA,eAAe,GACb,GACe;EAEf,AADA,EAAU,EAAI,GACd,EAAS,IAAI;EAEb,IAAI;GAQF,AAPA,MAAM,EAA+B;IACnC,aAAa,EAAO;IACpB,IAAI,EAAO;IACX,UAAU,CAAC,EAAO;IAClB,MAAM,EAAO;IACb,WAAW,EAAO;GACpB,CAAC,GACD,MAAM,EAAkB;EAC1B,SAAS,GAAuB;GAC9B,EAAS,EAAiB,CAAY,CAAC;EACzC,UAAU;GACR,EAAU,EAAK;EACjB;CACF;CAEA,eAAe,KAAqC;EAC7C,OAKL;GADA,EAAU,EAAI,GACd,EAAS,IAAI;GAEb,IAAI;IAGF,AAFA,MAAM,GAA+B,EAAmB,EAAE,GAC1D,EAAsB,IAAI,GAC1B,MAAM,EAAkB;GAC1B,SAAS,GAAuB;IAC9B,EAAS,EAAiB,CAAY,CAAC;GACzC,UAAU;IACR,EAAU,EAAK;GACjB;EAVa;CAWf;CAEA,IAAM,KAAe,SACe;EAChC,SAAS,MAA4D;GACnE;IACE,MAAM;IACN,eAAqB,EAAc;KAAE;KAAQ,MAAM;IAAO,CAAC;GAC7D;GACA;IACE,MAAM,EAAO,WAAW,OAAO;IAC/B,eAAqB,KAAK,GAAqB,CAAM;IACrD,SAAS,EAAO,WAAW,0BAA0B;GACvD;GACA;IACE,MAAM;IACN,eACE,EAAsB;KAAE,IAAI,EAAO;KAAI,MAAM,EAAO;IAAK,CAAC;IAC5D,SAAS;GACX;EACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAAC,CAAiB,CACpB;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,GAAD;GAAuB;aAAvB,CACI,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IACE,aAAY;IACZ,OAAM;cAEN,kBAAC,GAAD;KACE,MAAM;KACN,UAAS;KACT,eACE,EAAc;MAAE,QAAQ;MAAM,MAAM;KAAS,CAAC;KAEhD,SAAQ;eACT;IAEO,CAAA;GACK,CAAA,EACL,CAAA,GAEZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IACE,YACE,kBAAC,GAAD;KAAY,WAAW,EAAO;KAAoB,MAAK;eACrD,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAQ,MAAM;gBACZ,kBAAC,GAAD;OACE,WAAA;OACA,QAAQ,GAAgB;OACxB,MAAK;iBAEL,kBAAC,GAAD;QACE,WAAA;QACA,WACE,MACS;SAET,AADA,GAAc,EAAM,OAAO,KAAK,GAChC,EAAgB,CAAC;QACnB;QACA,aAAY;QACZ,MAAK;QACL,OAAO;QACP,SAAQ;OACT,CAAA;MACQ,CAAA;KACL,CAAA,EACE,CAAA;IACF,CAAA;IAEd,KACE,kBAAC,IAAD;KACE,WAAW;KACX,WAAW,MAAoB;MAE7B,AADA,EAAkB,EAAyB,CAAS,CAAC,GACrD,EAAgB,CAAC;KACnB;eAEC,EAAqB,KAAK,MACzB,kBAAC,IAAD,EAAA,UAA8B,EAAU,MAAe,GAAzC,EAAU,GAA+B,CACxD;IACE,CAAA;cAvCT,CA0CG,IACC,kBAAC,GAAD;KAAY,OAAM;KAAa,SAAQ;eACpC;IACS,CAAA,IACV,MACJ,kBAAC,IAAD;KACE,SAAS;KACA;KACT,YAAY;KACZ,WAAA;KACA,SAAS,KAAW;KACpB,YAAY;MACV,SAAS;MACT,WAAW,MAAe;OACxB,EAAgB,CAAI;MACtB;MACA,mBAAmB,MAAmB;OAEpC,AADA,EAAgB,CAAC,GACjB,EAAoB,CAAQ;MAC9B;MACA,UAAU;MACV,eAAe;MACf,iBAAiB;MACjB,sBAAsB,GAAM,GAAI,MAC9B,MAAM,EAAK,GAAG,EAAG,OAAO,EAAM;MAChC,qBAAqB;MACrB,OAAO;KACT;IACD,CAAA,CACM;MACG,CAAA,CACL;;EAEb,kBAAC,GAAD;GACE,SAAS;GACT,OAAO;GACP,eAAqB,EAAc,IAAI;GACvC,UAAU;EACX,CAAA;EACD,kBAAC,GAAD;GACE,YAAW;GACX,oBAAoB,EAAE,SAAS,sBAAsB;GACrD,aAAY;GACZ,SAAS;GACT,iBAAgB;GAChB,WAAU;GACV,gBAAsB,EAAsB,IAAI;GAChD,eAAqB,EAAsB,IAAI;GAC/C,iBAAuB,KAAK,GAAoB;GAChD,MAAM,EAAQ;GACd,iBAAA;GACA,iBAAA;GACA,MAAK;GACL,gBAAe;GACf,OAAM;aAEN,kBAAC,GAAD;IAAY,OAAM;IAAe,SAAQ;cAAzC;KAAgD;KACvC,GAAoB,QAAQ;KAAG;IAC5B;;EACP,CAAA;CACP,EAAA,CAAA;AAEN;AASA,SAAS,EAAc,EACrB,YACA,UACA,YACA,eAMe;CACf,IAAM,CAAC,GAAa,KAAkB,EAAS,EAAE,GAC3C,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAM,KAAW,EAAS,EAAE,GAC7B,CAAC,GAAW,KAAgB,EAAS,GAAG;CAE9C,QAAsB;EACf,MAIL,EAAe,EAAM,QAAQ,eAAe,EAAE,GAC9C,EAAS,IAAI,GACb,EAAQ,EAAM,QAAQ,QAAQ,EAAE,GAChC,EAAa,OAAO,EAAM,QAAQ,aAAa,CAAC,CAAC;CACnD,GAAG,CAAC,CAAK,CAAC;CAEV,eAAe,IAA+B;EAC5C,IAAM,IAAc,EAAK,KAAK,GACxB,IAAkB,OAAO,CAAS;EAExC,IAAI,CAAC,GAAa;GAChB,EAAS,SAAS;GAClB;EACF;EAEA,IAAI,CAAC,OAAO,UAAU,CAAe,GAAG;GACtC,EAAS,SAAS;GAClB;EACF;EAEA,IAAI;GACF,MAAM,EAAS;IACb,aAAa,EAAY,KAAK,KAAK;IACnC,UAAU,GAAO,QAAQ,YAAY;IACrC,MAAM;IACN,WAAW;GACb,CAAC;EACH,SAAS,GAAsB;GAC7B,EAAS,EAAiB,CAAW,CAAC;EACxC;CACF;CAEA,OACE,kBAAC,GAAD;EACE,YAAW;EACX,oBAAoB,EAAE,UAAU,CAAC,EAAK,KAAK,EAAE;EAC7C,aAAa,GAAO,SAAS,SAAS,OAAO;EACpC;EACT,WAAU;EACV,UAAU;EACD;EACT,iBAAuB,KAAK,EAAc;EAC1C,MAAM,EAAQ;EACd,iBAAA;EACA,iBAAA;EACA,MAAK;EACL,OAAO,GAAO,SAAS,SAAS,SAAS;YAb3C,CAeE,kBAAC,OAAD;GAAK,WAAW,EAAO;aAAvB;IACE,kBAAC,GAAD;KAAc,OAAM;KAAO,MAAK;KAAe,UAAA;eAC7C,kBAAC,GAAD;MACE,WAAA;MACA,WAAA;MACA,WAAW,MAA+C;OAExD,AADA,EAAQ,EAAM,OAAO,KAAK,GAC1B,EAAS,IAAI;MACf;MACA,aAAY;MACZ,OAAO;MACP,SAAQ;KACT,CAAA;IACW,CAAA;IACd,kBAAC,GAAD;KAAc,OAAM;KAAK,MAAK;eAC5B,kBAAC,GAAD;MACE,WAAA;MACA,WAAW,MAA+C;OAExD,AADA,EAAa,EAAM,OAAO,KAAK,GAC/B,EAAS,IAAI;MACf;MACA,aAAY;MACZ,OAAO;MACP,SAAQ;KACT,CAAA;IACW,CAAA;IACd,kBAAC,GAAD;KAAc,OAAM;KAAK,MAAK;eAC5B,kBAAC,GAAD;MACE,WAAW,MAAkD;OAE3D,AADA,EAAe,EAAM,OAAO,KAAK,GACjC,EAAS,IAAI;MACf;MACA,aAAY;MACZ,OAAO;KACR,CAAA;IACW,CAAA;GACX;MACJ,IACC,kBAAC,GAAD;GAAY,OAAM;GAAa,SAAQ;aACpC;EACS,CAAA,IACV,IACC;;AAEX;AAEA,SAAS,EAAoB,EAC3B,eAGe;CACf,OAAO,IACL,kBAAC,GAAD;EAAO,MAAK;EAAM,MAAK;EAAK,SAAQ;CAAe,CAAA,IAEnD,kBAAC,GAAD;EAAO,MAAK;EAAM,MAAK;EAAK,SAAQ;CAAgB,CAAA;AAExD;AAEA,SAAS,EAAyB,GAAsC;CAKtE,OAJI,MAAc,YAAY,MAAc,aACnC,IAGF;AACT;AAEA,SAAS,EACP,GACgC;CAChC,OAAO;AACT;AAEA,SAAS,EAAiB,GAAwB;CAChD,OAAO,aAAiB,QAAQ,EAAM,UAAU;AAClD"}
@@ -1,2 +1,2 @@
1
- "use client";require('../dashboard-page.css');const e=require("./app-navigation-BRRFCkxZ.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)(r.Layout,{children:[(0,i.jsx)(e.t,{activeHref:u}),(0,i.jsxs)(r.Layout.Main,{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-DcDiWQp2.cjs.map
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"}