@rytass/bpm-core-react 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/dist/chunks/FormBuilderView-B_KGPjlp.cjs +3 -0
  3. package/dist/chunks/FormBuilderView-B_KGPjlp.cjs.map +1 -0
  4. package/dist/chunks/FormBuilderView-D8DrQOXD.js +1090 -0
  5. package/dist/chunks/FormBuilderView-D8DrQOXD.js.map +1 -0
  6. package/dist/chunks/{approval-instance-list-page-UNIIgUZy.cjs → approval-instance-list-page-BMUKxzcz.cjs} +2 -2
  7. package/dist/chunks/{approval-instance-list-page-UNIIgUZy.cjs.map → approval-instance-list-page-BMUKxzcz.cjs.map} +1 -1
  8. package/dist/chunks/{approval-instance-list-page-BtEc8Cs3.js → approval-instance-list-page-YZcGGDD8.js} +3 -3
  9. package/dist/chunks/{approval-instance-list-page-BtEc8Cs3.js.map → approval-instance-list-page-YZcGGDD8.js.map} +1 -1
  10. package/dist/chunks/{auth-provider-D2P-qWmY.cjs → auth-provider-4BeCw7cI.cjs} +2 -2
  11. package/dist/chunks/{auth-provider-D2P-qWmY.cjs.map → auth-provider-4BeCw7cI.cjs.map} +1 -1
  12. package/dist/chunks/{auth-provider-TTO9eNZV.js → auth-provider-B5oPmvk2.js} +2 -2
  13. package/dist/chunks/{auth-provider-TTO9eNZV.js.map → auth-provider-B5oPmvk2.js.map} +1 -1
  14. package/dist/chunks/compose-PMrmi-LE.js +451 -0
  15. package/dist/chunks/compose-PMrmi-LE.js.map +1 -0
  16. package/dist/chunks/compose-ziVbRYdo.cjs +2 -0
  17. package/dist/chunks/compose-ziVbRYdo.cjs.map +1 -0
  18. package/dist/chunks/{dashboard-page-CQRBJxze.js → dashboard-page-DJ9vOPga.js} +4 -4
  19. package/dist/chunks/{dashboard-page-CQRBJxze.js.map → dashboard-page-DJ9vOPga.js.map} +1 -1
  20. package/dist/chunks/{dashboard-page-DrDChhg1.cjs → dashboard-page-DwHQY6Ki.cjs} +2 -2
  21. package/dist/chunks/{dashboard-page-DrDChhg1.cjs.map → dashboard-page-DwHQY6Ki.cjs.map} +1 -1
  22. package/dist/chunks/{delegations-CFXaJrdX.cjs → delegations-C2wLWsDQ.cjs} +2 -2
  23. package/dist/chunks/{delegations-CFXaJrdX.cjs.map → delegations-C2wLWsDQ.cjs.map} +1 -1
  24. package/dist/chunks/{delegations-DwbYkNUg.cjs → delegations-DDEk-WI6.cjs} +2 -2
  25. package/dist/chunks/{delegations-DwbYkNUg.cjs.map → delegations-DDEk-WI6.cjs.map} +1 -1
  26. package/dist/chunks/{delegations-FTLaWo1Y.js → delegations-ZNtodFaD.js} +2 -2
  27. package/dist/chunks/{delegations-FTLaWo1Y.js.map → delegations-ZNtodFaD.js.map} +1 -1
  28. package/dist/chunks/{delegations-D5pPEWsP.js → delegations-iVnRi3QE.js} +2 -2
  29. package/dist/chunks/{delegations-D5pPEWsP.js.map → delegations-iVnRi3QE.js.map} +1 -1
  30. package/dist/chunks/designer-DCn6_v4b.cjs +65 -0
  31. package/dist/chunks/designer-DCn6_v4b.cjs.map +1 -0
  32. package/dist/chunks/designer-mOMxJ0Py.js +2576 -0
  33. package/dist/chunks/designer-mOMxJ0Py.js.map +1 -0
  34. package/dist/chunks/detail-Bml-vXHX.js +1622 -0
  35. package/dist/chunks/detail-Bml-vXHX.js.map +1 -0
  36. package/dist/chunks/detail-CWeCrmtC.cjs +2 -0
  37. package/dist/chunks/detail-CWeCrmtC.cjs.map +1 -0
  38. package/dist/chunks/{login-BfmfCclF.cjs → login-9bCXyjbX.cjs} +2 -2
  39. package/dist/chunks/{login-BfmfCclF.cjs.map → login-9bCXyjbX.cjs.map} +1 -1
  40. package/dist/chunks/{login-xgI4wLHe.js → login-BKxpLibd.js} +3 -3
  41. package/dist/chunks/{login-xgI4wLHe.js.map → login-BKxpLibd.js.map} +1 -1
  42. package/dist/chunks/{notifications-a-FCxV02.cjs → notifications-BKs4--96.cjs} +2 -2
  43. package/dist/chunks/{notifications-a-FCxV02.cjs.map → notifications-BKs4--96.cjs.map} +1 -1
  44. package/dist/chunks/{notifications-BoNa1BXD.js → notifications-CSulztkU.js} +2 -2
  45. package/dist/chunks/{notifications-BoNa1BXD.js.map → notifications-CSulztkU.js.map} +1 -1
  46. package/dist/chunks/router-adapter--gYs13E8.cjs +2 -0
  47. package/dist/chunks/{router-adapter-BybHrCNP.cjs.map → router-adapter--gYs13E8.cjs.map} +1 -1
  48. package/dist/chunks/{router-adapter-BdHZXLS3.js → router-adapter-DftlFTOd.js} +2 -2
  49. package/dist/chunks/{router-adapter-BdHZXLS3.js.map → router-adapter-DftlFTOd.js.map} +1 -1
  50. package/dist/chunks/{routes-config-dxahImVe.js → routes-config-RBYQtUd0.js} +2 -3
  51. package/dist/chunks/routes-config-RBYQtUd0.js.map +1 -0
  52. package/dist/chunks/routes-config-fDVHmvXi.cjs +2 -0
  53. package/dist/chunks/routes-config-fDVHmvXi.cjs.map +1 -0
  54. package/dist/index.cjs +1 -1
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/index.js +270 -130
  57. package/dist/index.js.map +1 -1
  58. package/dist/lib/routes-config.d.ts +6 -4
  59. package/dist/next/BPMNextProviders.d.ts +1 -1
  60. package/dist/next/index.cjs +1 -1
  61. package/dist/next/index.cjs.map +1 -1
  62. package/dist/next/index.js +14 -24
  63. package/dist/next/index.js.map +1 -1
  64. package/dist/next/workflow-chat-route.cjs +19 -0
  65. package/dist/next/workflow-chat-route.cjs.map +1 -0
  66. package/dist/next/workflow-chat-route.d.ts +17 -0
  67. package/dist/next/workflow-chat-route.js +31 -0
  68. package/dist/next/workflow-chat-route.js.map +1 -0
  69. package/dist/pages/admin/delegations/index.cjs +1 -1
  70. package/dist/pages/admin/delegations/index.js +1 -1
  71. package/dist/pages/delegations/index.cjs +1 -1
  72. package/dist/pages/delegations/index.js +1 -1
  73. package/dist/pages/instances/detail/index.cjs +1 -1
  74. package/dist/pages/instances/detail/index.js +1 -1
  75. package/dist/pages/login/index.cjs +1 -1
  76. package/dist/pages/login/index.js +1 -1
  77. package/dist/pages/settings/notifications/index.cjs +1 -1
  78. package/dist/pages/settings/notifications/index.js +1 -1
  79. package/dist/pages/templates/compose/index.cjs +2 -0
  80. package/dist/pages/templates/compose/index.cjs.map +1 -0
  81. package/dist/pages/templates/compose/index.d.ts +13 -0
  82. package/dist/pages/templates/compose/index.js +14 -0
  83. package/dist/pages/templates/compose/index.js.map +1 -0
  84. package/dist/pages/templates/designer/index.cjs +1 -1
  85. package/dist/pages/templates/designer/index.cjs.map +1 -1
  86. package/dist/pages/templates/designer/index.js +7 -2
  87. package/dist/pages/templates/designer/index.js.map +1 -1
  88. package/dist/pages/templates/index.cjs +1 -1
  89. package/dist/pages/templates/index.cjs.map +1 -1
  90. package/dist/pages/templates/index.js +3 -3
  91. package/dist/pages/templates/index.js.map +1 -1
  92. package/dist/views/admin/delegations/index.cjs +1 -1
  93. package/dist/views/admin/delegations/index.js +1 -1
  94. package/dist/views/admin/index.cjs +1 -1
  95. package/dist/views/admin/index.js +1 -1
  96. package/dist/views/cc/index.cjs +1 -1
  97. package/dist/views/cc/index.js +1 -1
  98. package/dist/views/dashboard/index.cjs +1 -1
  99. package/dist/views/dashboard/index.js +1 -1
  100. package/dist/views/delegations/index.cjs +1 -1
  101. package/dist/views/delegations/index.js +1 -1
  102. package/dist/views/forms/builder/FormBuilderView.d.ts +13 -4
  103. package/dist/views/forms/builder/index.cjs +1 -1
  104. package/dist/views/forms/builder/index.js +1 -1
  105. package/dist/views/forms/builder/json-code-editor.d.ts +1 -1
  106. package/dist/views/inbox/index.cjs +1 -1
  107. package/dist/views/inbox/index.js +3 -3
  108. package/dist/views/instances/detail/InstanceDetailView.d.ts +11 -1
  109. package/dist/views/instances/detail/index.cjs +1 -1
  110. package/dist/views/instances/detail/index.d.ts +5 -0
  111. package/dist/views/instances/detail/index.js +2 -2
  112. package/dist/views/instances/detail/sections/InstanceAttachmentsSection.d.ts +15 -0
  113. package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +33 -0
  114. package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +29 -0
  115. package/dist/views/instances/detail/sections/InstanceSignaturesSection.d.ts +14 -0
  116. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +44 -0
  117. package/dist/views/instances/detail/sections/container-helpers.d.ts +8 -0
  118. package/dist/views/instances/detail/sections/shared.d.ts +103 -0
  119. package/dist/views/instances/new/index.cjs +1 -1
  120. package/dist/views/instances/new/index.js +3 -3
  121. package/dist/views/login/index.cjs +1 -1
  122. package/dist/views/login/index.js +1 -1
  123. package/dist/views/search/index.cjs +1 -1
  124. package/dist/views/search/index.js +1 -1
  125. package/dist/views/sent/index.cjs +1 -1
  126. package/dist/views/sent/index.js +1 -1
  127. package/dist/views/settings/index.cjs +1 -1
  128. package/dist/views/settings/index.js +1 -1
  129. package/dist/views/settings/notifications/index.cjs +1 -1
  130. package/dist/views/settings/notifications/index.js +1 -1
  131. package/dist/views/templates/TemplatesView.d.ts +5 -0
  132. package/dist/views/templates/compose/TemplateComposeWizardView.d.ts +8 -0
  133. package/dist/views/templates/compose/index.cjs +1 -0
  134. package/dist/views/templates/compose/index.d.ts +2 -0
  135. package/dist/views/templates/compose/index.js +2 -0
  136. package/dist/views/templates/compose/steps/ComposeFormStep.d.ts +15 -0
  137. package/dist/views/templates/compose/steps/ComposeReviewStep.d.ts +12 -0
  138. package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +11 -0
  139. package/dist/views/templates/compose/use-template-compose-wizard.d.ts +46 -0
  140. package/dist/views/templates/designer/TemplateDesignerView.d.ts +60 -2
  141. package/dist/views/templates/designer/chrome-workflow-chat.d.ts +12 -0
  142. package/dist/views/templates/designer/index.cjs +1 -51
  143. package/dist/views/templates/designer/index.js +2 -2272
  144. package/dist/views/templates/designer/use-workflow-chat.d.ts +21 -0
  145. package/dist/views/templates/designer/use-workflow-designer-controller.d.ts +41 -0
  146. package/dist/views/templates/designer/workflow-chat-drawer.d.ts +16 -0
  147. package/dist/views/templates/index.cjs +2 -1
  148. package/dist/views/templates/index.cjs.map +1 -0
  149. package/dist/views/templates/index.js +265 -4
  150. package/dist/views/templates/index.js.map +1 -0
  151. package/dist/views/templates/versions/index.cjs +1 -1
  152. package/dist/views/templates/versions/index.cjs.map +1 -1
  153. package/dist/views/templates/versions/index.js +39 -43
  154. package/dist/views/templates/versions/index.js.map +1 -1
  155. package/package.json +22 -19
  156. package/dist/chunks/builder-C3E-8OJu.js +0 -1300
  157. package/dist/chunks/builder-C3E-8OJu.js.map +0 -1
  158. package/dist/chunks/builder-f-Q_0NUs.cjs +0 -3
  159. package/dist/chunks/builder-f-Q_0NUs.cjs.map +0 -1
  160. package/dist/chunks/detail-B9JkYNHc.cjs +0 -2
  161. package/dist/chunks/detail-B9JkYNHc.cjs.map +0 -1
  162. package/dist/chunks/detail-CSxI04gB.js +0 -1518
  163. package/dist/chunks/detail-CSxI04gB.js.map +0 -1
  164. package/dist/chunks/form-name-modal-C3OEvkCV.js +0 -64
  165. package/dist/chunks/form-name-modal-C3OEvkCV.js.map +0 -1
  166. package/dist/chunks/form-name-modal-uZCHbtRH.cjs +0 -2
  167. package/dist/chunks/form-name-modal-uZCHbtRH.cjs.map +0 -1
  168. package/dist/chunks/router-adapter-BybHrCNP.cjs +0 -2
  169. package/dist/chunks/routes-config-2aKbWq2H.cjs +0 -2
  170. package/dist/chunks/routes-config-2aKbWq2H.cjs.map +0 -1
  171. package/dist/chunks/routes-config-dxahImVe.js.map +0 -1
  172. package/dist/chunks/templates-CL8bPvgn.cjs +0 -2
  173. package/dist/chunks/templates-CL8bPvgn.cjs.map +0 -1
  174. package/dist/chunks/templates-DNfDOPGm.js +0 -380
  175. package/dist/chunks/templates-DNfDOPGm.js.map +0 -1
  176. package/dist/pages/forms/builder/index.cjs +0 -2
  177. package/dist/pages/forms/builder/index.cjs.map +0 -1
  178. package/dist/pages/forms/builder/index.d.ts +0 -21
  179. package/dist/pages/forms/builder/index.js +0 -15
  180. package/dist/pages/forms/builder/index.js.map +0 -1
  181. package/dist/pages/forms/index.cjs +0 -2
  182. package/dist/pages/forms/index.cjs.map +0 -1
  183. package/dist/pages/forms/index.d.ts +0 -17
  184. package/dist/pages/forms/index.js +0 -14
  185. package/dist/pages/forms/index.js.map +0 -1
  186. package/dist/views/forms/FormsView.d.ts +0 -2
  187. package/dist/views/forms/form-name-modal.d.ts +0 -12
  188. package/dist/views/forms/index.cjs +0 -2
  189. package/dist/views/forms/index.cjs.map +0 -1
  190. package/dist/views/forms/index.d.ts +0 -2
  191. package/dist/views/forms/index.js +0 -186
  192. package/dist/views/forms/index.js.map +0 -1
  193. package/dist/views/templates/designer/index.cjs.map +0 -1
  194. package/dist/views/templates/designer/index.js.map +0 -1
  195. package/dist/views/templates/template-name-modal.d.ts +0 -22
