@rytass/bpm-core-react 0.18.0 → 0.18.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 (271) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/chunks/FormBuilderView-CHaAQL5v.cjs +3 -0
  3. package/dist/chunks/FormBuilderView-CHaAQL5v.cjs.map +1 -0
  4. package/dist/chunks/{FormBuilderView-BVKY1j_0.js → FormBuilderView-vQfVc08Z.js} +485 -481
  5. package/dist/chunks/FormBuilderView-vQfVc08Z.js.map +1 -0
  6. package/dist/chunks/{FormRendererView-BsTwZkqU.js → FormRendererView-CTLlG13b.js} +300 -189
  7. package/dist/chunks/FormRendererView-CTLlG13b.js.map +1 -0
  8. package/dist/chunks/FormRendererView-ChmM_4Yc.cjs +4 -0
  9. package/dist/chunks/FormRendererView-ChmM_4Yc.cjs.map +1 -0
  10. package/dist/chunks/admin-pickers-BjbkBpSJ.cjs +2 -0
  11. package/dist/chunks/admin-pickers-BjbkBpSJ.cjs.map +1 -0
  12. package/dist/chunks/{admin-pickers-Djq3h-UR.js → admin-pickers-DfGxsjpp.js} +42 -42
  13. package/dist/chunks/admin-pickers-DfGxsjpp.js.map +1 -0
  14. package/dist/chunks/{approval-instance-list-page-CPXMP3PL.js → approval-instance-list-page-BnI4t5mD.js} +7 -8
  15. package/dist/chunks/{approval-instance-list-page-CPXMP3PL.js.map → approval-instance-list-page-BnI4t5mD.js.map} +1 -1
  16. package/dist/chunks/{approval-instance-list-page-ax0pm8bt.cjs → approval-instance-list-page-fqvmkBlg.cjs} +2 -2
  17. package/dist/chunks/{approval-instance-list-page-ax0pm8bt.cjs.map → approval-instance-list-page-fqvmkBlg.cjs.map} +1 -1
  18. package/dist/chunks/{approver-filled-form-Dm3Iw7iw.cjs → approver-filled-form-B4zPg9kz.cjs} +2 -2
  19. package/dist/chunks/approver-filled-form-B4zPg9kz.cjs.map +1 -0
  20. package/dist/chunks/{approver-filled-form-ZEwpmsHJ.js → approver-filled-form-Bgazhbvd.js} +40 -36
  21. package/dist/chunks/approver-filled-form-Bgazhbvd.js.map +1 -0
  22. package/dist/chunks/auth-provider-4BeCw7cI.cjs.map +1 -1
  23. package/dist/chunks/{auth-provider-B5oPmvk2.js → auth-provider-C2b-5mGt.js} +2 -3
  24. package/dist/chunks/{auth-provider-B5oPmvk2.js.map → auth-provider-C2b-5mGt.js.map} +1 -1
  25. package/dist/chunks/{bpm-form-field-Cao0rMol.js → bpm-form-field-9B-Det0u.js} +2 -3
  26. package/dist/chunks/{bpm-form-field-Cao0rMol.js.map → bpm-form-field-9B-Det0u.js.map} +1 -1
  27. package/dist/chunks/bpm-form-field-Bc6k4ZEO.cjs.map +1 -1
  28. package/dist/chunks/{categories-riC33J_j.js → categories-BAdxjNSA.js} +14 -15
  29. package/dist/chunks/{categories-riC33J_j.js.map → categories-BAdxjNSA.js.map} +1 -1
  30. package/dist/chunks/{categories-AxxhqjLZ.cjs → categories-DQUtVEiV.cjs} +2 -2
  31. package/dist/chunks/{categories-AxxhqjLZ.cjs.map → categories-DQUtVEiV.cjs.map} +1 -1
  32. package/dist/chunks/{compose-B1GlrZW9.js → compose-D9ipJpF_.js} +131 -148
  33. package/dist/chunks/compose-D9ipJpF_.js.map +1 -0
  34. package/dist/chunks/compose-DtfX8DQ9.cjs +2 -0
  35. package/dist/chunks/compose-DtfX8DQ9.cjs.map +1 -0
  36. package/dist/chunks/{dashboard-page-DdBvV6YI.js → dashboard-page-BoqNhjT_.js} +5 -6
  37. package/dist/chunks/{dashboard-page-DdBvV6YI.js.map → dashboard-page-BoqNhjT_.js.map} +1 -1
  38. package/dist/chunks/{dashboard-page-BWQBSGDq.cjs → dashboard-page-D7YJ3udk.cjs} +2 -2
  39. package/dist/chunks/{dashboard-page-BWQBSGDq.cjs.map → dashboard-page-D7YJ3udk.cjs.map} +1 -1
  40. package/dist/chunks/{delegations-MxF3uJGW.js → delegations-BfhCDz5e.js} +15 -16
  41. package/dist/chunks/{delegations-MxF3uJGW.js.map → delegations-BfhCDz5e.js.map} +1 -1
  42. package/dist/chunks/{delegations-Ckf03icM.cjs → delegations-BmFGcuhA.cjs} +2 -2
  43. package/dist/chunks/{delegations-Ckf03icM.cjs.map → delegations-BmFGcuhA.cjs.map} +1 -1
  44. package/dist/chunks/{delegations-V9HIe3_P.cjs → delegations-CcS0SHbf.cjs} +2 -2
  45. package/dist/chunks/{delegations-V9HIe3_P.cjs.map → delegations-CcS0SHbf.cjs.map} +1 -1
  46. package/dist/chunks/{delegations-xUt1tj8d.js → delegations-DBh5TT6G.js} +16 -17
  47. package/dist/chunks/{delegations-xUt1tj8d.js.map → delegations-DBh5TT6G.js.map} +1 -1
  48. package/dist/chunks/designer-Df79YzUn.cjs +65 -0
  49. package/dist/chunks/designer-Df79YzUn.cjs.map +1 -0
  50. package/dist/chunks/{designer-BCLrjb4H.js → designer-ubnZbP-A.js} +1791 -1407
  51. package/dist/chunks/designer-ubnZbP-A.js.map +1 -0
  52. package/dist/chunks/detail-BBC9kqXd.cjs +5 -0
  53. package/dist/chunks/detail-BBC9kqXd.cjs.map +1 -0
  54. package/dist/chunks/{detail-4F39ggBn.js → detail-C6XKZjlF.js} +1033 -1005
  55. package/dist/chunks/detail-C6XKZjlF.js.map +1 -0
  56. package/dist/chunks/{format-date-time-CB-LxzqT.js → format-date-time-B0LdmWg4.js} +2 -3
  57. package/dist/chunks/{format-date-time-CB-LxzqT.js.map → format-date-time-B0LdmWg4.js.map} +1 -1
  58. package/dist/chunks/format-date-time-D-cx5M8z.cjs.map +1 -1
  59. package/dist/chunks/{format-member-label-DudVI55w.js → format-member-label-C73FuP-d.js} +2 -3
  60. package/dist/chunks/{format-member-label-DudVI55w.js.map → format-member-label-C73FuP-d.js.map} +1 -1
  61. package/dist/chunks/format-member-label-t7ANTF62.cjs.map +1 -1
  62. package/dist/chunks/language-provider-Bdnx3Gxl.cjs.map +1 -1
  63. package/dist/chunks/{language-provider-B3cEbLe4.js → language-provider-phkWOapf.js} +2 -3
  64. package/dist/chunks/{language-provider-B3cEbLe4.js.map → language-provider-phkWOapf.js.map} +1 -1
  65. package/dist/chunks/{login-C6qlTC6F.js → login-D6cc3bo7.js} +4 -5
  66. package/dist/chunks/{login-C6qlTC6F.js.map → login-D6cc3bo7.js.map} +1 -1
  67. package/dist/chunks/{login-AtVxZBsC.cjs → login-uvVcltrS.cjs} +2 -2
  68. package/dist/chunks/{login-AtVxZBsC.cjs.map → login-uvVcltrS.cjs.map} +1 -1
  69. package/dist/chunks/notifications-Bc4mgSds.cjs.map +1 -1
  70. package/dist/chunks/{notifications-DJ5wzCye.js → notifications-Cvme5Qbl.js} +2 -3
  71. package/dist/chunks/{notifications-DJ5wzCye.js.map → notifications-Cvme5Qbl.js.map} +1 -1
  72. package/dist/chunks/orgs-B_2J2tLX.cjs +2 -0
  73. package/dist/chunks/{orgs-BeeDDWL1.cjs.map → orgs-B_2J2tLX.cjs.map} +1 -1
  74. package/dist/chunks/{orgs-8hje_l2n.js → orgs-DqxMds26.js} +48 -49
  75. package/dist/chunks/{orgs-8hje_l2n.js.map → orgs-DqxMds26.js.map} +1 -1
  76. package/dist/chunks/{providers-B_d5tbCL.js → providers-BbCs23sk.js} +21 -25
  77. package/dist/chunks/{providers-B_d5tbCL.js.map → providers-BbCs23sk.js.map} +1 -1
  78. package/dist/chunks/{providers-chuJvMgv.cjs → providers-D_KAgOOu.cjs} +2 -2
  79. package/dist/chunks/{providers-chuJvMgv.cjs.map → providers-D_KAgOOu.cjs.map} +1 -1
  80. package/dist/chunks/router-adapter--gYs13E8.cjs.map +1 -1
  81. package/dist/chunks/{router-adapter-DftlFTOd.js → router-adapter-CkxCyzf5.js} +2 -3
  82. package/dist/chunks/{router-adapter-DftlFTOd.js.map → router-adapter-CkxCyzf5.js.map} +1 -1
  83. package/dist/chunks/{routes-config-yZbESPlw.js → routes-config-BcNaWJWJ.js} +2 -3
  84. package/dist/chunks/{routes-config-yZbESPlw.js.map → routes-config-BcNaWJWJ.js.map} +1 -1
  85. package/dist/chunks/routes-config-C1j_vFKo.cjs.map +1 -1
  86. package/dist/chunks/task-decision-3d17ZvZE.js +29 -0
  87. package/dist/chunks/task-decision-3d17ZvZE.js.map +1 -0
  88. package/dist/chunks/task-decision-CqZ4WQOC.cjs +2 -0
  89. package/dist/chunks/task-decision-CqZ4WQOC.cjs.map +1 -0
  90. package/dist/chunks/{use-bpm-member-D57LKe_u.js → use-bpm-member-BPzcNU1g.js} +3 -4
  91. package/dist/chunks/{use-bpm-member-D57LKe_u.js.map → use-bpm-member-BPzcNU1g.js.map} +1 -1
  92. package/dist/chunks/use-bpm-member-DpNAQtNC.cjs.map +1 -1
  93. package/dist/chunks/{users-Pl6hY5Y5.js → users-BBtiZ9QQ.js} +22 -25
  94. package/dist/chunks/{users-Pl6hY5Y5.js.map → users-BBtiZ9QQ.js.map} +1 -1
  95. package/dist/chunks/{users-O2L_M3BK.cjs → users-EqSzDhuj.cjs} +2 -2
  96. package/dist/chunks/{users-O2L_M3BK.cjs.map → users-EqSzDhuj.cjs.map} +1 -1
  97. package/dist/components/admin-picker-options.d.cts +11 -0
  98. package/dist/components/admin-picker-options.d.ts +11 -0
  99. package/dist/components/admin-pickers.d.cts +2 -11
  100. package/dist/components/admin-pickers.d.ts +2 -11
  101. package/dist/index.cjs +1 -1
  102. package/dist/index.cjs.map +1 -1
  103. package/dist/index.js +17 -19
  104. package/dist/index.js.map +1 -1
  105. package/dist/lib/task-decision.d.cts +16 -0
  106. package/dist/lib/task-decision.d.ts +16 -0
  107. package/dist/lib/use-org-unit-names.d.cts +10 -0
  108. package/dist/lib/use-org-unit-names.d.ts +10 -0
  109. package/dist/next/index.cjs +1 -1
  110. package/dist/next/index.cjs.map +1 -1
  111. package/dist/next/index.js +7 -8
  112. package/dist/next/index.js.map +1 -1
  113. package/dist/next/workflow-chat-route.cjs +19 -1
  114. package/dist/next/workflow-chat-route.cjs.map +1 -1
  115. package/dist/next/workflow-chat-route.js +2 -3
  116. package/dist/next/workflow-chat-route.js.map +1 -1
  117. package/dist/pages/admin/delegations/index.cjs +1 -1
  118. package/dist/pages/admin/delegations/index.cjs.map +1 -1
  119. package/dist/pages/admin/delegations/index.js +2 -3
  120. package/dist/pages/admin/orgs/index.cjs +1 -1
  121. package/dist/pages/admin/orgs/index.cjs.map +1 -1
  122. package/dist/pages/admin/orgs/index.js +2 -3
  123. package/dist/pages/admin/users/index.cjs +1 -1
  124. package/dist/pages/admin/users/index.cjs.map +1 -1
  125. package/dist/pages/admin/users/index.js +2 -3
  126. package/dist/pages/admin/webhook-endpoints/index.cjs.map +1 -1
  127. package/dist/pages/admin/webhook-endpoints/index.js +1 -2
  128. package/dist/pages/cc/index.cjs.map +1 -1
  129. package/dist/pages/cc/index.js +1 -2
  130. package/dist/pages/dashboard/index.cjs.map +1 -1
  131. package/dist/pages/dashboard/index.js +1 -2
  132. package/dist/pages/delegations/index.cjs +1 -1
  133. package/dist/pages/delegations/index.cjs.map +1 -1
  134. package/dist/pages/delegations/index.js +2 -3
  135. package/dist/pages/inbox/index.cjs.map +1 -1
  136. package/dist/pages/inbox/index.js +1 -2
  137. package/dist/pages/instances/detail/index.cjs +1 -1
  138. package/dist/pages/instances/detail/index.cjs.map +1 -1
  139. package/dist/pages/instances/detail/index.js +2 -3
  140. package/dist/pages/instances/new/index.cjs.map +1 -1
  141. package/dist/pages/instances/new/index.js +1 -2
  142. package/dist/pages/login/index.cjs +1 -1
  143. package/dist/pages/login/index.cjs.map +1 -1
  144. package/dist/pages/login/index.js +2 -3
  145. package/dist/pages/root/index.cjs.map +1 -1
  146. package/dist/pages/root/index.js +1 -2
  147. package/dist/pages/search/index.cjs.map +1 -1
  148. package/dist/pages/search/index.js +1 -2
  149. package/dist/pages/sent/index.cjs.map +1 -1
  150. package/dist/pages/sent/index.js +1 -2
  151. package/dist/pages/settings/notifications/index.cjs.map +1 -1
  152. package/dist/pages/settings/notifications/index.js +2 -3
  153. package/dist/pages/templates/categories/index.cjs +1 -1
  154. package/dist/pages/templates/categories/index.cjs.map +1 -1
  155. package/dist/pages/templates/categories/index.js +2 -3
  156. package/dist/pages/templates/compose/index.cjs +1 -1
  157. package/dist/pages/templates/compose/index.cjs.map +1 -1
  158. package/dist/pages/templates/compose/index.js +2 -3
  159. package/dist/pages/templates/designer/index.cjs +1 -1
  160. package/dist/pages/templates/designer/index.cjs.map +1 -1
  161. package/dist/pages/templates/designer/index.js +2 -3
  162. package/dist/pages/templates/index.cjs.map +1 -1
  163. package/dist/pages/templates/index.js +1 -2
  164. package/dist/pages/templates/versions/index.cjs.map +1 -1
  165. package/dist/pages/templates/versions/index.js +1 -2
  166. package/dist/views/admin/delegations/index.cjs +1 -1
  167. package/dist/views/admin/delegations/index.js +1 -1
  168. package/dist/views/admin/index.cjs +1 -1
  169. package/dist/views/admin/index.js +3 -3
  170. package/dist/views/admin/orgs/index.cjs +1 -1
  171. package/dist/views/admin/orgs/index.js +1 -1
  172. package/dist/views/admin/users/index.cjs +1 -1
  173. package/dist/views/admin/users/index.js +1 -1
  174. package/dist/views/admin/webhook-endpoints/index.cjs +1 -1
  175. package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
  176. package/dist/views/admin/webhook-endpoints/index.js +52 -53
  177. package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
  178. package/dist/views/cc/index.cjs +1 -1
  179. package/dist/views/cc/index.cjs.map +1 -1
  180. package/dist/views/cc/index.js +2 -3
  181. package/dist/views/dashboard/index.cjs +1 -1
  182. package/dist/views/dashboard/index.cjs.map +1 -1
  183. package/dist/views/dashboard/index.js +2 -3
  184. package/dist/views/delegations/index.cjs +1 -1
  185. package/dist/views/delegations/index.js +1 -1
  186. package/dist/views/forms/builder/index.cjs +1 -1
  187. package/dist/views/forms/builder/index.js +1 -1
  188. package/dist/views/forms/renderer/index.cjs +1 -1
  189. package/dist/views/forms/renderer/index.js +1 -1
  190. package/dist/views/forms/renderer/org-unit-field-options.d.cts +44 -0
  191. package/dist/views/forms/renderer/org-unit-field-options.d.ts +44 -0
  192. package/dist/views/forms/renderer/org-unit-field.d.cts +23 -0
  193. package/dist/views/forms/renderer/org-unit-field.d.ts +23 -0
  194. package/dist/views/inbox/index.cjs +1 -1
  195. package/dist/views/inbox/index.cjs.map +1 -1
  196. package/dist/views/inbox/index.js +133 -137
  197. package/dist/views/inbox/index.js.map +1 -1
  198. package/dist/views/instances/approver-filled-form.d.cts +9 -2
  199. package/dist/views/instances/approver-filled-form.d.ts +9 -2
  200. package/dist/views/instances/detail/index.cjs +1 -1
  201. package/dist/views/instances/detail/index.js +1 -1
  202. package/dist/views/instances/detail/sections/InstanceHistorySection.d.cts +8 -1
  203. package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +8 -1
  204. package/dist/views/instances/detail/sections/container-helpers.d.cts +0 -1
  205. package/dist/views/instances/detail/sections/container-helpers.d.ts +0 -1
  206. package/dist/views/instances/detail/sections/shared.d.cts +2 -2
  207. package/dist/views/instances/detail/sections/shared.d.ts +2 -2
  208. package/dist/views/instances/new/index.cjs +1 -1
  209. package/dist/views/instances/new/index.cjs.map +1 -1
  210. package/dist/views/instances/new/index.js +14 -15
  211. package/dist/views/instances/new/index.js.map +1 -1
  212. package/dist/views/login/index.cjs +1 -1
  213. package/dist/views/login/index.js +1 -1
  214. package/dist/views/search/index.cjs +1 -1
  215. package/dist/views/search/index.cjs.map +1 -1
  216. package/dist/views/search/index.js +2 -3
  217. package/dist/views/sent/index.cjs +1 -1
  218. package/dist/views/sent/index.cjs.map +1 -1
  219. package/dist/views/sent/index.js +2 -3
  220. package/dist/views/settings/index.js +1 -1
  221. package/dist/views/settings/notifications/index.js +1 -1
  222. package/dist/views/templates/categories/index.cjs +1 -1
  223. package/dist/views/templates/categories/index.js +1 -1
  224. package/dist/views/templates/compose/index.cjs +1 -1
  225. package/dist/views/templates/compose/index.js +1 -1
  226. package/dist/views/templates/designer/approver-resolver-model.d.cts +211 -0
  227. package/dist/views/templates/designer/approver-resolver-model.d.ts +211 -0
  228. package/dist/views/templates/designer/dry-run-assignee-label.d.cts +2 -0
  229. package/dist/views/templates/designer/dry-run-assignee-label.d.ts +2 -0
  230. package/dist/views/templates/designer/dry-run-sample-data.d.cts +6 -0
  231. package/dist/views/templates/designer/dry-run-sample-data.d.ts +6 -0
  232. package/dist/views/templates/designer/dynamic-form-resolver-options.d.cts +25 -0
  233. package/dist/views/templates/designer/dynamic-form-resolver-options.d.ts +25 -0
  234. package/dist/views/templates/designer/index.cjs +1 -1
  235. package/dist/views/templates/designer/index.js +1 -1
  236. package/dist/views/templates/designer/node-actor-resolver-options.d.cts +38 -0
  237. package/dist/views/templates/designer/node-actor-resolver-options.d.ts +38 -0
  238. package/dist/views/templates/index.cjs +1 -1
  239. package/dist/views/templates/index.cjs.map +1 -1
  240. package/dist/views/templates/index.js +50 -51
  241. package/dist/views/templates/index.js.map +1 -1
  242. package/dist/views/templates/versions/index.cjs +1 -1
  243. package/dist/views/templates/versions/index.cjs.map +1 -1
  244. package/dist/views/templates/versions/index.js +7 -8
  245. package/dist/views/templates/versions/index.js.map +1 -1
  246. package/package.json +3 -3
  247. package/dist/chunks/FormBuilderView-BVKY1j_0.js.map +0 -1
  248. package/dist/chunks/FormBuilderView-SrGltzFT.cjs +0 -3
  249. package/dist/chunks/FormBuilderView-SrGltzFT.cjs.map +0 -1
  250. package/dist/chunks/FormRendererView-BsTwZkqU.js.map +0 -1
  251. package/dist/chunks/FormRendererView-GpsE03np.cjs +0 -4
  252. package/dist/chunks/FormRendererView-GpsE03np.cjs.map +0 -1
  253. package/dist/chunks/admin-pickers-BRHk3qKq.cjs +0 -2
  254. package/dist/chunks/admin-pickers-BRHk3qKq.cjs.map +0 -1
  255. package/dist/chunks/admin-pickers-Djq3h-UR.js.map +0 -1
  256. package/dist/chunks/approver-filled-form-Dm3Iw7iw.cjs.map +0 -1
  257. package/dist/chunks/approver-filled-form-ZEwpmsHJ.js.map +0 -1
  258. package/dist/chunks/compose-B1GlrZW9.js.map +0 -1
  259. package/dist/chunks/compose-DZk-SfHT.cjs +0 -2
  260. package/dist/chunks/compose-DZk-SfHT.cjs.map +0 -1
  261. package/dist/chunks/designer-BCLrjb4H.js.map +0 -1
  262. package/dist/chunks/designer-BYYxEN9L.cjs +0 -65
  263. package/dist/chunks/designer-BYYxEN9L.cjs.map +0 -1
  264. package/dist/chunks/detail-4F39ggBn.js.map +0 -1
  265. package/dist/chunks/detail-BkMtA_0K.cjs +0 -2
  266. package/dist/chunks/detail-BkMtA_0K.cjs.map +0 -1
  267. package/dist/chunks/orgs-BeeDDWL1.cjs +0 -2
  268. package/dist/chunks/task-node-label-BF6UllxP.cjs +0 -2
  269. package/dist/chunks/task-node-label-BF6UllxP.cjs.map +0 -1
  270. package/dist/chunks/task-node-label-CWZgOBj0.js +0 -9
  271. package/dist/chunks/task-node-label-CWZgOBj0.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"auth-provider-B5oPmvk2.js","names":["styles","useRouterAdapter","auth_provider_module_default","AuthContext","createContext","AuthProvider","router","loading","setLoading","useState","member","setMember","refresh","useCallback","current","readApiCurrentMember","login","next","loginApi","input","logout","logoutApi","loginPath","useEffect","active","isPublicPath","publicPaths","readCurrentPath","value","useMemo","AuthLoadingState","useAuth","ctx","useContext","Typography","label","p","pathname"],"sources":["../../src/lib/auth-provider.module.scss","../../src/lib/auth-provider.tsx"],"sourcesContent":[".authLoading {\n align-items: center;\n background: var(--mzn-color-bg-body);\n display: flex;\n min-height: 100vh;\n justify-content: center;\n padding: 32px;\n}\n","'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { Typography } from '@mezzanine-ui/react';\nimport {\n loginApi,\n logoutApi,\n readApiCurrentMember,\n type ApiMember,\n} from '@rytass/bpm-core-client';\nimport { useRouterAdapter } from './router-adapter';\nimport styles from './auth-provider.module.scss';\n\ninterface AuthContextValue {\n readonly loading: boolean;\n readonly member: ApiMember | null;\n readonly login: (input: {\n readonly identifier: string;\n readonly password: string;\n }) => Promise<ApiMember>;\n readonly logout: () => Promise<void>;\n readonly refresh: () => Promise<ApiMember | null>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport interface AuthProviderProps {\n readonly children: ReactNode;\n /**\n * Paths that should not redirect to `/login` when there is no session.\n * Defaults to `['/login']`. Override when your host runs the login UI\n * under a different path.\n */\n readonly publicPaths?: readonly string[];\n /**\n * Where to send unauthenticated users. Defaults to `'/login'`.\n */\n readonly loginPath?: string;\n}\n\n/**\n * BPM auth context provider. Reads / writes the host BPM API session via\n * `@rytass/bpm-core-client` (`loginApi` / `logoutApi` / `readApiCurrentMember`)\n * and uses the host-supplied {@link useRouterAdapter} to redirect\n * unauthenticated users.\n */\nexport function AuthProvider({\n children,\n publicPaths = ['/login'],\n loginPath = '/login',\n}: AuthProviderProps): ReactElement {\n const router = useRouterAdapter();\n const [loading, setLoading] = useState(true);\n const [member, setMember] = useState<ApiMember | null>(null);\n\n const refresh = useCallback(async (): Promise<ApiMember | null> => {\n const current = await readApiCurrentMember();\n setMember(current);\n return current;\n }, []);\n\n const login = useCallback(\n async (input: {\n readonly identifier: string;\n readonly password: string;\n }): Promise<ApiMember> => {\n const next = await loginApi(input);\n setMember(next);\n return next;\n },\n [],\n );\n\n const logout = useCallback(async (): Promise<void> => {\n await logoutApi();\n setMember(null);\n router.replace(loginPath);\n }, [loginPath, router]);\n\n useEffect((): (() => void) => {\n let active = true;\n setLoading(true);\n void (async () => {\n try {\n const current = await readApiCurrentMember();\n if (active) setMember(current);\n } catch {\n if (active) setMember(null);\n } finally {\n if (active) setLoading(false);\n }\n })();\n return (): void => {\n active = false;\n };\n }, []);\n\n useEffect((): void => {\n if (loading || isPublicPath(router.pathname, publicPaths) || member) return;\n router.replace(\n `${loginPath}?next=${encodeURIComponent(readCurrentPath(router.pathname))}`,\n );\n }, [loading, loginPath, member, publicPaths, router]);\n\n const value = useMemo<AuthContextValue>(\n () => ({ loading, login, logout, member, refresh }),\n [loading, login, logout, member, refresh],\n );\n\n if (loading && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"確認登入狀態\" />;\n }\n if (!loading && !member && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"前往登入頁\" />;\n }\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\n/**\n * Access the BPM auth context. Throws when used outside `<AuthProvider>`.\n */\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error('useAuth must be used inside <AuthProvider>');\n return ctx;\n}\n\nfunction AuthLoadingState({\n label,\n}: {\n readonly label: string;\n}): ReactElement {\n return (\n <main className={styles.authLoading}>\n <Typography color=\"text-neutral\" variant=\"body\">\n {label}\n </Typography>\n </main>\n );\n}\n\nfunction isPublicPath(\n pathname: string | null,\n publicPaths: readonly string[],\n): boolean {\n return publicPaths.some((p) => p === pathname);\n}\n\nfunction readCurrentPath(pathname: string | null): string {\n if (typeof window === 'undefined') return pathname ?? '/';\n return `${window.location.pathname}${window.location.search}`;\n}\n"],"mappings":";;;;;;kDCiCMG,IAAcC,EAAuC,IAAI;AAsB/D,SAAgBC,EAAa,EAC3B,aACA,iBAAc,CAAC,QAAQ,GACvB,eAAY,YACsB;CAClC,IAAMC,IAASL,EAAiB,GAC1B,CAACM,GAASC,KAAcC,EAAS,EAAI,GACrC,CAACC,GAAQC,KAAaF,EAA2B,IAAI,GAErDG,IAAUC,EAAY,YAAuC;EACjE,IAAMC,IAAU,MAAMC,EAAqB;EAE3C,OADAJ,EAAUG,CAAO,GACVA;CACT,GAAG,CAAC,CAAC,GAECE,IAAQH,EACZ,OAAO,MAGmB;EACxB,IAAMI,IAAO,MAAMC,EAASC,CAAK;EAEjC,OADAR,EAAUM,CAAI,GACPA;CACT,GACA,CAAC,CACH,GAEMG,IAASP,EAAY,YAA2B;EAGpD,AAFA,MAAMQ,EAAU,GAChBV,EAAU,IAAI,GACdL,EAAO,QAAQgB,CAAS;CAC1B,GAAG,CAACA,GAAWhB,CAAM,CAAC;CAoBtB,AAlBAiB,QAA8B;EAC5B,IAAIC,IAAS;EAYb,OAXAhB,EAAW,EAAI,IACT,YAAY;GAChB,IAAI;IACF,IAAMM,IAAU,MAAMC,EAAqB;IAC3C,AAAIS,KAAQb,EAAUG,CAAO;GAC/B,QAAQ;IACN,AAAIU,KAAQb,EAAU,IAAI;GAC5B,UAAU;IACR,AAAIa,KAAQhB,EAAW,EAAK;GAC9B;EACF,EAAA,CAAG,SACgB;GACjB,IAAS;EACX;CACF,GAAG,CAAC,CAAC,GAELe,QAAsB;EACpB,AAAIhB,KAAWkB,EAAanB,EAAO,UAAUoB,CAAW,KAAKhB,KAC7DJ,EAAO,QACL,GAAGgB,EAAU,QAAQ,mBAAmBK,EAAgBrB,EAAO,QAAQ,CAAC,GAC1E;CACF,GAAG;EAACC;EAASe;EAAWZ;EAAQgB;EAAapB;CAAM,CAAC;CAEpD,IAAMsB,IAAQC,SACL;EAAE;EAAS;EAAO;EAAQ;EAAQ;CAAQ,IACjD;EAACtB;EAASS;EAAOI;EAAQV;EAAQE;CAAO,CAC1C;CAQA,OANIL,KAAW,CAACkB,EAAanB,EAAO,UAAUoB,CAAW,IAChD,kBAACI,GAAD,EAAkB,OAAM,SAAU,CAAA,IAEvC,CAACvB,KAAW,CAACG,KAAU,CAACe,EAAanB,EAAO,UAAUoB,CAAW,IAC5D,kBAACI,GAAD,EAAkB,OAAM,QAAS,CAAA,IAEnC,kBAAC3B,EAAY,UAAb;EAA6B;EAAQ;CAA+B,CAAA;AAC7E;AAKA,SAAgB4B,IAA4B;CAC1C,IAAMC,IAAMC,EAAW9B,CAAW;CAClC,IAAI,CAAC6B,GAAK,MAAU,MAAM,4CAA4C;CACtE,OAAOA;AACT;AAEA,SAASF,EAAiB,EACxB,YAGe;CACf,OACE,kBAAC,QAAD;EAAM,WAAW9B,EAAO;EACtB,UAAA,kBAACkC,GAAD;GAAY,OAAM;GAAe,SAAQ;GACtC,UAAAC;EACS,CAAA;CACR,CAAA;AAEV;AAEA,SAASV,EACP,GACA,GACS;CACT,OAAOC,EAAY,MAAM,MAAMU,MAAMC,CAAQ;AAC/C;AAEA,SAASV,EAAgB,GAAiC;CAExD,OADI,OAAO,SAAW,MAAoBU,KAAY,MAC/C,GAAG,OAAO,SAAS,WAAW,OAAO,SAAS;AACvD"}
