@rytass/bpm-core-react 0.17.6 → 0.17.7

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 (98) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/chunks/{FormBuilderView-aBcA-_tt.cjs → FormBuilderView-CUOyS07f.cjs} +2 -2
  3. package/dist/chunks/{FormBuilderView-aBcA-_tt.cjs.map → FormBuilderView-CUOyS07f.cjs.map} +1 -1
  4. package/dist/chunks/{FormBuilderView-BYL42M0d.js → FormBuilderView-ClLnQ1e_.js} +2 -2
  5. package/dist/chunks/{FormBuilderView-BYL42M0d.js.map → FormBuilderView-ClLnQ1e_.js.map} +1 -1
  6. package/dist/chunks/{FormRendererView-cZGOOjU5.js → FormRendererView-BsTwZkqU.js} +207 -198
  7. package/dist/chunks/FormRendererView-BsTwZkqU.js.map +1 -0
  8. package/dist/chunks/FormRendererView-GpsE03np.cjs +4 -0
  9. package/dist/chunks/FormRendererView-GpsE03np.cjs.map +1 -0
  10. package/dist/chunks/approver-filled-form-D1DmqDVP.cjs +2 -0
  11. package/dist/chunks/approver-filled-form-D1DmqDVP.cjs.map +1 -0
  12. package/dist/chunks/approver-filled-form-DuQGPtNB.js +95 -0
  13. package/dist/chunks/approver-filled-form-DuQGPtNB.js.map +1 -0
  14. package/dist/chunks/{compose-DOEaPfEC.cjs → compose-DjEJi5Dv.cjs} +2 -2
  15. package/dist/chunks/{compose-DOEaPfEC.cjs.map → compose-DjEJi5Dv.cjs.map} +1 -1
  16. package/dist/chunks/{compose-v1Vcw9hE.js → compose-WekGZj74.js} +4 -4
  17. package/dist/chunks/{compose-v1Vcw9hE.js.map → compose-WekGZj74.js.map} +1 -1
  18. package/dist/chunks/{designer-DBBrktom.js → designer-D87ILhjz.js} +1664 -1182
  19. package/dist/chunks/designer-D87ILhjz.js.map +1 -0
  20. package/dist/chunks/designer-DESS0CMl.cjs +65 -0
  21. package/dist/chunks/designer-DESS0CMl.cjs.map +1 -0
  22. package/dist/chunks/detail-D49NuNCn.cjs +2 -0
  23. package/dist/chunks/detail-D49NuNCn.cjs.map +1 -0
  24. package/dist/chunks/{detail-B_bSg31B.js → detail-URwxkcro.js} +1036 -847
  25. package/dist/chunks/detail-URwxkcro.js.map +1 -0
  26. package/dist/chunks/{providers-H_vPRsSN.js → providers-B_d5tbCL.js} +178 -167
  27. package/dist/chunks/providers-B_d5tbCL.js.map +1 -0
  28. package/dist/chunks/providers-chuJvMgv.cjs +2 -0
  29. package/dist/chunks/providers-chuJvMgv.cjs.map +1 -0
  30. package/dist/index.cjs +1 -1
  31. package/dist/index.js +1 -1
  32. package/dist/next/index.cjs +1 -1
  33. package/dist/next/index.js +1 -1
  34. package/dist/next/workflow-chat-route.cjs +1 -0
  35. package/dist/next/workflow-chat-route.cjs.map +1 -1
  36. package/dist/next/workflow-chat-route.d.cts +1 -1
  37. package/dist/next/workflow-chat-route.d.ts +1 -1
  38. package/dist/next/workflow-chat-route.js +1 -1
  39. package/dist/next/workflow-chat-route.js.map +1 -1
  40. package/dist/pages/instances/detail/index.cjs +1 -1
  41. package/dist/pages/instances/detail/index.js +1 -1
  42. package/dist/pages/templates/compose/index.cjs +1 -1
  43. package/dist/pages/templates/compose/index.js +1 -1
  44. package/dist/pages/templates/designer/index.cjs +1 -1
  45. package/dist/pages/templates/designer/index.js +1 -1
  46. package/dist/views/forms/builder/index.cjs +1 -1
  47. package/dist/views/forms/builder/index.js +1 -1
  48. package/dist/views/forms/renderer/FormRendererView.d.cts +16 -1
  49. package/dist/views/forms/renderer/FormRendererView.d.ts +16 -1
  50. package/dist/views/forms/renderer/index.cjs +1 -1
  51. package/dist/views/forms/renderer/index.js +1 -1
  52. package/dist/views/inbox/index.cjs +1 -1
  53. package/dist/views/inbox/index.cjs.map +1 -1
  54. package/dist/views/inbox/index.js +109 -99
  55. package/dist/views/inbox/index.js.map +1 -1
  56. package/dist/views/instances/approver-filled-form.d.cts +76 -0
  57. package/dist/views/instances/approver-filled-form.d.ts +76 -0
  58. package/dist/views/instances/detail/index.cjs +1 -1
  59. package/dist/views/instances/detail/index.js +1 -1
  60. package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +30 -2
  61. package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +30 -2
  62. package/dist/views/instances/detail/sections/InstanceHistorySection.d.cts +4 -1
  63. package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +4 -1
  64. package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +21 -0
  65. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +21 -0
  66. package/dist/views/instances/detail/sections/container-helpers.d.cts +1 -1
  67. package/dist/views/instances/detail/sections/container-helpers.d.ts +1 -1
  68. package/dist/views/instances/detail/sections/shared.d.cts +11 -2
  69. package/dist/views/instances/detail/sections/shared.d.ts +11 -2
  70. package/dist/views/instances/new/index.cjs +1 -1
  71. package/dist/views/instances/new/index.cjs.map +1 -1
  72. package/dist/views/instances/new/index.js +88 -87
  73. package/dist/views/instances/new/index.js.map +1 -1
  74. package/dist/views/instances/viewer-field-access.d.cts +22 -0
  75. package/dist/views/instances/viewer-field-access.d.ts +22 -0
  76. package/dist/views/templates/compose/index.cjs +1 -1
  77. package/dist/views/templates/compose/index.js +1 -1
  78. package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.cts +33 -0
  79. package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.ts +33 -0
  80. package/dist/views/templates/designer/field-access-matrix/FieldAccessNodeSection.d.cts +20 -0
  81. package/dist/views/templates/designer/field-access-matrix/FieldAccessNodeSection.d.ts +20 -0
  82. package/dist/views/templates/designer/field-access-matrix/field-access-copy.d.cts +22 -0
  83. package/dist/views/templates/designer/field-access-matrix/field-access-copy.d.ts +22 -0
  84. package/dist/views/templates/designer/index.cjs +1 -1
  85. package/dist/views/templates/designer/index.js +1 -1
  86. package/package.json +3 -3
  87. package/dist/chunks/FormRendererView-DRFi_IH7.cjs +0 -4
  88. package/dist/chunks/FormRendererView-DRFi_IH7.cjs.map +0 -1
  89. package/dist/chunks/FormRendererView-cZGOOjU5.js.map +0 -1
  90. package/dist/chunks/designer-CTXMqCD2.cjs +0 -65
  91. package/dist/chunks/designer-CTXMqCD2.cjs.map +0 -1
  92. package/dist/chunks/designer-DBBrktom.js.map +0 -1
  93. package/dist/chunks/detail-BQSVgVlO.cjs +0 -2
  94. package/dist/chunks/detail-BQSVgVlO.cjs.map +0 -1
  95. package/dist/chunks/detail-B_bSg31B.js.map +0 -1
  96. package/dist/chunks/providers-DP7b0TMN.cjs +0 -2
  97. package/dist/chunks/providers-DP7b0TMN.cjs.map +0 -1
  98. package/dist/chunks/providers-H_vPRsSN.js.map +0 -1
@@ -1,12 +1,27 @@
1
1
  import { CSSProperties, ReactElement } from 'react';
2
2
  import { FormDataSourceValueSnapshots, FormDefinitionSchema, FormFieldDefinition, FormUiSchema } from '@rytass/bpm-core-shared/form';
3
3
  import { FormRendererValues } from '@rytass/bpm-core-client/form';
4
+ import { ResolvedFieldAccess } from '@rytass/bpm-core-shared';
4
5
  import { FormDataSourceFieldState, FormRendererDataSourceContext } from './form-data-source-field.cjs';