@@ -0,0 +1,21 @@
1
+ import { UseChatHelpers } from '@ai-sdk/react';
2
+ import { UIMessage } from 'ai';
3
+ import { WorkflowDesignerController } from './use-workflow-designer-controller';
4
+ /**
5
+ * Connects the workflow designer chat UI to the LLM.
6
+ *
7
+ * The server route (`@rytass/bpm-core-react/next/workflow-chat-route`) advertises
8
+ * the workflow tools with no `execute`, so every tool call is forwarded here.
9
+ * `onToolCall` runs it against the same {@link WorkflowDesignerController} the UI
10
+ * uses — so the assistant draws on the canvas exactly as a user would — and feeds
11
+ * the resulting snapshot back to the model, forming the observe→act loop.
12
+ *
13
+ * All tools are dynamic on the client (their names are not statically wired into
14
+ * `useChat`), so we handle (not skip) `toolCall.dynamic`.
15
+ */
16
+ export interface UseWorkflowChatOptions {
17
+ readonly controller: WorkflowDesignerController;
18
+ /** Chat API route. Defaults to same-origin `/api/chat`. */
19
+ readonly api?: string;
20
+ }
21
+ export declare function useWorkflowChat({ controller, api, }: UseWorkflowChatOptions): UseChatHelpers<UIMessage>;
@@ -0,0 +1,41 @@
1
+ import { WorkflowCommand, WorkflowCommandResult, WorkflowDesignerState, WorkflowMacroCommand, WorkflowDirectory, WorkflowSnapshot, WorkflowTool, WorkflowToolResult } from '@rytass/bpm-core-shared';
2
+ import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
3
+ /**
4
+ * Bridges the pure, framework-agnostic workflow command layer
5
+ * (`@rytass/bpm-core-shared`) to React. It owns the {@link WorkflowDesignerState}
6
+ * and is the single dispatch path through which both the designer UI and the
7
+ * LLM assistant mutate the workflow — guaranteeing the assistant can do exactly
8
+ * what a user can.
9
+ *
10
+ * The pure reducer only describes logical structure; this hook injects the
11
+ * pixel concern: whenever a command reports `effects.layout`, the supplied
12
+ * `layout` function (dagre) recomputes node positions, and `onLayout` is invoked
13
+ * so the host can refit the viewport.
14
+ */
15
+ export interface UseWorkflowDesignerControllerOptions {
16
+ readonly initialState: WorkflowDesignerState;
17
+ /** Recompute node pixel positions (dagre) — runs after topology changes. */
18
+ readonly layout: (definition: WorkflowDefinition) => WorkflowDefinition;
19
+ /** Notified with the laid-out definition so the host can refit the viewport. */
20
+ readonly onLayout?: (definition: WorkflowDefinition) => void;
21
+ /** Org directory backing the LLM's member/org lookup query tools. */
22
+ readonly directory?: WorkflowDirectory;
23
+ }
24
+ export interface WorkflowDesignerController {
25
+ readonly state: WorkflowDesignerState;
26
+ readonly snapshot: WorkflowSnapshot;
27
+ /** The advertised LLM tool catalog (JSON Schema input contracts). */
28
+ readonly tools: readonly WorkflowTool[];
29
+ /** Dispatch a single primitive command. */
30
+ readonly dispatch: (command: WorkflowCommand) => WorkflowCommandResult;
31
+ /** Dispatch a high-level macro command. */
32
+ readonly dispatchMacro: (command: WorkflowMacroCommand) => WorkflowCommandResult;
33
+ /** Execute an LLM tool call by name; mutations commit + relayout. Async
34
+ * because directory query tools may fetch from the host. */
35
+ readonly executeTool: (toolName: string, input: unknown) => Promise<WorkflowToolResult>;
36
+ /** Replace the whole state (e.g. after loading a draft from the server). */
37
+ readonly replaceState: (next: WorkflowDesignerState | ((current: WorkflowDesignerState) => WorkflowDesignerState)) => void;
38
+ /** Imperatively read the latest committed state (avoids stale closures). */
39
+ readonly getState: () => WorkflowDesignerState;
40
+ }
41
+ export declare function useWorkflowDesignerController({ directory, initialState, layout, onLayout, }: UseWorkflowDesignerControllerOptions): WorkflowDesignerController;
@@ -0,0 +1,16 @@
1
+ import { ReactElement } from 'react';
2
+ import { WorkflowDesignerController } from './use-workflow-designer-controller';
3
+ /**
4
+ * Right-side AI assistant drawer for the workflow designer. Users describe the
5
+ * flow in natural language; the assistant draws it on the canvas by driving the
6
+ * shared workflow toolset through {@link useWorkflowChat}. The layout (canvas +
7
+ * 420px panel) is untouched — this slides over it.
8
+ */
9
+ export interface WorkflowChatDrawerProps {
10
+ readonly controller: WorkflowDesignerController;
11
+ readonly open: boolean;
12
+ readonly onClose: () => void;
13
+ /** Chat API route. Defaults to same-origin `/api/chat`. */
14
+ readonly api?: string;
15
+ }
16
+ export declare function WorkflowChatDrawer({ api, controller, onClose, open, }: WorkflowChatDrawerProps): ReactElement;
@@ -1 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/categories-B6QZKZRt.cjs"),t=require("../../chunks/templates-CL8bPvgn.cjs"),n=require("./versions/index.cjs");exports.TemplateCategoriesView=e.t,exports.TemplateVersionsView=n.TemplateVersionsView,exports.TemplatesView=t.t;
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-fDVHmvXi.cjs"),i=require("../../chunks/categories-B6QZKZRt.cjs"),a=require("./versions/index.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@rytass/bpm-core-client/workflow"),u=require("@mezzanine-ui/react/ContentHeader");u=e.t(u,1);let d=require("@mezzanine-ui/core/form"),f=require("@mezzanine-ui/icons"),p=require("@rytass/bpm-core-client/template");var m=[10,20,50],h=[{key:`ALL`,label:`全部`},{key:`PUBLISHED`,label:`已發布`},{key:`DRAFT`,label:`草稿`}],g=100;function _(){let e=t.r(),a=r.r(),[_,D]=(0,o.useState)([]),[O,k]=(0,o.useState)(S),[A,j]=(0,o.useState)([]),[M,N]=(0,o.useState)(new Set),[P,F]=(0,o.useState)(null),[I,L]=(0,o.useState)(!0),[R,z]=(0,o.useState)(1),[B,V]=(0,o.useState)(10),[H,U]=(0,o.useState)(``),[W,G]=(0,o.useState)(`ALL`),[K,q]=(0,o.useState)(0),J=(0,o.useCallback)(async()=>{L(!0),F(null);try{let[e,t,n]=await Promise.all([(0,p.listApprovalTemplatesPage)({categoryId:O.categoryId,page:R,pageSize:B,searchText:H,status:W===`ALL`?null:W}),(0,l.listLaunchableTemplates)(),(0,p.listApprovalTemplateCategoriesPage)({page:1,pageSize:g,searchText:``,status:`ACTIVE`})]);j([...n.categories.map(C)]),D(e.templates),q(e.totalCount),N(new Set(t.map(e=>e.id)))}catch(e){F(v(e))}finally{L(!1)}},[O,R,B,H,W]);(0,o.useEffect)(()=>{J()},[J]);let Y=(0,o.useMemo)(()=>_.map(e=>({...e,categoryLabel:E(e),key:e.id,status:e.currentVersionId?`PUBLISHED`:`DRAFT`,updatedAt:n.t(e.updatedAt)})),[_]),X=(0,o.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`模板名稱`,width:220},{key:`status`,render:e=>(0,c.jsx)(b,{status:e.status}),title:`狀態`,width:120},{key:`category`,render:e=>(0,c.jsx)(x,{record:e}),title:`分類`,width:160},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:220}],[]),Z=(0,o.useMemo)(()=>({render:t=>[{disabled:e=>!M.has(e.id),name:`發起`,onClick:()=>e.push(a.caseNew(t.id)),variant:`base-primary`},{name:`設計`,onClick:()=>e.push(a.templateDesigner(t.id))},{name:`版本`,onClick:()=>e.push(a.templateVersions(t.id))}],variant:`base-secondary`,width:192}),[M,e]);return(0,c.jsx)(c.Fragment,{children:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(u.default,{description:`建立流程模板、維護草稿與發布版本。`,title:`簽核模板`,children:(0,c.jsx)(s.Button,{icon:f.PlusIcon,iconType:`leading`,onClick:()=>e.push(a.templateCompose()),variant:`base-primary`,children:`建立模板`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{filterArea:(0,c.jsx)(s.FilterArea,{className:i.n.templateFilterArea,size:`sub`,children:(0,c.jsxs)(s.FilterLine,{children:[(0,c.jsx)(s.Filter,{span:3,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:d.FormFieldLayout.VERTICAL,name:`templateSearchText`,children:(0,c.jsx)(s.Input,{fullWidth:!0,onChange:e=>{U(e.target.value),z(1)},placeholder:`關鍵字:搜尋模板名稱、分類或描述`,size:`sub`,value:H,variant:`base`})})}),(0,c.jsx)(s.Filter,{span:2,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:d.FormFieldLayout.VERTICAL,name:`templateCategoryFilter`,children:(0,c.jsx)(s.Select,{clearable:!1,fullWidth:!0,onChange:e=>{k(w(e,A)),z(1)},options:[S,...A],placeholder:`分類`,renderValue:e=>`分類:${T(e)}`,size:`sub`,value:O})})})]})}),tab:(0,c.jsx)(s.Tab,{activeKey:W,onChange:e=>{G(y(e)),z(1)},children:h.map(e=>(0,c.jsx)(s.TabItem,{children:e.label},e.key))}),children:[P?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:P}):null,(0,c.jsx)(s.Table,{actions:Z,columns:X,dataSource:Y,fullWidth:!0,loading:I,pagination:{current:R,onChange:e=>{z(e)},onChangePageSize:e=>{z(1),V(e)},pageSize:B,pageSizeLabel:`每頁筆數`,pageSizeOptions:m,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:K}})]})})]})})}function v(e){return e instanceof Error?e.message:`發生未知錯誤`}function y(e){return e===`PUBLISHED`||e===`DRAFT`?e:`ALL`}function b({status:e}){return e===`PUBLISHED`?(0,c.jsx)(s.Badge,{size:`sub`,text:`已發布`,variant:`dot-success`}):(0,c.jsx)(s.Badge,{size:`sub`,text:`草稿`,variant:`dot-inactive`})}function x({record:e}){return e.categoryDetail?.isActive===!1?(0,c.jsx)(s.Badge,{size:`sub`,text:`${e.categoryLabel}(停用)`,variant:`dot-inactive`}):(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.categoryLabel})}var S={categoryId:null,id:`ALL_CATEGORIES`,name:`全部分類`};function C(e){return{categoryId:e.id,id:e.id,name:e.name}}function w(e,t){if(!D(e))return S;let n=typeof e.id==`string`?e.id:null;return n===S.id?S:t.find(e=>e.id===n)??S}function T(e){return Array.isArray(e)||!D(e)?S.name:typeof e.name==`string`?e.name:S.name}function E(e){return e.categoryDetail?.name??e.category??`未分類`}function D(e){return typeof e==`object`&&!!e}exports.TemplateCategoriesView=i.t,exports.TemplateVersionsView=a.TemplateVersionsView,exports.TemplatesView=_;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/views/templates/TemplatesView.tsx"],"sourcesContent":["'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 PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\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 styles from './templates.module.scss';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\nimport {\n ApprovalTemplateListStatus,\n ApprovalTemplateRecord,\n ApprovalTemplateCategoryRecord,\n listApprovalTemplateCategoriesPage,\n listApprovalTemplatesPage,\n} from '@rytass/bpm-core-client/template';\nimport { listLaunchableTemplates } from '@rytass/bpm-core-client/workflow';\n\nconst TEMPLATE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst TEMPLATE_STATUS_TABS: readonly {\n readonly key: TemplateStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'PUBLISHED', label: '已發布' },\n { key: 'DRAFT', label: '草稿' },\n];\n\nconst TEMPLATE_CATEGORY_PAGE_SIZE = 100;\n\nexport interface TemplateCategoryOption {\n readonly categoryId: string | null;\n readonly id: string;\n readonly name: string;\n}\n\ntype TemplateStatusTabKey = 'ALL' | ApprovalTemplateListStatus;\n\ntype TemplateRow = Readonly<\n Record<string, unknown> &\n ApprovalTemplateRecord & {\n categoryLabel: string;\n key: string;\n status: ApprovalTemplateListStatus;\n }\n>;\n\n\nexport function TemplatesView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [templates, setTemplates] = useState<readonly ApprovalTemplateRecord[]>(\n [],\n );\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategoryOption>(\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n );\n const [categoryOptions, setCategoryOptions] = useState<\n readonly TemplateCategoryOption[]\n >([]);\n const [launchableTemplateIds, setLaunchableTemplateIds] = useState<\n ReadonlySet<string>\n >(new Set());\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [templatePage, setTemplatePage] = useState(1);\n const [templatePageSize, setTemplatePageSize] = useState(10);\n const [templateSearchText, setTemplateSearchText] = useState('');\n const [templateStatus, setTemplateStatus] =\n useState<TemplateStatusTabKey>('ALL');\n const [templateTotalCount, setTemplateTotalCount] = useState(0);\n\n const refreshTemplates = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const [\n templatePageResult,\n nextLaunchableTemplates,\n activeCategoryPageResult,\n ] = await Promise.all([\n listApprovalTemplatesPage({\n categoryId: categoryFilter.categoryId,\n page: templatePage,\n pageSize: templatePageSize,\n searchText: templateSearchText,\n status: templateStatus === 'ALL' ? null : templateStatus,\n }),\n listLaunchableTemplates(),\n listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: TEMPLATE_CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n }),\n ]);\n\n setCategoryOptions([\n ...activeCategoryPageResult.categories.map(readCategoryOption),\n ]);\n setTemplates(templatePageResult.templates);\n setTemplateTotalCount(templatePageResult.totalCount);\n setLaunchableTemplateIds(\n new Set(nextLaunchableTemplates.map((template) => template.id)),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [\n categoryFilter,\n templatePage,\n templatePageSize,\n templateSearchText,\n templateStatus,\n ]);\n\n useEffect((): void => {\n void refreshTemplates();\n }, [refreshTemplates]);\n\n const rows = useMemo(\n (): TemplateRow[] =>\n templates.map((template) => ({\n ...template,\n categoryLabel: readTemplateCategoryLabel(template),\n key: template.id,\n status: template.currentVersionId ? 'PUBLISHED' : 'DRAFT',\n updatedAt: formatDateTime(template.updatedAt),\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<TemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 220 },\n {\n key: 'status',\n render: (record: TemplateRow): ReactElement => (\n <TemplateStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'category',\n render: (record: TemplateRow): ReactElement => (\n <TemplateCategoryLabel record={record} />\n ),\n title: '分類',\n width: 160,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<TemplateRow> => ({\n render: (record): ReturnType<TableActions<TemplateRow>['render']> => [\n {\n disabled: (template): boolean =>\n !launchableTemplateIds.has(template.id),\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n {\n name: '設計',\n onClick: (): void => router.push(routes.templateDesigner(record.id)),\n },\n {\n name: '版本',\n onClick: (): void => router.push(routes.templateVersions(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 192,\n }),\n [launchableTemplateIds, router],\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 => router.push(routes.templateCompose())}\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=\"templateSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setTemplateSearchText(event.target.value);\n setTemplatePage(1);\n }}\n placeholder=\"關鍵字:搜尋模板名稱、分類或描述\"\n size=\"sub\"\n value={templateSearchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateCategoryFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategoryFilter(\n readCategoryFilterOption(option, categoryOptions),\n );\n setTemplatePage(1);\n }}\n options={[\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n ...categoryOptions,\n ]}\n placeholder=\"分類\"\n renderValue={(value): string =>\n `分類:${readTemplateCategoryFilterLabel(value)}`\n }\n size=\"sub\"\n value={categoryFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={templateStatus}\n onChange={(activeKey): void => {\n setTemplateStatus(readTemplateStatusTabKey(activeKey));\n setTemplatePage(1);\n }}\n >\n {TEMPLATE_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}\n pagination={{\n current: templatePage,\n onChange: (page): void => {\n setTemplatePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setTemplatePage(1);\n setTemplatePageSize(pageSize);\n },\n pageSize: templatePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: TEMPLATE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: templateTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nfunction readTemplateStatusTabKey(activeKey: Key): TemplateStatusTabKey {\n if (activeKey === 'PUBLISHED' || activeKey === 'DRAFT') {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction TemplateStatusBadge({\n status,\n}: {\n readonly status: ApprovalTemplateListStatus;\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateCategoryLabel({\n record,\n}: {\n readonly record: TemplateRow;\n}): ReactElement {\n if (record.categoryDetail?.isActive === false) {\n return (\n <Badge\n size=\"sub\"\n text={`${record.categoryLabel}(停用)`}\n variant=\"dot-inactive\"\n />\n );\n }\n\n return (\n <Typography component=\"span\" variant=\"body\">\n {record.categoryLabel}\n </Typography>\n );\n}\n\nconst UNCATEGORIZED_TEMPLATE_FILTER_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'ALL_CATEGORIES',\n name: '全部分類',\n};\n\nfunction readCategoryOption(\n category: ApprovalTemplateCategoryRecord,\n): TemplateCategoryOption {\n return {\n categoryId: category.id,\n id: category.id,\n name: category.name,\n };\n}\n\nfunction readCategoryFilterOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n if (id === UNCATEGORIZED_TEMPLATE_FILTER_OPTION.id) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION\n );\n}\n\nfunction readTemplateCategoryFilterLabel(value: unknown): string {\n if (Array.isArray(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n return typeof value.name === 'string'\n ? value.name\n : UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n}\n\nfunction readTemplateCategoryLabel(template: ApprovalTemplateRecord): string {\n return template.categoryDetail?.name ?? template.category ?? '未分類';\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":"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"}
@@ -1,4 +1,265 @@
1
- import { t as e } from "../../chunks/categories-DBPoSrsi.js";
2
- import { t } from "../../chunks/templates-DNfDOPGm.js";
3
- import { TemplateVersionsView as n } from "./versions/index.js";
4
- export { e as TemplateCategoriesView, n as TemplateVersionsView, t as TemplatesView };
1
+ "use client";
2
+ import { r as e } from "../../chunks/router-adapter-DftlFTOd.js";
3
+ import { t } from "../../chunks/format-date-time-CB-LxzqT.js";
4
+ import { r as n } from "../../chunks/routes-config-RBYQtUd0.js";
5
+ import { n as r, t as i } from "../../chunks/categories-DBPoSrsi.js";
6
+ import { TemplateVersionsView as a } from "./versions/index.js";
7
+ import { useCallback as o, useEffect as s, useMemo as c, useState as l } from "react";
8
+ import { Badge as u, Button as d, Filter as f, FilterArea as ee, FilterLine as te, FormField as p, Input as ne, PageHeader as re, Section as m, SectionGroup as h, Select as g, Tab as _, TabItem as ie, Table as v, Typography as y } from "@mezzanine-ui/react";
9
+ import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
10
+ import { listLaunchableTemplates as ae } from "@rytass/bpm-core-client/workflow";
11
+ import oe from "@mezzanine-ui/react/ContentHeader";
12
+ import { FormFieldLayout as C } from "@mezzanine-ui/core/form";
13
+ import { PlusIcon as w } from "@mezzanine-ui/icons";
14
+ import { listApprovalTemplateCategoriesPage as T, listApprovalTemplatesPage as E } from "@rytass/bpm-core-client/template";
15
+ //#region src/views/templates/TemplatesView.tsx
16
+ var D = [
17
+ 10,
18
+ 20,
19
+ 50
20
+ ], O = [
21
+ {
22
+ key: "ALL",
23
+ label: "全部"
24
+ },
25
+ {
26
+ key: "PUBLISHED",
27
+ label: "已發布"
28
+ },
29
+ {
30
+ key: "DRAFT",
31
+ label: "草稿"
32
+ }
33
+ ], k = 100;
34
+ function A() {
35
+ let i = e(), a = n(), [u, A] = l([]), [B, V] = l(F), [H, se] = l([]), [U, W] = l(/* @__PURE__ */ new Set()), [G, K] = l(null), [ce, q] = l(!0), [J, Y] = l(1), [X, le] = l(10), [Z, ue] = l(""), [Q, de] = l("ALL"), [fe, pe] = l(0), $ = o(async () => {
36
+ q(!0), K(null);
37
+ try {
38
+ let [e, t, n] = await Promise.all([
39
+ E({
40
+ categoryId: B.categoryId,
41
+ page: J,
42
+ pageSize: X,
43
+ searchText: Z,
44
+ status: Q === "ALL" ? null : Q
45
+ }),
46
+ ae(),
47
+ T({
48
+ page: 1,
49
+ pageSize: k,
50
+ searchText: "",
51
+ status: "ACTIVE"
52
+ })
53
+ ]);
54
+ se([...n.categories.map(I)]), A(e.templates), pe(e.totalCount), W(new Set(t.map((e) => e.id)));
55
+ } catch (e) {
56
+ K(j(e));
57
+ } finally {
58
+ q(!1);
59
+ }
60
+ }, [
61
+ B,
62
+ J,
63
+ X,
64
+ Z,
65
+ Q
66
+ ]);
67
+ s(() => {
68
+ $();
69
+ }, [$]);
70
+ let me = c(() => u.map((e) => ({
71
+ ...e,
72
+ categoryLabel: z(e),
73
+ key: e.id,
74
+ status: e.currentVersionId ? "PUBLISHED" : "DRAFT",
75
+ updatedAt: t(e.updatedAt)
76
+ })), [u]), he = c(() => [
77
+ {
78
+ dataIndex: "name",
79
+ key: "name",
80
+ title: "模板名稱",
81
+ width: 220
82
+ },
83
+ {
84
+ key: "status",
85
+ render: (e) => /* @__PURE__ */ x(N, { status: e.status }),
86
+ title: "狀態",
87
+ width: 120
88
+ },
89
+ {
90
+ key: "category",
91
+ render: (e) => /* @__PURE__ */ x(P, { record: e }),
92
+ title: "分類",
93
+ width: 160
94
+ },
95
+ {
96
+ dataIndex: "updatedAt",
97
+ key: "updatedAt",
98
+ title: "更新時間",
99
+ width: 220
100
+ }
101
+ ], []), ge = c(() => ({
102
+ render: (e) => [
103
+ {
104
+ disabled: (e) => !U.has(e.id),
105
+ name: "發起",
106
+ onClick: () => i.push(a.caseNew(e.id)),
107
+ variant: "base-primary"
108
+ },
109
+ {
110
+ name: "設計",
111
+ onClick: () => i.push(a.templateDesigner(e.id))
112
+ },
113
+ {
114
+ name: "版本",
115
+ onClick: () => i.push(a.templateVersions(e.id))
116
+ }
117
+ ],
118
+ variant: "base-secondary",
119
+ width: 192
120
+ }), [U, i]);
121
+ return /* @__PURE__ */ x(b, { children: /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(re, { children: /* @__PURE__ */ x(oe, {
122
+ description: "建立流程模板、維護草稿與發布版本。",
123
+ title: "簽核模板",
124
+ children: /* @__PURE__ */ x(d, {
125
+ icon: w,
126
+ iconType: "leading",
127
+ onClick: () => i.push(a.templateCompose()),
128
+ variant: "base-primary",
129
+ children: "建立模板"
130
+ })
131
+ }) }), /* @__PURE__ */ x(h, { children: /* @__PURE__ */ S(m, {
132
+ filterArea: /* @__PURE__ */ x(ee, {
133
+ className: r.templateFilterArea,
134
+ size: "sub",
135
+ children: /* @__PURE__ */ S(te, { children: [/* @__PURE__ */ x(f, {
136
+ span: 3,
137
+ children: /* @__PURE__ */ x(p, {
138
+ fullWidth: !0,
139
+ layout: C.VERTICAL,
140
+ name: "templateSearchText",
141
+ children: /* @__PURE__ */ x(ne, {
142
+ fullWidth: !0,
143
+ onChange: (e) => {
144
+ ue(e.target.value), Y(1);
145
+ },
146
+ placeholder: "關鍵字:搜尋模板名稱、分類或描述",
147
+ size: "sub",
148
+ value: Z,
149
+ variant: "base"
150
+ })
151
+ })
152
+ }), /* @__PURE__ */ x(f, {
153
+ span: 2,
154
+ children: /* @__PURE__ */ x(p, {
155
+ fullWidth: !0,
156
+ layout: C.VERTICAL,
157
+ name: "templateCategoryFilter",
158
+ children: /* @__PURE__ */ x(g, {
159
+ clearable: !1,
160
+ fullWidth: !0,
161
+ onChange: (e) => {
162
+ V(L(e, H)), Y(1);
163
+ },
164
+ options: [F, ...H],
165
+ placeholder: "分類",
166
+ renderValue: (e) => `分類:${R(e)}`,
167
+ size: "sub",
168
+ value: B
169
+ })
170
+ })
171
+ })] })
172
+ }),
173
+ tab: /* @__PURE__ */ x(_, {
174
+ activeKey: Q,
175
+ onChange: (e) => {
176
+ de(M(e)), Y(1);
177
+ },
178
+ children: O.map((e) => /* @__PURE__ */ x(ie, { children: e.label }, e.key))
179
+ }),
180
+ children: [G ? /* @__PURE__ */ x(y, {
181
+ color: "text-error",
182
+ variant: "body",
183
+ children: G
184
+ }) : null, /* @__PURE__ */ x(v, {
185
+ actions: ge,
186
+ columns: he,
187
+ dataSource: me,
188
+ fullWidth: !0,
189
+ loading: ce,
190
+ pagination: {
191
+ current: J,
192
+ onChange: (e) => {
193
+ Y(e);
194
+ },
195
+ onChangePageSize: (e) => {
196
+ Y(1), le(e);
197
+ },
198
+ pageSize: X,
199
+ pageSizeLabel: "每頁筆數",
200
+ pageSizeOptions: D,
201
+ renderResultSummary: (e, t, n) => `顯示 ${e}-${t} 筆,共 ${n} 筆`,
202
+ showPageSizeOptions: !0,
203
+ total: fe
204
+ }
205
+ })]
206
+ }) })] }) });
207
+ }
208
+ function j(e) {
209
+ return e instanceof Error ? e.message : "發生未知錯誤";
210
+ }
211
+ function M(e) {
212
+ return e === "PUBLISHED" || e === "DRAFT" ? e : "ALL";
213
+ }
214
+ function N({ status: e }) {
215
+ return e === "PUBLISHED" ? /* @__PURE__ */ x(u, {
216
+ size: "sub",
217
+ text: "已發布",
218
+ variant: "dot-success"
219
+ }) : /* @__PURE__ */ x(u, {
220
+ size: "sub",
221
+ text: "草稿",
222
+ variant: "dot-inactive"
223
+ });
224
+ }
225
+ function P({ record: e }) {
226
+ return e.categoryDetail?.isActive === !1 ? /* @__PURE__ */ x(u, {
227
+ size: "sub",
228
+ text: `${e.categoryLabel}(停用)`,
229
+ variant: "dot-inactive"
230
+ }) : /* @__PURE__ */ x(y, {
231
+ component: "span",
232
+ variant: "body",
233
+ children: e.categoryLabel
234
+ });
235
+ }
236
+ var F = {
237
+ categoryId: null,
238
+ id: "ALL_CATEGORIES",
239
+ name: "全部分類"
240
+ };
241
+ function I(e) {
242
+ return {
243
+ categoryId: e.id,
244
+ id: e.id,
245
+ name: e.name
246
+ };
247
+ }
248
+ function L(e, t) {
249
+ if (!B(e)) return F;
250
+ let n = typeof e.id == "string" ? e.id : null;
251
+ return n === F.id ? F : t.find((e) => e.id === n) ?? F;
252
+ }
253
+ function R(e) {
254
+ return Array.isArray(e) || !B(e) ? F.name : typeof e.name == "string" ? e.name : F.name;
255
+ }
256
+ function z(e) {
257
+ return e.categoryDetail?.name ?? e.category ?? "未分類";
258
+ }
259
+ function B(e) {
260
+ return typeof e == "object" && !!e;
261
+ }
262
+ //#endregion
263
+ export { i as TemplateCategoriesView, a as TemplateVersionsView, A as TemplatesView };
264
+
265
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/views/templates/TemplatesView.tsx"],"sourcesContent":["'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 PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\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 styles from './templates.module.scss';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\nimport {\n ApprovalTemplateListStatus,\n ApprovalTemplateRecord,\n ApprovalTemplateCategoryRecord,\n listApprovalTemplateCategoriesPage,\n listApprovalTemplatesPage,\n} from '@rytass/bpm-core-client/template';\nimport { listLaunchableTemplates } from '@rytass/bpm-core-client/workflow';\n\nconst TEMPLATE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst TEMPLATE_STATUS_TABS: readonly {\n readonly key: TemplateStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'PUBLISHED', label: '已發布' },\n { key: 'DRAFT', label: '草稿' },\n];\n\nconst TEMPLATE_CATEGORY_PAGE_SIZE = 100;\n\nexport interface TemplateCategoryOption {\n readonly categoryId: string | null;\n readonly id: string;\n readonly name: string;\n}\n\ntype TemplateStatusTabKey = 'ALL' | ApprovalTemplateListStatus;\n\ntype TemplateRow = Readonly<\n Record<string, unknown> &\n ApprovalTemplateRecord & {\n categoryLabel: string;\n key: string;\n status: ApprovalTemplateListStatus;\n }\n>;\n\n\nexport function TemplatesView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [templates, setTemplates] = useState<readonly ApprovalTemplateRecord[]>(\n [],\n );\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategoryOption>(\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n );\n const [categoryOptions, setCategoryOptions] = useState<\n readonly TemplateCategoryOption[]\n >([]);\n const [launchableTemplateIds, setLaunchableTemplateIds] = useState<\n ReadonlySet<string>\n >(new Set());\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [templatePage, setTemplatePage] = useState(1);\n const [templatePageSize, setTemplatePageSize] = useState(10);\n const [templateSearchText, setTemplateSearchText] = useState('');\n const [templateStatus, setTemplateStatus] =\n useState<TemplateStatusTabKey>('ALL');\n const [templateTotalCount, setTemplateTotalCount] = useState(0);\n\n const refreshTemplates = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const [\n templatePageResult,\n nextLaunchableTemplates,\n activeCategoryPageResult,\n ] = await Promise.all([\n listApprovalTemplatesPage({\n categoryId: categoryFilter.categoryId,\n page: templatePage,\n pageSize: templatePageSize,\n searchText: templateSearchText,\n status: templateStatus === 'ALL' ? null : templateStatus,\n }),\n listLaunchableTemplates(),\n listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: TEMPLATE_CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n }),\n ]);\n\n setCategoryOptions([\n ...activeCategoryPageResult.categories.map(readCategoryOption),\n ]);\n setTemplates(templatePageResult.templates);\n setTemplateTotalCount(templatePageResult.totalCount);\n setLaunchableTemplateIds(\n new Set(nextLaunchableTemplates.map((template) => template.id)),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [\n categoryFilter,\n templatePage,\n templatePageSize,\n templateSearchText,\n templateStatus,\n ]);\n\n useEffect((): void => {\n void refreshTemplates();\n }, [refreshTemplates]);\n\n const rows = useMemo(\n (): TemplateRow[] =>\n templates.map((template) => ({\n ...template,\n categoryLabel: readTemplateCategoryLabel(template),\n key: template.id,\n status: template.currentVersionId ? 'PUBLISHED' : 'DRAFT',\n updatedAt: formatDateTime(template.updatedAt),\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<TemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 220 },\n {\n key: 'status',\n render: (record: TemplateRow): ReactElement => (\n <TemplateStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'category',\n render: (record: TemplateRow): ReactElement => (\n <TemplateCategoryLabel record={record} />\n ),\n title: '分類',\n width: 160,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<TemplateRow> => ({\n render: (record): ReturnType<TableActions<TemplateRow>['render']> => [\n {\n disabled: (template): boolean =>\n !launchableTemplateIds.has(template.id),\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n {\n name: '設計',\n onClick: (): void => router.push(routes.templateDesigner(record.id)),\n },\n {\n name: '版本',\n onClick: (): void => router.push(routes.templateVersions(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 192,\n }),\n [launchableTemplateIds, router],\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 => router.push(routes.templateCompose())}\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=\"templateSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setTemplateSearchText(event.target.value);\n setTemplatePage(1);\n }}\n placeholder=\"關鍵字:搜尋模板名稱、分類或描述\"\n size=\"sub\"\n value={templateSearchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateCategoryFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategoryFilter(\n readCategoryFilterOption(option, categoryOptions),\n );\n setTemplatePage(1);\n }}\n options={[\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n ...categoryOptions,\n ]}\n placeholder=\"分類\"\n renderValue={(value): string =>\n `分類:${readTemplateCategoryFilterLabel(value)}`\n }\n size=\"sub\"\n value={categoryFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={templateStatus}\n onChange={(activeKey): void => {\n setTemplateStatus(readTemplateStatusTabKey(activeKey));\n setTemplatePage(1);\n }}\n >\n {TEMPLATE_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}\n pagination={{\n current: templatePage,\n onChange: (page): void => {\n setTemplatePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setTemplatePage(1);\n setTemplatePageSize(pageSize);\n },\n pageSize: templatePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: TEMPLATE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: templateTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nfunction readTemplateStatusTabKey(activeKey: Key): TemplateStatusTabKey {\n if (activeKey === 'PUBLISHED' || activeKey === 'DRAFT') {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction TemplateStatusBadge({\n status,\n}: {\n readonly status: ApprovalTemplateListStatus;\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateCategoryLabel({\n record,\n}: {\n readonly record: TemplateRow;\n}): ReactElement {\n if (record.categoryDetail?.isActive === false) {\n return (\n <Badge\n size=\"sub\"\n text={`${record.categoryLabel}(停用)`}\n variant=\"dot-inactive\"\n />\n );\n }\n\n return (\n <Typography component=\"span\" variant=\"body\">\n {record.categoryLabel}\n </Typography>\n );\n}\n\nconst UNCATEGORIZED_TEMPLATE_FILTER_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'ALL_CATEGORIES',\n name: '全部分類',\n};\n\nfunction readCategoryOption(\n category: ApprovalTemplateCategoryRecord,\n): TemplateCategoryOption {\n return {\n categoryId: category.id,\n id: category.id,\n name: category.name,\n };\n}\n\nfunction readCategoryFilterOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n if (id === UNCATEGORIZED_TEMPLATE_FILTER_OPTION.id) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION\n );\n}\n\nfunction readTemplateCategoryFilterLabel(value: unknown): string {\n if (Array.isArray(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n return typeof value.name === 'string'\n ? value.name\n : UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n}\n\nfunction readTemplateCategoryLabel(template: ApprovalTemplateRecord): string {\n return template.categoryDetail?.name ?? template.category ?? '未分類';\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/chunk-CMqjfN_6.cjs"),t=require("../../../chunks/router-adapter-BybHrCNP.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;
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-fDVHmvXi.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 狀態。`,onBackClick:()=>l.push(d.templates()),title:f?.template.name??`模板版本`})}),(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 { 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
+ {"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 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 onBackClick={(): void => router.push(routes.templates())}\n title={record?.template.name ?? '模板版本'}\n />\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":"qfAqCA,SAAgB,EAAqB,CACnC,cAC0C,CAC1C,IAAM,EAAS,EAAA,EAAiB,EAC1B,EAAS,EAAA,EAAa,EACtB,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAqD,IAAI,EAClE,CAAC,EAAO,IAAA,EAAA,EAAA,UAAoC,IAAI,EAChD,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,EAAI,EACrC,CAAC,EAAa,IAAA,EAAA,EAAA,UAA2B,EAAK,GAEpD,EAAA,EAAA,eAAsB,CACpB,EAAqB,CACvB,EAAG,CAAC,CAAU,CAAC,EAEf,IAAM,GAAA,EAAA,EAAA,cAED,GAAQ,UAAY,CAAC,GAAG,IAAK,IAAa,CACzC,YACE,GAAQ,aAAa,KAClB,GAAgB,EAAY,KAAO,EAAQ,uBAC9C,GAAG,OAAS,MACd,IAAK,EAAQ,GACb,YAAa,EAAA,EAAe,EAAQ,WAAW,EAC/C,OAAQ,EAAQ,OAChB,UAAW,EAAA,EAAe,EAAQ,SAAS,EAC3C,QAAS,IAAI,EAAQ,UACrB,UAAW,EAAQ,EACrB,EAAE,EACJ,CAAC,CAAM,CACT,EACM,GAAA,EAAA,EAAA,aAC6B,CAC/B,CAAE,UAAW,UAAW,IAAK,UAAW,MAAO,KAAM,MAAO,GAAI,EAChE,CAAE,UAAW,SAAU,IAAK,SAAU,MAAO,KAAM,MAAO,GAAI,EAC9D,CACE,UAAW,cACX,IAAK,cACL,MAAO,OACP,MAAO,GACT,EACA,CACE,UAAW,cACX,IAAK,cACL,MAAO,OACP,MAAO,GACT,EACA,CACE,UAAW,YACX,IAAK,YACL,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EACM,GAAA,EAAA,EAAA,cAC6B,CAC/B,OAAS,GAAwD,CAC/D,CACE,aAAyB,GAAe,EAAI,SAAW,QACvD,KAAM,WACN,YAAqB,KAAK,EAAe,EAAI,SAAS,CACxD,CACF,EACA,QAAS,iBACT,MAAO,GACT,GACA,CAAC,CAAW,CACd,EAEA,eAAe,GAAiC,CAC9C,EAAW,EAAI,EACf,EAAS,IAAI,EAEb,GAAI,CACF,EAAU,MAAA,EAAA,EAAA,sBAA2B,CAAU,CAAC,CAClD,OAAS,EAAuB,CAC9B,EAAS,EAAiB,CAAY,CAAC,CACzC,QAAU,CACR,EAAW,EAAK,CAClB,CACF,CAEA,eAAe,EAAe,EAAkC,CAC9D,EAAe,EAAI,EACnB,EAAS,IAAI,EAEb,GAAI,CACF,MAAA,EAAA,EAAA,iCAAsC,CAAS,EAC/C,MAAM,EAAgB,CACxB,OAAS,EAAuB,CAC9B,EAAS,EAAiB,CAAY,CAAC,CACzC,QAAU,CACR,EAAe,EAAK,CACtB,CACF,CAEA,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACI,EAAA,EAAA,KAAC,EAAA,WAAD,CAAA,UACE,EAAA,EAAA,KAAC,EAAA,QAAD,CACE,YAAY,wBACZ,gBAAyB,EAAO,KAAK,EAAO,UAAU,CAAC,EACvD,MAAO,GAAQ,SAAS,MAAQ,MACjC,CAAA,CACS,CAAA,GAEZ,EAAA,EAAA,KAAC,EAAA,aAAD,CAAA,UACE,EAAA,EAAA,MAAC,EAAA,QAAD,CAAA,SAAA,CACG,GACC,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,gBACpC,CACS,CAAA,EACV,MACJ,EAAA,EAAA,KAAC,EAAA,MAAD,CACW,UACA,UACT,WAAY,EACZ,UAAA,GACS,SACV,CAAA,CACM,CAAA,CAAA,CACG,CAAA,CACd,CAAA,CAAA,CAER,CAEA,SAAS,EAAiB,EAAwB,CAChD,OAAO,aAAiB,MAAQ,EAAM,QAAU,QAClD"}
@@ -1,27 +1,27 @@
1
1
  "use client";
2
- import { r as e } from "../../../chunks/router-adapter-BdHZXLS3.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 { r as n } from "../../../chunks/routes-config-dxahImVe.js";
4
+ import { r as n } from "../../../chunks/routes-config-RBYQtUd0.js";
5
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";
8
- import h from "@mezzanine-ui/react/ContentHeader";
9
- import { readTemplateDesigner as g, rollbackApprovalTemplateVersion as _ } from "@rytass/bpm-core-client/template";
6
+ import { PageHeader as o, Section as s, SectionGroup as c, Table as l, Typography as u } from "@mezzanine-ui/react";
7
+ import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
8
+ import m from "@mezzanine-ui/react/ContentHeader";
9
+ import { readTemplateDesigner as h, rollbackApprovalTemplateVersion as g } from "@rytass/bpm-core-client/template";
10
10
  //#region src/views/templates/versions/TemplateVersionsView.tsx
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);
11
+ function _({ templateId: _ }) {
12
+ let y = e(), b = n(), [x, S] = a(null), [C, w] = a(null), [T, E] = a(!0), [D, O] = a(!1);
13
13
  r(() => {
14
- N();
15
- }, [v]);
16
- let A = i(() => (S?.versions ?? []).map((e) => ({
17
- formVersion: S?.formVersions.find((t) => t.id === e.formDefinitionVersionId)?.label ?? "未綁定",
14
+ M();
15
+ }, [_]);
16
+ let k = i(() => (x?.versions ?? []).map((e) => ({
17
+ formVersion: x?.formVersions.find((t) => t.id === e.formDefinitionVersionId)?.label ?? "未綁定",
18
18
  key: e.id,
19
19
  publishedAt: t(e.publishedAt),
20
20
  status: e.status,
21
21
  updatedAt: t(e.updatedAt),
22
22
  version: `v${e.version}`,
23
23
  versionId: e.id
24
- })), [S]), j = i(() => [
24
+ })), [x]), A = i(() => [
25
25
  {
26
26
  dataIndex: "version",
27
27
  key: "version",
@@ -52,59 +52,55 @@ function v({ templateId: v }) {
52
52
  title: "更新時間",
53
53
  width: 200
54
54
  }
55
- ], []), M = i(() => ({
55
+ ], []), j = i(() => ({
56
56
  render: (e) => [{
57
- disabled: () => O || e.status === "DRAFT",
57
+ disabled: () => D || e.status === "DRAFT",
58
58
  name: "Rollback",
59
- onClick: () => void P(e.versionId)
59
+ onClick: () => void N(e.versionId)
60
60
  }],
61
61
  variant: "base-secondary",
62
62
  width: 104
63
- }), [O]);
64
- async function N() {
65
- D(!0), T(null);
63
+ }), [D]);
64
+ async function M() {
65
+ E(!0), w(null);
66
66
  try {
67
- C(await g(v));
67
+ S(await h(_));
68
68
  } catch (e) {
69
- T(y(e));
69
+ w(v(e));
70
70
  } finally {
71
- D(!1);
71
+ E(!1);
72
72
  }
73
73
  }
74
- async function P(e) {
75
- k(!0), T(null);
74
+ async function N(e) {
75
+ O(!0), w(null);
76
76
  try {
77
- await _(e), await N();
77
+ await g(e), await M();
78
78
  } catch (e) {
79
- T(y(e));
79
+ w(v(e));
80
80
  } finally {
81
- k(!1);
81
+ O(!1);
82
82
  }
83
83
  }
84
- return /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(s, { children: /* @__PURE__ */ p(h, {
84
+ return /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(o, { children: /* @__PURE__ */ f(m, {
85
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, {
86
+ onBackClick: () => y.push(b.templates()),
87
+ title: x?.template.name ?? "模板版本"
88
+ }) }), /* @__PURE__ */ f(c, { children: /* @__PURE__ */ p(s, { children: [C ? /* @__PURE__ */ f(u, {
93
89
  color: "text-error",
94
90
  variant: "body",
95
- children: w
96
- }) : null, /* @__PURE__ */ p(u, {
97
- actions: M,
98
- columns: j,
99
- dataSource: A,
91
+ children: C
92
+ }) : null, /* @__PURE__ */ f(l, {
93
+ actions: j,
94
+ columns: A,
95
+ dataSource: k,
100
96
  fullWidth: !0,
101
- loading: E
97
+ loading: T
102
98
  })] }) })] });
103
99
  }
104
- function y(e) {
100
+ function v(e) {
105
101
  return e instanceof Error ? e.message : "發生未知錯誤";
106
102
  }
107
103
  //#endregion
108
- export { v as TemplateVersionsView };
104
+ export { _ as TemplateVersionsView };
109
105
 
110
106
  //# sourceMappingURL=index.js.map