1
+ {"version":3,"file":"auth-provider-C2b-5mGt.js","names":["styles","useRouterAdapter","auth_provider_module_default","AuthContext","createContext","AuthProvider","router","loading","setLoading","useState","member","setMember","refresh","useCallback","current","readApiCurrentMember","login","next","loginApi","input","logout","logoutApi","loginPath","useEffect","active","isPublicPath","publicPaths","readCurrentPath","value","useMemo","AuthLoadingState","useAuth","ctx","useContext","Typography","label","p","pathname"],"sources":["../../src/lib/auth-provider.module.scss","../../src/lib/auth-provider.tsx"],"sourcesContent":[".authLoading {\n align-items: center;\n background: var(--mzn-color-bg-body);\n display: flex;\n min-height: 100vh;\n justify-content: center;\n padding: 32px;\n}\n","'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { Typography } from '@mezzanine-ui/react';\nimport {\n loginApi,\n logoutApi,\n readApiCurrentMember,\n type ApiMember,\n} from '@rytass/bpm-core-client';\nimport { useRouterAdapter } from './router-adapter';\nimport styles from './auth-provider.module.scss';\n\ninterface AuthContextValue {\n readonly loading: boolean;\n readonly member: ApiMember | null;\n readonly login: (input: {\n readonly identifier: string;\n readonly password: string;\n }) => Promise<ApiMember>;\n readonly logout: () => Promise<void>;\n readonly refresh: () => Promise<ApiMember | null>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport interface AuthProviderProps {\n readonly children: ReactNode;\n /**\n * Paths that should not redirect to `/login` when there is no session.\n * Defaults to `['/login']`. Override when your host runs the login UI\n * under a different path.\n */\n readonly publicPaths?: readonly string[];\n /**\n * Where to send unauthenticated users. Defaults to `'/login'`.\n */\n readonly loginPath?: string;\n}\n\n/**\n * BPM auth context provider. Reads / writes the host BPM API session via\n * `@rytass/bpm-core-client` (`loginApi` / `logoutApi` / `readApiCurrentMember`)\n * and uses the host-supplied {@link useRouterAdapter} to redirect\n * unauthenticated users.\n */\nexport function AuthProvider({\n children,\n publicPaths = ['/login'],\n loginPath = '/login',\n}: AuthProviderProps): ReactElement {\n const router = useRouterAdapter();\n const [loading, setLoading] = useState(true);\n const [member, setMember] = useState<ApiMember | null>(null);\n\n const refresh = useCallback(async (): Promise<ApiMember | null> => {\n const current = await readApiCurrentMember();\n setMember(current);\n return current;\n }, []);\n\n const login = useCallback(\n async (input: {\n readonly identifier: string;\n readonly password: string;\n }): Promise<ApiMember> => {\n const next = await loginApi(input);\n setMember(next);\n return next;\n },\n [],\n );\n\n const logout = useCallback(async (): Promise<void> => {\n await logoutApi();\n setMember(null);\n router.replace(loginPath);\n }, [loginPath, router]);\n\n useEffect((): (() => void) => {\n let active = true;\n setLoading(true);\n void (async () => {\n try {\n const current = await readApiCurrentMember();\n if (active) setMember(current);\n } catch {\n if (active) setMember(null);\n } finally {\n if (active) setLoading(false);\n }\n })();\n return (): void => {\n active = false;\n };\n }, []);\n\n useEffect((): void => {\n if (loading || isPublicPath(router.pathname, publicPaths) || member) return;\n router.replace(\n `${loginPath}?next=${encodeURIComponent(readCurrentPath(router.pathname))}`,\n );\n }, [loading, loginPath, member, publicPaths, router]);\n\n const value = useMemo<AuthContextValue>(\n () => ({ loading, login, logout, member, refresh }),\n [loading, login, logout, member, refresh],\n );\n\n if (loading && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"確認登入狀態\" />;\n }\n if (!loading && !member && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"前往登入頁\" />;\n }\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\n/**\n * Access the BPM auth context. Throws when used outside `<AuthProvider>`.\n */\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error('useAuth must be used inside <AuthProvider>');\n return ctx;\n}\n\nfunction AuthLoadingState({\n label,\n}: {\n readonly label: string;\n}): ReactElement {\n return (\n <main className={styles.authLoading}>\n <Typography color=\"text-neutral\" variant=\"body\">\n {label}\n </Typography>\n </main>\n );\n}\n\nfunction isPublicPath(\n pathname: string | null,\n publicPaths: readonly string[],\n): boolean {\n return publicPaths.some((p) => p === pathname);\n}\n\nfunction readCurrentPath(pathname: string | null): string {\n if (typeof window === 'undefined') return pathname ?? '/';\n return `${window.location.pathname}${window.location.search}`;\n}\n"],"mappings":";;;;;;A,kDCiCMG,IAAcC,EAAuC,IAAI;AAsB/D,SAAgBC,EAAa,EAC3B,aACA,iBAAc,CAAC,QAAQ,GACvB,eAAY,YACsB;CAClC,IAAMC,IAASL,EAAiB,GAC1B,CAACM,GAASC,KAAcC,EAAS,EAAI,GACrC,CAACC,GAAQC,KAAaF,EAA2B,IAAI,GAErDG,IAAUC,EAAY,YAAuC;EACjE,IAAMC,IAAU,MAAMC,EAAqB;EAE3C,OADAJ,EAAUG,CAAO,GACVA;CACT,GAAG,CAAC,CAAC,GAECE,IAAQH,EACZ,OAAO,MAGmB;EACxB,IAAMI,IAAO,MAAMC,EAASC,CAAK;EAEjC,OADAR,EAAUM,CAAI,GACPA;CACT,GACA,CAAC,CACH,GAEMG,IAASP,EAAY,YAA2B;EAGpD,AAFA,MAAMQ,EAAU,GAChBV,EAAU,IAAI,GACdL,EAAO,QAAQgB,CAAS;CAC1B,GAAG,CAACA,GAAWhB,CAAM,CAAC;CAoBtB,AAlBAiB,QAA8B;EAC5B,IAAIC,IAAS;EAYb,OAXAhB,EAAW,EAAI,IACT,YAAY;GAChB,IAAI;IACF,IAAMM,IAAU,MAAMC,EAAqB;IAC3C,AAAIS,KAAQb,EAAUG,CAAO;GAC/B,QAAQ;IACN,AAAIU,KAAQb,EAAU,IAAI;GAC5B,UAAU;IACR,AAAIa,KAAQhB,EAAW,EAAK;GAC9B;EACF,EAAA,CAAG,SACgB;GACjB,IAAS;EACX;CACF,GAAG,CAAC,CAAC,GAELe,QAAsB;EACpB,AAAIhB,KAAWkB,EAAanB,EAAO,UAAUoB,CAAW,KAAKhB,KAC7DJ,EAAO,QACL,GAAGgB,EAAU,QAAQ,mBAAmBK,EAAgBrB,EAAO,QAAQ,CAAC,GAC1E;CACF,GAAG;EAACC;EAASe;EAAWZ;EAAQgB;EAAapB;CAAM,CAAC;CAEpD,IAAMsB,IAAQC,SACL;EAAE;EAAS;EAAO;EAAQ;EAAQ;CAAQ,IACjD;EAACtB;EAASS;EAAOI;EAAQV;EAAQE;CAAO,CAC1C;CAQA,OANIL,KAAW,CAACkB,EAAanB,EAAO,UAAUoB,CAAW,IAChD,kBAACI,GAAD,EAAkB,OAAM,SAAU,CAAA,IAEvC,CAACvB,KAAW,CAACG,KAAU,CAACe,EAAanB,EAAO,UAAUoB,CAAW,IAC5D,kBAACI,GAAD,EAAkB,OAAM,QAAS,CAAA,IAEnC,kBAAC3B,EAAY,UAAb;EAA6B;EAAQ;CAA+B,CAAA;AAC7E;AAKA,SAAgB4B,IAA4B;CAC1C,IAAMC,IAAMC,EAAW9B,CAAW;CAClC,IAAI,CAAC6B,GAAK,MAAU,MAAM,4CAA4C;CACtE,OAAOA;AACT;AAEA,SAASF,EAAiB,EACxB,YAGe;CACf,OACE,kBAAC,QAAD;EAAM,WAAW9B,EAAO;EACtB,UAAA,kBAACkC,GAAD;GAAY,OAAM;GAAe,SAAQ;GACtC,UAAAC;EACS,CAAA;CACR,CAAA;AAEV;AAEA,SAASV,EACP,GACA,GACS;CACT,OAAOC,EAAY,MAAM,MAAMU,MAAMC,CAAQ;AAC/C;AAEA,SAASV,EAAgB,GAAiC;CAExD,OADI,OAAO,SAAW,MAAoBU,KAAY,MAC/C,GAAG,OAAO,SAAS,WAAW,OAAO,SAAS;AACvD"}
@@ -2,7 +2,7 @@
2
2
  import { FormField as e } from "@mezzanine-ui/react";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  import { FormFieldDensity as n, FormFieldLayout as r } from "@mezzanine-ui/core/form";