5
6
  export interface FormRendererProps {
6
7
  readonly dataSourceContext?: FormRendererDataSourceContext;
7
8
  readonly dataSourceInitialValues?: FormRendererValues;
8
9
  readonly emptyText?: string;
9
10
  readonly errors?: Readonly<Record<string, string>>;
11
+ /**
12
+ * Per top-level field, what this viewer may see and edit (ADR 20 §3.3,
13
+ * `resolveFieldAccess`). A field with `visible: false` is not rendered; one
14
+ * with `editable: true` stays editable inside a `readonly` form, and one
15
+ * with `editable: false` is read-only in an editable form. The form's own
16
+ * rules (`hidden`, `visibleWhen`, `readonlyWhen`) still apply. A field the
17
+ * map leaves out follows `readonly`; leaving the prop out changes nothing.
18
+ */
19
+ readonly fieldAccess?: Readonly<Record<string, ResolvedFieldAccess>>;
20
+ /**
21
+ * Short text shown after a field's label (Mezzanine `labelOptionalMarker`),
22
+ * per top-level field — e.g. 「本關補填」 on the fields an approver fills.
23
+ */
24
+ readonly fieldLabelMarkers?: Readonly<Record<string, string>>;
10
25
  readonly maxWidth?: CSSProperties['maxWidth'];
11
26
  readonly onChange?: (values: FormRendererValues) => void;
12
27
  readonly onDataSourceStateChange?: (fieldKey: string, state: Pick<FormDataSourceFieldState, 'hasValue' | 'invalidValues' | 'status'>) => void;
@@ -20,5 +35,5 @@ export interface FormRendererProps {
20
35
  readonly uiSchema: FormUiSchema;
21
36
  readonly value?: FormRendererValues;
22
37
  }
23
- export declare function FormRenderer({ dataSourceContext, dataSourceInitialValues, emptyText, errors, maxWidth, onChange, onDataSourceStateChange, onUploadAttachment, optionSnapshots, readonly, schema, singleColumn, uiSchema, value, }: FormRendererProps): ReactElement;
38
+ export declare function FormRenderer({ dataSourceContext, dataSourceInitialValues, emptyText, errors, fieldAccess, fieldLabelMarkers, maxWidth, onChange, onDataSourceStateChange, onUploadAttachment, optionSnapshots, readonly, schema, singleColumn, uiSchema, value, }: FormRendererProps): ReactElement;
24
39
  export { FormRenderer as FormRendererView };
@@ -1,12 +1,27 @@
1
1
  import { CSSProperties, ReactElement } from 'react';
2
2
  import { FormDataSourceValueSnapshots, FormDefinitionSchema, FormFieldDefinition, FormUiSchema } from '@rytass/bpm-core-shared/form';
3
3
  import { FormRendererValues } from '@rytass/bpm-core-client/form';
4
+ import { ResolvedFieldAccess } from '@rytass/bpm-core-shared';
4
5
  import { FormDataSourceFieldState, FormRendererDataSourceContext } from './form-data-source-field.js';
5
6
  export interface FormRendererProps {
6
7
  readonly dataSourceContext?: FormRendererDataSourceContext;
7
8
  readonly dataSourceInitialValues?: FormRendererValues;
8
9
  readonly emptyText?: string;
9
10
  readonly errors?: Readonly<Record<string, string>>;
11
+ /**
12
+ * Per top-level field, what this viewer may see and edit (ADR 20 §3.3,
13
+ * `resolveFieldAccess`). A field with `visible: false` is not rendered; one
14
+ * with `editable: true` stays editable inside a `readonly` form, and one
15
+ * with `editable: false` is read-only in an editable form. The form's own
16
+ * rules (`hidden`, `visibleWhen`, `readonlyWhen`) still apply. A field the
17
+ * map leaves out follows `readonly`; leaving the prop out changes nothing.
18
+ */
19
+ readonly fieldAccess?: Readonly<Record<string, ResolvedFieldAccess>>;
20
+ /**
21
+ * Short text shown after a field's label (Mezzanine `labelOptionalMarker`),
22
+ * per top-level field — e.g. 「本關補填」 on the fields an approver fills.
23
+ */
24
+ readonly fieldLabelMarkers?: Readonly<Record<string, string>>;
10
25
  readonly maxWidth?: CSSProperties['maxWidth'];
11
26
  readonly onChange?: (values: FormRendererValues) => void;
12
27
  readonly onDataSourceStateChange?: (fieldKey: string, state: Pick<FormDataSourceFieldState, 'hasValue' | 'invalidValues' | 'status'>) => void;
@@ -20,5 +35,5 @@ export interface FormRendererProps {
20
35
  readonly uiSchema: FormUiSchema;
21
36
  readonly value?: FormRendererValues;
22
37
  }
23
- export declare function FormRenderer({ dataSourceContext, dataSourceInitialValues, emptyText, errors, maxWidth, onChange, onDataSourceStateChange, onUploadAttachment, optionSnapshots, readonly, schema, singleColumn, uiSchema, value, }: FormRendererProps): ReactElement;
38
+ export declare function FormRenderer({ dataSourceContext, dataSourceInitialValues, emptyText, errors, fieldAccess, fieldLabelMarkers, maxWidth, onChange, onDataSourceStateChange, onUploadAttachment, optionSnapshots, readonly, schema, singleColumn, uiSchema, value, }: FormRendererProps): ReactElement;
24
39
  export { FormRenderer as FormRendererView };
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-DRFi_IH7.cjs");exports.FormRenderer=e.t,exports.FormRendererView=e.t,exports.isFormDataSourceFieldSubmissionBlocked=e.i,exports.readFormDataSourceFieldStatusMessage=e.a,exports.readFormDataSourceSubmissionBlockMessage=e.o,exports.useFormDataSourceField=e.s;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-GpsE03np.cjs");exports.FormRenderer=e.t,exports.FormRendererView=e.t,exports.isFormDataSourceFieldSubmissionBlocked=e.i,exports.readFormDataSourceFieldStatusMessage=e.a,exports.readFormDataSourceSubmissionBlockMessage=e.o,exports.useFormDataSourceField=e.s;
@@ -1 +1 @@
1
- export { t as FormRenderer, t as FormRendererView, i as isFormDataSourceFieldSubmissionBlocked, a as readFormDataSourceFieldStatusMessage, o as readFormDataSourceSubmissionBlockMessage, s as useFormDataSourceField } from "../../../chunks/FormRendererView-cZGOOjU5.js";
1
+ export { t as FormRenderer, t as FormRendererView, i as isFormDataSourceFieldSubmissionBlocked, a as readFormDataSourceFieldStatusMessage, o as readFormDataSourceSubmissionBlockMessage, s as useFormDataSourceField } from "../../../chunks/FormRendererView-BsTwZkqU.js";
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/router-adapter--gYs13E8.cjs"),n=require("../../chunks/auth-provider-4BeCw7cI.cjs"),r=require("../../chunks/format-date-time-D-cx5M8z.cjs"),i=require("../../chunks/routes-config-C1j_vFKo.cjs"),a=require("../../chunks/task-node-label-BF6UllxP.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/icons");function f(){let e=t.r(),a=i.r(),{member:f}=n.n(),h=f?.memberId??null,[g,_]=(0,o.useState)(`pending`),[v,y]=(0,o.useState)(null),[x,C]=(0,o.useState)([]),[T,E]=(0,o.useState)(!0),[D,O]=(0,o.useState)([]);(0,o.useEffect)(()=>{h&&I()},[h]);let A=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{dataIndex:`statusLabel`,key:`statusLabel`,title:`狀態`,width:120},{key:`slaDueAt`,render:e=>(0,c.jsx)(s.Typography,{color:e.slaStatusColor,component:`span`,variant:`body`,children:e.slaStatusText}),title:`SLA`,width:180},{key:`createdAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:r.t(e.createdAt)}),title:`建立時間`,width:220}],[]),j=(0,o.useMemo)(()=>({render:t=>[{name:`處理`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),M=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{key:`decisionLabel`,render:e=>(0,c.jsx)(s.Typography,{color:b(e.decisionAction),component:`span`,variant:`body`,children:e.decisionLabel}),title:`決議`,width:120},{key:`decisionComment`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.decisionCommentText}),title:`意見`,width:240},{key:`instanceStateLabel`,render:e=>(0,c.jsx)(s.Typography,{color:S(e.instanceState),component:`span`,variant:`body`,children:e.instanceStateLabel}),title:`流程狀態`,width:140},{key:`decidedAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:w(e.decidedAt)}),title:`簽核時間`,width:220}],[]),N=(0,o.useMemo)(()=>({render:t=>[{name:`查看`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),P=(0,o.useMemo)(()=>x.filter(e=>e.instanceState===`RUNNING`),[x]);function F(e){_(e===`history`||e===`pending`||e===`tracking`?e:`pending`)}async function I(){E(!0),y(null);try{if(!h){O([]),C([]);return}let[e,t]=await Promise.all([(0,l.listInboxTasks)(h),(0,l.listApprovalHistoryTasks)(h)]),[n,r]=await Promise.all([p(e),m(t)]);O(n),C(r)}catch(e){y(k(e))}finally{E(!1)}}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(u.default,{description:`目前以 ${f?.name??h??`目前登入會員`} 查詢待處理與歷史簽核任務。`,title:`我的待簽`,children:(0,c.jsx)(s.Button,{icon:d.PlusIcon,iconType:`leading`,onClick:()=>e.push(a.caseNew()),variant:`base-primary`,children:`發起簽核`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{children:[v?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:v}):null,(0,c.jsxs)(s.Tab,{activeKey:g,onChange:F,size:`sub`,children:[(0,c.jsx)(s.TabItem,{badgeCount:T?void 0:D.length,children:`待簽核`},`pending`),(0,c.jsx)(s.TabItem,{badgeCount:T?void 0:P.length,children:`已處理未結束`},`tracking`),(0,c.jsx)(s.TabItem,{children:`歷史簽核記錄`},`history`)]}),g===`pending`?(0,c.jsx)(s.Table,{actions:j,columns:A,dataSource:D,fullWidth:!0,loading:T}):null,g===`tracking`?(0,c.jsx)(s.Table,{actions:N,columns:M,dataSource:P,fullWidth:!0,loading:T}):null,g===`history`?(0,c.jsx)(s.Table,{actions:N,columns:M,dataSource:x,fullWidth:!0,loading:T}):null]})})]})}async function p(e){let t=await h(e);return e.map((e,n)=>({...e,caseTitle:g(e,t[n]??null),key:e.id,nodeText:a.t(e),slaStatusColor:E(e.slaDueAt),slaStatusText:T(e.slaDueAt),statusLabel:O(e.status)}))}async function m(e){let[t,n]=await Promise.all([Promise.all(e.map(e=>(0,l.listTaskDecisions)(e.id))),h(e)]);return e.map((e,r)=>{let i=_(t[r]??[]),o=n[r]??null;return{...e,caseTitle:g(e,o),decisionAction:i?.action??null,decisionComment:i?.comment??null,decisionCommentText:C(i?.comment??null),decisionLabel:y(i?.action??null),decidedAt:i?.decidedAt??e.completedAt,instanceState:o?.state??null,instanceStateLabel:x(o?.state??null),key:e.id,nodeText:a.t(e)}})}async function h(e){return Promise.all(e.map(async e=>{try{return(await(0,l.readApprovalInstance)(e.instanceId)).instance}catch{return null}}))}function g(e,t){return t?(0,l.readApprovalInstanceCaseTitle)(t):e.instanceId}function _(e){return[...e].sort(v)[0]??null}function v(e,t){return new Date(t.decidedAt).getTime()-new Date(e.decidedAt).getTime()}function y(e){return e===`APPROVED`?`同意`:e===`REJECTED`?`拒絕`:e===`RETURNED`?`退回`:e===`TRANSFERRED`?`轉派`:`未記錄`}function b(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`RETURNED`?`text-error`:`text-neutral`}function x(e){return e===`RUNNING`?`進行中`:e===`APPROVED`?`已通過`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`CANCELLED`?`已取消`:e===`EXPIRED`?`已逾期`:e===`DRAFT`?`草稿`:`-`}function S(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`CANCELLED`||e===`EXPIRED`?`text-error`:`text-neutral`}function C(e){return(e?.trim()??``)||`-`}function w(e){return r.t(e)}function T(e){if(!e)return`-`;let t=new Date(e).getTime(),n=Date.now(),r=D(Math.abs(t-n));return t<n?`已逾期 ${r}`:`剩餘 ${r}`}function E(e){return e?new Date(e).getTime()<Date.now()?`text-error`:`text-success`:`text-neutral`}function D(e){let t=Math.max(1,Math.ceil(e/6e4)),n=Math.floor(t/1440),r=Math.floor(t%1440/60),i=t%60;return n>0?`${n}天 ${r}小時`:r>0?`${r}小時 ${i}分鐘`:`${i}分鐘`}function O(e){return e===`PENDING`?`待處理`:e===`IN_PROGRESS`?`處理中`:e===`COMPLETED`?`已完成`:e===`TRANSFERRED`?`已轉派`:e===`CANCELLED`?`已取消`:e}function k(e){return e instanceof Error?e.message:`發生未知錯誤`}exports.InboxView=f;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/router-adapter--gYs13E8.cjs"),n=require("../../chunks/auth-provider-4BeCw7cI.cjs"),r=require("../../chunks/format-date-time-D-cx5M8z.cjs"),i=require("../../chunks/routes-config-C1j_vFKo.cjs"),a=require("../../chunks/task-node-label-BF6UllxP.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/icons");function f(){let e=t.r(),a=i.r(),{member:f}=n.n(),h=f?.memberId??null,[g,_]=(0,o.useState)(`pending`),[v,y]=(0,o.useState)(null),[x,C]=(0,o.useState)([]),[T,E]=(0,o.useState)(!0),[D,O]=(0,o.useState)([]);(0,o.useEffect)(()=>{h&&I()},[h]);let A=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{dataIndex:`statusLabel`,key:`statusLabel`,title:`狀態`,width:120},{key:`fill`,render:e=>e.hasFillableFields?(0,c.jsx)(s.Badge,{size:`sub`,text:`需補填`,variant:`dot-warning`}):null,title:`補填`,width:120},{key:`slaDueAt`,render:e=>(0,c.jsx)(s.Typography,{color:e.slaStatusColor,component:`span`,variant:`body`,children:e.slaStatusText}),title:`SLA`,width:180},{key:`createdAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:r.t(e.createdAt)}),title:`建立時間`,width:220}],[]),j=(0,o.useMemo)(()=>({render:t=>[{name:`處理`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),M=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{key:`decisionLabel`,render:e=>(0,c.jsx)(s.Typography,{color:b(e.decisionAction),component:`span`,variant:`body`,children:e.decisionLabel}),title:`決議`,width:120},{key:`decisionComment`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.decisionCommentText}),title:`意見`,width:240},{key:`instanceStateLabel`,render:e=>(0,c.jsx)(s.Typography,{color:S(e.instanceState),component:`span`,variant:`body`,children:e.instanceStateLabel}),title:`流程狀態`,width:140},{key:`decidedAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:w(e.decidedAt)}),title:`簽核時間`,width:220}],[]),N=(0,o.useMemo)(()=>({render:t=>[{name:`查看`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),P=(0,o.useMemo)(()=>x.filter(e=>e.instanceState===`RUNNING`),[x]);function F(e){_(e===`history`||e===`pending`||e===`tracking`?e:`pending`)}async function I(){E(!0),y(null);try{if(!h){O([]),C([]);return}let[e,t]=await Promise.all([(0,l.listInboxTasks)(h),(0,l.listApprovalHistoryTasks)(h)]),[n,r]=await Promise.all([p(e),m(t)]);O(n),C(r)}catch(e){y(k(e))}finally{E(!1)}}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(u.default,{description:`目前以 ${f?.name??h??`目前登入會員`} 查詢待處理與歷史簽核任務。`,title:`我的待簽`,children:(0,c.jsx)(s.Button,{icon:d.PlusIcon,iconType:`leading`,onClick:()=>e.push(a.caseNew()),variant:`base-primary`,children:`發起簽核`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{children:[v?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:v}):null,(0,c.jsxs)(s.Tab,{activeKey:g,onChange:F,size:`sub`,children:[(0,c.jsx)(s.TabItem,{badgeCount:T?void 0:D.length,children:`待簽核`},`pending`),(0,c.jsx)(s.TabItem,{badgeCount:T?void 0:P.length,children:`已處理未結束`},`tracking`),(0,c.jsx)(s.TabItem,{children:`歷史簽核記錄`},`history`)]}),g===`pending`?(0,c.jsx)(s.Table,{actions:j,columns:A,dataSource:D,fullWidth:!0,loading:T}):null,g===`tracking`?(0,c.jsx)(s.Table,{actions:N,columns:M,dataSource:P,fullWidth:!0,loading:T}):null,g===`history`?(0,c.jsx)(s.Table,{actions:N,columns:M,dataSource:x,fullWidth:!0,loading:T}):null]})})]})}async function p(e){let t=await h(e);return e.map((e,n)=>({...e,caseTitle:g(e,t[n]??null),key:e.id,nodeText:a.t(e),slaStatusColor:E(e.slaDueAt),slaStatusText:T(e.slaDueAt),statusLabel:O(e.status)}))}async function m(e){let[t,n]=await Promise.all([Promise.all(e.map(e=>(0,l.listTaskDecisions)(e.id))),h(e)]);return e.map((e,r)=>{let i=_(t[r]??[]),o=n[r]??null;return{...e,caseTitle:g(e,o),decisionAction:i?.action??null,decisionComment:i?.comment??null,decisionCommentText:C(i?.comment??null),decisionLabel:y(i?.action??null),decidedAt:i?.decidedAt??e.completedAt,instanceState:o?.state??null,instanceStateLabel:x(o?.state??null),key:e.id,nodeText:a.t(e)}})}async function h(e){return Promise.all(e.map(async e=>{try{return(await(0,l.readApprovalInstance)(e.instanceId)).instance}catch{return null}}))}function g(e,t){return t?(0,l.readApprovalInstanceCaseTitle)(t):e.instanceId}function _(e){return[...e].sort(v)[0]??null}function v(e,t){return new Date(t.decidedAt).getTime()-new Date(e.decidedAt).getTime()}function y(e){return e===`APPROVED`?`同意`:e===`REJECTED`?`拒絕`:e===`RETURNED`?`退回`:e===`TRANSFERRED`?`轉派`:`未記錄`}function b(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`RETURNED`?`text-error`:`text-neutral`}function x(e){return e===`RUNNING`?`進行中`:e===`APPROVED`?`已通過`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`CANCELLED`?`已取消`:e===`EXPIRED`?`已逾期`:e===`DRAFT`?`草稿`:`-`}function S(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`CANCELLED`||e===`EXPIRED`?`text-error`:`text-neutral`}function C(e){return(e?.trim()??``)||`-`}function w(e){return r.t(e)}function T(e){if(!e)return`-`;let t=new Date(e).getTime(),n=Date.now(),r=D(Math.abs(t-n));return t<n?`已逾期 ${r}`:`剩餘 ${r}`}function E(e){return e?new Date(e).getTime()<Date.now()?`text-error`:`text-success`:`text-neutral`}function D(e){let t=Math.max(1,Math.ceil(e/6e4)),n=Math.floor(t/1440),r=Math.floor(t%1440/60),i=t%60;return n>0?`${n}天 ${r}小時`:r>0?`${r}小時 ${i}分鐘`:`${i}分鐘`}function O(e){return e===`PENDING`?`待處理`:e===`IN_PROGRESS`?`處理中`:e===`COMPLETED`?`已完成`:e===`TRANSFERRED`?`已轉派`:e===`CANCELLED`?`已取消`:e}function k(e){return e instanceof Error?e.message:`發生未知錯誤`}exports.InboxView=f;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useRouterAdapter","useBPMRoutes","useAuth","useState","useMemo","Typography","formatDateTime","listInboxTasks","listApprovalHistoryTasks","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Tab","TabItem","Table","readTaskNodeText","listTaskDecisions","readApprovalInstance","readApprovalInstanceCaseTitle","require_rolldown_runtime","require_router_adapter","require_auth_provider","require_format_date_time","require_routes_config","require_task_node_label","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","error","setError","historyRows","setHistoryRows","loading","setLoading","pendingRows","setPendingRows","refreshTasks","pendingColumns","record","pendingTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","trackingRows","row","handleTabChange","activeKey","nextPendingTasks","nextHistoryTasks","nextPendingRows","nextHistoryRows","readInboxTaskRows","readApprovalHistoryRows","requestError","readErrorMessage","instances","readTaskInstances","tasks","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","decision","readLatestTaskDecision","instance","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","decisions","compareTaskDecisionDesc","right","left","action","state","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport { type Key, ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\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 type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n ApprovalInstanceRecord,\n listApprovalHistoryTasks,\n listInboxTasks,\n listTaskDecisions,\n readApprovalInstance,\n readApprovalInstanceCaseTitle,\n TaskDecisionRecord,\n TaskRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useAuth } from '../../lib/auth-provider';\nimport { readTaskNodeText } from '../../lib/task-node-label';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\n\ntype InboxTabKey = 'history' | 'pending' | 'tracking';\n\ntype InboxTaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n key: string;\n nodeText: string;\n slaStatusColor: 'text-error' | 'text-neutral' | 'text-success';\n slaStatusText: string;\n statusLabel: string;\n }\n>;\n\ntype ApprovalHistoryRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n decisionAction: TaskDecisionRecord['action'] | null;\n decisionComment: string | null;\n decisionCommentText: string;\n decisionLabel: string;\n decidedAt: string | null;\n instanceState: ApprovalInstanceRecord['state'] | null;\n instanceStateLabel: string;\n key: string;\n nodeText: string;\n }\n>;\n\n\n/**\n * Framework-agnostic view for the BPM \"我的待簽\" inbox. Mechanical port of\n * `apps/client/src/app/inbox/page.tsx` — renders pending tasks, tracking,\n * and history tabs.\n */\nexport function InboxView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activeTab, setActiveTab] = useState<InboxTabKey>('pending');\n const [error, setError] = useState<string | null>(null);\n const [historyRows, setHistoryRows] = useState<ApprovalHistoryRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [pendingRows, setPendingRows] = useState<InboxTaskRow[]>([]);\n\n useEffect((): void => {\n if (!currentMemberId) {\n return;\n }\n\n void refreshTasks();\n }, [currentMemberId]);\n\n const pendingColumns = useMemo(\n (): TableColumn<InboxTaskRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'slaDueAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography\n color={record.slaStatusColor}\n component=\"span\"\n variant=\"body\"\n >\n {record.slaStatusText}\n </Typography>\n ),\n title: 'SLA',\n width: 180,\n },\n {\n key: 'createdAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.createdAt)}\n </Typography>\n ),\n title: '建立時間',\n width: 220,\n },\n ],\n [],\n );\n const pendingTableActions = useMemo(\n (): TableActions<InboxTaskRow> => ({\n render: (record): ReturnType<TableActions<InboxTaskRow>['render']> => [\n {\n name: '處理',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const historyColumns = useMemo(\n (): TableColumn<ApprovalHistoryRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n key: 'decisionLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readTaskDecisionColor(record.decisionAction)}\n component=\"span\"\n variant=\"body\"\n >\n {record.decisionLabel}\n </Typography>\n ),\n title: '決議',\n width: 120,\n },\n {\n key: 'decisionComment',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.decisionCommentText}\n </Typography>\n ),\n title: '意見',\n width: 240,\n },\n {\n key: 'instanceStateLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.instanceState)}\n component=\"span\"\n variant=\"body\"\n >\n {record.instanceStateLabel}\n </Typography>\n ),\n title: '流程狀態',\n width: 140,\n },\n {\n key: 'decidedAt',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatHistoryDateTime(record.decidedAt)}\n </Typography>\n ),\n title: '簽核時間',\n width: 220,\n },\n ],\n [],\n );\n const historyTableActions = useMemo(\n (): TableActions<ApprovalHistoryRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalHistoryRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const trackingRows = useMemo(\n (): ApprovalHistoryRow[] =>\n historyRows.filter((row) => row.instanceState === 'RUNNING'),\n [historyRows],\n );\n\n function handleTabChange(activeKey: Key): void {\n if (\n activeKey === 'history' ||\n activeKey === 'pending' ||\n activeKey === 'tracking'\n ) {\n setActiveTab(activeKey);\n return;\n }\n\n setActiveTab('pending');\n }\n\n async function refreshTasks(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n if (!currentMemberId) {\n setPendingRows([]);\n setHistoryRows([]);\n return;\n }\n\n const [nextPendingTasks, nextHistoryTasks] = await Promise.all([\n listInboxTasks(currentMemberId),\n listApprovalHistoryTasks(currentMemberId),\n ]);\n const [nextPendingRows, nextHistoryRows] = await Promise.all([\n readInboxTaskRows(nextPendingTasks),\n readApprovalHistoryRows(nextHistoryTasks),\n ]);\n\n setPendingRows(nextPendingRows);\n setHistoryRows(nextHistoryRows);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={`目前以 ${member?.name ?? currentMemberId ?? '目前登入會員'} 查詢待處理與歷史簽核任務。`}\n title=\"我的待簽\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.caseNew())}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab activeKey={activeTab} onChange={handleTabChange} size=\"sub\">\n <TabItem\n badgeCount={loading ? undefined : pendingRows.length}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={loading ? undefined : trackingRows.length}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={pendingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={trackingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={historyRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nasync function readInboxTaskRows(\n tasks: readonly TaskRecord[],\n): Promise<InboxTaskRow[]> {\n const instances = await readTaskInstances(tasks);\n\n return tasks.map(\n (task, index): InboxTaskRow => ({\n ...task,\n caseTitle: readTaskCaseTitle(task, instances[index] ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n slaStatusColor: readSlaStatusColor(task.slaDueAt),\n slaStatusText: readSlaStatusText(task.slaDueAt),\n statusLabel: readTaskStatusLabel(task.status),\n }),\n );\n}\n\nasync function readApprovalHistoryRows(\n tasks: readonly TaskRecord[],\n): Promise<ApprovalHistoryRow[]> {\n const [decisionLists, instances] = await Promise.all([\n Promise.all(tasks.map((task) => listTaskDecisions(task.id))),\n readTaskInstances(tasks),\n ]);\n\n return tasks.map((task, index): ApprovalHistoryRow => {\n const decision = readLatestTaskDecision(decisionLists[index] ?? []);\n const instance = instances[index] ?? null;\n\n return {\n ...task,\n caseTitle: readTaskCaseTitle(task, instance),\n decisionAction: decision?.action ?? null,\n decisionComment: decision?.comment ?? null,\n decisionCommentText: readDecisionCommentText(decision?.comment ?? null),\n decisionLabel: readTaskDecisionLabel(decision?.action ?? null),\n decidedAt: decision?.decidedAt ?? task.completedAt,\n instanceState: instance?.state ?? null,\n instanceStateLabel: readInstanceStateLabel(instance?.state ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n };\n });\n}\n\nasync function readTaskInstances(\n tasks: readonly TaskRecord[],\n): Promise<readonly (ApprovalInstanceRecord | null)[]> {\n return Promise.all(\n tasks.map(async (task): Promise<ApprovalInstanceRecord | null> => {\n try {\n return (await readApprovalInstance(task.instanceId)).instance;\n } catch {\n return null;\n }\n }),\n );\n}\n\nfunction readTaskCaseTitle(\n task: TaskRecord,\n instance: ApprovalInstanceRecord | null,\n): string {\n return instance ? readApprovalInstanceCaseTitle(instance) : task.instanceId;\n}\n\nfunction readLatestTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n): TaskDecisionRecord | null {\n return [...decisions].sort(compareTaskDecisionDesc)[0] ?? null;\n}\n\nfunction compareTaskDecisionDesc(\n left: TaskDecisionRecord,\n right: TaskDecisionRecord,\n): number {\n return (\n new Date(right.decidedAt).getTime() - new Date(left.decidedAt).getTime()\n );\n}\n\nfunction readTaskDecisionLabel(\n action: TaskDecisionRecord['action'] | null,\n): string {\n if (action === 'APPROVED') {\n return '同意';\n }\n\n if (action === 'REJECTED') {\n return '拒絕';\n }\n\n if (action === 'RETURNED') {\n return '退回';\n }\n\n if (action === 'TRANSFERRED') {\n return '轉派';\n }\n\n return '未記錄';\n}\n\nfunction readTaskDecisionColor(\n action: TaskDecisionRecord['action'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (action === 'APPROVED') {\n return 'text-success';\n }\n\n if (action === 'REJECTED' || action === 'RETURNED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readInstanceStateLabel(\n state: ApprovalInstanceRecord['state'] | null,\n): string {\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n if (state === 'APPROVED') {\n return '已通過';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n return '-';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceRecord['state'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') {\n return 'text-success';\n }\n\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readDecisionCommentText(comment: string | null): string {\n const trimmedComment = comment?.trim() ?? '';\n\n return trimmedComment || '-';\n}\n\nfunction formatHistoryDateTime(value: string | null): string {\n return formatDateTime(value);\n}\n\nfunction readSlaStatusText(value: string | null): string {\n if (!value) {\n return '-';\n }\n\n const dueAt = new Date(value).getTime();\n const now = Date.now();\n const diffMs = Math.abs(dueAt - now);\n const label = formatDuration(diffMs);\n\n return dueAt < now ? `已逾期 ${label}` : `剩餘 ${label}`;\n}\n\nfunction readSlaStatusColor(\n value: string | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (!value) {\n return 'text-neutral';\n }\n\n return new Date(value).getTime() < Date.now() ? 'text-error' : 'text-success';\n}\n\nfunction formatDuration(value: number): string {\n const totalMinutes = Math.max(1, Math.ceil(value / 60_000));\n const days = Math.floor(totalMinutes / 1440);\n const hours = Math.floor((totalMinutes % 1440) / 60);\n const minutes = totalMinutes % 60;\n\n if (days > 0) {\n return `${days}天 ${hours}小時`;\n }\n\n if (hours > 0) {\n return `${hours}小時 ${minutes}分鐘`;\n }\n\n return `${minutes}分鐘`;\n}\n\nfunction readTaskStatusLabel(status: TaskRecord['status']): string {\n if (status === 'PENDING') {\n return '待處理';\n }\n\n if (status === 'IN_PROGRESS') {\n return '處理中';\n }\n\n if (status === 'COMPLETED') {\n return '已完成';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n if (status === 'CANCELLED') {\n return '已取消';\n }\n\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["useRouterAdapter","useBPMRoutes","useAuth","useState","useMemo","Badge","Typography","formatDateTime","listInboxTasks","listApprovalHistoryTasks","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Tab","TabItem","Table","readTaskNodeText","listTaskDecisions","readApprovalInstance","readApprovalInstanceCaseTitle","require_rolldown_runtime","require_router_adapter","require_auth_provider","require_format_date_time","require_routes_config","require_task_node_label","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","error","setError","historyRows","setHistoryRows","loading","setLoading","pendingRows","setPendingRows","refreshTasks","pendingColumns","record","pendingTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","trackingRows","row","handleTabChange","activeKey","nextPendingTasks","nextHistoryTasks","nextPendingRows","nextHistoryRows","readInboxTaskRows","readApprovalHistoryRows","requestError","readErrorMessage","instances","readTaskInstances","tasks","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","decision","readLatestTaskDecision","instance","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","decisions","compareTaskDecisionDesc","right","left","action","state","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport { type Key, ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n PageHeader,\n Section,\n SectionGroup,\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 type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n ApprovalInstanceRecord,\n listApprovalHistoryTasks,\n listInboxTasks,\n listTaskDecisions,\n readApprovalInstance,\n readApprovalInstanceCaseTitle,\n TaskDecisionRecord,\n TaskRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useAuth } from '../../lib/auth-provider';\nimport { readTaskNodeText } from '../../lib/task-node-label';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\n\ntype InboxTabKey = 'history' | 'pending' | 'tracking';\n\ntype InboxTaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n key: string;\n nodeText: string;\n slaStatusColor: 'text-error' | 'text-neutral' | 'text-success';\n slaStatusText: string;\n statusLabel: string;\n }\n>;\n\ntype ApprovalHistoryRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n decisionAction: TaskDecisionRecord['action'] | null;\n decisionComment: string | null;\n decisionCommentText: string;\n decisionLabel: string;\n decidedAt: string | null;\n instanceState: ApprovalInstanceRecord['state'] | null;\n instanceStateLabel: string;\n key: string;\n nodeText: string;\n }\n>;\n\n\n/**\n * Framework-agnostic view for the BPM \"我的待簽\" inbox. Mechanical port of\n * `apps/client/src/app/inbox/page.tsx` — renders pending tasks, tracking,\n * and history tabs.\n */\nexport function InboxView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activeTab, setActiveTab] = useState<InboxTabKey>('pending');\n const [error, setError] = useState<string | null>(null);\n const [historyRows, setHistoryRows] = useState<ApprovalHistoryRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [pendingRows, setPendingRows] = useState<InboxTaskRow[]>([]);\n\n useEffect((): void => {\n if (!currentMemberId) {\n return;\n }\n\n void refreshTasks();\n }, [currentMemberId]);\n\n const pendingColumns = useMemo(\n (): TableColumn<InboxTaskRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'fill',\n // Approving one of these needs the case page, where the fill is entered.\n render: (record: InboxTaskRow): ReactElement | null =>\n record.hasFillableFields ? (\n <Badge size=\"sub\" text=\"需補填\" variant=\"dot-warning\" />\n ) : null,\n title: '補填',\n width: 120,\n },\n {\n key: 'slaDueAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography\n color={record.slaStatusColor}\n component=\"span\"\n variant=\"body\"\n >\n {record.slaStatusText}\n </Typography>\n ),\n title: 'SLA',\n width: 180,\n },\n {\n key: 'createdAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.createdAt)}\n </Typography>\n ),\n title: '建立時間',\n width: 220,\n },\n ],\n [],\n );\n const pendingTableActions = useMemo(\n (): TableActions<InboxTaskRow> => ({\n render: (record): ReturnType<TableActions<InboxTaskRow>['render']> => [\n {\n name: '處理',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const historyColumns = useMemo(\n (): TableColumn<ApprovalHistoryRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n key: 'decisionLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readTaskDecisionColor(record.decisionAction)}\n component=\"span\"\n variant=\"body\"\n >\n {record.decisionLabel}\n </Typography>\n ),\n title: '決議',\n width: 120,\n },\n {\n key: 'decisionComment',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.decisionCommentText}\n </Typography>\n ),\n title: '意見',\n width: 240,\n },\n {\n key: 'instanceStateLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.instanceState)}\n component=\"span\"\n variant=\"body\"\n >\n {record.instanceStateLabel}\n </Typography>\n ),\n title: '流程狀態',\n width: 140,\n },\n {\n key: 'decidedAt',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatHistoryDateTime(record.decidedAt)}\n </Typography>\n ),\n title: '簽核時間',\n width: 220,\n },\n ],\n [],\n );\n const historyTableActions = useMemo(\n (): TableActions<ApprovalHistoryRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalHistoryRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const trackingRows = useMemo(\n (): ApprovalHistoryRow[] =>\n historyRows.filter((row) => row.instanceState === 'RUNNING'),\n [historyRows],\n );\n\n function handleTabChange(activeKey: Key): void {\n if (\n activeKey === 'history' ||\n activeKey === 'pending' ||\n activeKey === 'tracking'\n ) {\n setActiveTab(activeKey);\n return;\n }\n\n setActiveTab('pending');\n }\n\n async function refreshTasks(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n if (!currentMemberId) {\n setPendingRows([]);\n setHistoryRows([]);\n return;\n }\n\n const [nextPendingTasks, nextHistoryTasks] = await Promise.all([\n listInboxTasks(currentMemberId),\n listApprovalHistoryTasks(currentMemberId),\n ]);\n const [nextPendingRows, nextHistoryRows] = await Promise.all([\n readInboxTaskRows(nextPendingTasks),\n readApprovalHistoryRows(nextHistoryTasks),\n ]);\n\n setPendingRows(nextPendingRows);\n setHistoryRows(nextHistoryRows);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={`目前以 ${member?.name ?? currentMemberId ?? '目前登入會員'} 查詢待處理與歷史簽核任務。`}\n title=\"我的待簽\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.caseNew())}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab activeKey={activeTab} onChange={handleTabChange} size=\"sub\">\n <TabItem\n badgeCount={loading ? undefined : pendingRows.length}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={loading ? undefined : trackingRows.length}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={pendingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={trackingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={historyRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nasync function readInboxTaskRows(\n tasks: readonly TaskRecord[],\n): Promise<InboxTaskRow[]> {\n const instances = await readTaskInstances(tasks);\n\n return tasks.map(\n (task, index): InboxTaskRow => ({\n ...task,\n caseTitle: readTaskCaseTitle(task, instances[index] ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n slaStatusColor: readSlaStatusColor(task.slaDueAt),\n slaStatusText: readSlaStatusText(task.slaDueAt),\n statusLabel: readTaskStatusLabel(task.status),\n }),\n );\n}\n\nasync function readApprovalHistoryRows(\n tasks: readonly TaskRecord[],\n): Promise<ApprovalHistoryRow[]> {\n const [decisionLists, instances] = await Promise.all([\n Promise.all(tasks.map((task) => listTaskDecisions(task.id))),\n readTaskInstances(tasks),\n ]);\n\n return tasks.map((task, index): ApprovalHistoryRow => {\n const decision = readLatestTaskDecision(decisionLists[index] ?? []);\n const instance = instances[index] ?? null;\n\n return {\n ...task,\n caseTitle: readTaskCaseTitle(task, instance),\n decisionAction: decision?.action ?? null,\n decisionComment: decision?.comment ?? null,\n decisionCommentText: readDecisionCommentText(decision?.comment ?? null),\n decisionLabel: readTaskDecisionLabel(decision?.action ?? null),\n decidedAt: decision?.decidedAt ?? task.completedAt,\n instanceState: instance?.state ?? null,\n instanceStateLabel: readInstanceStateLabel(instance?.state ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n };\n });\n}\n\nasync function readTaskInstances(\n tasks: readonly TaskRecord[],\n): Promise<readonly (ApprovalInstanceRecord | null)[]> {\n return Promise.all(\n tasks.map(async (task): Promise<ApprovalInstanceRecord | null> => {\n try {\n return (await readApprovalInstance(task.instanceId)).instance;\n } catch {\n return null;\n }\n }),\n );\n}\n\nfunction readTaskCaseTitle(\n task: TaskRecord,\n instance: ApprovalInstanceRecord | null,\n): string {\n return instance ? readApprovalInstanceCaseTitle(instance) : task.instanceId;\n}\n\nfunction readLatestTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n): TaskDecisionRecord | null {\n return [...decisions].sort(compareTaskDecisionDesc)[0] ?? null;\n}\n\nfunction compareTaskDecisionDesc(\n left: TaskDecisionRecord,\n right: TaskDecisionRecord,\n): number {\n return (\n new Date(right.decidedAt).getTime() - new Date(left.decidedAt).getTime()\n );\n}\n\nfunction readTaskDecisionLabel(\n action: TaskDecisionRecord['action'] | null,\n): string {\n if (action === 'APPROVED') {\n return '同意';\n }\n\n if (action === 'REJECTED') {\n return '拒絕';\n }\n\n if (action === 'RETURNED') {\n return '退回';\n }\n\n if (action === 'TRANSFERRED') {\n return '轉派';\n }\n\n return '未記錄';\n}\n\nfunction readTaskDecisionColor(\n action: TaskDecisionRecord['action'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (action === 'APPROVED') {\n return 'text-success';\n }\n\n if (action === 'REJECTED' || action === 'RETURNED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readInstanceStateLabel(\n state: ApprovalInstanceRecord['state'] | null,\n): string {\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n if (state === 'APPROVED') {\n return '已通過';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n return '-';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceRecord['state'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') {\n return 'text-success';\n }\n\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readDecisionCommentText(comment: string | null): string {\n const trimmedComment = comment?.trim() ?? '';\n\n return trimmedComment || '-';\n}\n\nfunction formatHistoryDateTime(value: string | null): string {\n return formatDateTime(value);\n}\n\nfunction readSlaStatusText(value: string | null): string {\n if (!value) {\n return '-';\n }\n\n const dueAt = new Date(value).getTime();\n const now = Date.now();\n const diffMs = Math.abs(dueAt - now);\n const label = formatDuration(diffMs);\n\n return dueAt < now ? `已逾期 ${label}` : `剩餘 ${label}`;\n}\n\nfunction readSlaStatusColor(\n value: string | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (!value) {\n return 'text-neutral';\n }\n\n return new Date(value).getTime() < Date.now() ? 'text-error' : 'text-success';\n}\n\nfunction formatDuration(value: number): string {\n const totalMinutes = Math.max(1, Math.ceil(value / 60_000));\n const days = Math.floor(totalMinutes / 1440);\n const hours = Math.floor((totalMinutes % 1440) / 60);\n const minutes = totalMinutes % 60;\n\n if (days > 0) {\n return `${days}天 ${hours}小時`;\n }\n\n if (hours > 0) {\n return `${hours}小時 ${minutes}分鐘`;\n }\n\n return `${minutes}分鐘`;\n}\n\nfunction readTaskStatusLabel(status: TaskRecord['status']): string {\n if (status === 'PENDING') {\n return '待處理';\n }\n\n if (status === 'IN_PROGRESS') {\n return '處理中';\n }\n\n if (status === 'COMPLETED') {\n return '已完成';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n if (status === 'CANCELLED') {\n return '已取消';\n }\n\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
@@ -5,18 +5,18 @@ import { t as n } from "../../chunks/format-date-time-CB-LxzqT.js";
5
5
  import { r } from "../../chunks/routes-config-yZbESPlw.js";
6
6
  import { t as i } from "../../chunks/task-node-label-CWZgOBj0.js";
7
7
  import { useEffect as a, useMemo as o, useState as s } from "react";
8
- import { Button as c, PageHeader as l, Section as u, SectionGroup as d, Tab as f, TabItem as p, Table as m, Typography as h } from "@mezzanine-ui/react";
9
- import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
10
- import { listApprovalHistoryTasks as y, listInboxTasks as b, listTaskDecisions as x, readApprovalInstance as S, readApprovalInstanceCaseTitle as C } from "@rytass/bpm-core-client/workflow";
11
- import w from "@mezzanine-ui/react/ContentHeader";
12
- import { PlusIcon as T } from "@mezzanine-ui/icons";
8
+ import { Badge as c, Button as l, PageHeader as u, Section as d, SectionGroup as f, Tab as p, TabItem as m, Table as h, Typography as g } from "@mezzanine-ui/react";
9
+ import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
10
+ import { listApprovalHistoryTasks as b, listInboxTasks as x, listTaskDecisions as S, readApprovalInstance as C, readApprovalInstanceCaseTitle as w } from "@rytass/bpm-core-client/workflow";
11
+ import T from "@mezzanine-ui/react/ContentHeader";
12
+ import { PlusIcon as E } from "@mezzanine-ui/icons";
13
13
  //#region src/views/inbox/InboxView.tsx
14
- function E() {
15
- let i = e(), x = r(), { member: S } = t(), C = S?.memberId ?? null, [E, k] = s("pending"), [A, j] = s(null), [M, N] = s([]), [F, L] = s(!0), [z, B] = s([]);
14
+ function D() {
15
+ let i = e(), S = r(), { member: C } = t(), w = C?.memberId ?? null, [D, A] = s("pending"), [j, M] = s(null), [N, P] = s([]), [I, R] = s(!0), [B, V] = s([]);
16
16
  a(() => {
17
- C && J();
18
- }, [C]);
19
- let V = o(() => [
17
+ w && Y();
18
+ }, [w]);
19
+ let H = o(() => [
20
20
  {
21
21
  dataIndex: "caseTitle",
22
22
  key: "caseTitle",
@@ -35,9 +35,19 @@ function E() {
35
35
  title: "狀態",
36
36
  width: 120
37
37
  },
38
+ {
39
+ key: "fill",
40
+ render: (e) => e.hasFillableFields ? /* @__PURE__ */ v(c, {
41
+ size: "sub",
42
+ text: "需補填",
43
+ variant: "dot-warning"
44
+ }) : null,
45
+ title: "補填",
46
+ width: 120
47
+ },
38
48
  {
39
49
  key: "slaDueAt",
40
- render: (e) => /* @__PURE__ */ _(h, {
50
+ render: (e) => /* @__PURE__ */ v(g, {
41
51
  color: e.slaStatusColor,
42
52
  component: "span",
43
53
  variant: "body",
@@ -48,7 +58,7 @@ function E() {
48
58
  },
49
59
  {
50
60
  key: "createdAt",
51
- render: (e) => /* @__PURE__ */ _(h, {
61
+ render: (e) => /* @__PURE__ */ v(g, {
52
62
  component: "span",
53
63
  variant: "body",
54
64
  children: n(e.createdAt)
@@ -56,14 +66,14 @@ function E() {
56
66
  title: "建立時間",
57
67
  width: 220
58
68
  }
59
- ], []), H = o(() => ({
69
+ ], []), U = o(() => ({
60
70
  render: (e) => [{
61
71
  name: "處理",
62
- onClick: () => i.push(x.caseDetail(e.instanceId))
72
+ onClick: () => i.push(S.caseDetail(e.instanceId))
63
73
  }],
64
74
  variant: "base-secondary",
65
75
  width: 88
66
- }), [i, x]), W = o(() => [
76
+ }), [i, S]), G = o(() => [
67
77
  {
68
78
  dataIndex: "caseTitle",
69
79
  key: "caseTitle",
@@ -78,8 +88,8 @@ function E() {
78
88
  },
79
89
  {
80
90
  key: "decisionLabel",
81
- render: (e) => /* @__PURE__ */ _(h, {
82
- color: P(e.decisionAction),
91
+ render: (e) => /* @__PURE__ */ v(g, {
92
+ color: F(e.decisionAction),
83
93
  component: "span",
84
94
  variant: "body",
85
95
  children: e.decisionLabel
@@ -89,7 +99,7 @@ function E() {
89
99
  },
90
100
  {
91
101
  key: "decisionComment",
92
- render: (e) => /* @__PURE__ */ _(h, {
102
+ render: (e) => /* @__PURE__ */ v(g, {
93
103
  component: "span",
94
104
  variant: "body",
95
105
  children: e.decisionCommentText
@@ -99,8 +109,8 @@ function E() {
99
109
  },
100
110
  {
101
111
  key: "instanceStateLabel",
102
- render: (e) => /* @__PURE__ */ _(h, {
103
- color: I(e.instanceState),
112
+ render: (e) => /* @__PURE__ */ v(g, {
113
+ color: L(e.instanceState),
104
114
  component: "span",
105
115
  variant: "body",
106
116
  children: e.instanceStateLabel
@@ -110,181 +120,181 @@ function E() {
110
120
  },
111
121
  {
112
122
  key: "decidedAt",
113
- render: (e) => /* @__PURE__ */ _(h, {
123
+ render: (e) => /* @__PURE__ */ v(g, {
114
124
  component: "span",
115
125
  variant: "body",
116
- children: R(e.decidedAt)
126
+ children: z(e.decidedAt)
117
127
  }),
118
128
  title: "簽核時間",
119
129
  width: 220
120
130
  }
121
- ], []), G = o(() => ({
131
+ ], []), K = o(() => ({
122
132
  render: (e) => [{
123
133
  name: "查看",
124
- onClick: () => i.push(x.caseDetail(e.instanceId))
134
+ onClick: () => i.push(S.caseDetail(e.instanceId))
125
135
  }],
126
136
  variant: "base-secondary",
127
137
  width: 88
128
- }), [i, x]), K = o(() => M.filter((e) => e.instanceState === "RUNNING"), [M]);
129
- function q(e) {
130
- k(e === "history" || e === "pending" || e === "tracking" ? e : "pending");
138
+ }), [i, S]), q = o(() => N.filter((e) => e.instanceState === "RUNNING"), [N]);
139
+ function J(e) {
140
+ A(e === "history" || e === "pending" || e === "tracking" ? e : "pending");
131
141
  }
132
- async function J() {
133
- L(!0), j(null);
142
+ async function Y() {
143
+ R(!0), M(null);
134
144
  try {
135
- if (!C) {
136
- B([]), N([]);
145
+ if (!w) {
146
+ V([]), P([]);
137
147
  return;
138
148
  }
139
- let [e, t] = await Promise.all([b(C), y(C)]), [n, r] = await Promise.all([D(e), O(t)]);
140
- B(n), N(r);
149
+ let [e, t] = await Promise.all([x(w), b(w)]), [n, r] = await Promise.all([O(e), k(t)]);
150
+ V(n), P(r);
141
151
  } catch (e) {
142
- j(U(e));
152
+ M(W(e));
143
153
  } finally {
144
- L(!1);
154
+ R(!1);
145
155
  }
146
156
  }
147
- return /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(l, { children: /* @__PURE__ */ _(w, {
148
- description: `目前以 ${S?.name ?? C ?? "目前登入會員"} 查詢待處理與歷史簽核任務。`,
157
+ return /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v(u, { children: /* @__PURE__ */ v(T, {
158
+ description: `目前以 ${C?.name ?? w ?? "目前登入會員"} 查詢待處理與歷史簽核任務。`,
149
159
  title: "我的待簽",
150
- children: /* @__PURE__ */ _(c, {
151
- icon: T,
160
+ children: /* @__PURE__ */ v(l, {
161
+ icon: E,
152
162
  iconType: "leading",
153
- onClick: () => i.push(x.caseNew()),
163
+ onClick: () => i.push(S.caseNew()),
154
164
  variant: "base-primary",
155
165
  children: "發起簽核"
156
166
  })
157
- }) }), /* @__PURE__ */ _(d, { children: /* @__PURE__ */ v(u, { children: [
158
- A ? /* @__PURE__ */ _(h, {
167
+ }) }), /* @__PURE__ */ v(f, { children: /* @__PURE__ */ y(d, { children: [
168
+ j ? /* @__PURE__ */ v(g, {
159
169
  color: "text-error",
160
170
  variant: "body",
161
- children: A
171
+ children: j
162
172
  }) : null,
163
- /* @__PURE__ */ v(f, {
164
- activeKey: E,
165
- onChange: q,
173
+ /* @__PURE__ */ y(p, {
174
+ activeKey: D,
175
+ onChange: J,
166
176
  size: "sub",
167
177
  children: [
168
- /* @__PURE__ */ _(p, {
169
- badgeCount: F ? void 0 : z.length,
178
+ /* @__PURE__ */ v(m, {
179
+ badgeCount: I ? void 0 : B.length,
170
180
  children: "待簽核"
171
181
  }, "pending"),
172
- /* @__PURE__ */ _(p, {
173
- badgeCount: F ? void 0 : K.length,
182
+ /* @__PURE__ */ v(m, {
183
+ badgeCount: I ? void 0 : q.length,
174
184
  children: "已處理未結束"
175
185
  }, "tracking"),
176
- /* @__PURE__ */ _(p, { children: "歷史簽核記錄" }, "history")
186
+ /* @__PURE__ */ v(m, { children: "歷史簽核記錄" }, "history")
177
187
  ]
178
188
  }),
179
- E === "pending" ? /* @__PURE__ */ _(m, {
180
- actions: H,
181
- columns: V,
182
- dataSource: z,
189
+ D === "pending" ? /* @__PURE__ */ v(h, {
190
+ actions: U,
191
+ columns: H,
192
+ dataSource: B,
183
193
  fullWidth: !0,
184
- loading: F
194
+ loading: I
185
195
  }) : null,
186
- E === "tracking" ? /* @__PURE__ */ _(m, {
187
- actions: G,
188
- columns: W,
189
- dataSource: K,
196
+ D === "tracking" ? /* @__PURE__ */ v(h, {
197
+ actions: K,
198
+ columns: G,
199
+ dataSource: q,
190
200
  fullWidth: !0,
191
- loading: F
201
+ loading: I
192
202
  }) : null,
193
- E === "history" ? /* @__PURE__ */ _(m, {
194
- actions: G,
195
- columns: W,
196
- dataSource: M,
203
+ D === "history" ? /* @__PURE__ */ v(h, {
204
+ actions: K,
205
+ columns: G,
206
+ dataSource: N,
197
207
  fullWidth: !0,
198
- loading: F
208
+ loading: I
199
209
  }) : null
200
210
  ] }) })] });
201
211
  }
202
- async function D(e) {
203
- let t = await k(e);
212
+ async function O(e) {
213
+ let t = await A(e);
204
214
  return e.map((e, n) => ({
205
215
  ...e,
206
- caseTitle: A(e, t[n] ?? null),
216
+ caseTitle: j(e, t[n] ?? null),
207
217
  key: e.id,
208
218
  nodeText: i(e),
209
- slaStatusColor: B(e.slaDueAt),
210
- slaStatusText: z(e.slaDueAt),
211
- statusLabel: H(e.status)
219
+ slaStatusColor: V(e.slaDueAt),
220
+ slaStatusText: B(e.slaDueAt),
221
+ statusLabel: U(e.status)
212
222
  }));
213
223
  }
214
- async function O(e) {
215
- let [t, n] = await Promise.all([Promise.all(e.map((e) => x(e.id))), k(e)]);
224
+ async function k(e) {
225
+ let [t, n] = await Promise.all([Promise.all(e.map((e) => S(e.id))), A(e)]);
216
226
  return e.map((e, r) => {
217
- let a = j(t[r] ?? []), o = n[r] ?? null;
227
+ let a = M(t[r] ?? []), o = n[r] ?? null;
218
228
  return {
219
229
  ...e,
220
- caseTitle: A(e, o),
230
+ caseTitle: j(e, o),
221
231
  decisionAction: a?.action ?? null,
222
232
  decisionComment: a?.comment ?? null,
223
- decisionCommentText: L(a?.comment ?? null),
224
- decisionLabel: N(a?.action ?? null),
233
+ decisionCommentText: R(a?.comment ?? null),
234
+ decisionLabel: P(a?.action ?? null),
225
235
  decidedAt: a?.decidedAt ?? e.completedAt,
226
236
  instanceState: o?.state ?? null,
227
- instanceStateLabel: F(o?.state ?? null),
237
+ instanceStateLabel: I(o?.state ?? null),
228
238
  key: e.id,
229
239
  nodeText: i(e)
230
240
  };
231
241
  });
232
242
  }
233
- async function k(e) {
243
+ async function A(e) {
234
244
  return Promise.all(e.map(async (e) => {
235
245
  try {
236
- return (await S(e.instanceId)).instance;
246
+ return (await C(e.instanceId)).instance;
237
247
  } catch {
238
248
  return null;
239
249
  }
240
250
  }));
241
251
  }
242
- function A(e, t) {
243
- return t ? C(t) : e.instanceId;
252
+ function j(e, t) {
253
+ return t ? w(t) : e.instanceId;
244
254
  }
245
- function j(e) {
246
- return [...e].sort(M)[0] ?? null;
255
+ function M(e) {
256
+ return [...e].sort(N)[0] ?? null;
247
257
  }
248
- function M(e, t) {
258
+ function N(e, t) {
249
259
  return new Date(t.decidedAt).getTime() - new Date(e.decidedAt).getTime();
250
260
  }
251
- function N(e) {
261
+ function P(e) {
252
262
  return e === "APPROVED" ? "同意" : e === "REJECTED" ? "拒絕" : e === "RETURNED" ? "退回" : e === "TRANSFERRED" ? "轉派" : "未記錄";
253
263
  }
254
- function P(e) {
264
+ function F(e) {
255
265
  return e === "APPROVED" ? "text-success" : e === "REJECTED" || e === "RETURNED" ? "text-error" : "text-neutral";
256
266
  }
257
- function F(e) {
267
+ function I(e) {
258
268
  return e === "RUNNING" ? "進行中" : e === "APPROVED" ? "已通過" : e === "REJECTED" ? "已拒絕" : e === "RETURNED" ? "已退回" : e === "CANCELLED" ? "已取消" : e === "EXPIRED" ? "已逾期" : e === "DRAFT" ? "草稿" : "-";
259
269
  }
260
- function I(e) {
270
+ function L(e) {
261
271
  return e === "APPROVED" ? "text-success" : e === "REJECTED" || e === "CANCELLED" || e === "EXPIRED" ? "text-error" : "text-neutral";
262
272
  }
263
- function L(e) {
273
+ function R(e) {
264
274
  return (e?.trim() ?? "") || "-";
265
275
  }
266
- function R(e) {
276
+ function z(e) {
267
277
  return n(e);
268
278
  }
269
- function z(e) {
279
+ function B(e) {
270
280
  if (!e) return "-";
271
- let t = new Date(e).getTime(), n = Date.now(), r = V(Math.abs(t - n));
281
+ let t = new Date(e).getTime(), n = Date.now(), r = H(Math.abs(t - n));
272
282
  return t < n ? `已逾期 ${r}` : `剩餘 ${r}`;
273
283
  }
274
- function B(e) {
284
+ function V(e) {
275
285
  return e ? new Date(e).getTime() < Date.now() ? "text-error" : "text-success" : "text-neutral";
276
286
  }
277
- function V(e) {
287
+ function H(e) {
278
288
  let t = Math.max(1, Math.ceil(e / 6e4)), n = Math.floor(t / 1440), r = Math.floor(t % 1440 / 60), i = t % 60;
279
289
  return n > 0 ? `${n}天 ${r}小時` : r > 0 ? `${r}小時 ${i}分鐘` : `${i}分鐘`;
280
290
  }
281
- function H(e) {
291
+ function U(e) {
282
292
  return e === "PENDING" ? "待處理" : e === "IN_PROGRESS" ? "處理中" : e === "COMPLETED" ? "已完成" : e === "TRANSFERRED" ? "已轉派" : e === "CANCELLED" ? "已取消" : e;
283
293
  }
284
- function U(e) {
294
+ function W(e) {
285
295
  return e instanceof Error ? e.message : "發生未知錯誤";
286
296
  }
287
297
  //#endregion
288
- export { E as InboxView };
298
+ export { D as InboxView };
289
299
 
290
300
  //# sourceMappingURL=index.js.map