@rytass/bpm-core-react 0.3.8 → 0.4.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 (232) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/README.md +69 -4
  3. package/dist/chunks/approval-instance-list-page-BF2r5D2-.js +278 -0
  4. package/dist/chunks/approval-instance-list-page-BF2r5D2-.js.map +1 -0
  5. package/dist/chunks/approval-instance-list-page-C5ZKPHdA.cjs +2 -0
  6. package/dist/chunks/approval-instance-list-page-C5ZKPHdA.cjs.map +1 -0
  7. package/dist/chunks/auth-provider-4BeCw7cI.cjs +2 -0
  8. package/dist/chunks/auth-provider-4BeCw7cI.cjs.map +1 -0
  9. package/dist/chunks/auth-provider-B5oPmvk2.js +83 -0
  10. package/dist/chunks/auth-provider-B5oPmvk2.js.map +1 -0
  11. package/dist/chunks/{builder-D950gct_.js → builder-BLVnnpnP.js} +474 -478
  12. package/dist/chunks/builder-BLVnnpnP.js.map +1 -0
  13. package/dist/chunks/builder-DVE9zIKH.cjs +3 -0
  14. package/dist/chunks/builder-DVE9zIKH.cjs.map +1 -0
  15. package/dist/chunks/categories-B6QZKZRt.cjs +2 -0
  16. package/dist/chunks/categories-B6QZKZRt.cjs.map +1 -0
  17. package/dist/chunks/categories-DBPoSrsi.js +382 -0
  18. package/dist/chunks/categories-DBPoSrsi.js.map +1 -0
  19. package/dist/chunks/chunk-CMqjfN_6.cjs +1 -0
  20. package/dist/chunks/dashboard-page-CddG1MnK.cjs +2 -0
  21. package/dist/chunks/dashboard-page-CddG1MnK.cjs.map +1 -0
  22. package/dist/chunks/dashboard-page-Ib8srCMy.js +119 -0
  23. package/dist/chunks/dashboard-page-Ib8srCMy.js.map +1 -0
  24. package/dist/chunks/delegations-C2wLWsDQ.cjs +2 -0
  25. package/dist/chunks/delegations-C2wLWsDQ.cjs.map +1 -0
  26. package/dist/chunks/delegations-DDEk-WI6.cjs +2 -0
  27. package/dist/chunks/delegations-DDEk-WI6.cjs.map +1 -0
  28. package/dist/chunks/delegations-ZNtodFaD.js +568 -0
  29. package/dist/chunks/delegations-ZNtodFaD.js.map +1 -0
  30. package/dist/chunks/delegations-iVnRi3QE.js +641 -0
  31. package/dist/chunks/delegations-iVnRi3QE.js.map +1 -0
  32. package/dist/chunks/detail-Dcr5mM8g.cjs +2 -0
  33. package/dist/chunks/detail-Dcr5mM8g.cjs.map +1 -0
  34. package/dist/chunks/detail-u9DdLhDW.js +1518 -0
  35. package/dist/chunks/detail-u9DdLhDW.js.map +1 -0
  36. package/dist/chunks/format-date-time-XxBzF0F5.cjs +2 -0
  37. package/dist/chunks/{format-date-time-26_pFvv4.cjs.map → format-date-time-XxBzF0F5.cjs.map} +1 -1
  38. package/dist/chunks/login-9bCXyjbX.cjs +2 -0
  39. package/dist/chunks/{login-CQ9MfwcC.cjs.map → login-9bCXyjbX.cjs.map} +1 -1
  40. package/dist/chunks/{login-C20yVxbc.js → login-BKxpLibd.js} +3 -2
  41. package/dist/chunks/{login-C20yVxbc.js.map → login-BKxpLibd.js.map} +1 -1
  42. package/dist/chunks/notifications-BKs4--96.cjs +2 -0
  43. package/dist/chunks/notifications-BKs4--96.cjs.map +1 -0
  44. package/dist/chunks/notifications-CSulztkU.js +193 -0
  45. package/dist/chunks/notifications-CSulztkU.js.map +1 -0
  46. package/dist/chunks/orgs-BIiqzHvb.cjs +2 -0
  47. package/dist/chunks/orgs-BIiqzHvb.cjs.map +1 -0
  48. package/dist/chunks/orgs-Cc18umVt.js +1944 -0
  49. package/dist/chunks/orgs-Cc18umVt.js.map +1 -0
  50. package/dist/chunks/router-adapter--gYs13E8.cjs +2 -0
  51. package/dist/chunks/router-adapter--gYs13E8.cjs.map +1 -0
  52. package/dist/chunks/router-adapter-DftlFTOd.js +23 -0
  53. package/dist/chunks/router-adapter-DftlFTOd.js.map +1 -0
  54. package/dist/chunks/templates-D44FSB46.js +380 -0
  55. package/dist/chunks/templates-D44FSB46.js.map +1 -0
  56. package/dist/chunks/templates-w96t83N-.cjs +2 -0
  57. package/dist/chunks/templates-w96t83N-.cjs.map +1 -0
  58. package/dist/chunks/users-CUY139DF.js +214 -0
  59. package/dist/chunks/users-CUY139DF.js.map +1 -0
  60. package/dist/chunks/users-qghSMtLn.cjs +2 -0
  61. package/dist/chunks/users-qghSMtLn.cjs.map +1 -0
  62. package/dist/components/approval-instance-list-page.d.ts +1 -2
  63. package/dist/components/bpm-notification-bell-button.d.ts +22 -0
  64. package/dist/components/dashboard-page.d.ts +1 -4
  65. package/dist/index.cjs +1 -1
  66. package/dist/index.cjs.map +1 -1
  67. package/dist/index.css +1 -0
  68. package/dist/index.d.ts +3 -1
  69. package/dist/index.js +206 -97
  70. package/dist/index.js.map +1 -1
  71. package/dist/lib/notification-drawer-provider.d.ts +3 -2
  72. package/dist/lib/notification-unread-provider.d.ts +6 -5
  73. package/dist/lib/providers.d.ts +3 -2
  74. package/dist/lib/use-bpm-logout.d.ts +12 -0
  75. package/dist/lib/use-bpm-member.d.ts +11 -0
  76. package/dist/next/BPMNextProviders.d.ts +1 -1
  77. package/dist/next/index.cjs +1 -1
  78. package/dist/next/index.cjs.map +1 -1
  79. package/dist/next/index.js +13 -23
  80. package/dist/next/index.js.map +1 -1
  81. package/dist/pages/admin/delegations/index.cjs +1 -1
  82. package/dist/pages/admin/delegations/index.js +1 -1
  83. package/dist/pages/admin/orgs/index.cjs +1 -1
  84. package/dist/pages/admin/orgs/index.js +1 -1
  85. package/dist/pages/admin/users/index.cjs +1 -1
  86. package/dist/pages/admin/users/index.js +1 -1
  87. package/dist/pages/delegations/index.cjs +1 -1
  88. package/dist/pages/delegations/index.js +1 -1
  89. package/dist/pages/forms/builder/index.cjs +1 -1
  90. package/dist/pages/forms/builder/index.js +1 -1
  91. package/dist/pages/instances/detail/index.cjs +1 -1
  92. package/dist/pages/instances/detail/index.js +1 -1
  93. package/dist/pages/login/index.cjs +1 -1
  94. package/dist/pages/login/index.js +1 -1
  95. package/dist/pages/settings/notifications/index.cjs +1 -1
  96. package/dist/pages/settings/notifications/index.js +1 -1
  97. package/dist/pages/templates/categories/index.cjs +1 -1
  98. package/dist/pages/templates/categories/index.js +1 -1
  99. package/dist/pages/templates/index.cjs +1 -1
  100. package/dist/pages/templates/index.js +1 -1
  101. package/dist/views/admin/delegations/AdminDelegationsView.d.ts +1 -4
  102. package/dist/views/admin/delegations/index.cjs +1 -1
  103. package/dist/views/admin/delegations/index.js +1 -1
  104. package/dist/views/admin/index.cjs +1 -1
  105. package/dist/views/admin/index.js +3 -3
  106. package/dist/views/admin/orgs/AdminOrgsView.d.ts +1 -4
  107. package/dist/views/admin/orgs/index.cjs +1 -1
  108. package/dist/views/admin/orgs/index.js +1 -1
  109. package/dist/views/admin/users/AdminUsersView.d.ts +1 -4
  110. package/dist/views/admin/users/index.cjs +1 -1
  111. package/dist/views/admin/users/index.js +1 -1
  112. package/dist/views/cc/CcView.d.ts +1 -3
  113. package/dist/views/cc/index.cjs +1 -1
  114. package/dist/views/cc/index.cjs.map +1 -1
  115. package/dist/views/cc/index.js +2 -3
  116. package/dist/views/cc/index.js.map +1 -1
  117. package/dist/views/dashboard/DashboardView.d.ts +1 -3
  118. package/dist/views/dashboard/index.cjs +1 -1
  119. package/dist/views/dashboard/index.cjs.map +1 -1
  120. package/dist/views/dashboard/index.js +3 -3
  121. package/dist/views/dashboard/index.js.map +1 -1
  122. package/dist/views/delegations/DelegationsView.d.ts +1 -4
  123. package/dist/views/delegations/index.cjs +1 -1
  124. package/dist/views/delegations/index.js +1 -1
  125. package/dist/views/forms/FormsView.d.ts +1 -3
  126. package/dist/views/forms/builder/index.cjs +1 -1
  127. package/dist/views/forms/builder/index.js +1 -1
  128. package/dist/views/forms/index.cjs +1 -1
  129. package/dist/views/forms/index.cjs.map +1 -1
  130. package/dist/views/forms/index.js +95 -99
  131. package/dist/views/forms/index.js.map +1 -1
  132. package/dist/views/inbox/InboxView.d.ts +1 -3
  133. package/dist/views/inbox/index.cjs +1 -1
  134. package/dist/views/inbox/index.cjs.map +1 -1
  135. package/dist/views/inbox/index.js +91 -94
  136. package/dist/views/inbox/index.js.map +1 -1
  137. package/dist/views/instances/detail/index.cjs +1 -1
  138. package/dist/views/instances/detail/index.js +1 -1
  139. package/dist/views/instances/new/index.cjs +1 -1
  140. package/dist/views/instances/new/index.cjs.map +1 -1
  141. package/dist/views/instances/new/index.js +71 -77
  142. package/dist/views/instances/new/index.js.map +1 -1
  143. package/dist/views/login/index.cjs +1 -1
  144. package/dist/views/login/index.js +1 -1
  145. package/dist/views/root/RootView.d.ts +1 -3
  146. package/dist/views/search/SearchView.d.ts +1 -3
  147. package/dist/views/search/index.cjs +1 -1
  148. package/dist/views/search/index.cjs.map +1 -1
  149. package/dist/views/search/index.js +2 -3
  150. package/dist/views/search/index.js.map +1 -1
  151. package/dist/views/sent/SentView.d.ts +1 -3
  152. package/dist/views/sent/index.cjs +1 -1
  153. package/dist/views/sent/index.cjs.map +1 -1
  154. package/dist/views/sent/index.js +2 -3
  155. package/dist/views/sent/index.js.map +1 -1
  156. package/dist/views/settings/index.cjs +1 -1
  157. package/dist/views/settings/index.js +1 -1
  158. package/dist/views/settings/notifications/SettingsNotificationsView.d.ts +1 -4
  159. package/dist/views/settings/notifications/index.cjs +1 -1
  160. package/dist/views/settings/notifications/index.js +1 -1
  161. package/dist/views/templates/TemplatesView.d.ts +1 -4
  162. package/dist/views/templates/categories/TemplateCategoriesView.d.ts +1 -4
  163. package/dist/views/templates/categories/index.cjs +1 -1
  164. package/dist/views/templates/categories/index.js +1 -1
  165. package/dist/views/templates/designer/TemplateDesignerView.d.ts +1 -2
  166. package/dist/views/templates/designer/index.cjs +7 -7
  167. package/dist/views/templates/designer/index.cjs.map +1 -1
  168. package/dist/views/templates/designer/index.js +707 -711
  169. package/dist/views/templates/designer/index.js.map +1 -1
  170. package/dist/views/templates/index.cjs +1 -1
  171. package/dist/views/templates/index.js +2 -2
  172. package/dist/views/templates/versions/TemplateVersionsView.d.ts +1 -2
  173. package/dist/views/templates/versions/index.cjs +1 -1
  174. package/dist/views/templates/versions/index.cjs.map +1 -1
  175. package/dist/views/templates/versions/index.js +45 -49
  176. package/dist/views/templates/versions/index.js.map +1 -1
  177. package/package.json +2 -2
  178. package/dist/app-navigation.css +0 -1
  179. package/dist/chunks/app-navigation-BSkMsEhy.js +0 -268
  180. package/dist/chunks/app-navigation-BSkMsEhy.js.map +0 -1
  181. package/dist/chunks/app-navigation-KnlJCUp1.cjs +0 -2
  182. package/dist/chunks/app-navigation-KnlJCUp1.cjs.map +0 -1
  183. package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs +0 -2
  184. package/dist/chunks/approval-instance-list-page-CVXgE2K3.cjs.map +0 -1
  185. package/dist/chunks/approval-instance-list-page-CqNdoZqx.js +0 -282
  186. package/dist/chunks/approval-instance-list-page-CqNdoZqx.js.map +0 -1
  187. package/dist/chunks/auth-provider-BV8Iiwfb.cjs +0 -2
  188. package/dist/chunks/auth-provider-BV8Iiwfb.cjs.map +0 -1
  189. package/dist/chunks/auth-provider-Bnox5gsx.js +0 -98
  190. package/dist/chunks/auth-provider-Bnox5gsx.js.map +0 -1
  191. package/dist/chunks/builder-CMlJfQHE.cjs +0 -3
  192. package/dist/chunks/builder-CMlJfQHE.cjs.map +0 -1
  193. package/dist/chunks/builder-D950gct_.js.map +0 -1
  194. package/dist/chunks/categories-5yEM3p3N.cjs +0 -2
  195. package/dist/chunks/categories-5yEM3p3N.cjs.map +0 -1
  196. package/dist/chunks/categories-BIpOG451.js +0 -387
  197. package/dist/chunks/categories-BIpOG451.js.map +0 -1
  198. package/dist/chunks/dashboard-page-Bx1-Ys3e.js +0 -122
  199. package/dist/chunks/dashboard-page-Bx1-Ys3e.js.map +0 -1
  200. package/dist/chunks/dashboard-page-CQNRbMkJ.cjs +0 -2
  201. package/dist/chunks/dashboard-page-CQNRbMkJ.cjs.map +0 -1
  202. package/dist/chunks/delegations-B2j-wNEO.js +0 -646
  203. package/dist/chunks/delegations-B2j-wNEO.js.map +0 -1
  204. package/dist/chunks/delegations-CsB9ozLu.cjs +0 -2
  205. package/dist/chunks/delegations-CsB9ozLu.cjs.map +0 -1
  206. package/dist/chunks/delegations-CvtwTXNP.cjs +0 -2
  207. package/dist/chunks/delegations-CvtwTXNP.cjs.map +0 -1
  208. package/dist/chunks/delegations-dKodb0WW.js +0 -573
  209. package/dist/chunks/delegations-dKodb0WW.js.map +0 -1
  210. package/dist/chunks/detail-BcGAqJ_R.js +0 -1523
  211. package/dist/chunks/detail-BcGAqJ_R.js.map +0 -1
  212. package/dist/chunks/detail-CqjqLd65.cjs +0 -2
  213. package/dist/chunks/detail-CqjqLd65.cjs.map +0 -1
  214. package/dist/chunks/format-date-time-26_pFvv4.cjs +0 -2
  215. package/dist/chunks/login-CQ9MfwcC.cjs +0 -2
  216. package/dist/chunks/notifications-2swRqDPF.js +0 -198
  217. package/dist/chunks/notifications-2swRqDPF.js.map +0 -1
  218. package/dist/chunks/notifications-BaYDebFt.cjs +0 -2
  219. package/dist/chunks/notifications-BaYDebFt.cjs.map +0 -1
  220. package/dist/chunks/orgs-CuHxxd_n.js +0 -1949
  221. package/dist/chunks/orgs-CuHxxd_n.js.map +0 -1
  222. package/dist/chunks/orgs-YMiVLNvL.cjs +0 -2
  223. package/dist/chunks/orgs-YMiVLNvL.cjs.map +0 -1
  224. package/dist/chunks/templates-DTkbSgFY.cjs +0 -2
  225. package/dist/chunks/templates-DTkbSgFY.cjs.map +0 -1
  226. package/dist/chunks/templates-DoDWM68t.js +0 -384
  227. package/dist/chunks/templates-DoDWM68t.js.map +0 -1
  228. package/dist/chunks/users-3ySyUW4u.cjs +0 -2
  229. package/dist/chunks/users-3ySyUW4u.cjs.map +0 -1
  230. package/dist/chunks/users-sMfrSjRQ.js +0 -219
  231. package/dist/chunks/users-sMfrSjRQ.js.map +0 -1
  232. package/dist/components/app-navigation.d.ts +0 -41
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/categories-5yEM3p3N.cjs"),t=require("../../chunks/templates-DTkbSgFY.cjs"),n=require("./versions/index.cjs");exports.TemplateCategoriesView=e.t,exports.TemplateVersionsView=n.TemplateVersionsView,exports.TemplatesView=t.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/categories-B6QZKZRt.cjs"),t=require("../../chunks/templates-w96t83N-.cjs"),n=require("./versions/index.cjs");exports.TemplateCategoriesView=e.t,exports.TemplateVersionsView=n.TemplateVersionsView,exports.TemplatesView=t.t;
@@ -1,4 +1,4 @@
1
- import { t as e } from "../../chunks/categories-BIpOG451.js";
2
- import { t } from "../../chunks/templates-DoDWM68t.js";
1
+ import { t as e } from "../../chunks/categories-DBPoSrsi.js";
2
+ import { t } from "../../chunks/templates-D44FSB46.js";
3
3
  import { TemplateVersionsView as n } from "./versions/index.js";