5
- //#region src/components/bpm-form-field.tsx
5
+ // src/components/bpm-form-field.tsx
6
6
  function i({ density: i = n.TIGHT, fullWidth: a = !0, layout: o = r.HORIZONTAL, ...s }) {
7
7
  return /* @__PURE__ */ t(e, {
8
8
  density: i,
@@ -11,7 +11,6 @@ function i({ density: i = n.TIGHT, fullWidth: a = !0, layout: o = r.HORIZONTAL,
11
11
  ...s
12
12
  });
13
13
  }
14
- //#endregion
15
14
  export { i as t };
16
15
 
17
- //# sourceMappingURL=bpm-form-field-Cao0rMol.js.map
16
+ //# sourceMappingURL=bpm-form-field-9B-Det0u.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bpm-form-field-Cao0rMol.js","names":["BPMFormField","FormFieldDensity","FormFieldLayout","props","FormField"],"sources":["../../src/components/bpm-form-field.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { FormField, type FormFieldProps } from '@mezzanine-ui/react';\nimport { FormFieldDensity, FormFieldLayout } from '@mezzanine-ui/core/form';\n\ntype BPMFormFieldProps = Omit<\n FormFieldProps,\n 'density' | 'fullWidth' | 'layout'\n> &\n Partial<Pick<FormFieldProps, 'density' | 'fullWidth' | 'layout'>>;\n\n/**\n * Mezzanine `<FormField>` pre-configured with the BPM admin defaults\n * (`TIGHT` density, `HORIZONTAL` layout, full width). Use everywhere a\n * label-aligned field is needed.\n */\nexport function BPMFormField({\n density = FormFieldDensity.TIGHT,\n fullWidth = true,\n layout = FormFieldLayout.HORIZONTAL,\n ...props\n}: BPMFormFieldProps): ReactElement {\n return (\n <FormField\n density={density}\n fullWidth={fullWidth}\n layout={layout}\n {...props}\n />\n );\n}\n"],"mappings":";;;;;AAiBA,SAAgBA,EAAa,EAC3B,aAAUC,EAAiB,OAC3B,eAAY,IACZ,YAASC,EAAgB,YACzB,GAAGC,KAC+B;CAClC,OACE,kBAACC,GAAD;EACW;EACE;EACH;EACR,GAAID;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"bpm-form-field-9B-Det0u.js","names":["BPMFormField","FormFieldDensity","FormFieldLayout","props","FormField"],"sources":["../../src/components/bpm-form-field.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { FormField, type FormFieldProps } from '@mezzanine-ui/react';\nimport { FormFieldDensity, FormFieldLayout } from '@mezzanine-ui/core/form';\n\ntype BPMFormFieldProps = Omit<\n FormFieldProps,\n 'density' | 'fullWidth' | 'layout'\n> &\n Partial<Pick<FormFieldProps, 'density' | 'fullWidth' | 'layout'>>;\n\n/**\n * Mezzanine `<FormField>` pre-configured with the BPM admin defaults\n * (`TIGHT` density, `HORIZONTAL` layout, full width). Use everywhere a\n * label-aligned field is needed.\n */\nexport function BPMFormField({\n density = FormFieldDensity.TIGHT,\n fullWidth = true,\n layout = FormFieldLayout.HORIZONTAL,\n ...props\n}: BPMFormFieldProps): ReactElement {\n return (\n <FormField\n density={density}\n fullWidth={fullWidth}\n layout={layout}\n {...props}\n />\n );\n}\n"],"mappings":";;;;;AAiBA,SAAgBA,EAAa,EAC3B,aAAUC,EAAiB,OAC3B,eAAY,IACZ,YAASC,EAAgB,YACzB,GAAGC,KAC+B;CAClC,OACE,kBAACC,GAAD;EACW;EACE;EACH;EACR,GAAID;CACL,CAAA;AAEL"}
@@ -1 +1 @@
1
- {"version":3,"file":"bpm-form-field-Bc6k4ZEO.cjs","names":["FormFieldDensity","FormFieldLayout","FormField","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_core_form","BPMFormField","props"],"sources":["../../src/components/bpm-form-field.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { FormField, type FormFieldProps } from '@mezzanine-ui/react';\nimport { FormFieldDensity, FormFieldLayout } from '@mezzanine-ui/core/form';\n\ntype BPMFormFieldProps = Omit<\n FormFieldProps,\n 'density' | 'fullWidth' | 'layout'\n> &\n Partial<Pick<FormFieldProps, 'density' | 'fullWidth' | 'layout'>>;\n\n/**\n * Mezzanine `<FormField>` pre-configured with the BPM admin defaults\n * (`TIGHT` density, `HORIZONTAL` layout, full width). Use everywhere a\n * label-aligned field is needed.\n */\nexport function BPMFormField({\n density = FormFieldDensity.TIGHT,\n fullWidth = true,\n layout = FormFieldLayout.HORIZONTAL,\n ...props\n}: BPMFormFieldProps): ReactElement {\n return (\n <FormField\n density={density}\n fullWidth={fullWidth}\n layout={layout}\n {...props}\n />\n );\n}\n"],"mappings":"sHAiBA,SAAgBM,EAAa,CAC3B,UAAUN,EAAAA,iBAAiB,MAC3B,YAAY,GACZ,SAASC,EAAAA,gBAAgB,WACzB,GAAGM,GAC+B,CAClC,OACE,EAAAH,EAAA,IAAA,CAACF,EAAAA,UAAD,CACW,UACE,YACH,SACR,GAAIK,CACL,CAAA,CAEL"}
1
+ {"version":3,"file":"bpm-form-field-Bc6k4ZEO.cjs","names":["FormFieldDensity","FormFieldLayout","FormField","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_core_form","BPMFormField","props"],"sources":["../../src/components/bpm-form-field.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { FormField, type FormFieldProps } from '@mezzanine-ui/react';\nimport { FormFieldDensity, FormFieldLayout } from '@mezzanine-ui/core/form';\n\ntype BPMFormFieldProps = Omit<\n FormFieldProps,\n 'density' | 'fullWidth' | 'layout'\n> &\n Partial<Pick<FormFieldProps, 'density' | 'fullWidth' | 'layout'>>;\n\n/**\n * Mezzanine `<FormField>` pre-configured with the BPM admin defaults\n * (`TIGHT` density, `HORIZONTAL` layout, full width). Use everywhere a\n * label-aligned field is needed.\n */\nexport function BPMFormField({\n density = FormFieldDensity.TIGHT,\n fullWidth = true,\n layout = FormFieldLayout.HORIZONTAL,\n ...props\n}: BPMFormFieldProps): ReactElement {\n return (\n <FormField\n density={density}\n fullWidth={fullWidth}\n layout={layout}\n {...props}\n />\n );\n}\n"],"mappings":"A,sHAiBA,SAAgBM,EAAa,CAC3B,UAAUN,EAAAA,iBAAiB,MAC3B,YAAY,GACZ,SAASC,EAAAA,gBAAgB,WACzB,GAAGM,GAC+B,CAClC,OACE,EAAAH,EAAA,IAAA,CAACF,EAAAA,UAAD,CACW,UACE,YACH,SACR,GAAIK,CACL,CAAA,CAEL,C"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { t as e } from "./format-date-time-CB-LxzqT.js";
3
- import { t } from "./bpm-form-field-Cao0rMol.js";
2
+ import { t as e } from "./bpm-form-field-9B-Det0u.js";
3
+ import { t } from "./format-date-time-B0LdmWg4.js";
4
4
  import { useCallback as n, useEffect as r, useMemo as i, useState as a } from "react";
5
5
  import { Badge as o, Button as s, Filter as c, FilterArea as l, FilterLine as u, FormField as d, Input as f, Modal as p, PageHeader as m, Section as h, SectionGroup as g, Tab as _, TabItem as v, Table as y, Textarea as b, Typography as x } from "@mezzanine-ui/react";
6
6
  import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
@@ -30,7 +30,7 @@ import '../categories.css';var A = {
30
30
  }
31
31
  ];
32
32
  function N() {
33
- let [t, o] = a([]), [b, N] = a(1), [F, I] = a(10), [L, R] = a("ALL"), [z, B] = a(0), [V, H] = a(null), [U, W] = a(null), [G, K] = a(!0), [q, J] = a(null), [Y, X] = a(!1), [Z, oe] = a(""), Q = n(async () => {
33
+ let [e, o] = a([]), [b, N] = a(1), [F, I] = a(10), [L, R] = a("ALL"), [z, B] = a(0), [V, H] = a(null), [U, W] = a(null), [G, K] = a(!0), [q, J] = a(null), [Y, X] = a(!1), [Z, oe] = a(""), Q = n(async () => {
34
34
  K(!0), W(null);
35
35
  try {
36
36
  let e = await O({
@@ -54,11 +54,11 @@ function N() {
54
54
  r(() => {
55
55
  Q();
56
56
  }, [Q]);
57
- let se = i(() => t.map((t) => ({
58
- ...t,
59
- key: t.id,
60
- updatedAtLabel: e(t.updatedAt)
61
- })), [t]), ce = i(() => [
57
+ let se = i(() => e.map((e) => ({
58
+ ...e,
59
+ key: e.id,
60
+ updatedAtLabel: t(e.updatedAt)
61
+ })), [e]), ce = i(() => [
62
62
  {
63
63
  dataIndex: "name",
64
64
  key: "name",
@@ -266,7 +266,7 @@ function N() {
266
266
  })
267
267
  ] });
268
268
  }
269
- function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
269
+ function ne({ loading: t, modal: n, onClose: i, onSubmit: o }) {
270
270
  let [s, c] = a(""), [l, u] = a(null), [d, m] = a(""), [h, g] = a("0");
271
271
  r(() => {
272
272
  n && (c(n.record?.description ?? ""), u(null), m(n.record?.name ?? ""), g(String(n.record?.sortOrder ?? 0)));
@@ -290,7 +290,7 @@ function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
290
290
  cancelText: "取消",
291
291
  confirmButtonProps: { disabled: !d.trim() },
292
292
  confirmText: n?.type === "EDIT" ? "儲存" : "建立",
293
- loading: e,
293
+ loading: t,
294
294
  modalType: "standard",
295
295
  onCancel: i,
296
296
  onClose: i,
@@ -303,7 +303,7 @@ function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
303
303
  children: [/* @__PURE__ */ w("div", {
304
304
  className: A.templateModalFields,
305
305
  children: [
306
- /* @__PURE__ */ C(t, {
306
+ /* @__PURE__ */ C(e, {
307
307
  label: "分類名稱",
308
308
  name: "categoryName",
309
309
  required: !0,
@@ -318,7 +318,7 @@ function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
318
318
  variant: "base"
319
319
  })
320
320
  }),
321
- /* @__PURE__ */ C(t, {
321
+ /* @__PURE__ */ C(e, {
322
322
  label: "排序",
323
323
  name: "categorySortOrder",
324
324
  children: /* @__PURE__ */ C(f, {
@@ -331,7 +331,7 @@ function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
331
331
  variant: "base"
332
332
  })
333
333
  }),
334
- /* @__PURE__ */ C(t, {
334
+ /* @__PURE__ */ C(e, {
335
335
  label: "說明",
336
336
  name: "categoryDescription",
337
337
  children: /* @__PURE__ */ C(b, {
@@ -370,7 +370,6 @@ function ae(e) {
370
370
  function P(e) {
371
371
  return e instanceof Error ? e.message : "發生未知錯誤";
372
372
  }
373
- //#endregion
374
373
  export { A as n, N as t };
375
374
 
376
- //# sourceMappingURL=categories-riC33J_j.js.map
375
+ //# sourceMappingURL=categories-BAdxjNSA.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"categories-riC33J_j.js","names":["_Fragment","styles","formatDateTime","Fragment$1","ContentHeader","templates_module_default","CATEGORY_PAGE_SIZE_OPTIONS","CATEGORY_STATUS_TABS","TemplateCategoriesView","categories","setCategories","useState","categoryPage","setCategoryPage","categoryPageSize","setCategoryPageSize","categoryStatus","setCategoryStatus","categoryTotalCount","setCategoryTotalCount","deleteConfirmation","setDeleteConfirmation","error","setError","loading","setLoading","modalState","setModalState","saving","setSaving","searchText","setSearchText","refreshCategories","useCallback","categoryPageResult","listApprovalTemplateCategoriesPage","readCategoryStatus","requestError","readErrorMessage","rows","useMemo","category","columns","CategoryStatusBadge","record","Typography","handleSaveCategory","updateApprovalTemplateCategory","input","createApprovalTemplateCategory","handleToggleCategory","handleConfirmDelete","deleteApprovalTemplateCategory","tableActions","PageHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","FilterLine","Filter","FormField","FormFieldLayout","Input","event","Tab","readCategoryStatusTabKey","activeKey","TabItem","statusTab","Table","page","pageSize","from","to","total","CategoryModal","Modal","description","setDescription","name","setName","sortOrder","setSortOrder","modal","handleConfirm","trimmedName","parsedSortOrder","onSubmit","submitError","onClose","BPMFormField","Textarea","isActive","Badge","status"],"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 {\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\n\nexport function TemplateCategoriesView(): 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 <>\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 </>\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
+ {"version":3,"file":"categories-BAdxjNSA.js","names":["_Fragment","styles","BPMFormField","Fragment$1","ContentHeader","templates_module_default","CATEGORY_PAGE_SIZE_OPTIONS","CATEGORY_STATUS_TABS","TemplateCategoriesView","categories","setCategories","useState","categoryPage","setCategoryPage","categoryPageSize","setCategoryPageSize","categoryStatus","setCategoryStatus","categoryTotalCount","setCategoryTotalCount","deleteConfirmation","setDeleteConfirmation","error","setError","loading","setLoading","modalState","setModalState","saving","setSaving","searchText","setSearchText","refreshCategories","useCallback","categoryPageResult","listApprovalTemplateCategoriesPage","readCategoryStatus","requestError","readErrorMessage","rows","useMemo","category","formatDateTime","columns","CategoryStatusBadge","record","Typography","handleSaveCategory","updateApprovalTemplateCategory","input","createApprovalTemplateCategory","handleToggleCategory","handleConfirmDelete","deleteApprovalTemplateCategory","tableActions","PageHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","FilterLine","Filter","FormField","FormFieldLayout","Input","event","Tab","readCategoryStatusTabKey","activeKey","TabItem","statusTab","Table","page","pageSize","from","to","total","CategoryModal","Modal","description","setDescription","name","setName","sortOrder","setSortOrder","modal","handleConfirm","trimmedName","parsedSortOrder","onSubmit","submitError","onClose","Textarea","isActive","Badge","status"],"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 {\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\n\nexport function TemplateCategoriesView(): 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 <>\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 </>\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('../categories.css');const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./format-date-time-D-cx5M8z.cjs"),n=require("./bpm-form-field-Bc6k4ZEO.cjs");let r=require("react"),i=require("@mezzanine-ui/react"),a=require("react/jsx-runtime"),o=require("@mezzanine-ui/core/form"),s=require("@mezzanine-ui/react/ContentHeader");s=e.t(s,1);let c=require("@mezzanine-ui/icons"),l=require("@rytass/bpm-core-client/template");var u={templateFilterArea:`bpm_templateFilterArea_nUL-R`,templateModalFields:`bpm_templateModalFields_hUxWp`},d=[10,20,50],f=[{key:`ALL`,label:`全部`},{key:`ACTIVE`,label:`啟用`},{key:`INACTIVE`,label:`停用`}];function p(){let[e,n]=(0,r.useState)([]),[p,y]=(0,r.useState)(1),[b,x]=(0,r.useState)(10),[S,C]=(0,r.useState)(`ALL`),[w,T]=(0,r.useState)(0),[E,D]=(0,r.useState)(null),[O,k]=(0,r.useState)(null),[A,j]=(0,r.useState)(!0),[M,N]=(0,r.useState)(null),[P,F]=(0,r.useState)(!1),[I,L]=(0,r.useState)(``),R=(0,r.useCallback)(async()=>{j(!0),k(null);try{let e=await(0,l.listApprovalTemplateCategoriesPage)({page:p,pageSize:b,searchText:I,status:_(S)});n(e.categories),T(e.totalCount)}catch(e){k(v(e))}finally{j(!1)}},[p,b,S,I]);(0,r.useEffect)(()=>{R()},[R]);let z=(0,r.useMemo)(()=>e.map(e=>({...e,key:e.id,updatedAtLabel:t.t(e.updatedAt)})),[e]),B=(0,r.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`分類名稱`,width:180},{key:`status`,render:e=>(0,a.jsx)(h,{isActive:e.isActive}),title:`狀態`,width:120},{dataIndex:`sortOrder`,key:`sortOrder`,title:`排序`,width:100},{key:`description`,render:e=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.description||`無`}),title:`說明`,width:260},{dataIndex:`updatedAtLabel`,key:`updatedAtLabel`,title:`更新時間`,width:220}],[]);async function V(e){F(!0),k(null);try{M?.type===`EDIT`&&M.record?await(0,l.updateApprovalTemplateCategory)({...e,id:M.record.id}):await(0,l.createApprovalTemplateCategory)(e),N(null),await R()}catch(e){throw k(v(e)),e}finally{F(!1)}}async function H(e){F(!0),k(null);try{await(0,l.updateApprovalTemplateCategory)({description:e.description,id:e.id,isActive:!e.isActive,name:e.name,sortOrder:e.sortOrder}),await R()}catch(e){k(v(e))}finally{F(!1)}}async function U(){if(E){F(!0),k(null);try{await(0,l.deleteApprovalTemplateCategory)(E.id),D(null),await R()}catch(e){k(v(e))}finally{F(!1)}}}let W=(0,r.useMemo)(()=>({render:e=>[{name:`編輯`,onClick:()=>N({record:e,type:`EDIT`})},{name:e.isActive?`停用`:`啟用`,onClick:()=>void H(e),variant:e.isActive?`destructive-secondary`:`base-secondary`},{name:`刪除`,onClick:()=>D({id:e.id,name:e.name}),variant:`destructive-secondary`}],variant:`base-secondary`,width:192}),[R]);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.PageHeader,{children:(0,a.jsx)(s.default,{description:`維護簽核模板分類,供模板建立、篩選與列表標示使用。`,title:`簽核模板分類`,children:(0,a.jsx)(i.Button,{icon:c.PlusIcon,iconType:`leading`,onClick:()=>N({record:null,type:`CREATE`}),variant:`base-primary`,children:`建立分類`})})}),(0,a.jsx)(i.SectionGroup,{children:(0,a.jsxs)(i.Section,{filterArea:(0,a.jsx)(i.FilterArea,{className:u.templateFilterArea,size:`sub`,children:(0,a.jsx)(i.FilterLine,{children:(0,a.jsx)(i.Filter,{span:3,children:(0,a.jsx)(i.FormField,{fullWidth:!0,layout:o.FormFieldLayout.VERTICAL,name:`categorySearchText`,children:(0,a.jsx)(i.Input,{fullWidth:!0,onChange:e=>{L(e.target.value),y(1)},placeholder:`關鍵字:搜尋分類名稱或說明`,size:`sub`,value:I,variant:`base`})})})})}),tab:(0,a.jsx)(i.Tab,{activeKey:S,onChange:e=>{C(g(e)),y(1)},children:f.map(e=>(0,a.jsx)(i.TabItem,{children:e.label},e.key))}),children:[O?(0,a.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:O}):null,(0,a.jsx)(i.Table,{actions:W,columns:B,dataSource:z,fullWidth:!0,loading:A||P,pagination:{current:p,onChange:e=>{y(e)},onChangePageSize:e=>{y(1),x(e)},pageSize:b,pageSizeLabel:`每頁筆數`,pageSizeOptions:d,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:w}})]})})]}),(0,a.jsx)(m,{loading:P,modal:M,onClose:()=>N(null),onSubmit:V}),(0,a.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{variant:`destructive-primary`},confirmText:`刪除`,loading:P,modalStatusType:`error`,modalType:`standard`,onCancel:()=>D(null),onClose:()=>D(null),onConfirm:()=>void U(),open:!!E,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`已被模板使用的分類無法刪除,請改用「停用」。`,title:`刪除分類`,children:(0,a.jsxs)(i.Typography,{color:`text-neutral`,variant:`body`,children:[`確定要刪除「`,E?.name??``,`」嗎?`]})})]})}function m({loading:e,modal:t,onClose:o,onSubmit:s}){let[c,l]=(0,r.useState)(``),[d,f]=(0,r.useState)(null),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)(`0`);(0,r.useEffect)(()=>{t&&(l(t.record?.description??``),f(null),m(t.record?.name??``),g(String(t.record?.sortOrder??0)))},[t]);async function _(){let e=p.trim(),n=Number(h);if(!e)f(`請輸入分類名稱`);else if(!Number.isInteger(n))f(`排序必須是整數`);else try{await s({description:c.trim()||null,isActive:t?.record?.isActive??!0,name:e,sortOrder:n})}catch(e){f(v(e))}}return(0,a.jsxs)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!p.trim()},confirmText:t?.type===`EDIT`?`儲存`:`建立`,loading:e,modalType:`standard`,onCancel:o,onClose:o,onConfirm:()=>void _(),open:!!t,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:t?.type===`EDIT`?`編輯分類`:`建立分類`,children:[(0,a.jsxs)(`div`,{className:u.templateModalFields,children:[(0,a.jsx)(n.t,{label:`分類名稱`,name:`categoryName`,required:!0,children:(0,a.jsx)(i.Input,{autoFocus:!0,fullWidth:!0,onChange:e=>{m(e.target.value),f(null)},placeholder:`例如:行政管理`,value:p,variant:`base`})}),(0,a.jsx)(n.t,{label:`排序`,name:`categorySortOrder`,children:(0,a.jsx)(i.Input,{fullWidth:!0,onChange:e=>{g(e.target.value),f(null)},placeholder:`0`,value:h,variant:`base`})}),(0,a.jsx)(n.t,{label:`說明`,name:`categoryDescription`,children:(0,a.jsx)(i.Textarea,{onChange:e=>{l(e.target.value),f(null)},placeholder:`補充分類用途`,value:c})})]}),d?(0,a.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:d}):null]})}function h({isActive:e}){return e?(0,a.jsx)(i.Badge,{size:`sub`,text:`啟用`,variant:`dot-success`}):(0,a.jsx)(i.Badge,{size:`sub`,text:`停用`,variant:`dot-inactive`})}function g(e){return e===`ACTIVE`||e===`INACTIVE`?e:`ALL`}function _(e){return e}function v(e){return e instanceof Error?e.message:`發生未知錯誤`}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return p}});
2
- //# sourceMappingURL=categories-AxxhqjLZ.cjs.map
1
+ "use client";require('../categories.css');const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./bpm-form-field-Bc6k4ZEO.cjs"),n=require("./format-date-time-D-cx5M8z.cjs");let r=require("react"),i=require("@mezzanine-ui/react"),a=require("react/jsx-runtime"),o=require("@mezzanine-ui/core/form"),s=require("@mezzanine-ui/react/ContentHeader");s=e.t(s,1);let c=require("@mezzanine-ui/icons"),l=require("@rytass/bpm-core-client/template");var u={templateFilterArea:`bpm_templateFilterArea_nUL-R`,templateModalFields:`bpm_templateModalFields_hUxWp`},d=[10,20,50],f=[{key:`ALL`,label:`全部`},{key:`ACTIVE`,label:`啟用`},{key:`INACTIVE`,label:`停用`}];function p(){let[e,t]=(0,r.useState)([]),[p,y]=(0,r.useState)(1),[b,x]=(0,r.useState)(10),[S,C]=(0,r.useState)(`ALL`),[w,T]=(0,r.useState)(0),[E,D]=(0,r.useState)(null),[O,k]=(0,r.useState)(null),[A,j]=(0,r.useState)(!0),[M,N]=(0,r.useState)(null),[P,F]=(0,r.useState)(!1),[I,L]=(0,r.useState)(``),R=(0,r.useCallback)(async()=>{j(!0),k(null);try{let e=await(0,l.listApprovalTemplateCategoriesPage)({page:p,pageSize:b,searchText:I,status:_(S)});t(e.categories),T(e.totalCount)}catch(e){k(v(e))}finally{j(!1)}},[p,b,S,I]);(0,r.useEffect)(()=>{R()},[R]);let z=(0,r.useMemo)(()=>e.map(e=>({...e,key:e.id,updatedAtLabel:n.t(e.updatedAt)})),[e]),B=(0,r.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`分類名稱`,width:180},{key:`status`,render:e=>(0,a.jsx)(h,{isActive:e.isActive}),title:`狀態`,width:120},{dataIndex:`sortOrder`,key:`sortOrder`,title:`排序`,width:100},{key:`description`,render:e=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.description||`無`}),title:`說明`,width:260},{dataIndex:`updatedAtLabel`,key:`updatedAtLabel`,title:`更新時間`,width:220}],[]);async function V(e){F(!0),k(null);try{M?.type===`EDIT`&&M.record?await(0,l.updateApprovalTemplateCategory)({...e,id:M.record.id}):await(0,l.createApprovalTemplateCategory)(e),N(null),await R()}catch(e){throw k(v(e)),e}finally{F(!1)}}async function H(e){F(!0),k(null);try{await(0,l.updateApprovalTemplateCategory)({description:e.description,id:e.id,isActive:!e.isActive,name:e.name,sortOrder:e.sortOrder}),await R()}catch(e){k(v(e))}finally{F(!1)}}async function U(){if(E){F(!0),k(null);try{await(0,l.deleteApprovalTemplateCategory)(E.id),D(null),await R()}catch(e){k(v(e))}finally{F(!1)}}}let W=(0,r.useMemo)(()=>({render:e=>[{name:`編輯`,onClick:()=>N({record:e,type:`EDIT`})},{name:e.isActive?`停用`:`啟用`,onClick:()=>void H(e),variant:e.isActive?`destructive-secondary`:`base-secondary`},{name:`刪除`,onClick:()=>D({id:e.id,name:e.name}),variant:`destructive-secondary`}],variant:`base-secondary`,width:192}),[R]);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.PageHeader,{children:(0,a.jsx)(s.default,{description:`維護簽核模板分類,供模板建立、篩選與列表標示使用。`,title:`簽核模板分類`,children:(0,a.jsx)(i.Button,{icon:c.PlusIcon,iconType:`leading`,onClick:()=>N({record:null,type:`CREATE`}),variant:`base-primary`,children:`建立分類`})})}),(0,a.jsx)(i.SectionGroup,{children:(0,a.jsxs)(i.Section,{filterArea:(0,a.jsx)(i.FilterArea,{className:u.templateFilterArea,size:`sub`,children:(0,a.jsx)(i.FilterLine,{children:(0,a.jsx)(i.Filter,{span:3,children:(0,a.jsx)(i.FormField,{fullWidth:!0,layout:o.FormFieldLayout.VERTICAL,name:`categorySearchText`,children:(0,a.jsx)(i.Input,{fullWidth:!0,onChange:e=>{L(e.target.value),y(1)},placeholder:`關鍵字:搜尋分類名稱或說明`,size:`sub`,value:I,variant:`base`})})})})}),tab:(0,a.jsx)(i.Tab,{activeKey:S,onChange:e=>{C(g(e)),y(1)},children:f.map(e=>(0,a.jsx)(i.TabItem,{children:e.label},e.key))}),children:[O?(0,a.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:O}):null,(0,a.jsx)(i.Table,{actions:W,columns:B,dataSource:z,fullWidth:!0,loading:A||P,pagination:{current:p,onChange:e=>{y(e)},onChangePageSize:e=>{y(1),x(e)},pageSize:b,pageSizeLabel:`每頁筆數`,pageSizeOptions:d,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:w}})]})})]}),(0,a.jsx)(m,{loading:P,modal:M,onClose:()=>N(null),onSubmit:V}),(0,a.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{variant:`destructive-primary`},confirmText:`刪除`,loading:P,modalStatusType:`error`,modalType:`standard`,onCancel:()=>D(null),onClose:()=>D(null),onConfirm:()=>void U(),open:!!E,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`已被模板使用的分類無法刪除,請改用「停用」。`,title:`刪除分類`,children:(0,a.jsxs)(i.Typography,{color:`text-neutral`,variant:`body`,children:[`確定要刪除「`,E?.name??``,`」嗎?`]})})]})}function m({loading:e,modal:n,onClose:o,onSubmit:s}){let[c,l]=(0,r.useState)(``),[d,f]=(0,r.useState)(null),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)(`0`);(0,r.useEffect)(()=>{n&&(l(n.record?.description??``),f(null),m(n.record?.name??``),g(String(n.record?.sortOrder??0)))},[n]);async function _(){let e=p.trim(),t=Number(h);if(!e)f(`請輸入分類名稱`);else if(!Number.isInteger(t))f(`排序必須是整數`);else try{await s({description:c.trim()||null,isActive:n?.record?.isActive??!0,name:e,sortOrder:t})}catch(e){f(v(e))}}return(0,a.jsxs)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!p.trim()},confirmText:n?.type===`EDIT`?`儲存`:`建立`,loading:e,modalType:`standard`,onCancel:o,onClose:o,onConfirm:()=>void _(),open:!!n,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:n?.type===`EDIT`?`編輯分類`:`建立分類`,children:[(0,a.jsxs)(`div`,{className:u.templateModalFields,children:[(0,a.jsx)(t.t,{label:`分類名稱`,name:`categoryName`,required:!0,children:(0,a.jsx)(i.Input,{autoFocus:!0,fullWidth:!0,onChange:e=>{m(e.target.value),f(null)},placeholder:`例如:行政管理`,value:p,variant:`base`})}),(0,a.jsx)(t.t,{label:`排序`,name:`categorySortOrder`,children:(0,a.jsx)(i.Input,{fullWidth:!0,onChange:e=>{g(e.target.value),f(null)},placeholder:`0`,value:h,variant:`base`})}),(0,a.jsx)(t.t,{label:`說明`,name:`categoryDescription`,children:(0,a.jsx)(i.Textarea,{onChange:e=>{l(e.target.value),f(null)},placeholder:`補充分類用途`,value:c})})]}),d?(0,a.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:d}):null]})}function h({isActive:e}){return e?(0,a.jsx)(i.Badge,{size:`sub`,text:`啟用`,variant:`dot-success`}):(0,a.jsx)(i.Badge,{size:`sub`,text:`停用`,variant:`dot-inactive`})}function g(e){return e===`ACTIVE`||e===`INACTIVE`?e:`ALL`}function _(e){return e}function v(e){return e instanceof Error?e.message:`發生未知錯誤`}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return p}});
2
+ //# sourceMappingURL=categories-DQUtVEiV.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"categories-AxxhqjLZ.cjs","names":["useState","useCallback","listApprovalTemplateCategoriesPage","useMemo","formatDateTime","Typography","updateApprovalTemplateCategory","createApprovalTemplateCategory","deleteApprovalTemplateCategory","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","styles","FilterLine","Filter","FormField","FormFieldLayout","Input","Tab","TabItem","Table","Modal","BPMFormField","Textarea","Badge","require_rolldown_runtime","require_format_date_time","require_bpm_form_field","react","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_core_form","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","_rytass_bpm_core_client_template","templates_module_default","CATEGORY_PAGE_SIZE_OPTIONS","CATEGORY_STATUS_TABS","TemplateCategoriesView","categories","setCategories","categoryPage","setCategoryPage","categoryPageSize","setCategoryPageSize","categoryStatus","setCategoryStatus","categoryTotalCount","setCategoryTotalCount","deleteConfirmation","setDeleteConfirmation","error","setError","loading","setLoading","modalState","setModalState","saving","setSaving","searchText","setSearchText","refreshCategories","categoryPageResult","readCategoryStatus","requestError","readErrorMessage","rows","category","columns","CategoryStatusBadge","record","handleSaveCategory","input","handleToggleCategory","handleConfirmDelete","tableActions","event","readCategoryStatusTabKey","activeKey","statusTab","page","pageSize","from","to","total","CategoryModal","description","setDescription","name","setName","sortOrder","setSortOrder","modal","handleConfirm","trimmedName","parsedSortOrder","onSubmit","submitError","onClose","isActive","status"],"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 {\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\n\nexport function TemplateCategoriesView(): 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 <>\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 </>\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":"+gBCsCMyC,EAA6B,CAAC,GAAI,GAAI,EAAE,EACxCC,EAGA,CACJ,CAAE,IAAK,MAAO,MAAO,IAAK,EAC1B,CAAE,IAAK,SAAU,MAAO,IAAK,EAC7B,CAAE,IAAK,WAAY,MAAO,IAAK,CACjC,EAsBA,SAAgBC,GAAuC,CACrD,GAAM,CAACC,EAAYC,IAAA,EAAiB7C,EAAAA,SAAAA,CAElC,CAAC,CAAC,EACE,CAAC8C,EAAcC,IAAA,EAAmB/C,EAAAA,SAAAA,CAAS,CAAC,EAC5C,CAACgD,EAAkBC,IAAA,EAAuBjD,EAAAA,SAAAA,CAAS,EAAE,EACrD,CAACkD,EAAgBC,IAAA,EACrBnD,EAAAA,SAAAA,CAA+B,KAAK,EAChC,CAACoD,EAAoBC,IAAA,EAAyBrD,EAAAA,SAAAA,CAAS,CAAC,EACxD,CAACsD,EAAoBC,IAAA,EACzBvD,EAAAA,SAAAA,CAAyC,IAAI,EACzC,CAACwD,EAAOC,IAAA,EAAYzD,EAAAA,SAAAA,CAAwB,IAAI,EAChD,CAAC0D,EAASC,IAAA,EAAc3D,EAAAA,SAAAA,CAAS,EAAI,EACrC,CAAC4D,EAAYC,IAAA,EAAiB7D,EAAAA,SAAAA,CAAoC,IAAI,EACtE,CAAC8D,EAAQC,IAAA,EAAa/D,EAAAA,SAAAA,CAAS,EAAK,EACpC,CAACgE,EAAYC,IAAA,EAAiBjE,EAAAA,SAAAA,CAAS,EAAE,EAEzCkE,GAAA,EAAoBjE,EAAAA,YAAAA,CAAY,SAA2B,CAC/D0D,EAAW,EAAI,EACfF,EAAS,IAAI,EAEb,GAAI,CACF,IAAMU,EAAqB,MAAA,EAAMjE,EAAAA,mCAAAA,CAAmC,CAClE,KAAM4C,EACN,SAAUE,EACV,aACA,OAAQoB,EAAmBlB,CAAc,CAC3C,CAAC,EAEDL,EAAcsB,EAAmB,UAAU,EAC3Cd,EAAsBc,EAAmB,UAAU,CACrD,OAASE,EAAuB,CAC9BZ,EAASa,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRV,EAAW,EAAK,CAClB,CACF,EAAG,CAACb,EAAcE,EAAkBE,EAAgBc,CAAU,CAAC,GAE/D,EAAA/B,EAAA,UAAA,KAAsB,CACpBiC,EAAuB,CACzB,EAAG,CAACA,CAAiB,CAAC,EAEtB,IAAMK,GAAA,EAAOpE,EAAAA,QAAAA,KAETyC,EAAW,IAAK,IAAc,CAC5B,GAAG4B,EACH,IAAKA,EAAS,GACd,eAAgBpE,EAAAA,EAAeoE,EAAS,SAAS,CACnD,EAAE,EACJ,CAAC5B,CAAU,CACb,EAEM6B,GAAA,EAAUtE,EAAAA,QAAAA,KACoB,CAChC,CAAE,UAAW,OAAQ,IAAK,OAAQ,MAAO,OAAQ,MAAO,GAAI,EAC5D,CACE,IAAK,SACL,OAAS,IACP,EAAAgC,EAAA,IAAA,CAACuC,EAAD,CAAqB,SAAUC,EAAO,QAAW,CAAA,EAEnD,MAAO,KACP,MAAO,GACT,EACA,CACE,UAAW,YACX,IAAK,YACL,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,cACL,OAAS,IACP,EAAAxC,EAAA,IAAA,CAAC9B,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAAsE,EAAO,aAAe,GACb,CAAA,EAEd,MAAO,KACP,MAAO,GACT,EACA,CACE,UAAW,iBACX,IAAK,iBACL,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EAEA,eAAeC,EAAmB,EAAyC,CACzEb,EAAU,EAAI,EACdN,EAAS,IAAI,EAEb,GAAI,CACEG,GAAY,OAAS,QAAUA,EAAW,OAC5C,MAAA,EAAMtD,EAAAA,+BAAAA,CAA+B,CACnC,GAAGuE,EACH,GAAIjB,EAAW,OAAO,EACxB,CAAC,EAED,MAAA,EAAMrD,EAAAA,+BAAAA,CAA+BsE,CAAK,EAG5ChB,EAAc,IAAI,EAClB,MAAMK,EAAkB,CAC1B,OAASG,EAAuB,CAE9B,MADAZ,EAASa,EAAiBD,CAAY,CAAC,EACjCA,CACR,QAAU,CACRN,EAAU,EAAK,CACjB,CACF,CAEA,eAAee,EACb,EACe,CACff,EAAU,EAAI,EACdN,EAAS,IAAI,EAEb,GAAI,CACF,MAAA,EAAMnD,EAAAA,+BAAAA,CAA+B,CACnC,YAAaqE,EAAO,YACpB,GAAIA,EAAO,GACX,SAAU,CAACA,EAAO,SAClB,KAAMA,EAAO,KACb,UAAWA,EAAO,SACpB,CAAC,EACD,MAAMT,EAAkB,CAC1B,OAASG,EAAuB,CAC9BZ,EAASa,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRN,EAAU,EAAK,CACjB,CACF,CAEA,eAAegB,GAAqC,CAClD,GAAKzB,EAIL,GAAU,EAAI,EACdG,EAAS,IAAI,EAEb,GAAI,CACF,MAAA,EAAMjD,EAAAA,+BAAAA,CAA+B8C,EAAmB,EAAE,EAC1DC,EAAsB,IAAI,EAC1B,MAAMW,EAAkB,CAC1B,OAASG,EAAuB,CAC9BZ,EAASa,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRN,EAAU,EAAK,CACjB,CAXc,CAYhB,CAEA,IAAMiB,GAAA,EAAe7E,EAAAA,QAAAA,MACe,CAChC,OAAS,GAA4D,CACnE,CACE,KAAM,KACN,YAAqB0D,EAAc,CAAE,SAAQ,KAAM,MAAO,CAAC,CAC7D,EACA,CACE,KAAMc,EAAO,SAAW,KAAO,KAC/B,YAAqB,KAAKG,EAAqBH,CAAM,EACrD,QAASA,EAAO,SAAW,wBAA0B,gBACvD,EACA,CACE,KAAM,KACN,YACEpB,EAAsB,CAAE,GAAIoB,EAAO,GAAI,KAAMA,EAAO,IAAK,CAAC,EAC5D,QAAS,uBACX,CACF,EACA,QAAS,iBACT,MAAO,GACT,GACA,CAACT,CAAiB,CACpB,EAEA,OACE,EAAA/B,EAAA,KAAA,CAAA1B,EAAAA,SAAA,CAAA,SAAA,EACE,EAAA0B,EAAA,KAAA,CAAA1B,EAAAA,SAAA,CAAA,SAAA,EACI,EAAA0B,EAAA,IAAA,CAACzB,EAAAA,WAAD,CAAA,UACE,EAAAyB,EAAA,IAAA,CAACxB,EAAAA,QAAD,CACE,YAAY,4BACZ,MAAM,SAEN,UAAA,EAAAwB,EAAA,IAAA,CAACvB,EAAAA,OAAD,CACE,KAAMC,EAAAA,SACN,SAAS,UACT,YACEgD,EAAc,CAAE,OAAQ,KAAM,KAAM,QAAS,CAAC,EAEhD,QAAQ,eACT,SAAA,MAEO,CAAA,CACK,CAAA,CACL,CAAA,GAEZ,EAAA1B,EAAA,IAAA,CAACrB,EAAAA,aAAD,CAAA,UACE,EAAAqB,EAAA,KAAA,CAACpB,EAAAA,QAAD,CACE,YACE,EAAAoB,EAAA,IAAA,CAACnB,EAAAA,WAAD,CAAY,UAAWC,EAAO,mBAAoB,KAAK,MACrD,UAAA,EAAAkB,EAAA,IAAA,CAACjB,EAAAA,WAAD,CAAA,UACE,EAAAiB,EAAA,IAAA,CAAChB,EAAAA,OAAD,CAAQ,KAAM,EACZ,UAAA,EAAAgB,EAAA,IAAA,CAACf,EAAAA,UAAD,CACE,UAAA,GACA,OAAQC,EAAAA,gBAAgB,SACxB,KAAK,qBAEL,UAAA,EAAAc,EAAA,IAAA,CAACb,EAAAA,MAAD,CACE,UAAA,GACA,SACE,GACS,CACT2C,EAAcgB,EAAM,OAAO,KAAK,EAChClC,EAAgB,CAAC,CACnB,EACA,YAAY,gBACZ,KAAK,MACL,MAAOiB,EACP,QAAQ,MACT,CAAA,CACQ,CAAA,CACL,CAAA,CACE,CAAA,CACF,CAAA,EAEd,KACE,EAAA7B,EAAA,IAAA,CAACZ,EAAAA,IAAD,CACE,UAAW2B,EACX,SAAW,GAAoB,CAC7BC,EAAkB+B,EAAyBC,CAAS,CAAC,EACrDpC,EAAgB,CAAC,CACnB,EAEC,SAAAL,EAAqB,IAAK,IACzB,EAAAP,EAAA,IAAA,CAACX,EAAAA,QAAD,CAAA,SAA8B4D,EAAU,KAAe,EAAzCA,EAAU,GAA+B,CACxD,CACE,CAAA,EAvCT,SAAA,CA0CG5B,GACC,EAAArB,EAAA,IAAA,CAAC9B,EAAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,OACpC,SAAAmD,CACS,CAAA,EACV,MACJ,EAAArB,EAAA,IAAA,CAACV,EAAAA,MAAD,CACE,QAASuD,EACA,UACT,WAAYT,EACZ,UAAA,GACA,QAASb,GAAWI,EACpB,WAAY,CACV,QAAShB,EACT,SAAW,GAAe,CACxBC,EAAgBsC,CAAI,CACtB,EACA,iBAAmB,GAAmB,CACpCtC,EAAgB,CAAC,EACjBE,EAAoBqC,CAAQ,CAC9B,EACA,SAAUtC,EACV,cAAe,OACf,gBAAiBP,EACjB,qBAAsB,EAAM,EAAI,IAC9B,MAAM8C,EAAK,GAAGC,EAAG,OAAOC,EAAM,IAChC,oBAAqB,GACrB,MAAOrC,CACT,CACD,CAAA,CACM,CACG,CAAA,CAAA,CAAA,CACd,CAAA,CAAA,GAEJ,EAAAjB,EAAA,IAAA,CAACuD,EAAD,CACE,QAAS5B,EACT,MAAOF,EACP,YAAqBC,EAAc,IAAI,EACvC,SAAUe,CACX,CAAA,GACD,EAAAzC,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,WAAW,KACX,mBAAoB,CAAE,QAAS,qBAAsB,EACrD,YAAY,KACZ,QAASoC,EACT,gBAAgB,QAChB,UAAU,WACV,aAAsBP,EAAsB,IAAI,EAChD,YAAqBA,EAAsB,IAAI,EAC/C,cAAuB,KAAKwB,EAAoB,EAChD,KAAM,EAAQzB,EACd,gBAAA,GACA,gBAAA,GACA,KAAK,UACL,eAAe,yBACf,MAAM,OAEN,UAAA,EAAAnB,EAAA,KAAA,CAAC9B,EAAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,OAAzC,SAAA,CAAgD,SACvCiD,GAAoB,MAAQ,GAAG,KAC5B,GACP,CAAA,CACP,CAAA,CAAA,CAEN,CASA,SAASoC,EAAc,CACrB,UACA,QACA,UACA,YAMe,CACf,GAAM,CAACC,EAAaC,IAAA,EAAkB5F,EAAAA,SAAAA,CAAS,EAAE,EAC3C,CAACwD,EAAOC,IAAA,EAAYzD,EAAAA,SAAAA,CAAwB,IAAI,EAChD,CAAC6F,EAAMC,IAAA,EAAW9F,EAAAA,SAAAA,CAAS,EAAE,EAC7B,CAAC+F,EAAWC,IAAA,EAAgBhG,EAAAA,SAAAA,CAAS,GAAG,GAE9C,EAAAiC,EAAA,UAAA,KAAsB,CACfgE,IAILL,EAAeK,EAAM,QAAQ,aAAe,EAAE,EAC9CxC,EAAS,IAAI,EACbqC,EAAQG,EAAM,QAAQ,MAAQ,EAAE,EAChCD,EAAa,OAAOC,EAAM,QAAQ,WAAa,CAAC,CAAC,EACnD,EAAG,CAACA,CAAK,CAAC,EAEV,eAAeC,GAA+B,CAC5C,IAAMC,EAAcN,EAAK,KAAK,EACxBO,EAAkB,OAAOL,CAAS,EAExC,GAAI,CAACI,EACH1C,EAAS,SAAS,OAIpB,GAAI,CAAC,OAAO,UAAU2C,CAAe,EACnC3C,EAAS,SAAS,OAIpB,GAAI,CACF,MAAM4C,EAAS,CACb,YAAaV,EAAY,KAAK,GAAK,KACnC,SAAUM,GAAO,QAAQ,UAAY,GACrC,KAAME,EACN,UAAWC,CACb,CAAC,CACH,OAASE,EAAsB,CAC7B7C,EAASa,EAAiBgC,CAAW,CAAC,CACxC,CACF,CAEA,OACE,EAAAnE,EAAA,KAAA,CAACT,EAAAA,MAAD,CACE,WAAW,KACX,mBAAoB,CAAE,SAAU,CAACmE,EAAK,KAAK,CAAE,EAC7C,YAAaI,GAAO,OAAS,OAAS,KAAO,KACpC,UACT,UAAU,WACV,SAAUM,EACD,UACT,cAAuB,KAAKL,EAAc,EAC1C,KAAM,EAAQD,EACd,gBAAA,GACA,gBAAA,GACA,KAAK,UACL,MAAOA,GAAO,OAAS,OAAS,OAAS,OAb3C,SAAA,EAeE,EAAA9D,EAAA,KAAA,CAAC,MAAD,CAAK,UAAWlB,EAAO,oBAAvB,SAAA,EACE,EAAAkB,EAAA,IAAA,CAACR,EAAAA,EAAD,CAAc,MAAM,OAAO,KAAK,eAAe,SAAA,GAC7C,UAAA,EAAAQ,EAAA,IAAA,CAACb,EAAAA,MAAD,CACE,UAAA,GACA,UAAA,GACA,SAAW,GAA+C,CACxDwE,EAAQb,EAAM,OAAO,KAAK,EAC1BxB,EAAS,IAAI,CACf,EACA,YAAY,UACZ,MAAOoC,EACP,QAAQ,MACT,CAAA,CACW,CAAA,GACd,EAAA1D,EAAA,IAAA,CAACR,EAAAA,EAAD,CAAc,MAAM,KAAK,KAAK,oBAC5B,UAAA,EAAAQ,EAAA,IAAA,CAACb,EAAAA,MAAD,CACE,UAAA,GACA,SAAW,GAA+C,CACxD0E,EAAaf,EAAM,OAAO,KAAK,EAC/BxB,EAAS,IAAI,CACf,EACA,YAAY,IACZ,MAAOsC,EACP,QAAQ,MACT,CAAA,CACW,CAAA,GACd,EAAA5D,EAAA,IAAA,CAACR,EAAAA,EAAD,CAAc,MAAM,KAAK,KAAK,sBAC5B,UAAA,EAAAQ,EAAA,IAAA,CAACP,EAAAA,SAAD,CACE,SAAW,GAAkD,CAC3DgE,EAAeX,EAAM,OAAO,KAAK,EACjCxB,EAAS,IAAI,CACf,EACA,YAAY,SACZ,MAAOkC,CACR,CAAA,CACW,CAAA,CACX,CACJ,CAAA,EAAAnC,GACC,EAAArB,EAAA,IAAA,CAAC9B,EAAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,OACpC,SAAAmD,CACS,CAAA,EACV,IACC,GAEX,CAEA,SAASkB,EAAoB,CAC3B,YAGe,CACf,OAAO8B,GACL,EAAArE,EAAA,IAAA,CAACN,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,KAAK,QAAQ,aAAe,CAAA,GAEnD,EAAAM,EAAA,IAAA,CAACN,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,KAAK,QAAQ,cAAgB,CAAA,CAExD,CAEA,SAASqD,EAAyB,EAAsC,CAKtE,OAJIC,IAAc,UAAYA,IAAc,WACnCA,EAGF,KACT,CAEA,SAASf,EACP,EACgC,CAChC,OAAOqC,CACT,CAEA,SAASnC,EAAiB,EAAwB,CAChD,OAAOd,aAAiB,MAAQA,EAAM,QAAU,QAClD"}
1
+ {"version":3,"file":"categories-DQUtVEiV.cjs","names":["useState","useCallback","listApprovalTemplateCategoriesPage","useMemo","formatDateTime","Typography","updateApprovalTemplateCategory","createApprovalTemplateCategory","deleteApprovalTemplateCategory","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","styles","FilterLine","Filter","FormField","FormFieldLayout","Input","Tab","TabItem","Table","Modal","BPMFormField","Textarea","Badge","require_rolldown_runtime","require_bpm_form_field","require_format_date_time","react","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_core_form","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","_rytass_bpm_core_client_template","templates_module_default","CATEGORY_PAGE_SIZE_OPTIONS","CATEGORY_STATUS_TABS","TemplateCategoriesView","categories","setCategories","categoryPage","setCategoryPage","categoryPageSize","setCategoryPageSize","categoryStatus","setCategoryStatus","categoryTotalCount","setCategoryTotalCount","deleteConfirmation","setDeleteConfirmation","error","setError","loading","setLoading","modalState","setModalState","saving","setSaving","searchText","setSearchText","refreshCategories","categoryPageResult","readCategoryStatus","requestError","readErrorMessage","rows","category","columns","CategoryStatusBadge","record","handleSaveCategory","input","handleToggleCategory","handleConfirmDelete","tableActions","event","readCategoryStatusTabKey","activeKey","statusTab","page","pageSize","from","to","total","CategoryModal","description","setDescription","name","setName","sortOrder","setSortOrder","modal","handleConfirm","trimmedName","parsedSortOrder","onSubmit","submitError","onClose","isActive","status"],"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 {\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\n\nexport function TemplateCategoriesView(): 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 <>\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 </>\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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"}