@rytass/bpm-core-react 0.21.3 → 0.22.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.
- package/CHANGELOG.md +38 -0
- package/dist/chunks/{FormBuilderView-Bq4TXdxF.cjs → FormBuilderView-Bok4Y59D.cjs} +2 -2
- package/dist/chunks/{FormBuilderView-Bq4TXdxF.cjs.map → FormBuilderView-Bok4Y59D.cjs.map} +1 -1
- package/dist/chunks/{FormBuilderView-DNsFwZgk.js → FormBuilderView-DbfbLZCI.js} +2 -2
- package/dist/chunks/{FormBuilderView-DNsFwZgk.js.map → FormBuilderView-DbfbLZCI.js.map} +1 -1
- package/dist/chunks/{FormRendererView-BF8Ge0Zk.js → FormRendererView-CAyPXhPq.js} +312 -307
- package/dist/chunks/FormRendererView-CAyPXhPq.js.map +1 -0
- package/dist/chunks/FormRendererView-iLlHFIUR.cjs +6 -0
- package/dist/chunks/FormRendererView-iLlHFIUR.cjs.map +1 -0
- package/dist/chunks/{compose-NHbyjV73.cjs → compose-DP1N4twA.cjs} +2 -2
- package/dist/chunks/{compose-NHbyjV73.cjs.map → compose-DP1N4twA.cjs.map} +1 -1
- package/dist/chunks/{compose-C_Y38ENa.js → compose-U1zs3Yof.js} +4 -4
- package/dist/chunks/{compose-C_Y38ENa.js.map → compose-U1zs3Yof.js.map} +1 -1
- package/dist/chunks/{designer-oDGvHWBJ.cjs → designer-CWL-dCQ_.cjs} +2 -2
- package/dist/chunks/{designer-oDGvHWBJ.cjs.map → designer-CWL-dCQ_.cjs.map} +1 -1
- package/dist/chunks/{designer-BRYIpeTC.js → designer-DPG7R_WP.js} +3 -3
- package/dist/chunks/{designer-BRYIpeTC.js.map → designer-DPG7R_WP.js.map} +1 -1
- package/dist/chunks/{detail-BLhZp1mO.cjs → detail-BUfsSal0.cjs} +2 -2
- package/dist/chunks/{detail-BLhZp1mO.cjs.map → detail-BUfsSal0.cjs.map} +1 -1
- package/dist/chunks/{detail-CkRgfU7l.js → detail-CHZDNNM6.js} +2 -2
- package/dist/chunks/{detail-CkRgfU7l.js.map → detail-CHZDNNM6.js.map} +1 -1
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/templates/compose/index.cjs +1 -1
- package/dist/pages/templates/compose/index.js +1 -1
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.js +1 -1
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/renderer/index.cjs +1 -1
- package/dist/views/forms/renderer/index.js +1 -1
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.cjs.map +1 -1
- package/dist/views/inbox/index.js +185 -94
- package/dist/views/inbox/index.js.map +1 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.js +1 -1
- package/dist/views/templates/compose/index.cjs +1 -1
- package/dist/views/templates/compose/index.js +1 -1
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunks/FormRendererView-BF8Ge0Zk.js.map +0 -1
- package/dist/chunks/FormRendererView-ZIfSRWPi.cjs +0 -6
- package/dist/chunks/FormRendererView-ZIfSRWPi.cjs.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/detail-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/detail-BUfsSal0.cjs");let t=require("react/jsx-runtime");var n={title:`案件詳情 | BPM Admin`};async function r({params:n}){let{id:r}=await n;return(0,t.jsx)(e.t,{instanceId:r})}exports.default=r,exports.metadata=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/compose-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/compose-DP1N4twA.cjs");let t=require("react/jsx-runtime"),n=require("next/server");var r={title:`建立模板(表單 + 流程) | BPM Admin`,description:`以精靈式流程一次完成 BPM 表單與簽核流程設計並發佈。`};async function i(){return await(0,n.connection)(),(0,t.jsx)(e.t,{aiAssistantAvailable:!!process.env.OPENAI_API_KEY,showAiAssistant:process.env.BPM_AI_ASSISTANT_ENABLED===`true`})}exports.default=i,exports.metadata=r;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/designer-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/designer-CWL-dCQ_.cjs");let t=require("react/jsx-runtime");var n={title:`流程設計器 | BPM Admin`,description:`以視覺化設計器編輯 BPM 簽核流程節點、條件與發佈版本。`};async function r({params:n}){let{id:r}=await n;return(0,t.jsx)(e.t,{aiAssistantAvailable:!!process.env.OPENAI_API_KEY,showAiAssistant:process.env.BPM_AI_ASSISTANT_ENABLED===`true`,showDryRun:process.env.BPM_TEMPLATE_DRY_RUN_ENABLED!==`false`,templateId:r})}exports.default=r,exports.metadata=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormBuilderView-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormBuilderView-Bok4Y59D.cjs");exports.FormBuilderView=e.t;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as FormBuilderView } from "../../../chunks/FormBuilderView-
|
|
1
|
+
export { t as FormBuilderView } from "../../../chunks/FormBuilderView-DbfbLZCI.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-iLlHFIUR.cjs");exports.FormRenderer=e.t,exports.FormRendererView=e.t,exports.isFormDataSourceFieldSubmissionBlocked=e.s,exports.readFileUploadSubmissionBlockMessage=e.a,exports.readFormDataSourceFieldStatusMessage=e.c,exports.readFormDataSourceSubmissionBlockMessage=e.l,exports.useFormDataSourceField=e.u;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as FormRenderer, t as FormRendererView, s as isFormDataSourceFieldSubmissionBlocked, a as readFileUploadSubmissionBlockMessage, c as readFormDataSourceFieldStatusMessage, l as readFormDataSourceSubmissionBlockMessage, u as useFormDataSourceField } from "../../../chunks/FormRendererView-
|
|
1
|
+
export { t as FormRenderer, t as FormRendererView, s as isFormDataSourceFieldSubmissionBlocked, a as readFileUploadSubmissionBlockMessage, c as readFormDataSourceFieldStatusMessage, l as readFormDataSourceSubmissionBlockMessage, u as useFormDataSourceField } from "../../../chunks/FormRendererView-CAyPXhPq.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/format-date-time-D-cx5M8z.cjs"),n=require("../../chunks/auth-provider-4BeCw7cI.cjs"),r=require("../../chunks/task-decision-CqZ4WQOC.cjs"),i=require("../../chunks/router-adapter--gYs13E8.cjs"),a=require("../../chunks/routes-config-C1j_vFKo.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");var f=100,p={display:`grid`,gap:`var(--mzn-spacing-gap-base)`,marginBottom:`var(--mzn-spacing-padding-vertical-spacious)`};function
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/format-date-time-D-cx5M8z.cjs"),n=require("../../chunks/auth-provider-4BeCw7cI.cjs"),r=require("../../chunks/task-decision-CqZ4WQOC.cjs"),i=require("../../chunks/router-adapter--gYs13E8.cjs"),a=require("../../chunks/routes-config-C1j_vFKo.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");var f=100,p={display:`grid`,gap:`var(--mzn-spacing-gap-base)`,marginBottom:`var(--mzn-spacing-padding-vertical-spacious)`},m=[10,20,50],h={page:1,pageSize:20};function g(){let e=i.r(),r=a.r(),{member:f}=n.n(),m=f?.memberId??null,[g,S]=(0,o.useState)(`pending`),[T,E]=(0,o.useState)(null),[D,O]=(0,o.useState)(h),[A,M]=(0,o.useState)(h),[P,F]=(0,o.useState)(h),I=_(m,{enabled:!0,paging:D,setPaging:O},E,async(e,t)=>v(await(0,l.listInboxTasksPage)({assigneeMemberId:e,...t}),C)),L=_(m,{enabled:!0,paging:A,setPaging:M},E,async(e,t)=>v(await(0,l.listApprovalHistoryTasksPage)({assigneeMemberId:e,instanceState:`RUNNING`,...t}),t=>w(t,e))),z=_(m,{enabled:g===`history`,paging:P,setPaging:F},E,async(e,t)=>v(await(0,l.listApprovalHistoryTasksPage)({assigneeMemberId:e,...t}),t=>w(t,e))),[B,V]=(0,o.useState)([]),[H,U]=(0,o.useState)(!1);(0,o.useEffect)(()=>{m?x(m).then(e=>{V(e?.rows??[]),U(e?.truncated??!1)},e=>E(R(e))):(V([]),U(!1))},[m]);let W=(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:t.t(e.createdAt)}),title:`建立時間`,width:220}],[]),G=(0,o.useMemo)(()=>({render:t=>[{name:`處理`,onClick:()=>e.push(r.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,r]),K=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{key:`startedAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:t.t(e.startedAt)}),title:`發起時間`,width:220}],[]),q=(0,o.useMemo)(()=>({render:t=>[{name:`重新送出`,onClick:()=>e.push(r.caseDetail(t.id))}],variant:`base-secondary`,width:120}),[e,r]),J=(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:k(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:j(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:N(e.decidedAt)}),title:`簽核時間`,width:220}],[]),Y=(0,o.useMemo)(()=>({render:t=>[{name:`查看`,onClick:()=>e.push(r.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,r]);function X(e){S(e===`history`||e===`pending`||e===`tracking`?e:`pending`)}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(u.default,{description:`目前以 ${f?.name??m??`目前登入會員`} 查詢待處理與歷史簽核任務。`,title:`我的待簽`,children:(0,c.jsx)(s.Button,{icon:d.PlusIcon,iconType:`leading`,onClick:()=>e.push(r.caseNew()),variant:`base-primary`,children:`發起簽核`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{children:[T?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:T}):null,(0,c.jsxs)(s.Tab,{activeKey:g,onChange:X,size:`sub`,children:[(0,c.jsx)(s.TabItem,{badgeCount:I.loading?void 0:I.total,children:`待簽核`},`pending`),(0,c.jsx)(s.TabItem,{badgeCount:L.loading?void 0:L.total,children:`已處理未結束`},`tracking`),(0,c.jsx)(s.TabItem,{children:`歷史簽核記錄`},`history`)]}),g===`pending`&&(B.length>0||H)?(0,c.jsxs)(`div`,{"data-returned-instances":``,style:p,children:[B.length>0?(0,c.jsx)(s.Typography,{component:`h2`,variant:`label-primary`,children:`被退回待重送`}):null,(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:b(B.length>0,H)}),B.length>0?(0,c.jsx)(s.Table,{actions:q,columns:K,dataSource:[...B],fullWidth:!0}):null]}):null,g===`pending`?(0,c.jsx)(s.Table,{actions:G,columns:W,dataSource:[...I.rows],fullWidth:!0,loading:I.loading,pagination:y(D,I.total,O)}):null,g===`tracking`?(0,c.jsx)(s.Table,{actions:Y,columns:J,dataSource:[...L.rows],fullWidth:!0,loading:L.loading,pagination:y(A,L.total,M)}):null,g===`history`?(0,c.jsx)(s.Table,{actions:Y,columns:J,dataSource:[...z.rows],fullWidth:!0,loading:z.loading,pagination:y(P,z.total,F)}):null]})})]})}function _(e,{enabled:t,paging:n,setPaging:r},i,a){let[s,c]=(0,o.useState)({loading:!0,rows:[],total:0}),l=(0,o.useRef)(0),u=(0,o.useRef)(a);u.current=a;let d=(0,o.useCallback)(async()=>{let t=l.current+1;if(l.current=t,!e)c({loading:!1,rows:[],total:0});else{c(e=>({...e,loading:!0}));try{let i=await u.current(e,n);if(l.current!==t)return;let a=Math.max(1,Math.ceil(i.total/n.pageSize));if(!i.rows.length&&n.page>a){r({...n,page:a});return}c({loading:!1,...i})}catch(e){l.current===t&&(i(R(e)),c(e=>({...e,loading:!1})))}}},[e,i,n,r]);return(0,o.useEffect)(()=>{t&&d()},[t,d]),s}async function v(e,t){return{rows:await t(e.tasks),total:e.totalCount}}function y(e,t,n){return{current:e.page,onChange:t=>n({...e,page:t}),onChangePageSize:e=>n({page:1,pageSize:e}),pageSize:e.pageSize,pageSizeLabel:`每頁筆數`,pageSizeOptions:m,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:t}}function b(e,t){return e?t?`你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。`:`你發起的案件被退回,請修改後重新送出。`:`前 ${f} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`}async function x(e){try{let t=await(0,l.listApprovalInstancesPage)({page:1,pageSize:f,searchText:null,state:`RETURNED`,templateId:null,view:`SENT`});return{rows:S(t.instances,e),truncated:t.totalCount>t.instances.length}}catch{return null}}function S(e,t){return e.filter(e=>e.initiatorMemberId===t).map(e=>({caseTitle:(0,l.readApprovalInstanceCaseTitle)(e),id:e.id,key:e.id,startedAt:e.startedAt}))}async function C(e){let t=await T(e);return e.map((e,n)=>({...e,caseTitle:E(e,t[n]??null),key:e.id,nodeText:r.o(e),slaStatusColor:F(e.slaDueAt),slaStatusText:P(e.slaDueAt),statusLabel:L(e.status)}))}async function w(e,t){let[n,i]=await Promise.all([Promise.all(e.map(e=>(0,l.listTaskDecisions)(e.id))),T(e)]);return e.map((e,a)=>{let o=n[a]??[],s=D(o,t),c=i[a]??null;return{...e,caseTitle:E(e,c),decisionAction:s?.action??null,decisionComment:s?.comment??null,decisionCommentText:M(s?.comment??null),decisionLabel:O(s?.action??null),decidedAt:s?.decidedAt??(o.length===0?e.completedAt:null),instanceState:c?.state??null,instanceStateLabel:A(c?.state??null),key:e.id,nodeText:r.o(e)}})}async function T(e){return Promise.all(e.map(async e=>{try{return(await(0,l.readApprovalInstance)(e.instanceId)).instance}catch{return null}}))}function E(e,t){return t?(0,l.readApprovalInstanceCaseTitle)(t):e.instanceId}function D(e,t){return r.i(e.filter(e=>e.decidedByMemberId===t))}function O(e){return e===`APPROVED`?`同意`:e===`REJECTED`?`拒絕`:e===`RETURNED`?`退回`:e===`TRANSFERRED`?`轉派`:`未記錄`}function k(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`RETURNED`?`text-error`:`text-neutral`}function A(e){return e===`RUNNING`?`進行中`:e===`APPROVED`?`已通過`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`CANCELLED`?`已取消`:e===`EXPIRED`?`已逾期`:e===`DRAFT`?`草稿`:`-`}function j(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`CANCELLED`||e===`EXPIRED`?`text-error`:`text-neutral`}function M(e){return(e?.trim()??``)||`-`}function N(e){return t.t(e)}function P(e){if(!e)return`-`;let t=new Date(e).getTime(),n=Date.now(),r=I(Math.abs(t-n));return t<n?`已逾期 ${r}`:`剩餘 ${r}`}function F(e){return e?new Date(e).getTime()<Date.now()?`text-error`:`text-success`:`text-neutral`}function I(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 L(e){return e===`PENDING`?`待處理`:e===`IN_PROGRESS`?`處理中`:e===`COMPLETED`?`已完成`:e===`TRANSFERRED`?`已轉派`:e===`CANCELLED`?`已取消`:e}function R(e){return e instanceof Error?e.message:`發生未知錯誤`}exports.InboxView=g;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
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","listApprovalInstancesPage","readApprovalInstanceCaseTitle","readTaskNodeText","listTaskDecisions","readApprovalInstance","readLatestTaskDecision","require_rolldown_runtime","require_format_date_time","require_auth_provider","require_task_decision","require_router_adapter","require_routes_config","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","RETURNED_INSTANCE_PAGE_SIZE","RETURNED_SECTION_STYLE","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","error","setError","historyRows","setHistoryRows","loading","setLoading","pendingRows","setPendingRows","returnedRows","setReturnedRows","returnedTruncated","setReturnedTruncated","refreshTasks","pendingColumns","record","pendingTableActions","returnedColumns","returnedTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","trackingRows","row","handleTabChange","activeKey","nextPendingTasks","nextHistoryTasks","returned","readReturnedInstances","nextPendingRows","nextHistoryRows","readInboxTaskRows","readApprovalHistoryRows","requestError","readErrorMessage","readReturnedSectionHint","hasRows","truncated","page","readReturnedInstanceRows","instances","instance","readTaskInstances","tasks","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","decisions","decision","readLatestOwnTaskDecision","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","action","state","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport {\n type CSSProperties,\n type Key,\n ReactElement,\n useEffect,\n useMemo,\n useState,\n} 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 type ApprovalInstancesPageResult,\n listApprovalHistoryTasks,\n listApprovalInstancesPage,\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 { readLatestTaskDecision } from '../../lib/task-decision';\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 ReturnedInstanceRow = Readonly<{\n caseTitle: string;\n id: string;\n key: string;\n startedAt: string | null;\n}>;\n\n/** The server caps a page at 100; more than that is left to 我發起的. */\nconst RETURNED_INSTANCE_PAGE_SIZE = 100;\n\nconst RETURNED_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n marginBottom: 'var(--mzn-spacing-padding-vertical-spacious)',\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 const [returnedRows, setReturnedRows] = useState<\n readonly ReturnedInstanceRow[]\n >([]);\n const [returnedTruncated, setReturnedTruncated] = useState(false);\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 returnedColumns = useMemo(\n (): TableColumn<ReturnedInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n {\n key: 'startedAt',\n render: (record: ReturnedInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n ],\n [],\n );\n const returnedTableActions = useMemo(\n (): TableActions<ReturnedInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ReturnedInstanceRow>['render']> => [\n {\n name: '重新送出',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 120,\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 setReturnedRows([]);\n setReturnedTruncated(false);\n return;\n }\n\n const [nextPendingTasks, nextHistoryTasks, returned] =\n await Promise.all([\n listInboxTasks(currentMemberId),\n listApprovalHistoryTasks(currentMemberId),\n readReturnedInstances(currentMemberId),\n ]);\n const [nextPendingRows, nextHistoryRows] = await Promise.all([\n readInboxTaskRows(nextPendingTasks),\n readApprovalHistoryRows(nextHistoryTasks, currentMemberId),\n ]);\n\n setPendingRows(nextPendingRows);\n setHistoryRows(nextHistoryRows);\n setReturnedRows(returned?.rows ?? []);\n setReturnedTruncated(returned?.truncated ?? false);\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 {/* A truncated page with none of the member's own cases still\n points to 我發起的: theirs may sit past the first page. */}\n {activeTab === 'pending' &&\n (returnedRows.length > 0 || returnedTruncated) ? (\n <div data-returned-instances=\"\" style={RETURNED_SECTION_STYLE}>\n {/* Without rows there is nothing here to resubmit, only the\n pointer to 我發起的. */}\n {returnedRows.length > 0 ? (\n <Typography component=\"h2\" variant=\"label-primary\">\n 被退回待重送\n </Typography>\n ) : null}\n <Typography color=\"text-neutral\" variant=\"caption\">\n {readReturnedSectionHint(\n returnedRows.length > 0,\n returnedTruncated,\n )}\n </Typography>\n {returnedRows.length > 0 ? (\n <Table\n actions={returnedTableActions}\n columns={returnedColumns}\n dataSource={[...returnedRows]}\n fullWidth\n />\n ) : null}\n </div>\n ) : null}\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\nfunction readReturnedSectionHint(\n hasRows: boolean,\n truncated: boolean,\n): string {\n if (!hasRows) {\n return `前 ${RETURNED_INSTANCE_PAGE_SIZE} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`;\n }\n\n return truncated\n ? '你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。'\n : '你發起的案件被退回,請修改後重新送出。';\n}\n\n/**\n * Returned cases are a side list: a failure here, in the request or in reading\n * its rows, hides that section instead of taking the pending and history tasks\n * down with it.\n */\nasync function readReturnedInstances(\n currentMemberId: string,\n): Promise<Readonly<{\n rows: readonly ReturnedInstanceRow[];\n truncated: boolean;\n}> | null> {\n try {\n // SENT also lists cases filed on someone else's behalf; only the\n // initiator may resubmit, so those are filtered out here.\n const page: ApprovalInstancesPageResult = await listApprovalInstancesPage({\n page: 1,\n pageSize: RETURNED_INSTANCE_PAGE_SIZE,\n searchText: null,\n state: 'RETURNED',\n templateId: null,\n view: 'SENT',\n });\n\n return {\n rows: readReturnedInstanceRows(page.instances, currentMemberId),\n // The total includes cases filed for someone else, so compare it with\n // what this page fetched rather than with the rows kept.\n truncated: page.totalCount > page.instances.length,\n };\n } catch {\n return null;\n }\n}\n\nfunction readReturnedInstanceRows(\n instances: readonly ApprovalInstanceRecord[],\n currentMemberId: string,\n): readonly ReturnedInstanceRow[] {\n return instances\n .filter(\n (instance): boolean => instance.initiatorMemberId === currentMemberId,\n )\n .map(\n (instance): ReturnedInstanceRow => ({\n caseTitle: readApprovalInstanceCaseTitle(instance),\n id: instance.id,\n key: instance.id,\n startedAt: instance.startedAt,\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 currentMemberId: string,\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 decisions = decisionLists[index] ?? [];\n const decision = readLatestOwnTaskDecision(decisions, currentMemberId);\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 // completedAt is when the last signer finished, so it can stand in only\n // when the task has no decisions at all.\n decidedAt:\n decision?.decidedAt ??\n (decisions.length === 0 ? task.completedAt : null),\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\n// A sequential or countersign task holds decisions from several signers, so\n// the newest one on the task can be somebody else's. A delegate is the one\n// recorded as deciding, and a principal never gets the delegated task in this\n// list.\nfunction readLatestOwnTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n currentMemberId: string,\n): TaskDecisionRecord | null {\n return readLatestTaskDecision(\n decisions.filter(\n (decision): boolean => decision.decidedByMemberId === currentMemberId,\n ),\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","listInboxTasksPage","listApprovalHistoryTasksPage","useMemo","Badge","Typography","formatDateTime","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Tab","TabItem","Table","useRef","useCallback","listApprovalInstancesPage","readApprovalInstanceCaseTitle","readTaskNodeText","listTaskDecisions","readApprovalInstance","readLatestTaskDecision","require_rolldown_runtime","require_format_date_time","require_auth_provider","require_task_decision","require_router_adapter","require_routes_config","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","RETURNED_INSTANCE_PAGE_SIZE","RETURNED_SECTION_STYLE","PAGE_SIZE_OPTIONS","FIRST_PAGE","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","error","setError","pendingPaging","setPendingPaging","trackingPaging","setTrackingPaging","historyPaging","setHistoryPaging","pending","useTabPage","readRows","memberId","paging","readInboxTaskRows","tracking","readApprovalHistoryRows","tasks","history","returnedRows","setReturnedRows","returnedTruncated","setReturnedTruncated","readReturnedInstances","returned","readErrorMessage","requestError","pendingColumns","record","pendingTableActions","returnedColumns","returnedTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","handleTabChange","activeKey","readReturnedSectionHint","readTablePagination","state","setState","latestRequestRef","loadRef","load","refresh","request","previous","loaded","lastPage","setPaging","onError","enabled","toRows","page","from","to","count","hasRows","truncated","readReturnedInstanceRows","instances","instance","readTaskInstances","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","decisions","decision","readLatestOwnTaskDecision","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","action","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport {\n type CSSProperties,\n type Key,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} 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 type ApprovalInstancesPageResult,\n listApprovalHistoryTasksPage,\n listApprovalInstancesPage,\n listInboxTasksPage,\n type MemberTaskPage,\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 { readLatestTaskDecision } from '../../lib/task-decision';\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 ReturnedInstanceRow = Readonly<{\n caseTitle: string;\n id: string;\n key: string;\n startedAt: string | null;\n}>;\n\n/** The server caps a page at 100; more than that is left to 我發起的. */\nconst RETURNED_INSTANCE_PAGE_SIZE = 100;\n\nconst RETURNED_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n marginBottom: 'var(--mzn-spacing-padding-vertical-spacious)',\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\ntype TabPaging = Readonly<{ page: number; pageSize: number }>;\n\ntype TabPage<TRow> = Readonly<{\n loading: boolean;\n rows: readonly TRow[];\n total: number;\n}>;\n\nconst PAGE_SIZE_OPTIONS = [10, 20, 50];\n\nconst FIRST_PAGE: TabPaging = { page: 1, pageSize: 20 };\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 [pendingPaging, setPendingPaging] = useState<TabPaging>(FIRST_PAGE);\n const [trackingPaging, setTrackingPaging] =\n useState<TabPaging>(FIRST_PAGE);\n const [historyPaging, setHistoryPaging] = useState<TabPaging>(FIRST_PAGE);\n const pending = useTabPage<InboxTaskRow>(\n currentMemberId,\n { enabled: true, paging: pendingPaging, setPaging: setPendingPaging },\n setError,\n async (memberId, paging) => {\n const page = await listInboxTasksPage({\n assigneeMemberId: memberId,\n ...paging,\n });\n\n return readRows(page, readInboxTaskRows);\n },\n );\n // Tasks of instances still under way: the same history, narrowed on the\n // server so the badge and the pages count every such task, not one page.\n const tracking = useTabPage<ApprovalHistoryRow>(\n currentMemberId,\n { enabled: true, paging: trackingPaging, setPaging: setTrackingPaging },\n setError,\n async (memberId, paging) => {\n const page = await listApprovalHistoryTasksPage({\n assigneeMemberId: memberId,\n instanceState: 'RUNNING',\n ...paging,\n });\n\n return readRows(page, (tasks) => readApprovalHistoryRows(tasks, memberId));\n },\n );\n // History has no badge, so it is read only once its tab is opened.\n const history = useTabPage<ApprovalHistoryRow>(\n currentMemberId,\n {\n enabled: activeTab === 'history',\n paging: historyPaging,\n setPaging: setHistoryPaging,\n },\n setError,\n async (memberId, paging) => {\n const page = await listApprovalHistoryTasksPage({\n assigneeMemberId: memberId,\n ...paging,\n });\n\n return readRows(page, (tasks) => readApprovalHistoryRows(tasks, memberId));\n },\n );\n const [returnedRows, setReturnedRows] = useState<\n readonly ReturnedInstanceRow[]\n >([]);\n const [returnedTruncated, setReturnedTruncated] = useState(false);\n\n useEffect((): void => {\n if (!currentMemberId) {\n setReturnedRows([]);\n setReturnedTruncated(false);\n\n return;\n }\n\n void readReturnedInstances(currentMemberId).then(\n (returned): void => {\n setReturnedRows(returned?.rows ?? []);\n setReturnedTruncated(returned?.truncated ?? false);\n },\n (requestError: unknown): void => setError(readErrorMessage(requestError)),\n );\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 returnedColumns = useMemo(\n (): TableColumn<ReturnedInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n {\n key: 'startedAt',\n render: (record: ReturnedInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n ],\n [],\n );\n const returnedTableActions = useMemo(\n (): TableActions<ReturnedInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ReturnedInstanceRow>['render']> => [\n {\n name: '重新送出',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 120,\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\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 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={pending.loading ? undefined : pending.total}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={tracking.loading ? undefined : tracking.total}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {/* A truncated page with none of the member's own cases still\n points to 我發起的: theirs may sit past the first page. */}\n {activeTab === 'pending' &&\n (returnedRows.length > 0 || returnedTruncated) ? (\n <div data-returned-instances=\"\" style={RETURNED_SECTION_STYLE}>\n {/* Without rows there is nothing here to resubmit, only the\n pointer to 我發起的. */}\n {returnedRows.length > 0 ? (\n <Typography component=\"h2\" variant=\"label-primary\">\n 被退回待重送\n </Typography>\n ) : null}\n <Typography color=\"text-neutral\" variant=\"caption\">\n {readReturnedSectionHint(\n returnedRows.length > 0,\n returnedTruncated,\n )}\n </Typography>\n {returnedRows.length > 0 ? (\n <Table\n actions={returnedTableActions}\n columns={returnedColumns}\n dataSource={[...returnedRows]}\n fullWidth\n />\n ) : null}\n </div>\n ) : null}\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={[...pending.rows]}\n fullWidth\n loading={pending.loading}\n pagination={readTablePagination(\n pendingPaging,\n pending.total,\n setPendingPaging,\n )}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={[...tracking.rows]}\n fullWidth\n loading={tracking.loading}\n pagination={readTablePagination(\n trackingPaging,\n tracking.total,\n setTrackingPaging,\n )}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={[...history.rows]}\n fullWidth\n loading={history.loading}\n pagination={readTablePagination(\n historyPaging,\n history.total,\n setHistoryPaging,\n )}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n/**\n * One tab's rows for the current member and paging. Only the latest request\n * may write, so paging quickly cannot let an earlier page's late answer\n * replace the one asked for last. Nothing is read while `enabled` is false.\n * A page past the end (the list shrank since it was chosen) moves to the last\n * page instead of showing an empty table.\n */\nfunction useTabPage<TRow>(\n memberId: string | null,\n {\n enabled,\n paging,\n setPaging,\n }: Readonly<{\n enabled: boolean;\n paging: TabPaging;\n setPaging: (paging: TabPaging) => void;\n }>,\n onError: (message: string | null) => void,\n load: (\n memberId: string,\n paging: TabPaging,\n ) => Promise<Readonly<{ rows: readonly TRow[]; total: number }>>,\n): TabPage<TRow> {\n const [state, setState] = useState<TabPage<TRow>>({\n loading: true,\n rows: [],\n total: 0,\n });\n const latestRequestRef = useRef(0);\n const loadRef = useRef(load);\n\n loadRef.current = load;\n\n const refresh = useCallback(async (): Promise<void> => {\n const request = latestRequestRef.current + 1;\n\n latestRequestRef.current = request;\n\n if (!memberId) {\n setState({ loading: false, rows: [], total: 0 });\n\n return;\n }\n\n setState((previous) => ({ ...previous, loading: true }));\n\n try {\n const loaded = await loadRef.current(memberId, paging);\n\n if (latestRequestRef.current !== request) {\n return;\n }\n\n const lastPage = Math.max(1, Math.ceil(loaded.total / paging.pageSize));\n\n if (!loaded.rows.length && paging.page > lastPage) {\n setPaging({ ...paging, page: lastPage });\n\n return;\n }\n\n setState({ loading: false, ...loaded });\n } catch (requestError: unknown) {\n if (latestRequestRef.current === request) {\n onError(readErrorMessage(requestError));\n setState((previous) => ({ ...previous, loading: false }));\n }\n }\n }, [memberId, onError, paging, setPaging]);\n\n useEffect((): void => {\n if (enabled) {\n void refresh();\n }\n }, [enabled, refresh]);\n\n return state;\n}\n\nasync function readRows<TRow>(\n page: MemberTaskPage,\n toRows: (tasks: readonly TaskRecord[]) => Promise<TRow[]>,\n): Promise<Readonly<{ rows: readonly TRow[]; total: number }>> {\n return { rows: await toRows(page.tasks), total: page.totalCount };\n}\n\nfunction readTablePagination(\n paging: TabPaging,\n total: number,\n setPaging: (paging: TabPaging) => void,\n): Readonly<{\n current: number;\n onChange: (page: number) => void;\n onChangePageSize: (pageSize: number) => void;\n pageSize: number;\n pageSizeLabel: string;\n pageSizeOptions: number[];\n renderResultSummary: (from: number, to: number, total: number) => string;\n showPageSizeOptions: boolean;\n total: number;\n}> {\n return {\n current: paging.page,\n onChange: (page: number): void => setPaging({ ...paging, page }),\n onChangePageSize: (pageSize: number): void =>\n setPaging({ page: 1, pageSize }),\n pageSize: paging.pageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: PAGE_SIZE_OPTIONS,\n renderResultSummary: (from: number, to: number, count: number): string =>\n `顯示 ${from}-${to} 筆,共 ${count} 筆`,\n showPageSizeOptions: true,\n total,\n };\n}\n\nfunction readReturnedSectionHint(\n hasRows: boolean,\n truncated: boolean,\n): string {\n if (!hasRows) {\n return `前 ${RETURNED_INSTANCE_PAGE_SIZE} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`;\n }\n\n return truncated\n ? '你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。'\n : '你發起的案件被退回,請修改後重新送出。';\n}\n\n/**\n * Returned cases are a side list: a failure here, in the request or in reading\n * its rows, hides that section instead of taking the pending and history tasks\n * down with it.\n */\nasync function readReturnedInstances(\n currentMemberId: string,\n): Promise<Readonly<{\n rows: readonly ReturnedInstanceRow[];\n truncated: boolean;\n}> | null> {\n try {\n // SENT also lists cases filed on someone else's behalf; only the\n // initiator may resubmit, so those are filtered out here.\n const page: ApprovalInstancesPageResult = await listApprovalInstancesPage({\n page: 1,\n pageSize: RETURNED_INSTANCE_PAGE_SIZE,\n searchText: null,\n state: 'RETURNED',\n templateId: null,\n view: 'SENT',\n });\n\n return {\n rows: readReturnedInstanceRows(page.instances, currentMemberId),\n // The total includes cases filed for someone else, so compare it with\n // what this page fetched rather than with the rows kept.\n truncated: page.totalCount > page.instances.length,\n };\n } catch {\n return null;\n }\n}\n\nfunction readReturnedInstanceRows(\n instances: readonly ApprovalInstanceRecord[],\n currentMemberId: string,\n): readonly ReturnedInstanceRow[] {\n return instances\n .filter(\n (instance): boolean => instance.initiatorMemberId === currentMemberId,\n )\n .map(\n (instance): ReturnedInstanceRow => ({\n caseTitle: readApprovalInstanceCaseTitle(instance),\n id: instance.id,\n key: instance.id,\n startedAt: instance.startedAt,\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 currentMemberId: string,\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 decisions = decisionLists[index] ?? [];\n const decision = readLatestOwnTaskDecision(decisions, currentMemberId);\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 // completedAt is when the last signer finished, so it can stand in only\n // when the task has no decisions at all.\n decidedAt:\n decision?.decidedAt ??\n (decisions.length === 0 ? task.completedAt : null),\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\n// A sequential or countersign task holds decisions from several signers, so\n// the newest one on the task can be somebody else's. A delegate is the one\n// recorded as deciding, and a principal never gets the delegated task in this\n// list.\nfunction readLatestOwnTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n currentMemberId: string,\n): TaskDecisionRecord | null {\n return readLatestTaskDecision(\n decisions.filter(\n (decision): boolean => decision.decidedByMemberId === currentMemberId,\n ),\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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"}
|