4
4
  export { e as TemplateCategoriesView, n as TemplateVersionsView, t as TemplatesView };
@@ -1,6 +1,5 @@
1
1
  import { ReactElement } from 'react';
2
2
  export interface TemplateVersionsViewProps {
3
3
  readonly templateId: string;
4
- readonly activeHref?: string;
5
4
  }
6
- export declare function TemplateVersionsView({ templateId, activeHref, }: TemplateVersionsViewProps): ReactElement;
5
+ export declare function TemplateVersionsView({ templateId, }: TemplateVersionsViewProps): ReactElement;
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/app-navigation-KnlJCUp1.cjs"),t=require("../../../chunks/auth-provider-BV8Iiwfb.cjs"),n=require("../../../chunks/format-date-time-26_pFvv4.cjs"),r=require("../../../chunks/routes-config-2aKbWq2H.cjs");let i=require("react"),a=require("@mezzanine-ui/react"),o=require("react/jsx-runtime"),s=require("@mezzanine-ui/react/ContentHeader");s=e.o(s,1);let c=require("@rytass/bpm-core-client/template");function l({templateId:l,activeHref:d}){let f=t.a(),p=r.r(),m=d??p.templates(),[h,g]=(0,i.useState)(null),[_,v]=(0,i.useState)(null),[y,b]=(0,i.useState)(!0),[x,S]=(0,i.useState)(!1);(0,i.useEffect)(()=>{E()},[l]);let C=(0,i.useMemo)(()=>(h?.versions??[]).map(e=>({formVersion:h?.formVersions.find(t=>t.id===e.formDefinitionVersionId)?.label??`未綁定`,key:e.id,publishedAt:n.t(e.publishedAt),status:e.status,updatedAt:n.t(e.updatedAt),version:`v${e.version}`,versionId:e.id})),[h]),w=(0,i.useMemo)(()=>[{dataIndex:`version`,key:`version`,title:`版本`,width:100},{dataIndex:`status`,key:`status`,title:`狀態`,width:140},{dataIndex:`formVersion`,key:`formVersion`,title:`表單版本`,width:220},{dataIndex:`publishedAt`,key:`publishedAt`,title:`發布時間`,width:200},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:200}],[]),T=(0,i.useMemo)(()=>({render:e=>[{disabled:()=>x||e.status===`DRAFT`,name:`Rollback`,onClick:()=>void D(e.versionId)}],variant:`base-secondary`,width:104}),[x]);async function E(){b(!0),v(null);try{g(await(0,c.readTemplateDesigner)(l))}catch(e){v(u(e))}finally{b(!1)}}async function D(e){S(!0),v(null);try{await(0,c.rollbackApprovalTemplateVersion)(e),await E()}catch(e){v(u(e))}finally{S(!1)}}return(0,o.jsxs)(e.t,{activeHref:m,children:[(0,o.jsx)(a.PageHeader,{children:(0,o.jsx)(s.default,{description:`查看發布、歸檔與 rollback 狀態。`,title:h?.template.name??`模板版本`,children:(0,o.jsx)(a.Button,{onClick:()=>f.push(p.templateDesigner(l)),variant:`base-secondary`,children:`回設計器`})})}),(0,o.jsx)(a.SectionGroup,{children:(0,o.jsxs)(a.Section,{children:[_?(0,o.jsx)(a.Typography,{color:`text-error`,variant:`body`,children:_}):null,(0,o.jsx)(a.Table,{actions:T,columns:w,dataSource:C,fullWidth:!0,loading:y})]})})]})}function u(e){return e instanceof Error?e.message:`發生未知錯誤`}exports.TemplateVersionsView=l;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/chunk-CMqjfN_6.cjs"),t=require("../../../chunks/router-adapter--gYs13E8.cjs"),n=require("../../../chunks/format-date-time-XxBzF0F5.cjs"),r=require("../../../chunks/routes-config-2aKbWq2H.cjs");let i=require("react"),a=require("@mezzanine-ui/react"),o=require("react/jsx-runtime"),s=require("@mezzanine-ui/react/ContentHeader");s=e.t(s,1);let c=require("@rytass/bpm-core-client/template");function l({templateId:e}){let l=t.r(),d=r.r(),[f,p]=(0,i.useState)(null),[m,h]=(0,i.useState)(null),[g,_]=(0,i.useState)(!0),[v,y]=(0,i.useState)(!1);(0,i.useEffect)(()=>{C()},[e]);let b=(0,i.useMemo)(()=>(f?.versions??[]).map(e=>({formVersion:f?.formVersions.find(t=>t.id===e.formDefinitionVersionId)?.label??`未綁定`,key:e.id,publishedAt:n.t(e.publishedAt),status:e.status,updatedAt:n.t(e.updatedAt),version:`v${e.version}`,versionId:e.id})),[f]),x=(0,i.useMemo)(()=>[{dataIndex:`version`,key:`version`,title:`版本`,width:100},{dataIndex:`status`,key:`status`,title:`狀態`,width:140},{dataIndex:`formVersion`,key:`formVersion`,title:`表單版本`,width:220},{dataIndex:`publishedAt`,key:`publishedAt`,title:`發布時間`,width:200},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:200}],[]),S=(0,i.useMemo)(()=>({render:e=>[{disabled:()=>v||e.status===`DRAFT`,name:`Rollback`,onClick:()=>void w(e.versionId)}],variant:`base-secondary`,width:104}),[v]);async function C(){_(!0),h(null);try{p(await(0,c.readTemplateDesigner)(e))}catch(e){h(u(e))}finally{_(!1)}}async function w(e){y(!0),h(null);try{await(0,c.rollbackApprovalTemplateVersion)(e),await C()}catch(e){h(u(e))}finally{y(!1)}}return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(a.PageHeader,{children:(0,o.jsx)(s.default,{description:`查看發布、歸檔與 rollback 狀態。`,title:f?.template.name??`模板版本`,children:(0,o.jsx)(a.Button,{onClick:()=>l.push(d.templateDesigner(e)),variant:`base-secondary`,children:`回設計器`})})}),(0,o.jsx)(a.SectionGroup,{children:(0,o.jsxs)(a.Section,{children:[m?(0,o.jsx)(a.Typography,{color:`text-error`,variant:`body`,children:m}):null,(0,o.jsx)(a.Table,{actions:S,columns:x,dataSource:b,fullWidth:!0,loading:g})]})})]})}function u(e){return e instanceof Error?e.message:`發生未知錯誤`}exports.TemplateVersionsView=l;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../../../../src/views/templates/versions/TemplateVersionsView.tsx"],"sourcesContent":["'use client';\n\nimport { ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { AppLayout } from '../../../components/app-navigation';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport {\n readTemplateDesigner,\n rollbackApprovalTemplateVersion,\n TemplateDesignerRecord,\n} from '@rytass/bpm-core-client/template';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype VersionRow = Readonly<\n Record<string, unknown> & {\n formVersion: string;\n key: string;\n publishedAt: string;\n status: string;\n updatedAt: string;\n version: string;\n versionId: string;\n }\n>;\n\nexport interface TemplateVersionsViewProps {\n readonly templateId: string;\n readonly activeHref?: string;\n}\n\nexport function TemplateVersionsView({\n templateId,\n activeHref,\n}: TemplateVersionsViewProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const resolvedActiveHref = activeHref ?? routes.templates();\n const [record, setRecord] = useState<TemplateDesignerRecord | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [rollingBack, setRollingBack] = useState(false);\n\n useEffect((): void => {\n void refreshVersions();\n }, [templateId]);\n\n const rows = useMemo(\n (): VersionRow[] =>\n (record?.versions ?? []).map((version) => ({\n formVersion:\n record?.formVersions.find(\n (formVersion) => formVersion.id === version.formDefinitionVersionId,\n )?.label ?? '未綁定',\n key: version.id,\n publishedAt: formatDateTime(version.publishedAt),\n status: version.status,\n updatedAt: formatDateTime(version.updatedAt),\n version: `v${version.version}`,\n versionId: version.id,\n })),\n [record],\n );\n const columns = useMemo(\n (): TableColumn<VersionRow>[] => [\n { dataIndex: 'version', key: 'version', title: '版本', width: 100 },\n { dataIndex: 'status', key: 'status', title: '狀態', width: 140 },\n {\n dataIndex: 'formVersion',\n key: 'formVersion',\n title: '表單版本',\n width: 220,\n },\n {\n dataIndex: 'publishedAt',\n key: 'publishedAt',\n title: '發布時間',\n width: 200,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 200,\n },\n ],\n [],\n );\n const actions = useMemo(\n (): TableActions<VersionRow> => ({\n render: (row): ReturnType<TableActions<VersionRow>['render']> => [\n {\n disabled: (): boolean => rollingBack || row.status === 'DRAFT',\n name: 'Rollback',\n onClick: (): void => void handleRollback(row.versionId),\n },\n ],\n variant: 'base-secondary',\n width: 104,\n }),\n [rollingBack],\n );\n\n async function refreshVersions(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n setRecord(await readTemplateDesigner(templateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleRollback(versionId: string): Promise<void> {\n setRollingBack(true);\n setError(null);\n\n try {\n await rollbackApprovalTemplateVersion(versionId);\n await refreshVersions();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setRollingBack(false);\n }\n }\n\n return (\n <AppLayout activeHref={resolvedActiveHref}>\n <PageHeader>\n <ContentHeader\n description=\"查看發布、歸檔與 rollback 狀態。\"\n title={record?.template.name ?? '模板版本'}\n >\n <Button\n onClick={(): void =>\n router.push(routes.templateDesigner(templateId))\n }\n variant=\"base-secondary\"\n >\n 回設計器\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </Section>\n </SectionGroup>\n </AppLayout>\n );\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":"index.cjs","names":[],"sources":["../../../../src/views/templates/versions/TemplateVersionsView.tsx"],"sourcesContent":["'use client';\n\nimport { ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport {\n readTemplateDesigner,\n rollbackApprovalTemplateVersion,\n TemplateDesignerRecord,\n} from '@rytass/bpm-core-client/template';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype VersionRow = Readonly<\n Record<string, unknown> & {\n formVersion: string;\n key: string;\n publishedAt: string;\n status: string;\n updatedAt: string;\n version: string;\n versionId: string;\n }\n>;\n\nexport interface TemplateVersionsViewProps {\n readonly templateId: string;\n}\n\nexport function TemplateVersionsView({\n templateId,\n}: TemplateVersionsViewProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [record, setRecord] = useState<TemplateDesignerRecord | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [rollingBack, setRollingBack] = useState(false);\n\n useEffect((): void => {\n void refreshVersions();\n }, [templateId]);\n\n const rows = useMemo(\n (): VersionRow[] =>\n (record?.versions ?? []).map((version) => ({\n formVersion:\n record?.formVersions.find(\n (formVersion) => formVersion.id === version.formDefinitionVersionId,\n )?.label ?? '未綁定',\n key: version.id,\n publishedAt: formatDateTime(version.publishedAt),\n status: version.status,\n updatedAt: formatDateTime(version.updatedAt),\n version: `v${version.version}`,\n versionId: version.id,\n })),\n [record],\n );\n const columns = useMemo(\n (): TableColumn<VersionRow>[] => [\n { dataIndex: 'version', key: 'version', title: '版本', width: 100 },\n { dataIndex: 'status', key: 'status', title: '狀態', width: 140 },\n {\n dataIndex: 'formVersion',\n key: 'formVersion',\n title: '表單版本',\n width: 220,\n },\n {\n dataIndex: 'publishedAt',\n key: 'publishedAt',\n title: '發布時間',\n width: 200,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 200,\n },\n ],\n [],\n );\n const actions = useMemo(\n (): TableActions<VersionRow> => ({\n render: (row): ReturnType<TableActions<VersionRow>['render']> => [\n {\n disabled: (): boolean => rollingBack || row.status === 'DRAFT',\n name: 'Rollback',\n onClick: (): void => void handleRollback(row.versionId),\n },\n ],\n variant: 'base-secondary',\n width: 104,\n }),\n [rollingBack],\n );\n\n async function refreshVersions(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n setRecord(await readTemplateDesigner(templateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleRollback(versionId: string): Promise<void> {\n setRollingBack(true);\n setError(null);\n\n try {\n await rollbackApprovalTemplateVersion(versionId);\n await refreshVersions();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setRollingBack(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"查看發布、歸檔與 rollback 狀態。\"\n title={record?.template.name ?? '模板版本'}\n >\n <Button\n onClick={(): void =>\n router.push(routes.templateDesigner(templateId))\n }\n variant=\"base-secondary\"\n >\n 回設計器\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
@@ -1,28 +1,27 @@
1
1
  "use client";
2
- import { a as e } from "../../../chunks/auth-provider-Bnox5gsx.js";
2
+ import { r as e } from "../../../chunks/router-adapter-DftlFTOd.js";
3
3
  import { t } from "../../../chunks/format-date-time-CB-LxzqT.js";
4
- import { t as n } from "../../../chunks/app-navigation-BSkMsEhy.js";
5
- import { r } from "../../../chunks/routes-config-dxahImVe.js";
6
- import { useEffect as i, useMemo as a, useState as o } from "react";
7
- import { Button as s, PageHeader as c, Section as l, SectionGroup as u, Table as d, Typography as f } from "@mezzanine-ui/react";
8
- import { jsx as p, jsxs as m } from "react/jsx-runtime";
4
+ import { r as n } from "../../../chunks/routes-config-dxahImVe.js";
5
+ import { useEffect as r, useMemo as i, useState as a } from "react";
6
+ import { Button as o, PageHeader as s, Section as c, SectionGroup as l, Table as u, Typography as d } from "@mezzanine-ui/react";
7
+ import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
9
8
  import h from "@mezzanine-ui/react/ContentHeader";
10
9
  import { readTemplateDesigner as g, rollbackApprovalTemplateVersion as _ } from "@rytass/bpm-core-client/template";
11
10
  //#region src/views/templates/versions/TemplateVersionsView.tsx
12
- function v({ templateId: v, activeHref: b }) {
13
- let x = e(), S = r(), C = b ?? S.templates(), [w, T] = o(null), [E, D] = o(null), [O, k] = o(!0), [A, j] = o(!1);
14
- i(() => {
15
- F();
11
+ function v({ templateId: v }) {
12
+ let b = e(), x = n(), [S, C] = a(null), [w, T] = a(null), [E, D] = a(!0), [O, k] = a(!1);
13
+ r(() => {
14
+ N();
16
15
  }, [v]);
17
- let M = a(() => (w?.versions ?? []).map((e) => ({
18
- formVersion: w?.formVersions.find((t) => t.id === e.formDefinitionVersionId)?.label ?? "未綁定",
16
+ let A = i(() => (S?.versions ?? []).map((e) => ({
17
+ formVersion: S?.formVersions.find((t) => t.id === e.formDefinitionVersionId)?.label ?? "未綁定",
19
18
  key: e.id,
20
19
  publishedAt: t(e.publishedAt),
21
20
  status: e.status,
22
21
  updatedAt: t(e.updatedAt),
23
22
  version: `v${e.version}`,
24
23
  versionId: e.id
25
- })), [w]), N = a(() => [
24
+ })), [S]), j = i(() => [
26
25
  {
27
26
  dataIndex: "version",
28
27
  key: "version",
@@ -53,57 +52,54 @@ function v({ templateId: v, activeHref: b }) {
53
52
  title: "更新時間",
54
53
  width: 200
55
54
  }
56
- ], []), P = a(() => ({
55
+ ], []), M = i(() => ({
57
56
  render: (e) => [{
58
- disabled: () => A || e.status === "DRAFT",
57
+ disabled: () => O || e.status === "DRAFT",
59
58
  name: "Rollback",
60
- onClick: () => void I(e.versionId)
59
+ onClick: () => void P(e.versionId)
61
60
  }],
62
61
  variant: "base-secondary",
63
62
  width: 104
64
- }), [A]);
65
- async function F() {
66
- k(!0), D(null);
63
+ }), [O]);
64
+ async function N() {
65
+ D(!0), T(null);
67
66
  try {
68
- T(await g(v));
67
+ C(await g(v));
69
68
  } catch (e) {
70
- D(y(e));
69
+ T(y(e));
71
70
  } finally {
72
- k(!1);
71
+ D(!1);
73
72
  }
74
73
  }
75
- async function I(e) {
76
- j(!0), D(null);
74
+ async function P(e) {
75
+ k(!0), T(null);
77
76
  try {
78
- await _(e), await F();
77
+ await _(e), await N();
79
78
  } catch (e) {
80
- D(y(e));
79
+ T(y(e));
81
80
  } finally {
82
- j(!1);
81
+ k(!1);
83
82
  }
84
83
  }
85
- return /* @__PURE__ */ m(n, {
86
- activeHref: C,
87
- children: [/* @__PURE__ */ p(c, { children: /* @__PURE__ */ p(h, {
88
- description: "查看發布、歸檔與 rollback 狀態。",
89
- title: w?.template.name ?? "模板版本",
90
- children: /* @__PURE__ */ p(s, {
91
- onClick: () => x.push(S.templateDesigner(v)),
92
- variant: "base-secondary",
93
- children: "回設計器"
94
- })
95
- }) }), /* @__PURE__ */ p(u, { children: /* @__PURE__ */ m(l, { children: [E ? /* @__PURE__ */ p(f, {
96
- color: "text-error",
97
- variant: "body",
98
- children: E
99
- }) : null, /* @__PURE__ */ p(d, {
100
- actions: P,
101
- columns: N,
102
- dataSource: M,
103
- fullWidth: !0,
104
- loading: O
105
- })] }) })]
106
- });
84
+ return /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(s, { children: /* @__PURE__ */ p(h, {
85
+ description: "查看發布、歸檔與 rollback 狀態。",
86
+ title: S?.template.name ?? "模板版本",
87
+ children: /* @__PURE__ */ p(o, {
88
+ onClick: () => b.push(x.templateDesigner(v)),
89
+ variant: "base-secondary",
90
+ children: "回設計器"
91
+ })
92
+ }) }), /* @__PURE__ */ p(l, { children: /* @__PURE__ */ m(c, { children: [w ? /* @__PURE__ */ p(d, {
93
+ color: "text-error",
94
+ variant: "body",
95
+ children: w
96
+ }) : null, /* @__PURE__ */ p(u, {
97
+ actions: M,
98
+ columns: j,
99
+ dataSource: A,
100
+ fullWidth: !0,
101
+ loading: E
102
+ })] }) })] });
107
103
  }
108
104
  function y(e) {
109
105
  return e instanceof Error ? e.message : "發生未知錯誤";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/views/templates/versions/TemplateVersionsView.tsx"],"sourcesContent":["'use client';\n\nimport { ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { AppLayout } from '../../../components/app-navigation';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport {\n readTemplateDesigner,\n rollbackApprovalTemplateVersion,\n TemplateDesignerRecord,\n} from '@rytass/bpm-core-client/template';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype VersionRow = Readonly<\n Record<string, unknown> & {\n formVersion: string;\n key: string;\n publishedAt: string;\n status: string;\n updatedAt: string;\n version: string;\n versionId: string;\n }\n>;\n\nexport interface TemplateVersionsViewProps {\n readonly templateId: string;\n readonly activeHref?: string;\n}\n\nexport function TemplateVersionsView({\n templateId,\n activeHref,\n}: TemplateVersionsViewProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const resolvedActiveHref = activeHref ?? routes.templates();\n const [record, setRecord] = useState<TemplateDesignerRecord | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [rollingBack, setRollingBack] = useState(false);\n\n useEffect((): void => {\n void refreshVersions();\n }, [templateId]);\n\n const rows = useMemo(\n (): VersionRow[] =>\n (record?.versions ?? []).map((version) => ({\n formVersion:\n record?.formVersions.find(\n (formVersion) => formVersion.id === version.formDefinitionVersionId,\n )?.label ?? '未綁定',\n key: version.id,\n publishedAt: formatDateTime(version.publishedAt),\n status: version.status,\n updatedAt: formatDateTime(version.updatedAt),\n version: `v${version.version}`,\n versionId: version.id,\n })),\n [record],\n );\n const columns = useMemo(\n (): TableColumn<VersionRow>[] => [\n { dataIndex: 'version', key: 'version', title: '版本', width: 100 },\n { dataIndex: 'status', key: 'status', title: '狀態', width: 140 },\n {\n dataIndex: 'formVersion',\n key: 'formVersion',\n title: '表單版本',\n width: 220,\n },\n {\n dataIndex: 'publishedAt',\n key: 'publishedAt',\n title: '發布時間',\n width: 200,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 200,\n },\n ],\n [],\n );\n const actions = useMemo(\n (): TableActions<VersionRow> => ({\n render: (row): ReturnType<TableActions<VersionRow>['render']> => [\n {\n disabled: (): boolean => rollingBack || row.status === 'DRAFT',\n name: 'Rollback',\n onClick: (): void => void handleRollback(row.versionId),\n },\n ],\n variant: 'base-secondary',\n width: 104,\n }),\n [rollingBack],\n );\n\n async function refreshVersions(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n setRecord(await readTemplateDesigner(templateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleRollback(versionId: string): Promise<void> {\n setRollingBack(true);\n setError(null);\n\n try {\n await rollbackApprovalTemplateVersion(versionId);\n await refreshVersions();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setRollingBack(false);\n }\n }\n\n return (\n <AppLayout activeHref={resolvedActiveHref}>\n <PageHeader>\n <ContentHeader\n description=\"查看發布、歸檔與 rollback 狀態。\"\n title={record?.template.name ?? '模板版本'}\n >\n <Button\n onClick={(): void =>\n router.push(routes.templateDesigner(templateId))\n }\n variant=\"base-secondary\"\n >\n 回設計器\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </Section>\n </SectionGroup>\n </AppLayout>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":";;;;;;;;;;;AAwCA,SAAgB,EAAqB,EACnC,eACA,iBAC0C;CAC1C,IAAM,IAAS,EAAiB,GAC1B,IAAS,EAAa,GACtB,IAAqB,KAAc,EAAO,UAAU,GACpD,CAAC,GAAQ,KAAa,EAAwC,IAAI,GAClE,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAS,KAAc,EAAS,EAAI,GACrC,CAAC,GAAa,KAAkB,EAAS,EAAK;CAEpD,QAAsB;EACpB,EAAqB;CACvB,GAAG,CAAC,CAAU,CAAC;CAEf,IAAM,IAAO,SAER,GAAQ,YAAY,CAAC,GAAG,KAAK,OAAa;EACzC,aACE,GAAQ,aAAa,MAClB,MAAgB,EAAY,OAAO,EAAQ,uBAC9C,GAAG,SAAS;EACd,KAAK,EAAQ;EACb,aAAa,EAAe,EAAQ,WAAW;EAC/C,QAAQ,EAAQ;EAChB,WAAW,EAAe,EAAQ,SAAS;EAC3C,SAAS,IAAI,EAAQ;EACrB,WAAW,EAAQ;CACrB,EAAE,GACJ,CAAC,CAAM,CACT,GACM,IAAU,QACmB;EAC/B;GAAE,WAAW;GAAW,KAAK;GAAW,OAAO;GAAM,OAAO;EAAI;EAChE;GAAE,WAAW;GAAU,KAAK;GAAU,OAAO;GAAM,OAAO;EAAI;EAC9D;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH,GACM,IAAU,SACmB;EAC/B,SAAS,MAAwD,CAC/D;GACE,gBAAyB,KAAe,EAAI,WAAW;GACvD,MAAM;GACN,eAAqB,KAAK,EAAe,EAAI,SAAS;EACxD,CACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAAC,CAAW,CACd;CAEA,eAAe,IAAiC;EAE9C,AADA,EAAW,EAAI,GACf,EAAS,IAAI;EAEb,IAAI;GACF,EAAU,MAAM,EAAqB,CAAU,CAAC;EAClD,SAAS,GAAuB;GAC9B,EAAS,EAAiB,CAAY,CAAC;EACzC,UAAU;GACR,EAAW,EAAK;EAClB;CACF;CAEA,eAAe,EAAe,GAAkC;EAE9D,AADA,EAAe,EAAI,GACnB,EAAS,IAAI;EAEb,IAAI;GAEF,AADA,MAAM,EAAgC,CAAS,GAC/C,MAAM,EAAgB;EACxB,SAAS,GAAuB;GAC9B,EAAS,EAAiB,CAAY,CAAC;EACzC,UAAU;GACR,EAAe,EAAK;EACtB;CACF;CAEA,OACE,kBAAC,GAAD;EAAW,YAAY;YAAvB,CACI,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;GACE,aAAY;GACZ,OAAO,GAAQ,SAAS,QAAQ;aAEhC,kBAAC,GAAD;IACE,eACE,EAAO,KAAK,EAAO,iBAAiB,CAAU,CAAC;IAEjD,SAAQ;cACT;GAEO,CAAA;EACK,CAAA,EACL,CAAA,GAEZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA,CACG,IACC,kBAAC,GAAD;GAAY,OAAM;GAAa,SAAQ;aACpC;EACS,CAAA,IACV,MACJ,kBAAC,GAAD;GACW;GACA;GACT,YAAY;GACZ,WAAA;GACS;EACV,CAAA,CACM,EAAA,CAAA,EACG,CAAA,CACL;;AAEjB;AAEA,SAAS,EAAiB,GAAwB;CAChD,OAAO,aAAiB,QAAQ,EAAM,UAAU;AAClD"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/views/templates/versions/TemplateVersionsView.tsx"],"sourcesContent":["'use client';\n\nimport { ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport {\n readTemplateDesigner,\n rollbackApprovalTemplateVersion,\n TemplateDesignerRecord,\n} from '@rytass/bpm-core-client/template';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype VersionRow = Readonly<\n Record<string, unknown> & {\n formVersion: string;\n key: string;\n publishedAt: string;\n status: string;\n updatedAt: string;\n version: string;\n versionId: string;\n }\n>;\n\nexport interface TemplateVersionsViewProps {\n readonly templateId: string;\n}\n\nexport function TemplateVersionsView({\n templateId,\n}: TemplateVersionsViewProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [record, setRecord] = useState<TemplateDesignerRecord | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [rollingBack, setRollingBack] = useState(false);\n\n useEffect((): void => {\n void refreshVersions();\n }, [templateId]);\n\n const rows = useMemo(\n (): VersionRow[] =>\n (record?.versions ?? []).map((version) => ({\n formVersion:\n record?.formVersions.find(\n (formVersion) => formVersion.id === version.formDefinitionVersionId,\n )?.label ?? '未綁定',\n key: version.id,\n publishedAt: formatDateTime(version.publishedAt),\n status: version.status,\n updatedAt: formatDateTime(version.updatedAt),\n version: `v${version.version}`,\n versionId: version.id,\n })),\n [record],\n );\n const columns = useMemo(\n (): TableColumn<VersionRow>[] => [\n { dataIndex: 'version', key: 'version', title: '版本', width: 100 },\n { dataIndex: 'status', key: 'status', title: '狀態', width: 140 },\n {\n dataIndex: 'formVersion',\n key: 'formVersion',\n title: '表單版本',\n width: 220,\n },\n {\n dataIndex: 'publishedAt',\n key: 'publishedAt',\n title: '發布時間',\n width: 200,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 200,\n },\n ],\n [],\n );\n const actions = useMemo(\n (): TableActions<VersionRow> => ({\n render: (row): ReturnType<TableActions<VersionRow>['render']> => [\n {\n disabled: (): boolean => rollingBack || row.status === 'DRAFT',\n name: 'Rollback',\n onClick: (): void => void handleRollback(row.versionId),\n },\n ],\n variant: 'base-secondary',\n width: 104,\n }),\n [rollingBack],\n );\n\n async function refreshVersions(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n setRecord(await readTemplateDesigner(templateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleRollback(versionId: string): Promise<void> {\n setRollingBack(true);\n setError(null);\n\n try {\n await rollbackApprovalTemplateVersion(versionId);\n await refreshVersions();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setRollingBack(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"查看發布、歸檔與 rollback 狀態。\"\n title={record?.template.name ?? '模板版本'}\n >\n <Button\n onClick={(): void =>\n router.push(routes.templateDesigner(templateId))\n }\n variant=\"base-secondary\"\n >\n 回設計器\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":";;;;;;;;;;AAsCA,SAAgB,EAAqB,EACnC,iBAC0C;CAC1C,IAAM,IAAS,EAAiB,GAC1B,IAAS,EAAa,GACtB,CAAC,GAAQ,KAAa,EAAwC,IAAI,GAClE,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAS,KAAc,EAAS,EAAI,GACrC,CAAC,GAAa,KAAkB,EAAS,EAAK;CAEpD,QAAsB;EACpB,EAAqB;CACvB,GAAG,CAAC,CAAU,CAAC;CAEf,IAAM,IAAO,SAER,GAAQ,YAAY,CAAC,GAAG,KAAK,OAAa;EACzC,aACE,GAAQ,aAAa,MAClB,MAAgB,EAAY,OAAO,EAAQ,uBAC9C,GAAG,SAAS;EACd,KAAK,EAAQ;EACb,aAAa,EAAe,EAAQ,WAAW;EAC/C,QAAQ,EAAQ;EAChB,WAAW,EAAe,EAAQ,SAAS;EAC3C,SAAS,IAAI,EAAQ;EACrB,WAAW,EAAQ;CACrB,EAAE,GACJ,CAAC,CAAM,CACT,GACM,IAAU,QACmB;EAC/B;GAAE,WAAW;GAAW,KAAK;GAAW,OAAO;GAAM,OAAO;EAAI;EAChE;GAAE,WAAW;GAAU,KAAK;GAAU,OAAO;GAAM,OAAO;EAAI;EAC9D;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH,GACM,IAAU,SACmB;EAC/B,SAAS,MAAwD,CAC/D;GACE,gBAAyB,KAAe,EAAI,WAAW;GACvD,MAAM;GACN,eAAqB,KAAK,EAAe,EAAI,SAAS;EACxD,CACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAAC,CAAW,CACd;CAEA,eAAe,IAAiC;EAE9C,AADA,EAAW,EAAI,GACf,EAAS,IAAI;EAEb,IAAI;GACF,EAAU,MAAM,EAAqB,CAAU,CAAC;EAClD,SAAS,GAAuB;GAC9B,EAAS,EAAiB,CAAY,CAAC;EACzC,UAAU;GACR,EAAW,EAAK;EAClB;CACF;CAEA,eAAe,EAAe,GAAkC;EAE9D,AADA,EAAe,EAAI,GACnB,EAAS,IAAI;EAEb,IAAI;GAEF,AADA,MAAM,EAAgC,CAAS,GAC/C,MAAM,EAAgB;EACxB,SAAS,GAAuB;GAC9B,EAAS,EAAiB,CAAY,CAAC;EACzC,UAAU;GACR,EAAe,EAAK;EACtB;CACF;CAEA,OACE,kBAAA,GAAA,EAAA,UAAA,CACI,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;EACE,aAAY;EACZ,OAAO,GAAQ,SAAS,QAAQ;YAEhC,kBAAC,GAAD;GACE,eACE,EAAO,KAAK,EAAO,iBAAiB,CAAU,CAAC;GAEjD,SAAQ;aACT;EAEO,CAAA;CACK,CAAA,EACL,CAAA,GAEZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA,CACG,IACC,kBAAC,GAAD;EAAY,OAAM;EAAa,SAAQ;YACpC;CACS,CAAA,IACV,MACJ,kBAAC,GAAD;EACW;EACA;EACT,YAAY;EACZ,WAAA;EACS;CACV,CAAA,CACM,EAAA,CAAA,EACG,CAAA,CACd,EAAA,CAAA;AAER;AAEA,SAAS,EAAiB,GAAwB;CAChD,OAAO,aAAiB,QAAQ,EAAM,UAAU;AAClD"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rytass/bpm-core-react",
3
- "version": "0.3.8",
4
- "description": "BPM approval workflow React components and views for the Rytass BPM stack. Self-contained AuthProvider, NotificationDrawer, AppNavigation, plus full views for inbox / instances / templates / forms / admin / settings that compose on top of Mezzanine UI and the BPM client functions.",
3
+ "version": "0.4.1",
4
+ "description": "BPM approval workflow React components and views for the Rytass BPM stack. Ships AuthProvider, NotificationDrawer + bell widget, host-facing hooks (useBPMMember / useBPMLogout / useBPMRoutes), and full page-body views for inbox / instances / templates / forms / admin / settings on top of Mezzanine UI and the BPM client functions. The host owns the navigation shell — BPM does not bundle a layout.",
5
5
  "keywords": [
6
6
  "bpm",
7
7
  "approval",
@@ -1 +0,0 @@
1
- .bpm_logo_QvBLU{object-fit:contain;width:24px;height:24px;margin:auto;display:block}.bpm_notificationBell_W-wl7{display:inline-flex;position:relative}.bpm_notificationBadge_Gy3Eq{color:#fff;pointer-events:none;background:#d92d20;border:1px solid #fff;border-radius:999px;justify-content:center;align-items:center;min-width:16px;height:16px;padding:0 4px;font-size:10px;font-weight:600;line-height:1;display:inline-flex;position:absolute;top:-4px;right:-4px}
@@ -1,268 +0,0 @@
1
- "use client";
2
- import { a as e, n as t } from "./auth-provider-Bnox5gsx.js";
3
- import { r as n } from "./routes-config-dxahImVe.js";
4
- import { createContext as r, useCallback as i, useContext as a, useEffect as o, useMemo as s, useState as c } from "react";
5
- import { Layout as l, Navigation as u, NavigationFooter as d, NavigationHeader as f, NavigationIconButton as p, NavigationOption as m, NavigationOptionCategory as h, NavigationUserMenu as g } from "@mezzanine-ui/react";
6
- import { logoutApi as _ } from "@rytass/bpm-core-client";
7
- import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
8
- import { readUnreadNotificationCount as x } from "@rytass/bpm-core-client/workflow";
9
- import { FileIcon as S, FolderIcon as C, HomeIcon as w, ListIcon as T, LogoutIcon as E, MailIcon as D, MailUnreadIcon as O, NotificationUnreadIcon as k, SearchIcon as A, ShareIcon as j, SwitchHorizontalIcon as M, SystemIcon as N, UserIcon as P } from "@mezzanine-ui/icons";
10
- import '../app-navigation.css';//#region src/lib/notification-drawer-provider.tsx
11
- var F = r(null);
12
- function I({ children: e }) {
13
- let [t, n] = c(!1), r = i(() => {
14
- n(!0);
15
- }, []), a = i(() => {
16
- n(!1);
17
- }, []), o = i(() => {
18
- n((e) => !e);
19
- }, []), l = s(() => ({
20
- close: a,
21
- isOpen: t,
22
- open: r,
23
- toggle: o
24
- }), [
25
- a,
26
- t,
27
- r,
28
- o
29
- ]);
30
- return /* @__PURE__ */ y(F.Provider, {
31
- value: l,
32
- children: e
33
- });
34
- }
35
- function L() {
36
- return a(F) || {
37
- close: () => void 0,
38
- isOpen: !1,
39
- open: () => void 0,
40
- toggle: () => void 0
41
- };
42
- }
43
- //#endregion
44
- //#region src/lib/notification-unread-provider.tsx
45
- var R = r(null);
46
- function z({ children: e }) {
47
- let { member: n } = t(), r = n?.memberId ?? null, [a, l] = c(0), u = i(async () => {
48
- if (!r) return l(0), 0;
49
- let e = await x(r);
50
- return l(e), e;
51
- }, [r]);
52
- o(() => {
53
- let e = !0;
54
- return (async () => {
55
- try {
56
- let t = await u();
57
- e && l(t);
58
- } catch {
59
- e && l(0);
60
- }
61
- })(), () => {
62
- e = !1;
63
- };
64
- }, [u]);
65
- let d = s(() => ({
66
- refreshUnreadCount: u,
67
- unreadCount: a
68
- }), [u, a]);
69
- return /* @__PURE__ */ y(R.Provider, {
70
- value: d,
71
- children: e
72
- });
73
- }
74
- function B() {
75
- return a(R) || {
76
- refreshUnreadCount: async () => 0,
77
- unreadCount: 0
78
- };
79
- }
80
- var V = {
81
- logo: "bpm_logo_QvBLU",
82
- notificationBell: "bpm_notificationBell_W-wl7",
83
- notificationBadge: "bpm_notificationBadge_Gy3Eq"
84
- };
85
- //#endregion
86
- //#region src/components/app-navigation.tsx
87
- function H(e) {
88
- return [
89
- {
90
- title: "我的工作",
91
- items: [
92
- {
93
- href: e.dashboard(),
94
- icon: w,
95
- label: "工作台"
96
- },
97
- {
98
- href: e.inbox(),
99
- icon: O,
100
- label: "我的待簽"
101
- },
102
- {
103
- href: e.sent(),
104
- icon: D,
105
- label: "我發起的"
106
- },
107
- {
108
- href: e.cc(),
109
- icon: j,
110
- label: "抄送給我"
111
- }
112
- ]
113
- },
114
- {
115
- title: "查詢與代理",
116
- items: [{
117
- href: e.search(),
118
- icon: A,
119
- label: "搜尋"
120
- }, {
121
- href: e.delegations(),
122
- icon: M,
123
- label: "個人代理"
124
- }]
125
- },
126
- {
127
- title: "簽核設計",
128
- items: [
129
- {
130
- href: e.templates(),
131
- icon: C,
132
- label: "簽核模板",
133
- requiresAdmin: !0
134
- },
135
- {
136
- href: e.templateCategories(),
137
- icon: T,
138
- label: "模板分類",
139
- requiresAdmin: !0
140
- },
141
- {
142
- href: e.forms(),
143
- icon: S,
144
- label: "表單設計",
145
- requiresAdmin: !0
146
- }
147
- ]
148
- },
149
- {
150
- title: "系統管理",
151
- items: [
152
- {
153
- href: e.adminOrgs(),
154
- icon: N,
155
- label: "組織管理",
156
- requiresAdmin: !0
157
- },
158
- {
159
- href: e.adminUsers(),
160
- icon: P,
161
- label: "會員對照",
162
- requiresAdmin: !0
163
- },
164
- {
165
- href: e.adminDelegations(),
166
- icon: j,
167
- label: "代理設定",
168
- requiresAdmin: !0
169
- }
170
- ]
171
- }
172
- ];
173
- }
174
- function U({ activeHref: r, logoSrc: i = "/rytass-logo.png", title: a = "BPM Admin", groups: o, children: s }) {
175
- let c = e(), v = n(), { member: x } = t(), { unreadCount: S } = B(), C = r ?? c.pathname ?? "", w = W(x), T = (o ?? H(v)).map((e) => ({
176
- title: e.title,
177
- items: e.items.filter((e) => !e.requiresAdmin || w)
178
- })).filter((e) => e.items.length > 0), D = async () => {
179
- await _(), c.replace("/login");
180
- };
181
- return /* @__PURE__ */ b(l, { children: [/* @__PURE__ */ y(u, {
182
- exactActivatedMatch: !0,
183
- children: [
184
- /* @__PURE__ */ y(f, {
185
- title: a,
186
- children: /* @__PURE__ */ y("img", {
187
- alt: "",
188
- className: V.logo,
189
- height: 24,
190
- src: i,
191
- width: 24
192
- })
193
- }, "header"),
194
- ...T.map((e) => /* @__PURE__ */ y(h, {
195
- title: e.title,
196
- children: e.items.map((e) => /* @__PURE__ */ y(m, {
197
- active: e.href === C,
198
- href: e.href,
199
- icon: e.icon,
200
- title: e.label
201
- }, e.href))
202
- }, e.title)),
203
- /* @__PURE__ */ b(d, { children: [
204
- /* @__PURE__ */ y(g, {
205
- options: [{
206
- id: "notification-settings",
207
- name: "通知設定"
208
- }, {
209
- id: "logout",
210
- name: "登出"
211
- }],
212
- onSelect: (e) => {
213
- if (e.id === "notification-settings") {
214
- c.push(v.notificationSettings());
215
- return;
216
- }
217
- e.id === "logout" && D();
218
- },
219
- children: /* @__PURE__ */ y(K, {})
220
- }),
221
- /* @__PURE__ */ y(G, { unreadCount: S }),
222
- /* @__PURE__ */ y(p, {
223
- "aria-label": "登出",
224
- icon: E,
225
- onClick: () => {
226
- D();
227
- },
228
- title: "登出",
229
- type: "button"
230
- })
231
- ] }, "footer")
232
- ]
233
- }), /* @__PURE__ */ y(l.Main, { children: s })] });
234
- }
235
- function W(e) {
236
- return e ? (e.roles ?? []).includes("BPM_ADMIN") || (e.permissions ?? []).some((e) => [
237
- "bpm:*",
238
- "bpm:admin",
239
- "bpm.admin",
240
- "bpm:admin:*"
241
- ].includes(e)) : !1;
242
- }
243
- function G({ unreadCount: e }) {
244
- let { open: t } = L();
245
- return /* @__PURE__ */ b("span", {
246
- className: V.notificationBell,
247
- children: [/* @__PURE__ */ y(p, {
248
- "aria-label": e > 0 ? `通知中心,${e} 則未讀` : "通知中心",
249
- icon: k,
250
- onClick: () => {
251
- t();
252
- },
253
- title: "通知中心",
254
- type: "button"
255
- }), e > 0 ? /* @__PURE__ */ y("span", {
256
- className: V.notificationBadge,
257
- children: e > 99 ? "99+" : e
258
- }) : null]
259
- });
260
- }
261
- function K() {
262
- let { member: e } = t();
263
- return e ? /* @__PURE__ */ y(v, { children: e.name }) : null;
264
- }
265
- //#endregion
266
- export { L as a, I as i, z as n, B as r, U as t };
267
-
268
- //# sourceMappingURL=app-navigation-BSkMsEhy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-navigation-BSkMsEhy.js","names":[],"sources":["../../src/lib/notification-drawer-provider.tsx","../../src/lib/notification-unread-provider.tsx","../../src/components/app-navigation.module.scss","../../src/components/app-navigation.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\ninterface NotificationDrawerContextValue {\n readonly close: () => void;\n readonly isOpen: boolean;\n readonly open: () => void;\n readonly toggle: () => void;\n}\n\nconst NotificationDrawerContext =\n createContext<NotificationDrawerContextValue | null>(null);\n\ninterface NotificationDrawerProviderProps {\n readonly children: ReactNode;\n}\n\n/**\n * Controls the open/closed state of the BPM notification drawer. Wraps\n * children with a context that `<NotificationDrawer />` reads to mount /\n * hide itself, and that `<AppLayout />` reads to open the drawer when\n * the bell icon is clicked.\n *\n * When used outside this provider, the returned hook is a safe no-op so\n * components don't crash in test or storybook environments.\n */\nexport function NotificationDrawerProvider({\n children,\n}: NotificationDrawerProviderProps): ReactElement {\n const [isOpen, setIsOpen] = useState(false);\n\n const open = useCallback((): void => {\n setIsOpen(true);\n }, []);\n const close = useCallback((): void => {\n setIsOpen(false);\n }, []);\n const toggle = useCallback((): void => {\n setIsOpen((current) => !current);\n }, []);\n\n const value = useMemo<NotificationDrawerContextValue>(\n () => ({ close, isOpen, open, toggle }),\n [close, isOpen, open, toggle],\n );\n\n return (\n <NotificationDrawerContext.Provider value={value}>\n {children}\n </NotificationDrawerContext.Provider>\n );\n}\n\n/**\n * Read the BPM notification drawer's open state and control helpers.\n * Returns a no-op stub when used outside `<NotificationDrawerProvider>`.\n */\nexport function useNotificationDrawer(): NotificationDrawerContextValue {\n const context = useContext(NotificationDrawerContext);\n if (!context) {\n return {\n close: (): void => undefined,\n isOpen: false,\n open: (): void => undefined,\n toggle: (): void => undefined,\n };\n }\n return context;\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 { readUnreadNotificationCount } from '@rytass/bpm-core-client/workflow';\nimport { useAuth } from './auth-provider';\n\ninterface NotificationUnreadContextValue {\n readonly refreshUnreadCount: () => Promise<number>;\n readonly unreadCount: number;\n}\n\nconst NotificationUnreadContext =\n createContext<NotificationUnreadContextValue | null>(null);\n\ninterface NotificationUnreadProviderProps {\n readonly children: ReactNode;\n}\n\n/**\n * Polls BPM for the current member's unread notification count via\n * `readUnreadNotificationCount` and exposes it through context for\n * `<AppLayout />` (bell badge) and `<NotificationDrawer />` (header\n * count). Refresh is triggered on mount and whenever the auth member id\n * changes; consumers can call `refreshUnreadCount()` after acknowledging\n * a notification.\n */\nexport function NotificationUnreadProvider({\n children,\n}: NotificationUnreadProviderProps): ReactElement {\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [unreadCount, setUnreadCount] = useState(0);\n\n const refreshUnreadCount = useCallback(async (): Promise<number> => {\n if (!currentMemberId) {\n setUnreadCount(0);\n return 0;\n }\n const next = await readUnreadNotificationCount(currentMemberId);\n setUnreadCount(next);\n return next;\n }, [currentMemberId]);\n\n useEffect((): (() => void) => {\n let active = true;\n void (async () => {\n try {\n const next = await refreshUnreadCount();\n if (active) setUnreadCount(next);\n } catch {\n if (active) setUnreadCount(0);\n }\n })();\n return (): void => {\n active = false;\n };\n }, [refreshUnreadCount]);\n\n const value = useMemo<NotificationUnreadContextValue>(\n () => ({ refreshUnreadCount, unreadCount }),\n [refreshUnreadCount, unreadCount],\n );\n\n return (\n <NotificationUnreadContext.Provider value={value}>\n {children}\n </NotificationUnreadContext.Provider>\n );\n}\n\n/**\n * Read the current unread-notification count and a manual refresh helper.\n * Returns a zero/no-op stub when used outside\n * `<NotificationUnreadProvider>`.\n */\nexport function useNotificationUnread(): NotificationUnreadContextValue {\n const context = useContext(NotificationUnreadContext);\n if (!context) {\n return {\n refreshUnreadCount: async (): Promise<number> => 0,\n unreadCount: 0,\n };\n }\n return context;\n}\n",".logo {\n display: block;\n height: 24px;\n margin: auto;\n object-fit: contain;\n width: 24px;\n}\n\n.notificationBell {\n display: inline-flex;\n position: relative;\n}\n\n.notificationBadge {\n align-items: center;\n background: #d92d20;\n border: 1px solid #fff;\n border-radius: 999px;\n color: #fff;\n display: inline-flex;\n font-size: 10px;\n font-weight: 600;\n height: 16px;\n justify-content: center;\n line-height: 1;\n min-width: 16px;\n padding: 0 4px;\n pointer-events: none;\n position: absolute;\n right: -4px;\n top: -4px;\n}\n","'use client';\n\nimport type { ReactElement, ReactNode } from 'react';\nimport {\n Layout,\n Navigation,\n NavigationFooter,\n NavigationHeader,\n NavigationIconButton,\n NavigationOption,\n NavigationOptionCategory,\n NavigationUserMenu,\n} from '@mezzanine-ui/react';\nimport {\n FileIcon,\n FolderIcon,\n HomeIcon,\n ListIcon,\n LogoutIcon,\n MailIcon,\n MailUnreadIcon,\n NotificationUnreadIcon,\n SearchIcon,\n ShareIcon,\n SystemIcon,\n SwitchHorizontalIcon,\n UserIcon,\n type IconDefinition,\n} from '@mezzanine-ui/icons';\nimport { logoutApi } from '@rytass/bpm-core-client';\nimport { useAuth } from '../lib/auth-provider';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { useNotificationDrawer } from '../lib/notification-drawer-provider';\nimport { useNotificationUnread } from '../lib/notification-unread-provider';\nimport { useBPMRoutes, type BPMRoutes } from '../lib/routes-config';\nimport styles from './app-navigation.module.scss';\n\ninterface NavigationItem {\n readonly href: string;\n readonly icon: IconDefinition;\n readonly label: string;\n readonly requiresAdmin?: boolean;\n}\n\nexport interface AppNavigationGroup {\n readonly title: string;\n readonly items: readonly NavigationItem[];\n}\n\nfunction createDefaultNavigationGroups(\n routes: BPMRoutes,\n): readonly AppNavigationGroup[] {\n return [\n {\n title: '我的工作',\n items: [\n { href: routes.dashboard(), icon: HomeIcon, label: '工作台' },\n { href: routes.inbox(), icon: MailUnreadIcon, label: '我的待簽' },\n { href: routes.sent(), icon: MailIcon, label: '我發起的' },\n { href: routes.cc(), icon: ShareIcon, label: '抄送給我' },\n ],\n },\n {\n title: '查詢與代理',\n items: [\n { href: routes.search(), icon: SearchIcon, label: '搜尋' },\n { href: routes.delegations(), icon: SwitchHorizontalIcon, label: '個人代理' },\n ],\n },\n {\n title: '簽核設計',\n items: [\n { href: routes.templates(), icon: FolderIcon, label: '簽核模板', requiresAdmin: true },\n { href: routes.templateCategories(), icon: ListIcon, label: '模板分類', requiresAdmin: true },\n { href: routes.forms(), icon: FileIcon, label: '表單設計', requiresAdmin: true },\n ],\n },\n {\n title: '系統管理',\n items: [\n { href: routes.adminOrgs(), icon: SystemIcon, label: '組織管理', requiresAdmin: true },\n { href: routes.adminUsers(), icon: UserIcon, label: '會員對照', requiresAdmin: true },\n { href: routes.adminDelegations(), icon: ShareIcon, label: '代理設定', requiresAdmin: true },\n ],\n },\n ];\n}\n\nexport interface AppLayoutProps {\n /** Override the active href detection (defaults to router's pathname). */\n readonly activeHref?: string;\n /** Logo image URL displayed in the sidebar header. */\n readonly logoSrc?: string;\n /** Sidebar title (defaults to \"BPM Admin\"). */\n readonly title?: string;\n /**\n * Override the entire navigation tree. When omitted, the default 4-group\n * BPM admin nav (`我的工作` / `查詢與代理` / `簽核設計` / `系統管理`) is used.\n */\n readonly groups?: readonly AppNavigationGroup[];\n /** Page content rendered inside the Mezzanine `<Layout.Main>` slot. */\n readonly children?: ReactNode;\n}\n\n/**\n * BPM admin layout shell — composes Mezzanine `<Layout>` + `<Navigation>`\n * with the default 4-group BPM tree, and exposes a `children` prop that\n * fills the `<Layout.Main>` slot.\n *\n * Why a single component instead of a `<Navigation>` wrapper: Mezzanine\n * `<Layout>` discovers its slot children by component-identity match\n * (`child.type === Navigation` / `LayoutMain` / etc.). Any custom wrapper\n * around `<Navigation>` is silently dropped, so the sidebar disappears.\n * Keeping the `<Navigation>` element as a direct child of `<Layout>` here\n * is mandatory for the slot to register.\n */\nexport function AppLayout({\n activeHref,\n logoSrc = '/rytass-logo.png',\n title = 'BPM Admin',\n groups,\n children,\n}: AppLayoutProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const { unreadCount } = useNotificationUnread();\n const resolvedActive = activeHref ?? router.pathname ?? '';\n const isAdmin = isAdminMember(member);\n const resolvedGroups = groups ?? createDefaultNavigationGroups(routes);\n const visibleGroups = resolvedGroups\n .map((group) => ({\n title: group.title,\n items: group.items.filter((item) => !item.requiresAdmin || isAdmin),\n }))\n .filter((group) => group.items.length > 0);\n\n const handleLogout = async (): Promise<void> => {\n await logoutApi();\n router.replace('/login');\n };\n\n const navigationChildren = [\n <NavigationHeader key=\"header\" title={title}>\n <img alt=\"\" className={styles.logo} height={24} src={logoSrc} width={24} />\n </NavigationHeader>,\n ...visibleGroups.map((group) => (\n <NavigationOptionCategory key={group.title} title={group.title}>\n {group.items.map((item) => (\n <NavigationOption\n active={item.href === resolvedActive}\n href={item.href}\n icon={item.icon}\n key={item.href}\n title={item.label}\n />\n ))}\n </NavigationOptionCategory>\n )),\n <NavigationFooter key=\"footer\">\n <NavigationUserMenu\n options={[\n { id: 'notification-settings', name: '通知設定' },\n { id: 'logout', name: '登出' },\n ]}\n onSelect={(option): void => {\n if (option.id === 'notification-settings') {\n router.push(routes.notificationSettings());\n return;\n }\n if (option.id === 'logout') {\n void handleLogout();\n }\n }}\n >\n <NavigationMemberName />\n </NavigationUserMenu>\n <NotificationBell unreadCount={unreadCount} />\n <NavigationIconButton\n aria-label=\"登出\"\n icon={LogoutIcon}\n onClick={(): void => {\n void handleLogout();\n }}\n title=\"登出\"\n type=\"button\"\n />\n </NavigationFooter>,\n ];\n\n return (\n <Layout>\n <Navigation exactActivatedMatch>{navigationChildren}</Navigation>\n <Layout.Main>{children}</Layout.Main>\n </Layout>\n );\n}\n\nfunction isAdminMember(member: ReturnType<typeof useAuth>['member']): boolean {\n if (!member) return false;\n return (\n (member.roles ?? []).includes('BPM_ADMIN') ||\n (member.permissions ?? []).some((p) =>\n ['bpm:*', 'bpm:admin', 'bpm.admin', 'bpm:admin:*'].includes(p),\n )\n );\n}\n\nfunction NotificationBell({\n unreadCount,\n}: {\n readonly unreadCount: number;\n}): ReactElement {\n const { open } = useNotificationDrawer();\n return (\n <span className={styles.notificationBell}>\n <NavigationIconButton\n aria-label={unreadCount > 0 ? `通知中心,${unreadCount} 則未讀` : '通知中心'}\n icon={NotificationUnreadIcon}\n onClick={(): void => {\n open();\n }}\n title=\"通知中心\"\n type=\"button\"\n />\n {unreadCount > 0 ? (\n <span className={styles.notificationBadge}>\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n ) : null}\n </span>\n );\n}\n\nfunction NavigationMemberName(): ReactElement | null {\n const { member } = useAuth();\n if (!member) return null;\n return <>{member.name}</>;\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use client";require('../app-navigation.css');var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require("./auth-provider-BV8Iiwfb.cjs"),l=require("./routes-config-2aKbWq2H.cjs");let u=require("react"),d=require("@mezzanine-ui/react"),f=require("@rytass/bpm-core-client"),p=require("react/jsx-runtime"),m=require("@rytass/bpm-core-client/workflow"),h=require("@mezzanine-ui/icons");var g=(0,u.createContext)(null);function _({children:e}){let[t,n]=(0,u.useState)(!1),r=(0,u.useCallback)(()=>{n(!0)},[]),i=(0,u.useCallback)(()=>{n(!1)},[]),a=(0,u.useCallback)(()=>{n(e=>!e)},[]),o=(0,u.useMemo)(()=>({close:i,isOpen:t,open:r,toggle:a}),[i,t,r,a]);return(0,p.jsx)(g.Provider,{value:o,children:e})}function v(){return(0,u.useContext)(g)||{close:()=>void 0,isOpen:!1,open:()=>void 0,toggle:()=>void 0}}var y=(0,u.createContext)(null);function b({children:e}){let{member:t}=c.n(),n=t?.memberId??null,[r,i]=(0,u.useState)(0),a=(0,u.useCallback)(async()=>{if(!n)return i(0),0;let e=await(0,m.readUnreadNotificationCount)(n);return i(e),e},[n]);(0,u.useEffect)(()=>{let e=!0;return(async()=>{try{let t=await a();e&&i(t)}catch{e&&i(0)}})(),()=>{e=!1}},[a]);let o=(0,u.useMemo)(()=>({refreshUnreadCount:a,unreadCount:r}),[a,r]);return(0,p.jsx)(y.Provider,{value:o,children:e})}function x(){return(0,u.useContext)(y)||{refreshUnreadCount:async()=>0,unreadCount:0}}var S={logo:`bpm_logo_QvBLU`,notificationBell:`bpm_notificationBell_W-wl7`,notificationBadge:`bpm_notificationBadge_Gy3Eq`};function C(e){return[{title:`我的工作`,items:[{href:e.dashboard(),icon:h.HomeIcon,label:`工作台`},{href:e.inbox(),icon:h.MailUnreadIcon,label:`我的待簽`},{href:e.sent(),icon:h.MailIcon,label:`我發起的`},{href:e.cc(),icon:h.ShareIcon,label:`抄送給我`}]},{title:`查詢與代理`,items:[{href:e.search(),icon:h.SearchIcon,label:`搜尋`},{href:e.delegations(),icon:h.SwitchHorizontalIcon,label:`個人代理`}]},{title:`簽核設計`,items:[{href:e.templates(),icon:h.FolderIcon,label:`簽核模板`,requiresAdmin:!0},{href:e.templateCategories(),icon:h.ListIcon,label:`模板分類`,requiresAdmin:!0},{href:e.forms(),icon:h.FileIcon,label:`表單設計`,requiresAdmin:!0}]},{title:`系統管理`,items:[{href:e.adminOrgs(),icon:h.SystemIcon,label:`組織管理`,requiresAdmin:!0},{href:e.adminUsers(),icon:h.UserIcon,label:`會員對照`,requiresAdmin:!0},{href:e.adminDelegations(),icon:h.ShareIcon,label:`代理設定`,requiresAdmin:!0}]}]}function w({activeHref:e,logoSrc:t=`/rytass-logo.png`,title:n=`BPM Admin`,groups:r,children:i}){let a=c.a(),o=l.r(),{member:s}=c.n(),{unreadCount:u}=x(),m=e??a.pathname??``,g=T(s),_=(r??C(o)).map(e=>({title:e.title,items:e.items.filter(e=>!e.requiresAdmin||g)})).filter(e=>e.items.length>0),v=async()=>{await(0,f.logoutApi)(),a.replace(`/login`)};return(0,p.jsxs)(d.Layout,{children:[(0,p.jsx)(d.Navigation,{exactActivatedMatch:!0,children:[(0,p.jsx)(d.NavigationHeader,{title:n,children:(0,p.jsx)(`img`,{alt:``,className:S.logo,height:24,src:t,width:24})},`header`),..._.map(e=>(0,p.jsx)(d.NavigationOptionCategory,{title:e.title,children:e.items.map(e=>(0,p.jsx)(d.NavigationOption,{active:e.href===m,href:e.href,icon:e.icon,title:e.label},e.href))},e.title)),(0,p.jsxs)(d.NavigationFooter,{children:[(0,p.jsx)(d.NavigationUserMenu,{options:[{id:`notification-settings`,name:`通知設定`},{id:`logout`,name:`登出`}],onSelect:e=>{if(e.id===`notification-settings`){a.push(o.notificationSettings());return}e.id===`logout`&&v()},children:(0,p.jsx)(D,{})}),(0,p.jsx)(E,{unreadCount:u}),(0,p.jsx)(d.NavigationIconButton,{"aria-label":`登出`,icon:h.LogoutIcon,onClick:()=>{v()},title:`登出`,type:`button`})]},`footer`)]}),(0,p.jsx)(d.Layout.Main,{children:i})]})}function T(e){return e?(e.roles??[]).includes(`BPM_ADMIN`)||(e.permissions??[]).some(e=>[`bpm:*`,`bpm:admin`,`bpm.admin`,`bpm:admin:*`].includes(e)):!1}function E({unreadCount:e}){let{open:t}=v();return(0,p.jsxs)(`span`,{className:S.notificationBell,children:[(0,p.jsx)(d.NavigationIconButton,{"aria-label":e>0?`通知中心,${e} 則未讀`:`通知中心`,icon:h.NotificationUnreadIcon,onClick:()=>{t()},title:`通知中心`,type:`button`}),e>0?(0,p.jsx)(`span`,{className:S.notificationBadge,children:e>99?`99+`:e}):null]})}function D(){let{member:e}=c.n();return e?(0,p.jsx)(p.Fragment,{children:e.name}):null}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return w}});
2
- //# sourceMappingURL=app-navigation-KnlJCUp1.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-navigation-KnlJCUp1.cjs","names":[],"sources":["../../src/lib/notification-drawer-provider.tsx","../../src/lib/notification-unread-provider.tsx","../../src/components/app-navigation.module.scss","../../src/components/app-navigation.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\ninterface NotificationDrawerContextValue {\n readonly close: () => void;\n readonly isOpen: boolean;\n readonly open: () => void;\n readonly toggle: () => void;\n}\n\nconst NotificationDrawerContext =\n createContext<NotificationDrawerContextValue | null>(null);\n\ninterface NotificationDrawerProviderProps {\n readonly children: ReactNode;\n}\n\n/**\n * Controls the open/closed state of the BPM notification drawer. Wraps\n * children with a context that `<NotificationDrawer />` reads to mount /\n * hide itself, and that `<AppLayout />` reads to open the drawer when\n * the bell icon is clicked.\n *\n * When used outside this provider, the returned hook is a safe no-op so\n * components don't crash in test or storybook environments.\n */\nexport function NotificationDrawerProvider({\n children,\n}: NotificationDrawerProviderProps): ReactElement {\n const [isOpen, setIsOpen] = useState(false);\n\n const open = useCallback((): void => {\n setIsOpen(true);\n }, []);\n const close = useCallback((): void => {\n setIsOpen(false);\n }, []);\n const toggle = useCallback((): void => {\n setIsOpen((current) => !current);\n }, []);\n\n const value = useMemo<NotificationDrawerContextValue>(\n () => ({ close, isOpen, open, toggle }),\n [close, isOpen, open, toggle],\n );\n\n return (\n <NotificationDrawerContext.Provider value={value}>\n {children}\n </NotificationDrawerContext.Provider>\n );\n}\n\n/**\n * Read the BPM notification drawer's open state and control helpers.\n * Returns a no-op stub when used outside `<NotificationDrawerProvider>`.\n */\nexport function useNotificationDrawer(): NotificationDrawerContextValue {\n const context = useContext(NotificationDrawerContext);\n if (!context) {\n return {\n close: (): void => undefined,\n isOpen: false,\n open: (): void => undefined,\n toggle: (): void => undefined,\n };\n }\n return context;\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 { readUnreadNotificationCount } from '@rytass/bpm-core-client/workflow';\nimport { useAuth } from './auth-provider';\n\ninterface NotificationUnreadContextValue {\n readonly refreshUnreadCount: () => Promise<number>;\n readonly unreadCount: number;\n}\n\nconst NotificationUnreadContext =\n createContext<NotificationUnreadContextValue | null>(null);\n\ninterface NotificationUnreadProviderProps {\n readonly children: ReactNode;\n}\n\n/**\n * Polls BPM for the current member's unread notification count via\n * `readUnreadNotificationCount` and exposes it through context for\n * `<AppLayout />` (bell badge) and `<NotificationDrawer />` (header\n * count). Refresh is triggered on mount and whenever the auth member id\n * changes; consumers can call `refreshUnreadCount()` after acknowledging\n * a notification.\n */\nexport function NotificationUnreadProvider({\n children,\n}: NotificationUnreadProviderProps): ReactElement {\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [unreadCount, setUnreadCount] = useState(0);\n\n const refreshUnreadCount = useCallback(async (): Promise<number> => {\n if (!currentMemberId) {\n setUnreadCount(0);\n return 0;\n }\n const next = await readUnreadNotificationCount(currentMemberId);\n setUnreadCount(next);\n return next;\n }, [currentMemberId]);\n\n useEffect((): (() => void) => {\n let active = true;\n void (async () => {\n try {\n const next = await refreshUnreadCount();\n if (active) setUnreadCount(next);\n } catch {\n if (active) setUnreadCount(0);\n }\n })();\n return (): void => {\n active = false;\n };\n }, [refreshUnreadCount]);\n\n const value = useMemo<NotificationUnreadContextValue>(\n () => ({ refreshUnreadCount, unreadCount }),\n [refreshUnreadCount, unreadCount],\n );\n\n return (\n <NotificationUnreadContext.Provider value={value}>\n {children}\n </NotificationUnreadContext.Provider>\n );\n}\n\n/**\n * Read the current unread-notification count and a manual refresh helper.\n * Returns a zero/no-op stub when used outside\n * `<NotificationUnreadProvider>`.\n */\nexport function useNotificationUnread(): NotificationUnreadContextValue {\n const context = useContext(NotificationUnreadContext);\n if (!context) {\n return {\n refreshUnreadCount: async (): Promise<number> => 0,\n unreadCount: 0,\n };\n }\n return context;\n}\n",".logo {\n display: block;\n height: 24px;\n margin: auto;\n object-fit: contain;\n width: 24px;\n}\n\n.notificationBell {\n display: inline-flex;\n position: relative;\n}\n\n.notificationBadge {\n align-items: center;\n background: #d92d20;\n border: 1px solid #fff;\n border-radius: 999px;\n color: #fff;\n display: inline-flex;\n font-size: 10px;\n font-weight: 600;\n height: 16px;\n justify-content: center;\n line-height: 1;\n min-width: 16px;\n padding: 0 4px;\n pointer-events: none;\n position: absolute;\n right: -4px;\n top: -4px;\n}\n","'use client';\n\nimport type { ReactElement, ReactNode } from 'react';\nimport {\n Layout,\n Navigation,\n NavigationFooter,\n NavigationHeader,\n NavigationIconButton,\n NavigationOption,\n NavigationOptionCategory,\n NavigationUserMenu,\n} from '@mezzanine-ui/react';\nimport {\n FileIcon,\n FolderIcon,\n HomeIcon,\n ListIcon,\n LogoutIcon,\n MailIcon,\n MailUnreadIcon,\n NotificationUnreadIcon,\n SearchIcon,\n ShareIcon,\n SystemIcon,\n SwitchHorizontalIcon,\n UserIcon,\n type IconDefinition,\n} from '@mezzanine-ui/icons';\nimport { logoutApi } from '@rytass/bpm-core-client';\nimport { useAuth } from '../lib/auth-provider';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { useNotificationDrawer } from '../lib/notification-drawer-provider';\nimport { useNotificationUnread } from '../lib/notification-unread-provider';\nimport { useBPMRoutes, type BPMRoutes } from '../lib/routes-config';\nimport styles from './app-navigation.module.scss';\n\ninterface NavigationItem {\n readonly href: string;\n readonly icon: IconDefinition;\n readonly label: string;\n readonly requiresAdmin?: boolean;\n}\n\nexport interface AppNavigationGroup {\n readonly title: string;\n readonly items: readonly NavigationItem[];\n}\n\nfunction createDefaultNavigationGroups(\n routes: BPMRoutes,\n): readonly AppNavigationGroup[] {\n return [\n {\n title: '我的工作',\n items: [\n { href: routes.dashboard(), icon: HomeIcon, label: '工作台' },\n { href: routes.inbox(), icon: MailUnreadIcon, label: '我的待簽' },\n { href: routes.sent(), icon: MailIcon, label: '我發起的' },\n { href: routes.cc(), icon: ShareIcon, label: '抄送給我' },\n ],\n },\n {\n title: '查詢與代理',\n items: [\n { href: routes.search(), icon: SearchIcon, label: '搜尋' },\n { href: routes.delegations(), icon: SwitchHorizontalIcon, label: '個人代理' },\n ],\n },\n {\n title: '簽核設計',\n items: [\n { href: routes.templates(), icon: FolderIcon, label: '簽核模板', requiresAdmin: true },\n { href: routes.templateCategories(), icon: ListIcon, label: '模板分類', requiresAdmin: true },\n { href: routes.forms(), icon: FileIcon, label: '表單設計', requiresAdmin: true },\n ],\n },\n {\n title: '系統管理',\n items: [\n { href: routes.adminOrgs(), icon: SystemIcon, label: '組織管理', requiresAdmin: true },\n { href: routes.adminUsers(), icon: UserIcon, label: '會員對照', requiresAdmin: true },\n { href: routes.adminDelegations(), icon: ShareIcon, label: '代理設定', requiresAdmin: true },\n ],\n },\n ];\n}\n\nexport interface AppLayoutProps {\n /** Override the active href detection (defaults to router's pathname). */\n readonly activeHref?: string;\n /** Logo image URL displayed in the sidebar header. */\n readonly logoSrc?: string;\n /** Sidebar title (defaults to \"BPM Admin\"). */\n readonly title?: string;\n /**\n * Override the entire navigation tree. When omitted, the default 4-group\n * BPM admin nav (`我的工作` / `查詢與代理` / `簽核設計` / `系統管理`) is used.\n */\n readonly groups?: readonly AppNavigationGroup[];\n /** Page content rendered inside the Mezzanine `<Layout.Main>` slot. */\n readonly children?: ReactNode;\n}\n\n/**\n * BPM admin layout shell — composes Mezzanine `<Layout>` + `<Navigation>`\n * with the default 4-group BPM tree, and exposes a `children` prop that\n * fills the `<Layout.Main>` slot.\n *\n * Why a single component instead of a `<Navigation>` wrapper: Mezzanine\n * `<Layout>` discovers its slot children by component-identity match\n * (`child.type === Navigation` / `LayoutMain` / etc.). Any custom wrapper\n * around `<Navigation>` is silently dropped, so the sidebar disappears.\n * Keeping the `<Navigation>` element as a direct child of `<Layout>` here\n * is mandatory for the slot to register.\n */\nexport function AppLayout({\n activeHref,\n logoSrc = '/rytass-logo.png',\n title = 'BPM Admin',\n groups,\n children,\n}: AppLayoutProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const { unreadCount } = useNotificationUnread();\n const resolvedActive = activeHref ?? router.pathname ?? '';\n const isAdmin = isAdminMember(member);\n const resolvedGroups = groups ?? createDefaultNavigationGroups(routes);\n const visibleGroups = resolvedGroups\n .map((group) => ({\n title: group.title,\n items: group.items.filter((item) => !item.requiresAdmin || isAdmin),\n }))\n .filter((group) => group.items.length > 0);\n\n const handleLogout = async (): Promise<void> => {\n await logoutApi();\n router.replace('/login');\n };\n\n const navigationChildren = [\n <NavigationHeader key=\"header\" title={title}>\n <img alt=\"\" className={styles.logo} height={24} src={logoSrc} width={24} />\n </NavigationHeader>,\n ...visibleGroups.map((group) => (\n <NavigationOptionCategory key={group.title} title={group.title}>\n {group.items.map((item) => (\n <NavigationOption\n active={item.href === resolvedActive}\n href={item.href}\n icon={item.icon}\n key={item.href}\n title={item.label}\n />\n ))}\n </NavigationOptionCategory>\n )),\n <NavigationFooter key=\"footer\">\n <NavigationUserMenu\n options={[\n { id: 'notification-settings', name: '通知設定' },\n { id: 'logout', name: '登出' },\n ]}\n onSelect={(option): void => {\n if (option.id === 'notification-settings') {\n router.push(routes.notificationSettings());\n return;\n }\n if (option.id === 'logout') {\n void handleLogout();\n }\n }}\n >\n <NavigationMemberName />\n </NavigationUserMenu>\n <NotificationBell unreadCount={unreadCount} />\n <NavigationIconButton\n aria-label=\"登出\"\n icon={LogoutIcon}\n onClick={(): void => {\n void handleLogout();\n }}\n title=\"登出\"\n type=\"button\"\n />\n </NavigationFooter>,\n ];\n\n return (\n <Layout>\n <Navigation exactActivatedMatch>{navigationChildren}</Navigation>\n <Layout.Main>{children}</Layout.Main>\n </Layout>\n );\n}\n\nfunction isAdminMember(member: ReturnType<typeof useAuth>['member']): boolean {\n if (!member) return false;\n return (\n (member.roles ?? []).includes('BPM_ADMIN') ||\n (member.permissions ?? []).some((p) =>\n ['bpm:*', 'bpm:admin', 'bpm.admin', 'bpm:admin:*'].includes(p),\n )\n );\n}\n\nfunction NotificationBell({\n unreadCount,\n}: {\n readonly unreadCount: number;\n}): ReactElement {\n const { open } = useNotificationDrawer();\n return (\n <span className={styles.notificationBell}>\n <NavigationIconButton\n aria-label={unreadCount > 0 ? `通知中心,${unreadCount} 則未讀` : '通知中心'}\n icon={NotificationUnreadIcon}\n onClick={(): void => {\n open();\n }}\n title=\"通知中心\"\n type=\"button\"\n />\n {unreadCount > 0 ? (\n <span className={styles.notificationBadge}>\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n ) : null}\n </span>\n );\n}\n\nfunction NavigationMemberName(): ReactElement | null {\n const { member } = useAuth();\n if (!member) return null;\n return <>{member.name}</>;\n}\n"],"mappings":"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"}