@rytass/bpm-core-react 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/dist/chunks/FormBuilderView-B_KGPjlp.cjs +3 -0
- package/dist/chunks/FormBuilderView-B_KGPjlp.cjs.map +1 -0
- package/dist/chunks/FormBuilderView-D8DrQOXD.js +1090 -0
- package/dist/chunks/FormBuilderView-D8DrQOXD.js.map +1 -0
- package/dist/chunks/{approval-instance-list-page-C5ZKPHdA.cjs → approval-instance-list-page-BMUKxzcz.cjs} +2 -2
- package/dist/chunks/{approval-instance-list-page-C5ZKPHdA.cjs.map → approval-instance-list-page-BMUKxzcz.cjs.map} +1 -1
- package/dist/chunks/{approval-instance-list-page-BF2r5D2-.js → approval-instance-list-page-YZcGGDD8.js} +2 -2
- package/dist/chunks/{approval-instance-list-page-BF2r5D2-.js.map → approval-instance-list-page-YZcGGDD8.js.map} +1 -1
- package/dist/chunks/compose-PMrmi-LE.js +451 -0
- package/dist/chunks/compose-PMrmi-LE.js.map +1 -0
- package/dist/chunks/compose-ziVbRYdo.cjs +2 -0
- package/dist/chunks/compose-ziVbRYdo.cjs.map +1 -0
- package/dist/chunks/{dashboard-page-Ib8srCMy.js → dashboard-page-DJ9vOPga.js} +2 -2
- package/dist/chunks/{dashboard-page-Ib8srCMy.js.map → dashboard-page-DJ9vOPga.js.map} +1 -1
- package/dist/chunks/{dashboard-page-CddG1MnK.cjs → dashboard-page-DwHQY6Ki.cjs} +2 -2
- package/dist/chunks/{dashboard-page-CddG1MnK.cjs.map → dashboard-page-DwHQY6Ki.cjs.map} +1 -1
- package/dist/chunks/designer-DCn6_v4b.cjs +65 -0
- package/dist/chunks/designer-DCn6_v4b.cjs.map +1 -0
- package/dist/chunks/designer-mOMxJ0Py.js +2576 -0
- package/dist/chunks/designer-mOMxJ0Py.js.map +1 -0
- package/dist/chunks/detail-Bml-vXHX.js +1622 -0
- package/dist/chunks/detail-Bml-vXHX.js.map +1 -0
- package/dist/chunks/detail-CWeCrmtC.cjs +2 -0
- package/dist/chunks/detail-CWeCrmtC.cjs.map +1 -0
- package/dist/chunks/{routes-config-dxahImVe.js → routes-config-RBYQtUd0.js} +2 -3
- package/dist/chunks/routes-config-RBYQtUd0.js.map +1 -0
- package/dist/chunks/routes-config-fDVHmvXi.cjs +2 -0
- package/dist/chunks/routes-config-fDVHmvXi.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +268 -128
- package/dist/index.js.map +1 -1
- package/dist/lib/routes-config.d.ts +6 -4
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.js +1 -1
- package/dist/next/workflow-chat-route.cjs +19 -0
- package/dist/next/workflow-chat-route.cjs.map +1 -0
- package/dist/next/workflow-chat-route.d.ts +17 -0
- package/dist/next/workflow-chat-route.js +31 -0
- package/dist/next/workflow-chat-route.js.map +1 -0
- 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 +2 -0
- package/dist/pages/templates/compose/index.cjs.map +1 -0
- package/dist/pages/templates/compose/index.d.ts +13 -0
- package/dist/pages/templates/compose/index.js +14 -0
- package/dist/pages/templates/compose/index.js.map +1 -0
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.cjs.map +1 -1
- package/dist/pages/templates/designer/index.js +7 -2
- package/dist/pages/templates/designer/index.js.map +1 -1
- package/dist/pages/templates/index.cjs +1 -1
- package/dist/pages/templates/index.cjs.map +1 -1
- package/dist/pages/templates/index.js +3 -3
- package/dist/pages/templates/index.js.map +1 -1
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.js +1 -1
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.js +1 -1
- package/dist/views/forms/builder/FormBuilderView.d.ts +13 -4
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/builder/json-code-editor.d.ts +1 -1
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.js +1 -1
- package/dist/views/instances/detail/InstanceDetailView.d.ts +11 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.d.ts +5 -0
- package/dist/views/instances/detail/index.js +2 -2
- package/dist/views/instances/detail/sections/InstanceAttachmentsSection.d.ts +15 -0
- package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +33 -0
- package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +29 -0
- package/dist/views/instances/detail/sections/InstanceSignaturesSection.d.ts +14 -0
- package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +44 -0
- package/dist/views/instances/detail/sections/container-helpers.d.ts +8 -0
- package/dist/views/instances/detail/sections/shared.d.ts +103 -0
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.js +1 -1
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.js +1 -1
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.js +1 -1
- package/dist/views/templates/TemplatesView.d.ts +5 -0
- package/dist/views/templates/compose/TemplateComposeWizardView.d.ts +8 -0
- package/dist/views/templates/compose/index.cjs +1 -0
- package/dist/views/templates/compose/index.d.ts +2 -0
- package/dist/views/templates/compose/index.js +2 -0
- package/dist/views/templates/compose/steps/ComposeFormStep.d.ts +15 -0
- package/dist/views/templates/compose/steps/ComposeReviewStep.d.ts +12 -0
- package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +11 -0
- package/dist/views/templates/compose/use-template-compose-wizard.d.ts +46 -0
- package/dist/views/templates/designer/TemplateDesignerView.d.ts +60 -2
- package/dist/views/templates/designer/chrome-workflow-chat.d.ts +12 -0
- package/dist/views/templates/designer/index.cjs +1 -51
- package/dist/views/templates/designer/index.js +2 -2272
- package/dist/views/templates/designer/use-workflow-chat.d.ts +21 -0
- package/dist/views/templates/designer/use-workflow-designer-controller.d.ts +41 -0
- package/dist/views/templates/designer/workflow-chat-drawer.d.ts +16 -0
- package/dist/views/templates/index.cjs +2 -1
- package/dist/views/templates/index.cjs.map +1 -0
- package/dist/views/templates/index.js +265 -4
- package/dist/views/templates/index.js.map +1 -0
- package/dist/views/templates/versions/index.cjs +1 -1
- package/dist/views/templates/versions/index.cjs.map +1 -1
- package/dist/views/templates/versions/index.js +38 -42
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +22 -19
- package/dist/chunks/builder-BLVnnpnP.js +0 -1300
- package/dist/chunks/builder-BLVnnpnP.js.map +0 -1
- package/dist/chunks/builder-DVE9zIKH.cjs +0 -3
- package/dist/chunks/builder-DVE9zIKH.cjs.map +0 -1
- package/dist/chunks/detail-Dcr5mM8g.cjs +0 -2
- package/dist/chunks/detail-Dcr5mM8g.cjs.map +0 -1
- package/dist/chunks/detail-u9DdLhDW.js +0 -1518
- package/dist/chunks/detail-u9DdLhDW.js.map +0 -1
- package/dist/chunks/form-name-modal-C3OEvkCV.js +0 -64
- package/dist/chunks/form-name-modal-C3OEvkCV.js.map +0 -1
- package/dist/chunks/form-name-modal-uZCHbtRH.cjs +0 -2
- package/dist/chunks/form-name-modal-uZCHbtRH.cjs.map +0 -1
- package/dist/chunks/routes-config-2aKbWq2H.cjs +0 -2
- package/dist/chunks/routes-config-2aKbWq2H.cjs.map +0 -1
- package/dist/chunks/routes-config-dxahImVe.js.map +0 -1
- package/dist/chunks/templates-D44FSB46.js +0 -380
- package/dist/chunks/templates-D44FSB46.js.map +0 -1
- package/dist/chunks/templates-w96t83N-.cjs +0 -2
- package/dist/chunks/templates-w96t83N-.cjs.map +0 -1
- package/dist/pages/forms/builder/index.cjs +0 -2
- package/dist/pages/forms/builder/index.cjs.map +0 -1
- package/dist/pages/forms/builder/index.d.ts +0 -21
- package/dist/pages/forms/builder/index.js +0 -15
- package/dist/pages/forms/builder/index.js.map +0 -1
- package/dist/pages/forms/index.cjs +0 -2
- package/dist/pages/forms/index.cjs.map +0 -1
- package/dist/pages/forms/index.d.ts +0 -17
- package/dist/pages/forms/index.js +0 -14
- package/dist/pages/forms/index.js.map +0 -1
- package/dist/views/forms/FormsView.d.ts +0 -2
- package/dist/views/forms/form-name-modal.d.ts +0 -12
- package/dist/views/forms/index.cjs +0 -2
- package/dist/views/forms/index.cjs.map +0 -1
- package/dist/views/forms/index.d.ts +0 -2
- package/dist/views/forms/index.js +0 -186
- package/dist/views/forms/index.js.map +0 -1
- package/dist/views/templates/designer/index.cjs.map +0 -1
- package/dist/views/templates/designer/index.js.map +0 -1
- package/dist/views/templates/template-name-modal.d.ts +0 -22
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use client";require('../detail.css');const e=require("./chunk-CMqjfN_6.cjs"),t=require("./auth-provider-4BeCw7cI.cjs"),n=require("./format-date-time-XxBzF0F5.cjs"),r=require("./bpm-form-field-Bc6k4ZEO.cjs"),i=require("./FormRendererView-BwVsH2eX.cjs");let a=require("react"),o=require("@mezzanine-ui/react"),s=require("react/jsx-runtime"),c=require("@rytass/bpm-core-client/workflow"),l=require("@mezzanine-ui/react/ContentHeader");l=e.t(l,1);let u=require("@mezzanine-ui/icons"),d=require("@rytass/bpm-core-client/form"),f=require("@xyflow/react"),p=require("dagre");p=e.t(p,1);let m=require("@mezzanine-ui/core/stepper"),h=require("react-pdf");var g={root:`bpm_root_ehm7w`,toolbar:`bpm_toolbar_R-tis`,pageControls:`bpm_pageControls_jM-rC`,zoomControls:`bpm_zoomControls_7RAbJ`,counter:`bpm_counter_ILUsD`,viewport:`bpm_viewport_DQXms`,page:`bpm_page_Cv5Rg`,state:`bpm_state_bpgp3`},_=760,ee=920,te=320,ne=32,re=.75,ie=1.75,v=.25;function ae({filename:e,fileUrl:t,onDownload:n}){let r=(0,a.useRef)(null),[i,c]=(0,a.useState)(null),[l,d]=(0,a.useState)(1),[f,p]=(0,a.useState)(1),[m,ae]=(0,a.useState)(_);(0,a.useEffect)(()=>{let e=r.current;if(!e||typeof ResizeObserver>`u`)return;let t=new ResizeObserver(e=>{let t=e[0]?.contentRect.width;t&&ae(t)});return t.observe(e),()=>t.disconnect()},[]),(0,a.useEffect)(()=>{c(null),d(1),p(1)},[t]);let b=(0,a.useMemo)(()=>{let e=Math.max(te,m-ne);return Math.round(Math.min(ee,e)*f)},[f,m]),oe=(0,a.useCallback)(e=>{c(e.numPages),d(1)},[]),x=l>1,se=i!==null&&l<i,ce=f>re,le=f<ie,ue=i===null?`第 ${l} 頁`:`第 ${l} / ${i} 頁`,de=`${Math.round(f*100)}%`;return(0,s.jsxs)(`section`,{"aria-label":`${e} PDF 預覽`,className:g.root,children:[(0,s.jsxs)(`div`,{className:g.toolbar,children:[(0,s.jsxs)(`div`,{className:g.pageControls,"aria-label":`頁面切換`,children:[(0,s.jsx)(o.Button,{"aria-label":`上一頁`,disabled:!x,icon:u.ChevronLeftIcon,onClick:()=>{d(e=>Math.max(1,e-1))},size:`minor`,variant:`base-secondary`}),(0,s.jsx)(o.Typography,{className:g.counter,component:`span`,variant:`body`,children:ue}),(0,s.jsx)(o.Button,{"aria-label":`下一頁`,disabled:!se,icon:u.ChevronRightIcon,onClick:()=>{d(e=>i===null?e:Math.min(i,e+1))},size:`minor`,variant:`base-secondary`})]}),(0,s.jsxs)(`div`,{className:g.zoomControls,"aria-label":`縮放`,children:[(0,s.jsx)(o.Button,{"aria-label":`縮小`,disabled:!ce,icon:u.ZoomOutIcon,onClick:()=>{p(e=>Math.max(re,e-v))},size:`minor`,variant:`base-secondary`}),(0,s.jsx)(o.Typography,{className:g.counter,component:`span`,variant:`body`,children:de}),(0,s.jsx)(o.Button,{"aria-label":`放大`,disabled:!le,icon:u.ZoomInIcon,onClick:()=>{p(e=>Math.min(ie,e+v))},size:`minor`,variant:`base-secondary`})]}),n?(0,s.jsx)(o.Button,{icon:u.DownloadIcon,iconType:`leading`,onClick:n,size:`minor`,variant:`base-primary`,children:`下載`}):null]}),(0,s.jsx)(`div`,{className:g.viewport,ref:r,children:(0,s.jsx)(h.Document,{error:(0,s.jsx)(y,{message:`PDF 無法載入。`}),file:t,loading:(0,s.jsx)(y,{message:`正在載入 PDF...`}),noData:(0,s.jsx)(y,{message:`沒有可預覽的 PDF。`}),onLoadSuccess:oe,children:(0,s.jsx)(h.Page,{className:g.page,loading:(0,s.jsx)(y,{message:`正在載入頁面...`}),pageNumber:l,renderAnnotationLayer:!0,renderTextLayer:!0,width:b})})})]})}function y({message:e}){return(0,s.jsx)(`div`,{className:g.state,children:(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:e})})}var b={display:`grid`,gap:16},oe={display:`flex`,flexWrap:`wrap`,gap:8},x=184,se=96,ce={display:`grid`,gap:16},le={display:`grid`,gap:12,width:`100%`},ue={minWidth:`100%`,width:`100%`},de={display:`grid`,gap:12,width:`100%`},fe={background:`#f8fafc`,border:`1px solid #e2e8f0`,borderRadius:8,height:`min(64vh, 620px)`,minHeight:440,overflow:`hidden`,width:`min(80vw, 1040px)`},S={background:`#ffffff`,border:`1px solid #cbd5e1`,borderRadius:8,boxShadow:`0 8px 18px rgba(15, 23, 42, 0.08)`,display:`grid`,gap:6,minHeight:82,padding:12,width:184},pe={borderRadius:999,fontSize:12,fontWeight:600,justifySelf:`start`,lineHeight:`18px`,padding:`0 8px`},C={color:`#64748b`,fontSize:12,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},me={opacity:0},he={display:`flex`,flexWrap:`wrap`,gap:8},ge={alignItems:`center`,background:`#ffffff`,border:`1px solid #cbd5e1`,borderRadius:8,color:`#334155`,display:`inline-flex`,fontSize:12,fontWeight:600,gap:6,lineHeight:`20px`,padding:`4px 8px`},_e={cursor:`help`,textDecoration:`underline dotted`,textUnderlineOffset:3},ve={color:`var(--mzn-color-text-error)`};function ye(e){e&&(e.style.width=`100%`)}var be={workflowRuntime:Xe};function xe({instanceId:e}){let{member:p}=t.n(),m=p?.memberId??null,[h,g]=(0,a.useState)([]),[_,ee]=(0,a.useState)(null),[te,ne]=(0,a.useState)([]),[re,ie]=(0,a.useState)([]),[v,y]=(0,a.useState)([]),[x,se]=(0,a.useState)(null),[S,pe]=(0,a.useState)([]),[C,me]=(0,a.useState)([]),[_e,ve]=(0,a.useState)([]),[xe,T]=(0,a.useState)(null),[Te,E]=(0,a.useState)(!0),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)(!1),[je,Me]=(0,a.useState)(``),[Ne,j]=(0,a.useState)(!1),[Pe,M]=(0,a.useState)(``),[N,P]=(0,a.useState)(null),[Fe,Ie]=(0,a.useState)(!1),[Le,F]=(0,a.useState)(``),[Re,I]=(0,a.useState)(!1),[ze,R]=(0,a.useState)(null),[We,B]=(0,a.useState)(``),[V,H]=(0,a.useState)(null),[Je,Ye]=(0,a.useState)(!1),[U,W]=(0,a.useState)([]),[G,K]=(0,a.useState)(!1),[Xe,q]=(0,a.useState)({}),[J,et]=(0,a.useState)({}),[Y,tt]=(0,a.useState)(null),[rt,it]=(0,a.useState)(null),at=Pe.trim(),ot=je.trim(),st=Le.trim(),ct=We.trim();(0,a.useEffect)(()=>{Ot()},[m,e]),(0,a.useEffect)(()=>{et(_?.formData??{})},[_]);let X=(0,a.useMemo)(()=>S.find(e=>He(e,m)&&(e.status===`PENDING`||e.status===`IN_PROGRESS`))??null,[m,S]),Z=(0,a.useMemo)(()=>X&&_?_.workflowSnapshot.nodes.find(e=>e.id===X.nodeId)??null:null,[X,_]),lt=(0,a.useMemo)(()=>Z&&_?Be(_.workflowSnapshot,Z):[],[Z,_]),ut=Z?.type===`userTask`&&Z.data.returnBehavior.allowReturn,dt=lt.find(e=>e.id===ze)??lt[0]??null,ft=!!(_&&_.initiatorMemberId===m&&(_.state===`RUNNING`||_.state===`RETURNED`)),Q=!!(_&&_.initiatorMemberId===m&&_.state===`RETURNED`),pt=(0,a.useMemo)(()=>new Map(_e.map(e=>[e.memberId,e])),[_e]),mt=(0,a.useMemo)(()=>S.map(e=>({...e,assigneeLabel:z(e,pt),key:e.id,nodeLabel:L(e.nodeId,_?.workflowSnapshot??null),statusLabel:Ve(e.status)})),[_,pt,S]),ht=(0,a.useMemo)(()=>Oe(te),[te]),gt=(0,a.useMemo)(()=>new Map(v.map(e=>[e.id,e])),[v]),_t=(0,a.useMemo)(()=>ke(h,S,C,_?.workflowSnapshot??null,_?.state??`RUNNING`,pt,ht,gt,x),[h,_,pt,x,gt,ht,S,C]),vt=(0,a.useMemo)(()=>Ae(_t),[_t]),$=(0,a.useMemo)(()=>_?Qe(_.workflowSnapshot):null,[_]),yt=(0,a.useMemo)(()=>_&&$?Ze($,S,C,_.state):[],[_,$,S,C]),bt=(0,a.useMemo)(()=>$?$e($):[],[$]),xt=(0,a.useMemo)(()=>_?nt(_.workflowSnapshot):[],[_]),St=(0,a.useMemo)(()=>[{dataIndex:`nodeLabel`,key:`nodeLabel`,title:`節點`,width:180},{key:`assigneeMemberId`,title:`處理者`,render:e=>(0,s.jsx)(o.Typography,{component:`span`,variant:`body`,children:e.assigneeLabel}),width:180},{dataIndex:`statusLabel`,key:`statusLabel`,title:`狀態`,width:120},{key:`createdAt`,render:e=>(0,s.jsx)(o.Typography,{component:`span`,variant:`body`,children:n.t(e.createdAt)}),title:`建立時間`,width:220}],[]),Ct=(0,a.useMemo)(()=>re.map(e=>({attachment:e,createdAt:e.createdAt,filename:e.filename,id:e.id,key:e.id,mimeType:e.mimeType,sizeLabel:Se(Number(e.sizeBytes))})),[re]),wt=(0,a.useMemo)(()=>[{dataIndex:`filename`,key:`filename`,title:`檔名`,width:260},{dataIndex:`mimeType`,key:`mimeType`,title:`類型`,width:180},{dataIndex:`sizeLabel`,key:`sizeLabel`,title:`大小`,width:120},{key:`createdAt`,render:e=>(0,s.jsx)(o.Typography,{component:`span`,variant:`body`,children:n.t(e.createdAt)}),title:`上傳時間`,width:220}],[]),Tt=(0,a.useMemo)(()=>({render:e=>[...e.mimeType===`application/pdf`?[{icon:u.FileSearchIcon,iconType:`leading`,name:`預覽`,onClick:()=>{jt(e.attachment)}}]:[],{icon:u.DownloadIcon,iconType:`leading`,name:`下載`,onClick:()=>{At(e.attachment)}}],variant:`base-secondary`,width:160}),[]),Et=(0,a.useMemo)(()=>v.map(e=>({algorithm:e.algorithm,hashLabel:Ce(e.signedPayloadHash),key:e.id,keyVersion:e.keyVersion,signedAtLabel:n.t(e.signedAt),signerMemberId:e.signerMemberId})),[v]),Dt=(0,a.useMemo)(()=>[{dataIndex:`signerMemberId`,key:`signerMemberId`,title:`簽章者`,width:160},{dataIndex:`algorithm`,key:`algorithm`,title:`演算法`,width:150},{dataIndex:`keyVersion`,key:`keyVersion`,title:`Key 版本`,width:100},{dataIndex:`hashLabel`,key:`hashLabel`,title:`Payload Hash`,width:180},{dataIndex:`signedAtLabel`,key:`signedAtLabel`,title:`簽章時間`,width:220}],[]);async function Ot(){E(!0),T(null);try{let t=await(0,c.readApprovalInstance)(e);g(t.activityLogs),ee(t.instance),pe(t.tasks),me(t.workflowTokens);let[n,r,i,a]=await Promise.all([De(t.tasks),Ee(t),(0,c.listAttachments)(t.instance.id),(0,c.readInstanceSignatures)(t.instance.id)]);ne(n),ve(r),ie(i),y(a.signatures),se(a.verification)}catch(e){T(w(e))}finally{E(!1)}}async function kt(e,t){if(!m)throw Error(`尚未登入,無法上傳附件`);return{id:(await(0,c.uploadAttachment)({file:t,formFieldPath:`form.${e.fieldKey}`})).id}}async function At(e){if(!m)return;let t=await(0,c.readAttachmentDownloadUrl)({id:e.id});window.open(t,`_blank`,`noopener,noreferrer`)}async function jt(e){if(!m)return;let t=await(0,c.readAttachmentPreviewUrl)({id:e.id});tt(e),it(t)}async function Mt({action:e,comment:t,returnToNodeId:n=null,transferToMemberId:r=null}){if(!(!m||!X)){O(!0),T(null);try{await(0,c.decideTask)({action:e,comment:t,decidedByMemberId:m,returnToNodeId:n,taskId:X.id,transferToMemberId:r}),Ie(!1),I(!1),K(!1),M(``),F(``),B(``),H(null),R(null),P(null),await Ot()}catch(e){T(w(e))}finally{O(!1)}}}function Nt(){M(``),P(null),Ie(!0)}function Pt(){D||(Ie(!1),M(``),P(null))}function Ft(){F(``),R(lt[0]?.id??null),I(!0)}function It(){D||(I(!1),F(``),R(null))}function Lt(){B(``),H(null),K(!0),zt(``)}function Rt(){D||(K(!1),B(``),H(null))}async function zt(e){Ye(!0);try{W((await(0,c.searchMembers)(e)).filter(e=>e.memberId!==m).map(Ge))}catch(e){T(w(e))}finally{Ye(!1)}}async function Bt(){if(!at){P(`請輸入拒絕原因`);return}await Mt({action:`REJECTED`,comment:at})}async function Vt(){if(!V){T(`請選擇轉派對象`);return}await Mt({action:`TRANSFERRED`,comment:ct||null,transferToMemberId:V.id})}async function Ht(){await Mt({action:`RETURNED`,comment:st||null,returnToNodeId:dt?.id??null})}async function Ut(){if(!(!m||!_||!ft)){if(O(!0),T(null),q({}),_.formDefinitionSnapshot.schema&&_.formDefinitionSnapshot.uiSchema){let e=(0,d.validateFormRendererValues)({schema:_.formDefinitionSnapshot.schema,uiSchema:_.formDefinitionSnapshot.uiSchema,values:J});if(!e.valid){q(e.errors),T(`請先補齊必填欄位。`),e.firstInvalidFieldKey&&(0,d.focusFormRendererField)(e.firstInvalidFieldKey),O(!1);return}}try{await(0,c.cancelApprovalInstance)({cancelledByMemberId:m,comment:ot||null,instanceId:_.id}),Me(``),j(!1),await Ot()}catch(e){T(w(e))}finally{O(!1)}}}async function Wt(){if(!(!m||!_||!Q)){O(!0),T(null);try{await(0,c.resubmitApprovalInstance)({formData:J,initiatorMemberId:m,instanceId:_.id,title:_.title}),await Ot()}catch(e){T(w(e))}finally{O(!1)}}}return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.PageHeader,{children:(0,s.jsxs)(l.default,{description:_?`${Ue(_.state)} · ${n.t(_.startedAt)}`:`載入案件內容。`,title:_?.title??`簽核案件`,children:[_?(0,s.jsx)(o.Button,{"aria-label":`查看流程圖`,icon:u.ShareIcon,iconType:`icon-only`,onClick:()=>A(!0),title:`查看流程圖`,variant:`base-secondary`,children:`流程圖`}):null,ft?(0,s.jsx)(o.Button,{disabled:D,icon:u.DangerousOutlineIcon,iconType:`leading`,onClick:()=>j(!0),variant:`destructive-secondary`,children:`取消案件`}):null,X?(0,s.jsxs)(s.Fragment,{children:[ut?(0,s.jsx)(o.Button,{disabled:D,icon:u.RefreshCcwIcon,iconType:`leading`,onClick:Ft,variant:`base-secondary`,children:`退回`}):null,(0,s.jsx)(o.Button,{disabled:D,icon:u.UserIcon,iconType:`leading`,onClick:Lt,variant:`base-secondary`,children:`轉派`}),(0,s.jsx)(o.Button,{disabled:D,icon:u.DangerousOutlineIcon,iconType:`leading`,onClick:Nt,variant:`destructive-secondary`,children:`拒絕`}),(0,s.jsx)(o.Button,{disabled:D,icon:u.CheckedIcon,iconType:`leading`,onClick:()=>void Mt({action:`APPROVED`,comment:null}),variant:`base-primary`,children:`同意`})]}):null]})}),(0,s.jsxs)(o.SectionGroup,{children:[(0,s.jsx)(o.Section,{children:(0,s.jsxs)(`div`,{style:b,children:[xe?(0,s.jsx)(o.Typography,{color:`text-error`,variant:`body`,children:xe}):null,Te?(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:`載入中...`}):null,_?.formDefinitionSnapshot.schema&&_.formDefinitionSnapshot.uiSchema?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.t,{errors:Xe,onChange:e=>{et(e),q({})},onUploadAttachment:Q?kt:void 0,readonly:!Q,schema:_.formDefinitionSnapshot.schema,uiSchema:_.formDefinitionSnapshot.uiSchema,value:Q?J:_.formData}),Q?(0,s.jsx)(`div`,{style:oe,children:(0,s.jsx)(o.Button,{disabled:D,icon:u.RefreshCcwIcon,iconType:`leading`,onClick:()=>void Wt(),variant:`base-primary`,children:`重新送出`})}):null]}):(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:`此案件沒有可顯示的表單快照。`})]})}),(0,s.jsx)(o.Section,{children:(0,s.jsxs)(`div`,{style:b,children:[(0,s.jsx)(o.Typography,{component:`h2`,variant:`h3`,children:`附件`}),Ct.length>0?(0,s.jsx)(o.Table,{actions:Tt,columns:wt,dataSource:Ct,fullWidth:!0}):(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:`此案件沒有附件。`})]})}),(0,s.jsxs)(o.Section,{children:[(0,s.jsx)(o.Typography,{component:`h2`,variant:`h3`,children:`任務`}),(0,s.jsx)(o.Table,{columns:St,dataSource:mt,fullWidth:!0})]}),(0,s.jsx)(o.Section,{children:(0,s.jsxs)(`div`,{style:b,children:[(0,s.jsx)(o.Typography,{component:`h2`,variant:`h3`,children:`簽章`}),(0,s.jsx)(o.Typography,{color:x?.valid?`text-success`:`text-error`,variant:`body`,children:x?x.valid?`簽章鏈已驗證,共 ${x.checkedCount} 筆。`:`簽章鏈驗證失敗:${x.errors.join(`、`)}`:`尚無簽章紀錄。`}),Et.length>0?(0,s.jsx)(o.Table,{columns:Dt,dataSource:Et,fullWidth:!0}):null]})}),(0,s.jsx)(o.Section,{children:(0,s.jsxs)(`div`,{style:b,children:[(0,s.jsx)(o.Typography,{component:`h2`,variant:`h3`,children:`歷程`}),_t.length>0?(0,s.jsx)(o.Stepper,{currentStep:vt,orientation:`vertical`,type:`dot`,children:_t.map(e=>(0,s.jsx)(we,{descriptionParts:e.descriptionParts,error:e.error,forcePending:e.forcePending,title:e.title},e.id))}):(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:`尚無歷程紀錄。`})]})})]}),_?(0,s.jsx)(o.Modal,{modalType:`standard`,onClose:()=>A(!1),open:k,showModalHeader:!0,size:`wide`,supportingText:`${Ue(_.state)} · ${n.t(_.startedAt)}`,title:`流程圖`,children:(0,s.jsxs)(`div`,{style:ce,children:[(0,s.jsx)(`div`,{style:fe,children:(0,s.jsxs)(f.ReactFlow,{edges:bt,fitView:!0,fitViewOptions:{padding:.18},maxZoom:1.2,minZoom:.2,nodes:yt,nodesDraggable:!1,nodesFocusable:!1,nodeTypes:be,panOnDrag:!0,proOptions:{hideAttribution:!0},children:[(0,s.jsx)(f.Background,{}),(0,s.jsx)(f.Controls,{showInteractive:!1})]})}),xt.length>0?(0,s.jsx)(`div`,{style:he,children:xt.map(e=>(0,s.jsx)(`span`,{style:ge,children:e},e))}):null]})}):null,(0,s.jsx)(o.Modal,{modalType:`standard`,onClose:()=>{tt(null),it(null)},open:!!(Y&&rt),showModalHeader:!0,size:`wide`,supportingText:Y?.filename??void 0,title:`PDF 預覽`,children:rt?(0,s.jsx)(ae,{filename:Y?.filename??`PDF 預覽`,fileUrl:rt,onDownload:Y?()=>void At(Y):void 0}):null}),(0,s.jsx)(o.Modal,{cancelText:`保留案件`,confirmButtonProps:{variant:`destructive-primary`},confirmText:`確認取消`,loading:D,modalStatusType:`error`,modalType:`standard`,onCancel:()=>j(!1),onClose:()=>j(!1),onConfirm:()=>void Ut(),open:Ne,showModalFooter:!0,showModalHeader:!0,supportingText:`取消後會關閉目前待簽任務與候選簽核人。`,title:`取消案件`,children:(0,s.jsxs)(`div`,{style:b,children:[(0,s.jsxs)(o.Typography,{variant:`body`,children:[`確定要取消「`,_?.title??``,`」嗎?`]}),(0,s.jsx)(r.t,{label:`取消原因`,name:`cancelComment`,children:(0,s.jsx)(o.Textarea,{onChange:e=>Me(e.target.value),placeholder:`可填寫取消原因`,resize:`vertical`,rows:3,value:je})})]})}),(0,s.jsx)(o.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!at,variant:`destructive-primary`},confirmText:`送出拒絕`,loading:D,modalStatusType:`error`,modalType:`standard`,onCancel:Pt,onClose:Pt,onConfirm:()=>void Bt(),open:Fe,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`拒絕案件時必須留下原因,供發起人與後續追蹤查看。`,title:`拒絕原因`,children:(0,s.jsxs)(`div`,{style:le,children:[(0,s.jsx)(r.t,{label:`拒絕原因`,name:`rejectReason`,required:!0,children:(0,s.jsx)(o.Textarea,{autoFocus:!0,onChange:e=>{M(e.target.value),P(null)},placeholder:`請說明拒絕原因`,ref:ye,resize:`vertical`,rows:4,style:ue,type:N?`error`:`default`,value:Pe})}),N?(0,s.jsx)(o.Typography,{color:`text-error`,variant:`body`,children:N}):null]})}),(0,s.jsx)(o.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!V},confirmText:`送出轉派`,loading:D,modalType:`standard`,onCancel:Rt,onClose:Rt,onConfirm:()=>void Vt(),open:G,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`轉派後,原任務會保留轉派紀錄,新的待簽任務會指派給指定成員。`,title:`轉派簽核`,children:(0,s.jsxs)(`div`,{style:de,children:[(0,s.jsx)(r.t,{label:`轉派對象`,name:`transferToMemberId`,required:!0,children:(0,s.jsx)(o.AutoComplete,{asyncData:!0,disabledOptionsFilter:!0,emptyText:`沒有符合的成員`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:`transfer-member-search`,spellCheck:!1},loading:Je,loadingText:`搜尋成員中...`,mode:`single`,onChange:e=>H(Ke(e)),onSearch:zt,onSearchTextChange:e=>H(qe(e,U)),onVisibilityChange:e=>{e&&zt(``)},options:[...U],placeholder:`搜尋姓名或信箱`,searchDebounceTime:300,value:V})}),(0,s.jsx)(r.t,{label:`轉派說明`,name:`transferComment`,children:(0,s.jsx)(o.Textarea,{onChange:e=>B(e.target.value),placeholder:`可補充轉派原因`,ref:ye,resize:`vertical`,rows:4,style:ue,value:We})})]})}),(0,s.jsx)(o.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!dt},confirmText:`送出退回`,loading:D,modalType:`standard`,onCancel:It,onClose:It,onConfirm:()=>void Ht(),open:Re,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`退回後,流程會回到指定節點並等待重新處理。`,title:`退回簽核`,children:(0,s.jsxs)(`div`,{style:de,children:[(0,s.jsx)(r.t,{label:`退回節點`,name:`returnTargetNodeId`,required:!0,children:(0,s.jsx)(o.Select,{clearable:!1,fullWidth:!0,onChange:e=>R(e?.id??null),options:[...lt],placeholder:`選擇退回節點`,value:dt})}),(0,s.jsx)(r.t,{label:`退回說明`,name:`returnComment`,children:(0,s.jsx)(o.Textarea,{onChange:e=>F(e.target.value),placeholder:`可補充需要修改的內容`,ref:ye,resize:`vertical`,rows:4,style:ue,value:Le})})]})})]})}function w(e){return e instanceof Error?e.message:`發生未知錯誤`}function Se(e){return!Number.isFinite(e)||e<=0?`-`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function Ce(e){return e.length>16?`${e.slice(0,12)}...`:e}function T(...e){return e.filter(e=>W(e??null)).join(` `)}var we=(0,a.forwardRef)(function({className:e,descriptionParts:t,error:n,forcePending:r=!1,index:i=0,orientation:c,status:l=`pending`,title:u,type:d=`number`,...f},p){let h=r?`pending`:l;return(0,s.jsxs)(`div`,{...f,className:T(m.stepClasses.host,d===`dot`?m.stepClasses.dot:null,n&&h!==`processing`?m.stepClasses.error:null,c===`horizontal`?m.stepClasses.horizontal:null,d===`number`?m.stepClasses.number:null,h===`pending`?m.stepClasses.pending:null,h===`processing`?m.stepClasses.processing:null,n&&h===`processing`?m.stepClasses.processingError:null,!n&&h===`succeeded`?m.stepClasses.succeeded:null,c===`vertical`?m.stepClasses.vertical:null,e),ref:p,children:[d===`dot`?(0,s.jsx)(`span`,{className:T(m.stepClasses.statusIndicator,m.stepClasses.statusIndicatorDot)}):(0,s.jsx)(`span`,{className:m.stepClasses.statusIndicator,children:i+1}),(0,s.jsxs)(`div`,{className:m.stepClasses.textContainer,children:[(0,s.jsxs)(o.Typography,{className:m.stepClasses.title,variant:`label-primary-highlight`,children:[u,(0,s.jsx)(`span`,{className:m.stepClasses.titleConnectLine})]}),t.length>0?(0,s.jsx)(o.Typography,{className:m.stepClasses.description,variant:`caption`,children:t.map((e,t)=>(0,s.jsxs)(a.Fragment,{children:[t>0?` · `:null,Te(e)]},`${e.type}-${t}`))}):null]})]})});function Te(e){return e.type===`text`?e.text:e.type===`dangerText`?(0,s.jsx)(`span`,{style:ve,children:e.text}):e.email?(0,s.jsxs)(s.Fragment,{children:[e.prefix,`:`,(0,s.jsx)(o.Tooltip,{title:e.email,children:({onMouseEnter:t,onMouseLeave:n,ref:r})=>(0,s.jsx)(`span`,{"data-testid":e.memberId?`member-tooltip-${e.memberId}`:void 0,onMouseEnter:t,onMouseLeave:n,ref:r,style:_e,children:e.label})})]}):`${e.prefix}:${e.label}`}async function Ee({activityLogs:e,tasks:t}){let n=[...new Set([...e.map(e=>e.actorMemberId),...t.map(e=>e.assigneeMemberId),...t.map(e=>e.originalAssigneeMemberId),...t.flatMap(e=>e.candidateMemberIds),...t.flatMap(e=>Je(e.delegationChainJson).flatMap(e=>[e.from,e.to]))].filter(W))];try{return await(0,c.resolveMemberProfiles)(n)}catch{return[]}}async function De(e){return(await Promise.all(e.map(e=>(0,c.listTaskDecisions)(e.id)))).flat()}function Oe(e){return e.reduce((e,t)=>{let n=e.get(t.taskId),r=!n||new Date(t.decidedAt).getTime()>new Date(n.decidedAt).getTime()?t:n;return new Map(e).set(t.taskId,r)},new Map)}function ke(e,t,n,r,i,a,o,s,c){let l=e.filter(je).map(e=>{let t=Ie(e),n=ze(e.nodeId,r);return{descriptionParts:[E(n?`節點:${n}`:`節點:全流程`),O(`操作者`,e.actorMemberId,a,`系統`),E(`時間:${B(e.createdAt)}`),...I(e,t,r,o,s,c,a)].filter(A),error:We(e,t),id:e.id,title:Le(e.eventType,t)}}),u=t.filter(K).map(e=>({descriptionParts:[E(`節點:${L(e.nodeId,r)}`),O(`處理者`,e.assigneeMemberId,a,`未指定`),E(`建立時間:${B(e.createdAt)}`)].filter(A),error:!1,id:`pending-task-${e.id}`,title:e.status===`IN_PROGRESS`?`簽核處理中`:`等待簽核處理`})),d=new Set([...e.filter(je).map(e=>e.nodeId),...t.map(e=>e.nodeId)].filter(W)),f=r?Ne(r,t,n,i,d).map(e=>({descriptionParts:[E(`${J(e.type)} · 尚未抵達`)].filter(A),error:!1,forcePending:!0,id:`future-node-${e.id}`,title:Fe(e)})):[];return[...l,...u,...f]}function E(e){return W(e)?{text:e,type:`text`}:null}function D(e){return W(e)?{text:e,type:`dangerText`}:null}function O(e,t,n,r){let i=t?n.get(t):null;return{email:i?.email??null,label:i?.name??r,memberId:t,prefix:e,type:`member`}}function k(e,t){if(!e)return`-`;let n=t.get(e);return n?`${n.name}(${n.email})`:e}function A(e){return!!e}function Ae(e){let t=e.findIndex(e=>e.id.startsWith(`pending-task-`)||e.id.startsWith(`future-node-`));return t===-1?e.length:t}function je(e){return e.eventType===`INSTANCE_STARTED`||e.eventType===`TASK_DECIDED`||e.eventType===`SLA_TRIGGERED`}function Me(e,t,n,r,i){if(e.type===`startEvent`||i.has(e.id))return!1;if(r===`REJECTED`)return!0;let a=q(e,t,n,r);return a.tone===`neutral`||a.tone===`waiting`}function Ne(e,t,n,r,i){if(r!==`RUNNING`&&r!==`REJECTED`)return[];let a=e.nodes.filter(e=>Me(e,t,n,r,i)),o=j(e,a,t,n,i),s=new Map(e.nodes.map((e,t)=>[e.id,t]));return a.filter(e=>o.has(e.id)).sort((e,t)=>{let n=o.get(e.id)??0,r=o.get(t.id)??0;return n===r?e.position.x===t.position.x?e.position.y===t.position.y?(s.get(e.id)??0)-(s.get(t.id)??0):e.position.y-t.position.y:e.position.x-t.position.x:n-r})}function j(e,t,n,r,i){let a=new Set(t.map(e=>e.id)),o=e.edges.reduce((e,t)=>{let n=[...e.get(t.source)??[],t.target];return new Map(e).set(t.source,n)},new Map);return Pe(e,n,r,i).reduce((e,t)=>P(e,M(t,o,a)),new Map)}function Pe(e,t,n,r){let i=n.filter(e=>e.status===`ACTIVE`||e.status===`WAITING`).map(e=>e.currentNodeId),a=t.filter(K).map(e=>e.nodeId),o=e.nodes.filter(e=>r.has(e.id)).map(e=>e.id),s=[...new Set([...i,...a,...o])],c=e.nodes.filter(e=>e.type===`startEvent`).map(e=>e.id);return s.length>0?s:c}function M(e,t,n){return N([{distance:0,nodeId:e}],t,n)}function N(e,t,n,r=new Set,i=new Map){let[a,...o]=e;if(!a)return i;if(r.has(a.nodeId))return N(o,t,n,r,i);let s=new Set(r).add(a.nodeId),c=n.has(a.nodeId)?new Map(i).set(a.nodeId,Math.min(i.get(a.nodeId)??a.distance,a.distance)):i;return N([...o,...(t.get(a.nodeId)??[]).map(e=>({distance:a.distance+1,nodeId:e}))],t,n,s,c)}function P(e,t){return[...t.entries()].reduce((e,[t,n])=>new Map(e).set(t,Math.min(e.get(t)??n,n)),e)}function Fe(e){return e.type===`userTask`?`未來簽核:${e.data.label}`:e.type===`serviceTask`?`未來知會:${e.data.label}`:e.type===`exclusiveGateway`?`未來分流:${e.data.label}`:e.type===`parallelGateway`?`未來匯合:${e.data.label}`:e.type===`endEvent`?`流程完成:${e.data.label}`:`未來節點:${e.data.label}`}function Ie(e){try{let t=JSON.parse(e.payloadJson);return G(t)?t:{}}catch{return{}}}function Le(e,t){return e===`INSTANCE_STARTED`?`案件已發起`:e===`TOKEN_CREATED`?`流程路徑已建立`:e===`ENGINE_PROCESS_REQUESTED`?`流程引擎已處理`:e===`TOKEN_ADVANCED`?`流程已前進`:e===`TASK_CREATED`?`待簽任務已建立`:e===`TASK_DECIDED`?F(V(t,`action`)):e===`SLA_TRIGGERED`?`時限提醒已觸發`:e}function F(e){return e===`APPROVED`?`已同意`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`TRANSFERRED`?`已轉派`:`簽核已決議`}function Re(e,t,n,r){if(e.eventType===`TASK_CREATED`){let e=V(t,`assigneeMemberId`),n=V(t,`originalAssigneeMemberId`);if(!e){let e=H(t,`candidateMemberIds`);return e.length?`候選簽核人:${e.map(e=>k(e,r)).join(`、`)}`:null}let i=k(e,r),a=k(n,r);return n&&n!==e?`待簽人:${i}(原簽核人:${a})`:`待簽人:${i}`}if(e.eventType===`TASK_DECIDED`){let e=V(t,`action`),n=V(t,`comment`),i=e?`決議:${R(e)}`:null,a=V(t,`transferToMemberId`);return e===`REJECTED`&&n?[i,`拒絕原因:${n}`].filter(W).join(` · `):e===`TRANSFERRED`?[i,`轉派給:${k(a,r)}`].filter(W).join(` · `):i}if(e.eventType===`TOKEN_ADVANCED`){let e=V(t,`action`);if(e)return`流程結果:${R(e)}`;let r=U(t,`arrivedCount`),i=U(t,`requiredCount`);if(r!==null&&i!==null)return`等待匯合:${r}/${i}`;let a=V(t,`fromNodeId`),o=V(t,`toNodeId`);if(a&&o)return`由 ${L(a,n)} 前進至 ${L(o,n)}`}if(e.eventType===`ENGINE_PROCESS_REQUESTED`){let e=V(t,`state`);return e?`案件狀態:${Ue(e)}`:null}return null}function I(e,t,n,r,i,a,o){if(e.eventType!==`TASK_DECIDED`)return[E(Re(e,t,n,o))].filter(A);let s=e.taskId?r.get(e.taskId):null,c=V(t,`action`)??s?.action??null,l=V(t,`comment`)??s?.comment??null,u=V(t,`transferToMemberId`)??s?.transferToMemberId??null,d=V(t,`signatureId`)??s?.signatureId??null,f=d?i.get(d):null;return[E(c?`決議:${R(c)}`:null),c===`REJECTED`?D(`拒絕原因:${l??`-`}`):null,c===`RETURNED`?E(`退回說明:${l??`-`}`):null,c===`TRANSFERRED`?E(`轉派給:${k(u,o)}`):null,c===`TRANSFERRED`?E(`轉派說明:${l??`-`}`):null,f?E(a?.valid?`簽章:已驗證(${Ce(f.signedPayloadHash)})`:`簽章:待檢查(${Ce(f.signedPayloadHash)})`):null].filter(A)}function ze(e,t){return e?L(e,t):null}function L(e,t){return t?.nodes.find(t=>t.id===e)?.data.label??e}function Be(e,t){if(t.type!==`userTask`||!t.data.returnBehavior.allowReturn)return[];if(t.data.returnBehavior.allowedTargets===`ANY`)return e.nodes.filter(e=>e.id!==t.id).map(e=>({id:e.id,name:`${e.data.label}(${J(e.type)})`}));let n=t.data.returnBehavior.allowedTargets===`INITIATOR`?e.nodes.find(e=>e.type===`startEvent`)?.id:e.edges.find(e=>e.target===t.id)?.source,r=e.nodes.find(e=>e.id===n);return r?[{id:r.id,name:`${r.data.label}(${J(r.type)})`}]:[]}function R(e){return e===`APPROVED`?`同意`:e===`REJECTED`?`拒絕`:e===`RETURNED`?`退回`:e===`TRANSFERRED`?`轉派`:e}function Ve(e){return e===`PENDING`?`待處理`:e===`IN_PROGRESS`?`處理中`:e===`COMPLETED`?`已完成`:e===`CANCELLED`?`已取消`:e===`TRANSFERRED`?`已轉派`:e}function z(e,t=new Map){let n=Je(e.delegationChainJson);if(!e.assigneeMemberId)return e.candidateMemberIds.length?`候選 ${e.candidateMemberIds.map(e=>k(e,t)).join(`、`)}`:`未指定`;let r=k(e.assigneeMemberId,t),i=k(e.originalAssigneeMemberId,t);return n.length===0||e.originalAssigneeMemberId===e.assigneeMemberId?r:`${r}(原:${i})`}function He(e,t){return t?e.assigneeMemberId===t||e.candidateMemberIds.includes(t):!1}function Ue(e){return e===`APPROVED`?`已同意`:e===`CANCELLED`?`已取消`:e===`DRAFT`?`草稿`:e===`EXPIRED`?`已逾期`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`RUNNING`?`進行中`:e}function We(e,t){return e.eventType===`SLA_TRIGGERED`||V(t,`action`)===`REJECTED`||V(t,`instanceState`)===`REJECTED`}function B(e){return n.t(e)}function V(e,t){let n=e[t];return typeof n==`string`?n:null}function H(e,t){let n=e[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}function Ge(e){return{email:e.email,id:e.memberId,name:`${e.name} · ${e.email}`}}function Ke(e){if(!G(e))return null;let t=e.email,n=e.id,r=e.name;return typeof n==`string`&&typeof r==`string`?{email:typeof t==`string`?t:null,id:n,name:r}:null}function qe(e,t){let n=e.trim().toLocaleLowerCase();if(!n)return null;let r=t.filter(e=>[e.id,e.name,e.email??``].some(e=>e.toLocaleLowerCase().includes(n)));return r.length===1?r[0]??null:null}function Je(e){try{let t=JSON.parse(e);return Array.isArray(t)?t.map(e=>G(e)?Ye(e):null).filter(e=>e!==null):[]}catch{return[]}}function Ye(e){let t=V(e,`from`),n=V(e,`to`),r=V(e,`reason`);return!t||!n||!r?null:{from:t,reason:r,ruleId:V(e,`ruleId`),to:n}}function U(e,t){let n=e[t];return typeof n==`number`?n:null}function W(e){return typeof e==`string`&&e.trim().length>0}function G(e){return typeof e==`object`&&!!e}function K(e){return e.status===`PENDING`||e.status===`IN_PROGRESS`}function Xe({data:e}){return(0,s.jsxs)(`div`,{style:et(e.tone),children:[(0,s.jsx)(f.Handle,{isConnectable:!1,position:f.Position.Left,style:me,type:`target`}),(0,s.jsx)(o.Typography,{component:`span`,ellipsis:!0,title:e.label,variant:`label-primary`,children:e.label}),(0,s.jsx)(`span`,{style:Y(e.tone),children:e.statusLabel}),(0,s.jsx)(`span`,{title:e.secondaryLabel,style:C,children:e.secondaryLabel||e.kindLabel}),(0,s.jsx)(f.Handle,{isConnectable:!1,position:f.Position.Right,style:me,type:`source`})]})}function Ze(e,t,n,r){return e.nodes.map(e=>{let i=q(e,t,n,r);return{data:{kindLabel:J(e.type),label:e.data.label,secondaryLabel:i.secondaryLabel,statusLabel:i.statusLabel,tone:i.tone},id:e.id,position:e.position,sourcePosition:f.Position.Right,targetPosition:f.Position.Left,type:`workflowRuntime`}})}function Qe(e){let t=new p.graphlib.Graph;return t.setDefaultEdgeLabel(()=>({})),t.setGraph({nodesep:56,rankdir:`LR`,ranksep:120}),e.nodes.forEach(e=>{t.setNode(e.id,{height:se,width:x})}),e.edges.forEach(e=>{t.setEdge(e.source,e.target)}),p.layout(t),{...e,nodes:e.nodes.map(e=>{let n=t.node(e.id);return n?{...e,position:{x:n.x-x/2,y:n.y-se/2}}:e})}}function $e(e){return e.edges.map(e=>{let t=tt(e);return{animated:!1,id:e.id,label:t,labelBgBorderRadius:6,labelBgPadding:[8,4],labelBgStyle:{fill:e.data.isDefault?`#f8fafc`:`#eff6ff`,stroke:e.data.isDefault?`#64748b`:`#2563eb`,strokeWidth:1},labelShowBg:!!t,labelStyle:{fill:e.data.isDefault?`#475569`:`#2563eb`,fontSize:12,fontWeight:600},source:e.source,style:{stroke:`#475569`,strokeWidth:1.5},target:e.target,type:e.type??`smoothstep`}})}function q(e,t,n,r){let i=t.filter(t=>t.nodeId===e.id),a=i.find(e=>e.status===`PENDING`||e.status===`IN_PROGRESS`),o=i.find(e=>e.status===`CANCELLED`),s=i.find(e=>e.status===`COMPLETED`),c=n.filter(t=>t.currentNodeId===e.id),l=c.find(e=>e.status===`ACTIVE`),u=c.find(e=>e.status===`WAITING`);return a?{secondaryLabel:`處理者 ${z(a)}`,statusLabel:`待處理`,tone:`current`}:o?{secondaryLabel:`已取消 ${z(o)}`,statusLabel:`已取消`,tone:`cancelled`}:s?{secondaryLabel:`已完成 ${z(s)}`,statusLabel:`已完成`,tone:`completed`}:l?{secondaryLabel:`token ${l.id}`,statusLabel:`執行中`,tone:`current`}:u?{secondaryLabel:`token ${u.id}`,statusLabel:`等待前置`,tone:`waiting`}:e.type===`startEvent`?{secondaryLabel:`流程已發起`,statusLabel:`已發起`,tone:`completed`}:e.type===`endEvent`&&r!==`RUNNING`?{secondaryLabel:r,statusLabel:r===`REJECTED`?`已拒絕`:`已完成`,tone:r===`REJECTED`?`cancelled`:`completed`}:{secondaryLabel:J(e.type),statusLabel:`未抵達`,tone:`neutral`}}function J(e){return e===`startEvent`?`開始`:e===`endEvent`?`完成`:e===`userTask`?`簽核節點`:e===`serviceTask`?`知會節點`:e===`exclusiveGateway`?`條件分流`:`平行處理`}function et(e){return e===`current`?{...S,border:`1px solid var(--mzn-color-primary, #0057ff)`,boxShadow:`0 0 0 3px rgba(0, 87, 255, 0.14)`}:e===`completed`?{...S,border:`1px solid #16a34a`}:e===`cancelled`?{...S,border:`1px solid #dc2626`,opacity:.72}:e===`waiting`?{...S,border:`1px dashed #64748b`}:S}function Y(e){let t=pe;return e===`current`?{...t,background:`#eff6ff`,color:`#2563eb`}:e===`completed`?{...t,background:`#f0fdf4`,color:`#15803d`}:e===`cancelled`?{...t,background:`#fef2f2`,color:`#dc2626`}:e===`waiting`?{...t,background:`#f8fafc`,color:`#475569`}:{...t,background:`#f1f5f9`,color:`#64748b`}}function tt(e){return e.data.label?e.data.label:e.data.isDefault?`其他情況`:e.data.condition??``}function nt(e){return e.edges.map(tt).filter(e=>e.trim().length>0)}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return xe}});
|
|
2
|
-
//# sourceMappingURL=detail-Dcr5mM8g.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detail-Dcr5mM8g.cjs","names":[],"sources":["../../src/components/pdf-preview.module.scss","../../src/components/pdf-preview.tsx","../../src/views/instances/detail/InstanceDetailView.tsx"],"sourcesContent":[".root {\n display: grid;\n gap: 12px;\n width: min(86vw, 1080px);\n}\n\n.toolbar {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n justify-content: space-between;\n}\n\n.pageControls,\n.zoomControls {\n align-items: center;\n display: flex;\n gap: 8px;\n}\n\n.counter {\n min-width: 92px;\n text-align: center;\n white-space: nowrap;\n}\n\n.viewport {\n align-items: flex-start;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n display: flex;\n height: min(72vh, 760px);\n justify-content: center;\n min-height: 420px;\n overflow: auto;\n padding: 16px;\n}\n\n.page {\n background: #ffffff;\n box-shadow: 0 12px 32px rgb(15 23 42 / 14%);\n color: #111827;\n}\n\n.state {\n align-items: center;\n display: flex;\n justify-content: center;\n min-height: 320px;\n width: 100%;\n}\n\n@media (max-width: 720px) {\n .root {\n width: 92vw;\n }\n\n .toolbar {\n align-items: stretch;\n display: grid;\n }\n\n .pageControls,\n .zoomControls {\n justify-content: space-between;\n }\n\n .counter {\n min-width: 84px;\n }\n\n .viewport {\n height: 68vh;\n min-height: 360px;\n padding: 12px;\n }\n}\n","'use client';\n\nimport {\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Button, Typography } from '@mezzanine-ui/react';\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n DownloadIcon,\n ZoomInIcon,\n ZoomOutIcon,\n} from '@mezzanine-ui/icons';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport type { PDFDocumentProxy } from 'pdfjs-dist';\nimport styles from './pdf-preview.module.scss';\n\n// pdfjs ships its worker as a separate chunk. Consumers should call\n// `configurePdfWorker(url)` (or set `pdfjs.GlobalWorkerOptions.workerSrc`\n// directly) before the first `<PDFPreview>` mounts. The library does not\n// hard-bundle a worker path because consumer bundlers may need to resolve\n// it through CDN, public/ asset pipeline, or pinned version.\nexport function configurePdfWorker(workerSrc: string): void {\n pdfjs.GlobalWorkerOptions.workerSrc = workerSrc;\n}\n\nconst DEFAULT_VIEWPORT_WIDTH = 760;\nconst MAX_PAGE_WIDTH = 920;\nconst MIN_PAGE_WIDTH = 320;\nconst PAGE_HORIZONTAL_PADDING = 32;\nconst MIN_SCALE = 0.75;\nconst MAX_SCALE = 1.75;\nconst SCALE_STEP = 0.25;\n\nexport interface PDFPreviewProps {\n readonly filename: string;\n readonly fileUrl: string;\n readonly onDownload?: () => void;\n}\n\n/**\n * Mezzanine-styled PDF preview powered by `react-pdf`. Used by the instance\n * detail view to preview PDF attachments inline.\n */\nexport function PDFPreview({\n filename,\n fileUrl,\n onDownload,\n}: PDFPreviewProps): ReactElement {\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const [numPages, setNumPages] = useState<number | null>(null);\n const [pageNumber, setPageNumber] = useState(1);\n const [scale, setScale] = useState(1);\n const [viewportWidth, setViewportWidth] = useState(DEFAULT_VIEWPORT_WIDTH);\n\n useEffect((): (() => void) | undefined => {\n const viewport = viewportRef.current;\n\n if (!viewport || typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const observer = new ResizeObserver((entries): void => {\n const nextWidth = entries[0]?.contentRect.width;\n\n if (nextWidth) {\n setViewportWidth(nextWidth);\n }\n });\n\n observer.observe(viewport);\n\n return (): void => observer.disconnect();\n }, []);\n\n useEffect((): void => {\n setNumPages(null);\n setPageNumber(1);\n setScale(1);\n }, [fileUrl]);\n\n const pageWidth = useMemo((): number => {\n const availableWidth = Math.max(\n MIN_PAGE_WIDTH,\n viewportWidth - PAGE_HORIZONTAL_PADDING,\n );\n const baseWidth = Math.min(MAX_PAGE_WIDTH, availableWidth);\n\n return Math.round(baseWidth * scale);\n }, [scale, viewportWidth]);\n\n const loadDocument = useCallback((document: PDFDocumentProxy): void => {\n setNumPages(document.numPages);\n setPageNumber(1);\n }, []);\n\n const hasPreviousPage = pageNumber > 1;\n const hasNextPage = numPages !== null && pageNumber < numPages;\n const canZoomOut = scale > MIN_SCALE;\n const canZoomIn = scale < MAX_SCALE;\n const pageLabel =\n numPages === null\n ? `第 ${pageNumber} 頁`\n : `第 ${pageNumber} / ${numPages} 頁`;\n const zoomLabel = `${Math.round(scale * 100)}%`;\n\n return (\n <section aria-label={`${filename} PDF 預覽`} className={styles.root}>\n <div className={styles.toolbar}>\n <div className={styles.pageControls} aria-label=\"頁面切換\">\n <Button\n aria-label=\"上一頁\"\n disabled={!hasPreviousPage}\n icon={ChevronLeftIcon}\n onClick={(): void => {\n setPageNumber((currentPageNumber) =>\n Math.max(1, currentPageNumber - 1),\n );\n }}\n size=\"minor\"\n variant=\"base-secondary\"\n />\n <Typography\n className={styles.counter}\n component=\"span\"\n variant=\"body\"\n >\n {pageLabel}\n </Typography>\n <Button\n aria-label=\"下一頁\"\n disabled={!hasNextPage}\n icon={ChevronRightIcon}\n onClick={(): void => {\n setPageNumber((currentPageNumber) =>\n numPages === null\n ? currentPageNumber\n : Math.min(numPages, currentPageNumber + 1),\n );\n }}\n size=\"minor\"\n variant=\"base-secondary\"\n />\n </div>\n <div className={styles.zoomControls} aria-label=\"縮放\">\n <Button\n aria-label=\"縮小\"\n disabled={!canZoomOut}\n icon={ZoomOutIcon}\n onClick={(): void => {\n setScale((currentScale) =>\n Math.max(MIN_SCALE, currentScale - SCALE_STEP),\n );\n }}\n size=\"minor\"\n variant=\"base-secondary\"\n />\n <Typography\n className={styles.counter}\n component=\"span\"\n variant=\"body\"\n >\n {zoomLabel}\n </Typography>\n <Button\n aria-label=\"放大\"\n disabled={!canZoomIn}\n icon={ZoomInIcon}\n onClick={(): void => {\n setScale((currentScale) =>\n Math.min(MAX_SCALE, currentScale + SCALE_STEP),\n );\n }}\n size=\"minor\"\n variant=\"base-secondary\"\n />\n </div>\n {onDownload ? (\n <Button\n icon={DownloadIcon}\n iconType=\"leading\"\n onClick={onDownload}\n size=\"minor\"\n variant=\"base-primary\"\n >\n 下載\n </Button>\n ) : null}\n </div>\n <div className={styles.viewport} ref={viewportRef}>\n <Document\n error={<PDFPreviewState message=\"PDF 無法載入。\" />}\n file={fileUrl}\n loading={<PDFPreviewState message=\"正在載入 PDF...\" />}\n noData={<PDFPreviewState message=\"沒有可預覽的 PDF。\" />}\n onLoadSuccess={loadDocument}\n >\n <Page\n className={styles.page}\n loading={<PDFPreviewState message=\"正在載入頁面...\" />}\n pageNumber={pageNumber}\n renderAnnotationLayer\n renderTextLayer\n width={pageWidth}\n />\n </Document>\n </div>\n </section>\n );\n}\n\nfunction PDFPreviewState({\n message,\n}: {\n readonly message: string;\n}): ReactElement {\n return (\n <div className={styles.state}>\n <Typography color=\"text-neutral\" variant=\"body\">\n {message}\n </Typography>\n </div>\n );\n}\n","'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n Fragment,\n RefCallback,\n ReactElement,\n forwardRef,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Background,\n Controls,\n Handle,\n Position,\n ReactFlow,\n type Edge as FlowEdge,\n type Node as FlowNode,\n type NodeProps,\n} from '@xyflow/react';\nimport * as dagre from 'dagre';\nimport {\n AutoComplete,\n Button,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Stepper,\n Table,\n Textarea,\n Tooltip,\n Typography,\n type StepProps,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { stepClasses } from '@mezzanine-ui/core/stepper';\nimport {\n CheckedIcon,\n DangerousOutlineIcon,\n DownloadIcon,\n FileSearchIcon,\n RefreshCcwIcon,\n ShareIcon,\n UserIcon,\n} from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n WorkflowDefinition,\n WorkflowNode,\n} from '@rytass/bpm-core-shared/workflow';\nimport {\n focusFormRendererField,\n validateFormRendererValues,\n} from '@rytass/bpm-core-client/form';\nimport {\n ActivityLogRecord,\n AttachmentRecord,\n ApprovalInstanceRecord,\n MemberProfileRecord,\n SignatureRecord,\n SignatureVerificationRecord,\n cancelApprovalInstance,\n decideTask,\n listAttachments,\n listTaskDecisions,\n readApprovalInstance,\n readAttachmentDownloadUrl,\n readAttachmentPreviewUrl,\n readInstanceSignatures,\n resubmitApprovalInstance,\n resolveMemberProfiles,\n searchMembers,\n TaskDecisionRecord,\n TaskRecord,\n WorkflowFormData,\n WorkflowTokenRecord,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport { PDFPreview } from '../../../components/pdf-preview';\n\nconst SECTION_BODY_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\nconst BUTTON_ROW_STYLE: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 8,\n};\n\nconst FLOW_NODE_LAYOUT_WIDTH = 184;\nconst FLOW_NODE_LAYOUT_HEIGHT = 96;\n\nconst FLOW_MODAL_BODY_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\nconst REJECT_REASON_FORM_STYLE: CSSProperties = {\n display: 'grid',\n gap: 12,\n width: '100%',\n};\n\nconst REJECT_REASON_TEXTAREA_STYLE: CSSProperties = {\n minWidth: '100%',\n width: '100%',\n};\n\nconst MODAL_FORM_STYLE: CSSProperties = {\n display: 'grid',\n gap: 12,\n width: '100%',\n};\n\nconst FLOW_CANVAS_STYLE: CSSProperties = {\n background: '#f8fafc',\n border: '1px solid #e2e8f0',\n borderRadius: 8,\n height: 'min(64vh, 620px)',\n minHeight: 440,\n overflow: 'hidden',\n width: 'min(80vw, 1040px)',\n};\n\nconst NODE_STYLE: CSSProperties = {\n background: '#ffffff',\n border: '1px solid #cbd5e1',\n borderRadius: 8,\n boxShadow: '0 8px 18px rgba(15, 23, 42, 0.08)',\n display: 'grid',\n gap: 6,\n minHeight: 82,\n padding: 12,\n width: 184,\n};\n\nconst NODE_STATUS_STYLE: CSSProperties = {\n borderRadius: 999,\n fontSize: 12,\n fontWeight: 600,\n justifySelf: 'start',\n lineHeight: '18px',\n padding: '0 8px',\n};\n\nconst NODE_SECONDARY_STYLE: CSSProperties = {\n color: '#64748b',\n fontSize: 12,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n};\n\nconst NODE_HANDLE_STYLE: CSSProperties = {\n opacity: 0,\n};\n\nconst EDGE_SUMMARY_STYLE: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 8,\n};\n\nconst EDGE_SUMMARY_ITEM_STYLE: CSSProperties = {\n alignItems: 'center',\n background: '#ffffff',\n border: '1px solid #cbd5e1',\n borderRadius: 8,\n color: '#334155',\n display: 'inline-flex',\n fontSize: 12,\n fontWeight: 600,\n gap: 6,\n lineHeight: '20px',\n padding: '4px 8px',\n};\n\nconst HISTORY_MEMBER_NAME_STYLE: CSSProperties = {\n cursor: 'help',\n textDecoration: 'underline dotted',\n textUnderlineOffset: 3,\n};\n\nconst HISTORY_DANGER_TEXT_STYLE: CSSProperties = {\n color: 'var(--mzn-color-text-error)',\n};\n\nfunction applyFullWidthTextareaHost(element: HTMLDivElement | null): void {\n if (!element) {\n return;\n }\n\n element.style.width = '100%';\n}\n\nconst READONLY_FLOW_NODE_TYPES = {\n workflowRuntime: WorkflowRuntimeNodeCard,\n};\n\ntype RuntimeTone =\n | 'cancelled'\n | 'completed'\n | 'current'\n | 'neutral'\n | 'waiting';\n\ninterface RuntimeNodeData extends Record<string, unknown> {\n readonly kindLabel: string;\n readonly label: string;\n readonly secondaryLabel: string;\n readonly statusLabel: string;\n readonly tone: RuntimeTone;\n}\n\ntype RuntimeFlowNode = FlowNode<RuntimeNodeData, 'workflowRuntime'>;\ntype RuntimeFlowEdge = FlowEdge<\n Readonly<Record<string, unknown>>,\n 'smoothstep'\n>;\n\ntype TaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n assigneeLabel: string;\n key: string;\n nodeLabel: string;\n statusLabel: string;\n }\n>;\n\ntype AttachmentRow = Readonly<\n Record<string, unknown> & {\n attachment: AttachmentRecord;\n createdAt: string;\n filename: string;\n id: string;\n key: string;\n mimeType: string;\n sizeLabel: string;\n }\n>;\n\ntype SignatureRow = Readonly<\n Record<string, unknown> & {\n algorithm: string;\n hashLabel: string;\n key: string;\n keyVersion: number;\n signedAtLabel: string;\n signerMemberId: string;\n }\n>;\n\ntype MemberOption = Readonly<{\n email: string | null;\n id: string;\n name: string;\n}>;\n\ninterface ActivityStepRecord {\n readonly descriptionParts: readonly ActivityStepDescriptionPart[];\n readonly error: boolean;\n readonly forcePending?: boolean;\n readonly id: string;\n readonly title: string;\n}\n\ntype ActivityStepDescriptionPart =\n | Readonly<{ text: string; type: 'text' }>\n | Readonly<{ text: string; type: 'dangerText' }>\n | Readonly<{\n email: string | null;\n label: string;\n memberId: string | null;\n prefix: string;\n type: 'member';\n }>;\n\nexport interface InstanceDetailViewProps {\n /** Approval instance id (Next.js `params.id` resolved by the page shim). */\n readonly instanceId: string;\n}\n\n/**\n * Framework-agnostic view for the BPM approval instance detail page.\n * Mechanical port of `apps/client/src/app/instances/[id]/page.tsx`. The\n * `instanceId` is provided by the host page wrapper (typically resolved\n * from `params.id` in the Next.js Server Component shim).\n */\nexport function InstanceDetailView({\n instanceId,\n}: InstanceDetailViewProps): ReactElement {\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activityLogs, setActivityLogs] = useState<\n readonly ActivityLogRecord[]\n >([]);\n const [instance, setInstance] = useState<ApprovalInstanceRecord | null>(null);\n const [taskDecisions, setTaskDecisions] = useState<\n readonly TaskDecisionRecord[]\n >([]);\n const [attachments, setAttachments] = useState<readonly AttachmentRecord[]>(\n [],\n );\n const [signatures, setSignatures] = useState<readonly SignatureRecord[]>([]);\n const [signatureVerification, setSignatureVerification] =\n useState<SignatureVerificationRecord | null>(null);\n const [tasks, setTasks] = useState<readonly TaskRecord[]>([]);\n const [workflowTokens, setWorkflowTokens] = useState<\n readonly WorkflowTokenRecord[]\n >([]);\n const [memberProfiles, setMemberProfiles] = useState<\n readonly MemberProfileRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [deciding, setDeciding] = useState(false);\n const [workflowModalOpen, setWorkflowModalOpen] = useState(false);\n const [cancelComment, setCancelComment] = useState('');\n const [cancelModalOpen, setCancelModalOpen] = useState(false);\n const [rejectReason, setRejectReason] = useState('');\n const [rejectReasonError, setRejectReasonError] = useState<string | null>(\n null,\n );\n const [rejectReasonModalOpen, setRejectReasonModalOpen] = useState(false);\n const [returnComment, setReturnComment] = useState('');\n const [returnModalOpen, setReturnModalOpen] = useState(false);\n const [returnTargetNodeId, setReturnTargetNodeId] = useState<string | null>(\n null,\n );\n const [transferComment, setTransferComment] = useState('');\n const [transferMember, setTransferMember] = useState<MemberOption | null>(\n null,\n );\n const [transferMemberLoading, setTransferMemberLoading] = useState(false);\n const [transferMemberOptions, setTransferMemberOptions] = useState<\n readonly MemberOption[]\n >([]);\n const [transferModalOpen, setTransferModalOpen] = useState(false);\n const [resubmitFormErrors, setResubmitFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [resubmitFormData, setResubmitFormData] = useState<WorkflowFormData>(\n {},\n );\n const [previewAttachment, setPreviewAttachment] =\n useState<AttachmentRecord | null>(null);\n const [previewUrl, setPreviewUrl] = useState<string | null>(null);\n const trimmedRejectReason = rejectReason.trim();\n const trimmedCancelComment = cancelComment.trim();\n const trimmedReturnComment = returnComment.trim();\n const trimmedTransferComment = transferComment.trim();\n\n useEffect((): void => {\n void refreshInstance();\n }, [currentMemberId, instanceId]);\n\n useEffect((): void => {\n setResubmitFormData(instance?.formData ?? {});\n }, [instance]);\n\n const currentTask = useMemo(\n (): TaskRecord | null =>\n tasks.find(\n (task) =>\n canMemberActOnTask(task, currentMemberId) &&\n (task.status === 'PENDING' || task.status === 'IN_PROGRESS'),\n ) ?? null,\n [currentMemberId, tasks],\n );\n const currentTaskNode = useMemo(\n (): WorkflowNode | null =>\n currentTask && instance\n ? (instance.workflowSnapshot.nodes.find(\n (node) => node.id === currentTask.nodeId,\n ) ?? null)\n : null,\n [currentTask, instance],\n );\n const returnTargetOptions = useMemo(\n (): readonly { readonly id: string; readonly name: string }[] =>\n currentTaskNode && instance\n ? readReturnTargetOptions(instance.workflowSnapshot, currentTaskNode)\n : [],\n [currentTaskNode, instance],\n );\n const canReturnCurrentTask =\n currentTaskNode?.type === 'userTask' &&\n currentTaskNode.data.returnBehavior.allowReturn;\n const selectedReturnTargetOption =\n returnTargetOptions.find((option) => option.id === returnTargetNodeId) ??\n returnTargetOptions[0] ??\n null;\n const canCancelInstance = Boolean(\n instance &&\n instance.initiatorMemberId === currentMemberId &&\n (instance.state === 'RUNNING' || instance.state === 'RETURNED'),\n );\n const canResubmitInstance = Boolean(\n instance &&\n instance.initiatorMemberId === currentMemberId &&\n instance.state === 'RETURNED',\n );\n const memberProfilesById = useMemo(\n (): ReadonlyMap<string, MemberProfileRecord> =>\n new Map(memberProfiles.map((profile) => [profile.memberId, profile])),\n [memberProfiles],\n );\n const taskRows = useMemo(\n (): TaskRow[] =>\n tasks.map((task) => ({\n ...task,\n assigneeLabel: readTaskAssigneeLabel(task, memberProfilesById),\n key: task.id,\n nodeLabel: readNodeDisplayLabel(\n task.nodeId,\n instance?.workflowSnapshot ?? null,\n ),\n statusLabel: readTaskStatusLabel(task.status),\n })),\n [instance, memberProfilesById, tasks],\n );\n const taskDecisionsByTaskId = useMemo(\n (): ReadonlyMap<string, TaskDecisionRecord> =>\n readLatestTaskDecisionsByTaskId(taskDecisions),\n [taskDecisions],\n );\n const signaturesById = useMemo(\n (): ReadonlyMap<string, SignatureRecord> =>\n new Map(signatures.map((signature) => [signature.id, signature])),\n [signatures],\n );\n const activitySteps = useMemo(\n (): ActivityStepRecord[] =>\n readActivityStepRecords(\n activityLogs,\n tasks,\n workflowTokens,\n instance?.workflowSnapshot ?? null,\n instance?.state ?? 'RUNNING',\n memberProfilesById,\n taskDecisionsByTaskId,\n signaturesById,\n signatureVerification,\n ),\n [\n activityLogs,\n instance,\n memberProfilesById,\n signatureVerification,\n signaturesById,\n taskDecisionsByTaskId,\n tasks,\n workflowTokens,\n ],\n );\n const currentActivityStep = useMemo(\n (): number => readCurrentActivityStep(activitySteps),\n [activitySteps],\n );\n const layoutedWorkflowSnapshot = useMemo(\n (): WorkflowDefinition | null =>\n instance\n ? layoutRuntimeWorkflowDefinition(instance.workflowSnapshot)\n : null,\n [instance],\n );\n const flowNodes = useMemo(\n (): RuntimeFlowNode[] =>\n instance && layoutedWorkflowSnapshot\n ? readRuntimeFlowNodes(\n layoutedWorkflowSnapshot,\n tasks,\n workflowTokens,\n instance.state,\n )\n : [],\n [instance, layoutedWorkflowSnapshot, tasks, workflowTokens],\n );\n const flowEdges = useMemo(\n (): RuntimeFlowEdge[] =>\n layoutedWorkflowSnapshot\n ? readRuntimeFlowEdges(layoutedWorkflowSnapshot)\n : [],\n [layoutedWorkflowSnapshot],\n );\n const edgeSummaries = useMemo(\n (): readonly string[] =>\n instance ? readEdgeSummaries(instance.workflowSnapshot) : [],\n [instance],\n );\n const taskColumns = useMemo(\n (): TableColumn<TaskRow>[] => [\n { dataIndex: 'nodeLabel', key: 'nodeLabel', title: '節點', width: 180 },\n {\n key: 'assigneeMemberId',\n title: '處理者',\n render: (record: TaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.assigneeLabel}\n </Typography>\n ),\n width: 180,\n },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'createdAt',\n render: (record: TaskRow): 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 attachmentRows = useMemo(\n (): AttachmentRow[] =>\n attachments.map((attachment) => ({\n attachment,\n createdAt: attachment.createdAt,\n filename: attachment.filename,\n id: attachment.id,\n key: attachment.id,\n mimeType: attachment.mimeType,\n sizeLabel: formatFileSize(Number(attachment.sizeBytes)),\n })),\n [attachments],\n );\n const attachmentColumns = useMemo(\n (): TableColumn<AttachmentRow>[] => [\n { dataIndex: 'filename', key: 'filename', title: '檔名', width: 260 },\n { dataIndex: 'mimeType', key: 'mimeType', title: '類型', width: 180 },\n { dataIndex: 'sizeLabel', key: 'sizeLabel', title: '大小', width: 120 },\n {\n key: 'createdAt',\n render: (record: AttachmentRow): 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 attachmentActions = useMemo(\n (): TableActions<AttachmentRow> => ({\n render: (record): ReturnType<TableActions<AttachmentRow>['render']> => [\n ...(record.mimeType === 'application/pdf'\n ? [\n {\n icon: FileSearchIcon,\n iconType: 'leading' as const,\n name: '預覽',\n onClick: (): void => {\n void handlePreviewAttachment(record.attachment);\n },\n },\n ]\n : []),\n {\n icon: DownloadIcon,\n iconType: 'leading',\n name: '下載',\n onClick: (): void => {\n void handleDownloadAttachment(record.attachment);\n },\n },\n ],\n variant: 'base-secondary',\n width: 160,\n }),\n [],\n );\n const signatureRows = useMemo(\n (): SignatureRow[] =>\n signatures.map((signature) => ({\n algorithm: signature.algorithm,\n hashLabel: readShortHash(signature.signedPayloadHash),\n key: signature.id,\n keyVersion: signature.keyVersion,\n signedAtLabel: formatDateTime(signature.signedAt),\n signerMemberId: signature.signerMemberId,\n })),\n [signatures],\n );\n const signatureColumns = useMemo(\n (): TableColumn<SignatureRow>[] => [\n {\n dataIndex: 'signerMemberId',\n key: 'signerMemberId',\n title: '簽章者',\n width: 160,\n },\n { dataIndex: 'algorithm', key: 'algorithm', title: '演算法', width: 150 },\n {\n dataIndex: 'keyVersion',\n key: 'keyVersion',\n title: 'Key 版本',\n width: 100,\n },\n {\n dataIndex: 'hashLabel',\n key: 'hashLabel',\n title: 'Payload Hash',\n width: 180,\n },\n {\n dataIndex: 'signedAtLabel',\n key: 'signedAtLabel',\n title: '簽章時間',\n width: 220,\n },\n ],\n [],\n );\n\n async function refreshInstance(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n const nextRecord = await readApprovalInstance(instanceId);\n setActivityLogs(nextRecord.activityLogs);\n setInstance(nextRecord.instance);\n setTasks(nextRecord.tasks);\n setWorkflowTokens(nextRecord.workflowTokens);\n const [\n nextTaskDecisions,\n nextMemberProfiles,\n nextAttachments,\n nextSignatures,\n ] = await Promise.all([\n readTaskDecisionsForTasks(nextRecord.tasks),\n readMemberProfilesForTimeline(nextRecord),\n listAttachments(nextRecord.instance.id),\n readInstanceSignatures(nextRecord.instance.id),\n ]);\n setTaskDecisions(nextTaskDecisions);\n setMemberProfiles(nextMemberProfiles);\n setAttachments(nextAttachments);\n setSignatures(nextSignatures.signatures);\n setSignatureVerification(nextSignatures.verification);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n async function handleDownloadAttachment(\n attachment: AttachmentRecord,\n ): Promise<void> {\n if (!currentMemberId) {\n return;\n }\n\n const url = await readAttachmentDownloadUrl({\n id: attachment.id,\n });\n\n window.open(url, '_blank', 'noopener,noreferrer');\n }\n\n async function handlePreviewAttachment(\n attachment: AttachmentRecord,\n ): Promise<void> {\n if (!currentMemberId) {\n return;\n }\n\n const url = await readAttachmentPreviewUrl({\n id: attachment.id,\n });\n\n setPreviewAttachment(attachment);\n setPreviewUrl(url);\n }\n\n async function handleDecision({\n action,\n comment,\n returnToNodeId = null,\n transferToMemberId = null,\n }: Readonly<{\n action: 'APPROVED' | 'REJECTED' | 'RETURNED' | 'TRANSFERRED';\n comment: string | null;\n returnToNodeId?: string | null;\n transferToMemberId?: string | null;\n }>): Promise<void> {\n if (!currentMemberId || !currentTask) {\n return;\n }\n\n setDeciding(true);\n setError(null);\n\n try {\n await decideTask({\n action,\n comment,\n decidedByMemberId: currentMemberId,\n returnToNodeId,\n taskId: currentTask.id,\n transferToMemberId,\n });\n setRejectReasonModalOpen(false);\n setReturnModalOpen(false);\n setTransferModalOpen(false);\n setRejectReason('');\n setReturnComment('');\n setTransferComment('');\n setTransferMember(null);\n setReturnTargetNodeId(null);\n setRejectReasonError(null);\n await refreshInstance();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setDeciding(false);\n }\n }\n\n function openRejectReasonModal(): void {\n setRejectReason('');\n setRejectReasonError(null);\n setRejectReasonModalOpen(true);\n }\n\n function closeRejectReasonModal(): void {\n if (deciding) {\n return;\n }\n\n setRejectReasonModalOpen(false);\n setRejectReason('');\n setRejectReasonError(null);\n }\n\n function openReturnModal(): void {\n setReturnComment('');\n setReturnTargetNodeId(returnTargetOptions[0]?.id ?? null);\n setReturnModalOpen(true);\n }\n\n function closeReturnModal(): void {\n if (deciding) {\n return;\n }\n\n setReturnModalOpen(false);\n setReturnComment('');\n setReturnTargetNodeId(null);\n }\n\n function openTransferModal(): void {\n setTransferComment('');\n setTransferMember(null);\n setTransferModalOpen(true);\n void handleSearchTransferMembers('');\n }\n\n function closeTransferModal(): void {\n if (deciding) {\n return;\n }\n\n setTransferModalOpen(false);\n setTransferComment('');\n setTransferMember(null);\n }\n\n async function handleSearchTransferMembers(\n searchText: string,\n ): Promise<void> {\n setTransferMemberLoading(true);\n\n try {\n setTransferMemberOptions(\n (await searchMembers(searchText))\n .filter((searchedMember) => searchedMember.memberId !== currentMemberId)\n .map(readMemberOption),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setTransferMemberLoading(false);\n }\n }\n\n async function handleRejectConfirm(): Promise<void> {\n if (!trimmedRejectReason) {\n setRejectReasonError('請輸入拒絕原因');\n return;\n }\n\n await handleDecision({\n action: 'REJECTED',\n comment: trimmedRejectReason,\n });\n }\n\n async function handleTransferConfirm(): Promise<void> {\n if (!transferMember) {\n setError('請選擇轉派對象');\n return;\n }\n\n await handleDecision({\n action: 'TRANSFERRED',\n comment: trimmedTransferComment || null,\n transferToMemberId: transferMember.id,\n });\n }\n\n async function handleReturnConfirm(): Promise<void> {\n await handleDecision({\n action: 'RETURNED',\n comment: trimmedReturnComment || null,\n returnToNodeId: selectedReturnTargetOption?.id ?? null,\n });\n }\n\n async function handleCancelInstance(): Promise<void> {\n if (!currentMemberId || !instance || !canCancelInstance) {\n return;\n }\n\n setDeciding(true);\n setError(null);\n setResubmitFormErrors({});\n\n if (\n instance.formDefinitionSnapshot.schema &&\n instance.formDefinitionSnapshot.uiSchema\n ) {\n const validation = validateFormRendererValues({\n schema: instance.formDefinitionSnapshot.schema,\n uiSchema: instance.formDefinitionSnapshot.uiSchema,\n values: resubmitFormData,\n });\n\n if (!validation.valid) {\n setResubmitFormErrors(validation.errors);\n setError('請先補齊必填欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n setDeciding(false);\n\n return;\n }\n }\n\n try {\n await cancelApprovalInstance({\n cancelledByMemberId: currentMemberId,\n comment: trimmedCancelComment || null,\n instanceId: instance.id,\n });\n setCancelComment('');\n setCancelModalOpen(false);\n await refreshInstance();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setDeciding(false);\n }\n }\n\n async function handleResubmitInstance(): Promise<void> {\n if (!currentMemberId || !instance || !canResubmitInstance) {\n return;\n }\n\n setDeciding(true);\n setError(null);\n\n try {\n await resubmitApprovalInstance({\n formData: resubmitFormData,\n initiatorMemberId: currentMemberId,\n instanceId: instance.id,\n title: instance.title,\n });\n await refreshInstance();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setDeciding(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n instance\n ? `${readInstanceStateLabel(instance.state)} · ${formatDateTime(\n instance.startedAt,\n )}`\n : '載入案件內容。'\n }\n title={instance?.title ?? '簽核案件'}\n >\n {instance ? (\n <Button\n aria-label=\"查看流程圖\"\n icon={ShareIcon}\n iconType=\"icon-only\"\n onClick={(): void => setWorkflowModalOpen(true)}\n title=\"查看流程圖\"\n variant=\"base-secondary\"\n >\n 流程圖\n </Button>\n ) : null}\n {canCancelInstance ? (\n <Button\n disabled={deciding}\n icon={DangerousOutlineIcon}\n iconType=\"leading\"\n onClick={(): void => setCancelModalOpen(true)}\n variant=\"destructive-secondary\"\n >\n 取消案件\n </Button>\n ) : null}\n {currentTask ? (\n <>\n {canReturnCurrentTask ? (\n <Button\n disabled={deciding}\n icon={RefreshCcwIcon}\n iconType=\"leading\"\n onClick={openReturnModal}\n variant=\"base-secondary\"\n >\n 退回\n </Button>\n ) : null}\n <Button\n disabled={deciding}\n icon={UserIcon}\n iconType=\"leading\"\n onClick={openTransferModal}\n variant=\"base-secondary\"\n >\n 轉派\n </Button>\n <Button\n disabled={deciding}\n icon={DangerousOutlineIcon}\n iconType=\"leading\"\n onClick={openRejectReasonModal}\n variant=\"destructive-secondary\"\n >\n 拒絕\n </Button>\n <Button\n disabled={deciding}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={(): void =>\n void handleDecision({ action: 'APPROVED', comment: null })\n }\n variant=\"base-primary\"\n >\n 同意\n </Button>\n </>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={SECTION_BODY_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n {instance?.formDefinitionSnapshot.schema &&\n instance.formDefinitionSnapshot.uiSchema ? (\n <>\n <FormRenderer\n errors={resubmitFormErrors}\n onChange={(values): void => {\n setResubmitFormData(values);\n setResubmitFormErrors({});\n }}\n onUploadAttachment={\n canResubmitInstance ? handleUploadAttachment : undefined\n }\n readonly={!canResubmitInstance}\n schema={instance.formDefinitionSnapshot.schema}\n uiSchema={instance.formDefinitionSnapshot.uiSchema}\n value={\n canResubmitInstance ? resubmitFormData : instance.formData\n }\n />\n {canResubmitInstance ? (\n <div style={BUTTON_ROW_STYLE}>\n <Button\n disabled={deciding}\n icon={RefreshCcwIcon}\n iconType=\"leading\"\n onClick={(): void => void handleResubmitInstance()}\n variant=\"base-primary\"\n >\n 重新送出\n </Button>\n </div>\n ) : null}\n </>\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 此案件沒有可顯示的表單快照。\n </Typography>\n )}\n </div>\n </Section>\n\n <Section>\n <div style={SECTION_BODY_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 附件\n </Typography>\n {attachmentRows.length > 0 ? (\n <Table\n actions={attachmentActions}\n columns={attachmentColumns}\n dataSource={attachmentRows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 此案件沒有附件。\n </Typography>\n )}\n </div>\n </Section>\n\n <Section>\n <Typography component=\"h2\" variant=\"h3\">\n 任務\n </Typography>\n <Table columns={taskColumns} dataSource={taskRows} fullWidth />\n </Section>\n\n <Section>\n <div style={SECTION_BODY_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 簽章\n </Typography>\n <Typography\n color={\n signatureVerification?.valid ? 'text-success' : 'text-error'\n }\n variant=\"body\"\n >\n {signatureVerification\n ? signatureVerification.valid\n ? `簽章鏈已驗證,共 ${signatureVerification.checkedCount} 筆。`\n : `簽章鏈驗證失敗:${signatureVerification.errors.join('、')}`\n : '尚無簽章紀錄。'}\n </Typography>\n {signatureRows.length > 0 ? (\n <Table\n columns={signatureColumns}\n dataSource={signatureRows}\n fullWidth\n />\n ) : null}\n </div>\n </Section>\n\n <Section>\n <div style={SECTION_BODY_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 歷程\n </Typography>\n {activitySteps.length > 0 ? (\n <Stepper\n currentStep={currentActivityStep}\n orientation=\"vertical\"\n type=\"dot\"\n >\n {activitySteps.map((activityStep) => (\n <ActivityHistoryStep\n descriptionParts={activityStep.descriptionParts}\n error={activityStep.error}\n forcePending={activityStep.forcePending}\n key={activityStep.id}\n title={activityStep.title}\n />\n ))}\n </Stepper>\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 尚無歷程紀錄。\n </Typography>\n )}\n </div>\n </Section>\n </SectionGroup>\n\n {instance ? (\n <Modal\n modalType=\"standard\"\n onClose={(): void => setWorkflowModalOpen(false)}\n open={workflowModalOpen}\n showModalHeader\n size=\"wide\"\n supportingText={`${readInstanceStateLabel(\n instance.state,\n )} · ${formatDateTime(instance.startedAt)}`}\n title=\"流程圖\"\n >\n <div style={FLOW_MODAL_BODY_STYLE}>\n <div style={FLOW_CANVAS_STYLE}>\n <ReactFlow\n edges={flowEdges}\n fitView\n fitViewOptions={{ padding: 0.18 }}\n maxZoom={1.2}\n minZoom={0.2}\n nodes={flowNodes}\n nodesDraggable={false}\n nodesFocusable={false}\n nodeTypes={READONLY_FLOW_NODE_TYPES}\n panOnDrag\n proOptions={{ hideAttribution: true }}\n >\n <Background />\n <Controls showInteractive={false} />\n </ReactFlow>\n </div>\n {edgeSummaries.length > 0 ? (\n <div style={EDGE_SUMMARY_STYLE}>\n {edgeSummaries.map((summary) => (\n <span key={summary} style={EDGE_SUMMARY_ITEM_STYLE}>\n {summary}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n </Modal>\n ) : null}\n <Modal\n modalType=\"standard\"\n onClose={(): void => {\n setPreviewAttachment(null);\n setPreviewUrl(null);\n }}\n open={Boolean(previewAttachment && previewUrl)}\n showModalHeader\n size=\"wide\"\n supportingText={previewAttachment?.filename ?? undefined}\n title=\"PDF 預覽\"\n >\n {previewUrl ? (\n <PDFPreview\n filename={previewAttachment?.filename ?? 'PDF 預覽'}\n fileUrl={previewUrl}\n onDownload={\n previewAttachment\n ? (): void => void handleDownloadAttachment(previewAttachment)\n : undefined\n }\n />\n ) : null}\n </Modal>\n <Modal\n cancelText=\"保留案件\"\n confirmButtonProps={{ variant: 'destructive-primary' }}\n confirmText=\"確認取消\"\n loading={deciding}\n modalStatusType=\"error\"\n modalType=\"standard\"\n onCancel={(): void => setCancelModalOpen(false)}\n onClose={(): void => setCancelModalOpen(false)}\n onConfirm={(): void => void handleCancelInstance()}\n open={cancelModalOpen}\n showModalFooter\n showModalHeader\n supportingText=\"取消後會關閉目前待簽任務與候選簽核人。\"\n title=\"取消案件\"\n >\n <div style={SECTION_BODY_STYLE}>\n <Typography variant=\"body\">\n 確定要取消「{instance?.title ?? ''}」嗎?\n </Typography>\n <BPMFormField label=\"取消原因\" name=\"cancelComment\">\n <Textarea\n onChange={(event): void =>\n setCancelComment(event.target.value)\n }\n placeholder=\"可填寫取消原因\"\n resize=\"vertical\"\n rows={3}\n value={cancelComment}\n />\n </BPMFormField>\n </div>\n </Modal>\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !trimmedRejectReason,\n variant: 'destructive-primary',\n }}\n confirmText=\"送出拒絕\"\n loading={deciding}\n modalStatusType=\"error\"\n modalType=\"standard\"\n onCancel={closeRejectReasonModal}\n onClose={closeRejectReasonModal}\n onConfirm={(): void => void handleRejectConfirm()}\n open={rejectReasonModalOpen}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"拒絕案件時必須留下原因,供發起人與後續追蹤查看。\"\n title=\"拒絕原因\"\n >\n <div style={REJECT_REASON_FORM_STYLE}>\n <BPMFormField label=\"拒絕原因\" name=\"rejectReason\" required>\n <Textarea\n autoFocus\n onChange={(event: ChangeEvent<HTMLTextAreaElement>): void => {\n setRejectReason(event.target.value);\n setRejectReasonError(null);\n }}\n placeholder=\"請說明拒絕原因\"\n ref={applyFullWidthTextareaHost}\n resize=\"vertical\"\n rows={4}\n style={REJECT_REASON_TEXTAREA_STYLE}\n type={rejectReasonError ? 'error' : 'default'}\n value={rejectReason}\n />\n </BPMFormField>\n {rejectReasonError ? (\n <Typography color=\"text-error\" variant=\"body\">\n {rejectReasonError}\n </Typography>\n ) : null}\n </div>\n </Modal>\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !transferMember,\n }}\n confirmText=\"送出轉派\"\n loading={deciding}\n modalType=\"standard\"\n onCancel={closeTransferModal}\n onClose={closeTransferModal}\n onConfirm={(): void => void handleTransferConfirm()}\n open={transferModalOpen}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"轉派後,原任務會保留轉派紀錄,新的待簽任務會指派給指定成員。\"\n title=\"轉派簽核\"\n >\n <div style={MODAL_FORM_STYLE}>\n <BPMFormField label=\"轉派對象\" name=\"transferToMemberId\" required>\n <AutoComplete\n asyncData\n disabledOptionsFilter\n emptyText=\"沒有符合的成員\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'transfer-member-search',\n spellCheck: false,\n }}\n loading={transferMemberLoading}\n loadingText=\"搜尋成員中...\"\n mode=\"single\"\n onChange={(option): void =>\n setTransferMember(readMemberOptionFromValue(option))\n }\n onSearch={handleSearchTransferMembers}\n onSearchTextChange={(searchText): void =>\n setTransferMember(\n readUniqueMemberOption(searchText, transferMemberOptions),\n )\n }\n onVisibilityChange={(open): void => {\n if (open) {\n void handleSearchTransferMembers('');\n }\n }}\n options={[...transferMemberOptions]}\n placeholder=\"搜尋姓名或信箱\"\n searchDebounceTime={300}\n value={transferMember}\n />\n </BPMFormField>\n <BPMFormField label=\"轉派說明\" name=\"transferComment\">\n <Textarea\n onChange={(event: ChangeEvent<HTMLTextAreaElement>): void =>\n setTransferComment(event.target.value)\n }\n placeholder=\"可補充轉派原因\"\n ref={applyFullWidthTextareaHost}\n resize=\"vertical\"\n rows={4}\n style={REJECT_REASON_TEXTAREA_STYLE}\n value={transferComment}\n />\n </BPMFormField>\n </div>\n </Modal>\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !selectedReturnTargetOption,\n }}\n confirmText=\"送出退回\"\n loading={deciding}\n modalType=\"standard\"\n onCancel={closeReturnModal}\n onClose={closeReturnModal}\n onConfirm={(): void => void handleReturnConfirm()}\n open={returnModalOpen}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"退回後,流程會回到指定節點並等待重新處理。\"\n title=\"退回簽核\"\n >\n <div style={MODAL_FORM_STYLE}>\n <BPMFormField label=\"退回節點\" name=\"returnTargetNodeId\" required>\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n setReturnTargetNodeId(option?.id ?? null)\n }\n options={[...returnTargetOptions]}\n placeholder=\"選擇退回節點\"\n value={selectedReturnTargetOption}\n />\n </BPMFormField>\n <BPMFormField label=\"退回說明\" name=\"returnComment\">\n <Textarea\n onChange={(event: ChangeEvent<HTMLTextAreaElement>): void =>\n setReturnComment(event.target.value)\n }\n placeholder=\"可補充需要修改的內容\"\n ref={applyFullWidthTextareaHost}\n resize=\"vertical\"\n rows={4}\n style={REJECT_REASON_TEXTAREA_STYLE}\n value={returnComment}\n />\n </BPMFormField>\n </div>\n </Modal>\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nfunction formatFileSize(sizeBytes: number): string {\n if (!Number.isFinite(sizeBytes) || sizeBytes <= 0) {\n return '-';\n }\n\n if (sizeBytes < 1024) {\n return `${sizeBytes} B`;\n }\n\n if (sizeBytes < 1024 * 1024) {\n return `${(sizeBytes / 1024).toFixed(1)} KB`;\n }\n\n return `${(sizeBytes / 1024 / 1024).toFixed(1)} MB`;\n}\n\nfunction readShortHash(hash: string): string {\n return hash.length > 16 ? `${hash.slice(0, 12)}...` : hash;\n}\n\nfunction joinClassNames(\n ...classNames: readonly (string | null | undefined)[]\n): string {\n return classNames\n .filter((className): className is string =>\n isPresentText(className ?? null),\n )\n .join(' ');\n}\n\ninterface ActivityHistoryStepProps extends StepProps {\n readonly descriptionParts: readonly ActivityStepDescriptionPart[];\n readonly forcePending?: boolean;\n}\n\nconst ActivityHistoryStep = forwardRef<\n HTMLDivElement,\n ActivityHistoryStepProps\n>(function ActivityHistoryStep(\n {\n className,\n descriptionParts,\n error,\n forcePending = false,\n index = 0,\n orientation,\n status = 'pending',\n title,\n type = 'number',\n ...rest\n },\n ref,\n): ReactElement {\n const displayStatus = forcePending ? 'pending' : status;\n\n return (\n <div\n {...rest}\n className={joinClassNames(\n stepClasses.host,\n type === 'dot' ? stepClasses.dot : null,\n error && displayStatus !== 'processing' ? stepClasses.error : null,\n orientation === 'horizontal' ? stepClasses.horizontal : null,\n type === 'number' ? stepClasses.number : null,\n displayStatus === 'pending' ? stepClasses.pending : null,\n displayStatus === 'processing' ? stepClasses.processing : null,\n error && displayStatus === 'processing'\n ? stepClasses.processingError\n : null,\n !error && displayStatus === 'succeeded' ? stepClasses.succeeded : null,\n orientation === 'vertical' ? stepClasses.vertical : null,\n className,\n )}\n ref={ref}\n >\n {type === 'dot' ? (\n <span\n className={joinClassNames(\n stepClasses.statusIndicator,\n stepClasses.statusIndicatorDot,\n )}\n />\n ) : (\n <span className={stepClasses.statusIndicator}>{index + 1}</span>\n )}\n <div className={stepClasses.textContainer}>\n <Typography\n className={stepClasses.title}\n variant=\"label-primary-highlight\"\n >\n {title}\n <span className={stepClasses.titleConnectLine} />\n </Typography>\n {descriptionParts.length > 0 ? (\n <Typography className={stepClasses.description} variant=\"caption\">\n {descriptionParts.map((part, partIndex) => (\n <Fragment key={`${part.type}-${partIndex}`}>\n {partIndex > 0 ? ' · ' : null}\n {renderActivityDescriptionPart(part)}\n </Fragment>\n ))}\n </Typography>\n ) : null}\n </div>\n </div>\n );\n});\n\nfunction renderActivityDescriptionPart(\n part: ActivityStepDescriptionPart,\n): ReactElement | string {\n if (part.type === 'text') {\n return part.text;\n }\n\n if (part.type === 'dangerText') {\n return <span style={HISTORY_DANGER_TEXT_STYLE}>{part.text}</span>;\n }\n\n if (!part.email) {\n return `${part.prefix}:${part.label}`;\n }\n\n return (\n <>\n {part.prefix}:\n <Tooltip title={part.email}>\n {({ onMouseEnter, onMouseLeave, ref }): ReactElement => (\n <span\n data-testid={\n part.memberId ? `member-tooltip-${part.memberId}` : undefined\n }\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n ref={ref as RefCallback<HTMLSpanElement>}\n style={HISTORY_MEMBER_NAME_STYLE}\n >\n {part.label}\n </span>\n )}\n </Tooltip>\n </>\n );\n}\n\nasync function readMemberProfilesForTimeline({\n activityLogs,\n tasks,\n}: {\n readonly activityLogs: readonly ActivityLogRecord[];\n readonly tasks: readonly TaskRecord[];\n}): Promise<readonly MemberProfileRecord[]> {\n const memberIds = [\n ...new Set(\n [\n ...activityLogs.map((activityLog) => activityLog.actorMemberId),\n ...tasks.map((task) => task.assigneeMemberId),\n ...tasks.map((task) => task.originalAssigneeMemberId),\n ...tasks.flatMap((task) => task.candidateMemberIds),\n ...tasks.flatMap((task) =>\n readDelegationChain(task.delegationChainJson).flatMap((step) => [\n step.from,\n step.to,\n ]),\n ),\n ].filter(isPresentText),\n ),\n ];\n\n try {\n return await resolveMemberProfiles(memberIds);\n } catch {\n return [];\n }\n}\n\nasync function readTaskDecisionsForTasks(\n tasks: readonly TaskRecord[],\n): Promise<readonly TaskDecisionRecord[]> {\n const decisionLists = await Promise.all(\n tasks.map((task) => listTaskDecisions(task.id)),\n );\n\n return decisionLists.flat();\n}\n\nfunction readLatestTaskDecisionsByTaskId(\n taskDecisions: readonly TaskDecisionRecord[],\n): ReadonlyMap<string, TaskDecisionRecord> {\n return taskDecisions.reduce<ReadonlyMap<string, TaskDecisionRecord>>(\n (decisionsByTaskId, decision) => {\n const currentDecision = decisionsByTaskId.get(decision.taskId);\n const nextDecision =\n !currentDecision ||\n new Date(decision.decidedAt).getTime() >\n new Date(currentDecision.decidedAt).getTime()\n ? decision\n : currentDecision;\n\n return new Map(decisionsByTaskId).set(decision.taskId, nextDecision);\n },\n new Map(),\n );\n}\n\nfunction readActivityStepRecords(\n activityLogs: readonly ActivityLogRecord[],\n tasks: readonly TaskRecord[],\n tokens: readonly WorkflowTokenRecord[],\n workflow: WorkflowDefinition | null,\n instanceState: ApprovalInstanceRecord['state'],\n memberProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n taskDecisionsByTaskId: ReadonlyMap<string, TaskDecisionRecord>,\n signaturesById: ReadonlyMap<string, SignatureRecord>,\n signatureVerification: SignatureVerificationRecord | null,\n): ActivityStepRecord[] {\n const historySteps = activityLogs\n .filter(isUserMeaningfulActivity)\n .map((activityLog): ActivityStepRecord => {\n const payload = readActivityPayload(activityLog);\n const nodeLabel = readActivityNodeLabel(activityLog.nodeId, workflow);\n const descriptionParts = [\n readTextDescriptionPart(\n nodeLabel ? `節點:${nodeLabel}` : '節點:全流程',\n ),\n readMemberDescriptionPart(\n '操作者',\n activityLog.actorMemberId,\n memberProfilesById,\n '系統',\n ),\n readTextDescriptionPart(\n `時間:${formatActivityDateTime(activityLog.createdAt)}`,\n ),\n ...readActivityDetailParts(\n activityLog,\n payload,\n workflow,\n taskDecisionsByTaskId,\n signaturesById,\n signatureVerification,\n memberProfilesById,\n ),\n ].filter(isActivityDescriptionPart);\n\n return {\n descriptionParts,\n error: isActivityError(activityLog, payload),\n id: activityLog.id,\n title: readActivityEventLabel(activityLog.eventType, payload),\n };\n });\n const pendingTaskSteps = tasks.filter(isPendingTask).map(\n (task): ActivityStepRecord => ({\n descriptionParts: [\n readTextDescriptionPart(\n `節點:${readNodeDisplayLabel(task.nodeId, workflow)}`,\n ),\n readMemberDescriptionPart(\n '處理者',\n task.assigneeMemberId,\n memberProfilesById,\n '未指定',\n ),\n readTextDescriptionPart(\n `建立時間:${formatActivityDateTime(task.createdAt)}`,\n ),\n ].filter(isActivityDescriptionPart),\n error: false,\n id: `pending-task-${task.id}`,\n title: task.status === 'IN_PROGRESS' ? '簽核處理中' : '等待簽核處理',\n }),\n );\n const representedNodeIds = new Set(\n [\n ...activityLogs\n .filter(isUserMeaningfulActivity)\n .map((activityLog) => activityLog.nodeId),\n ...tasks.map((task) => task.nodeId),\n ].filter(isPresentText),\n );\n const futureNodeSteps = workflow\n ? readFutureTimelineNodes(\n workflow,\n tasks,\n tokens,\n instanceState,\n representedNodeIds,\n ).map(\n (node): ActivityStepRecord => ({\n descriptionParts: [\n readTextDescriptionPart(\n `${readNodeKindLabel(node.type)} · 尚未抵達`,\n ),\n ].filter(isActivityDescriptionPart),\n error: false,\n forcePending: true,\n id: `future-node-${node.id}`,\n title: readFutureNodeStepTitle(node),\n }),\n )\n : [];\n\n return [...historySteps, ...pendingTaskSteps, ...futureNodeSteps];\n}\n\nfunction readTextDescriptionPart(\n text: string | null,\n): ActivityStepDescriptionPart | null {\n return isPresentText(text) ? { text, type: 'text' } : null;\n}\n\nfunction readDangerTextDescriptionPart(\n text: string | null,\n): ActivityStepDescriptionPart | null {\n return isPresentText(text) ? { text, type: 'dangerText' } : null;\n}\n\nfunction readMemberDescriptionPart(\n prefix: string,\n memberId: string | null,\n memberProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n fallbackLabel: string,\n): ActivityStepDescriptionPart {\n const profile = memberId ? memberProfilesById.get(memberId) : null;\n\n return {\n email: profile?.email ?? null,\n label: profile?.name ?? fallbackLabel,\n memberId,\n prefix,\n type: 'member',\n };\n}\n\nfunction readMemberDisplayText(\n memberId: string | null,\n memberProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n): string {\n if (!memberId) {\n return '-';\n }\n\n const profile = memberProfilesById.get(memberId);\n\n return profile ? `${profile.name}(${profile.email})` : memberId;\n}\n\nfunction isActivityDescriptionPart(\n part: ActivityStepDescriptionPart | null,\n): part is ActivityStepDescriptionPart {\n return Boolean(part);\n}\n\nfunction readCurrentActivityStep(\n activitySteps: readonly ActivityStepRecord[],\n): number {\n const firstPendingStepIndex = activitySteps.findIndex(\n (activityStep) =>\n activityStep.id.startsWith('pending-task-') ||\n activityStep.id.startsWith('future-node-'),\n );\n\n return firstPendingStepIndex === -1\n ? activitySteps.length\n : firstPendingStepIndex;\n}\n\nfunction isUserMeaningfulActivity(activityLog: ActivityLogRecord): boolean {\n return (\n activityLog.eventType === 'INSTANCE_STARTED' ||\n activityLog.eventType === 'TASK_DECIDED' ||\n activityLog.eventType === 'SLA_TRIGGERED'\n );\n}\n\nfunction isFutureTimelineNode(\n node: WorkflowNode,\n tasks: readonly TaskRecord[],\n tokens: readonly WorkflowTokenRecord[],\n instanceState: ApprovalInstanceRecord['state'],\n representedNodeIds: ReadonlySet<string>,\n): boolean {\n if (node.type === 'startEvent' || representedNodeIds.has(node.id)) {\n return false;\n }\n\n if (instanceState === 'REJECTED') {\n return true;\n }\n\n const state = readNodeRuntimeState(node, tasks, tokens, instanceState);\n\n return state.tone === 'neutral' || state.tone === 'waiting';\n}\n\nfunction readFutureTimelineNodes(\n workflow: WorkflowDefinition,\n tasks: readonly TaskRecord[],\n tokens: readonly WorkflowTokenRecord[],\n instanceState: ApprovalInstanceRecord['state'],\n representedNodeIds: ReadonlySet<string>,\n): readonly WorkflowNode[] {\n if (instanceState !== 'RUNNING' && instanceState !== 'REJECTED') {\n return [];\n }\n\n const futureNodes = workflow.nodes.filter((node) =>\n isFutureTimelineNode(\n node,\n tasks,\n tokens,\n instanceState,\n representedNodeIds,\n ),\n );\n const reachableDistances = readReachableFutureNodeDistances(\n workflow,\n futureNodes,\n tasks,\n tokens,\n representedNodeIds,\n );\n const originalNodeIndexes = new Map(\n workflow.nodes.map((node, index) => [node.id, index]),\n );\n\n return futureNodes\n .filter((node) => reachableDistances.has(node.id))\n .sort((left, right) => {\n const leftDistance = reachableDistances.get(left.id) ?? 0;\n const rightDistance = reachableDistances.get(right.id) ?? 0;\n\n if (leftDistance !== rightDistance) {\n return leftDistance - rightDistance;\n }\n\n if (left.position.x !== right.position.x) {\n return left.position.x - right.position.x;\n }\n\n if (left.position.y !== right.position.y) {\n return left.position.y - right.position.y;\n }\n\n return (\n (originalNodeIndexes.get(left.id) ?? 0) -\n (originalNodeIndexes.get(right.id) ?? 0)\n );\n });\n}\n\nfunction readReachableFutureNodeDistances(\n workflow: WorkflowDefinition,\n futureNodes: readonly WorkflowNode[],\n tasks: readonly TaskRecord[],\n tokens: readonly WorkflowTokenRecord[],\n representedNodeIds: ReadonlySet<string>,\n): ReadonlyMap<string, number> {\n const futureNodeIds = new Set(futureNodes.map((node) => node.id));\n const outgoingNodeIds = workflow.edges.reduce<\n ReadonlyMap<string, readonly string[]>\n >((groups, edge) => {\n const nextTargets = [...(groups.get(edge.source) ?? []), edge.target];\n\n return new Map(groups).set(edge.source, nextTargets);\n }, new Map());\n const frontierNodeIds = readFutureTimelineFrontierNodeIds(\n workflow,\n tasks,\n tokens,\n representedNodeIds,\n );\n\n return frontierNodeIds.reduce<ReadonlyMap<string, number>>(\n (distances, nodeId) =>\n mergeFutureNodeDistances(\n distances,\n readFutureNodeDistancesFrom(nodeId, outgoingNodeIds, futureNodeIds),\n ),\n new Map(),\n );\n}\n\nfunction readFutureTimelineFrontierNodeIds(\n workflow: WorkflowDefinition,\n tasks: readonly TaskRecord[],\n tokens: readonly WorkflowTokenRecord[],\n representedNodeIds: ReadonlySet<string>,\n): readonly string[] {\n const tokenNodeIds = tokens\n .filter((token) => token.status === 'ACTIVE' || token.status === 'WAITING')\n .map((token) => token.currentNodeId);\n const pendingTaskNodeIds = tasks\n .filter(isPendingTask)\n .map((task) => task.nodeId);\n const representedFrontierNodeIds = workflow.nodes\n .filter((node) => representedNodeIds.has(node.id))\n .map((node) => node.id);\n const activeFrontierNodeIds = [\n ...new Set([\n ...tokenNodeIds,\n ...pendingTaskNodeIds,\n ...representedFrontierNodeIds,\n ]),\n ];\n const startNodeIds = workflow.nodes\n .filter((node) => node.type === 'startEvent')\n .map((node) => node.id);\n\n return activeFrontierNodeIds.length > 0\n ? activeFrontierNodeIds\n : startNodeIds;\n}\n\nfunction readFutureNodeDistancesFrom(\n startNodeId: string,\n outgoingNodeIds: ReadonlyMap<string, readonly string[]>,\n futureNodeIds: ReadonlySet<string>,\n): ReadonlyMap<string, number> {\n const initialQueue: readonly {\n readonly distance: number;\n readonly nodeId: string;\n }[] = [{ distance: 0, nodeId: startNodeId }];\n\n return walkFutureNodeDistances(initialQueue, outgoingNodeIds, futureNodeIds);\n}\n\nfunction walkFutureNodeDistances(\n queue: readonly { readonly distance: number; readonly nodeId: string }[],\n outgoingNodeIds: ReadonlyMap<string, readonly string[]>,\n futureNodeIds: ReadonlySet<string>,\n visitedNodeIds: ReadonlySet<string> = new Set(),\n distances: ReadonlyMap<string, number> = new Map(),\n): ReadonlyMap<string, number> {\n const [current, ...restQueue] = queue;\n\n if (!current) {\n return distances;\n }\n\n if (visitedNodeIds.has(current.nodeId)) {\n return walkFutureNodeDistances(\n restQueue,\n outgoingNodeIds,\n futureNodeIds,\n visitedNodeIds,\n distances,\n );\n }\n\n const nextVisitedNodeIds = new Set(visitedNodeIds).add(current.nodeId);\n const nextDistances = futureNodeIds.has(current.nodeId)\n ? new Map(distances).set(\n current.nodeId,\n Math.min(\n distances.get(current.nodeId) ?? current.distance,\n current.distance,\n ),\n )\n : distances;\n const nextQueue = [\n ...restQueue,\n ...(outgoingNodeIds.get(current.nodeId) ?? []).map((nodeId) => ({\n distance: current.distance + 1,\n nodeId,\n })),\n ];\n\n return walkFutureNodeDistances(\n nextQueue,\n outgoingNodeIds,\n futureNodeIds,\n nextVisitedNodeIds,\n nextDistances,\n );\n}\n\nfunction mergeFutureNodeDistances(\n currentDistances: ReadonlyMap<string, number>,\n nextDistances: ReadonlyMap<string, number>,\n): ReadonlyMap<string, number> {\n return [...nextDistances.entries()].reduce<ReadonlyMap<string, number>>(\n (mergedDistances, [nodeId, distance]) =>\n new Map(mergedDistances).set(\n nodeId,\n Math.min(mergedDistances.get(nodeId) ?? distance, distance),\n ),\n currentDistances,\n );\n}\n\nfunction readFutureNodeStepTitle(node: WorkflowNode): string {\n if (node.type === 'userTask') {\n return `未來簽核:${node.data.label}`;\n }\n\n if (node.type === 'serviceTask') {\n return `未來知會:${node.data.label}`;\n }\n\n if (node.type === 'exclusiveGateway') {\n return `未來分流:${node.data.label}`;\n }\n\n if (node.type === 'parallelGateway') {\n return `未來匯合:${node.data.label}`;\n }\n\n if (node.type === 'endEvent') {\n return `流程完成:${node.data.label}`;\n }\n\n return `未來節點:${node.data.label}`;\n}\n\nfunction readActivityPayload(\n activityLog: ActivityLogRecord,\n): Readonly<Record<string, unknown>> {\n try {\n const payload = JSON.parse(activityLog.payloadJson) as unknown;\n\n return isRecord(payload) ? payload : {};\n } catch {\n return {};\n }\n}\n\nfunction readActivityEventLabel(\n eventType: string,\n payload: Readonly<Record<string, unknown>>,\n): string {\n if (eventType === 'INSTANCE_STARTED') {\n return '案件已發起';\n }\n\n if (eventType === 'TOKEN_CREATED') {\n return '流程路徑已建立';\n }\n\n if (eventType === 'ENGINE_PROCESS_REQUESTED') {\n return '流程引擎已處理';\n }\n\n if (eventType === 'TOKEN_ADVANCED') {\n return '流程已前進';\n }\n\n if (eventType === 'TASK_CREATED') {\n return '待簽任務已建立';\n }\n\n if (eventType === 'TASK_DECIDED') {\n return readTaskDecisionEventLabel(readStringField(payload, 'action'));\n }\n\n if (eventType === 'SLA_TRIGGERED') {\n return '時限提醒已觸發';\n }\n\n return eventType;\n}\n\nfunction readTaskDecisionEventLabel(action: string | null): 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 readActivityDetail(\n activityLog: ActivityLogRecord,\n payload: Readonly<Record<string, unknown>>,\n workflow: WorkflowDefinition | null,\n memberProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n): string | null {\n if (activityLog.eventType === 'TASK_CREATED') {\n const assigneeMemberId = readStringField(payload, 'assigneeMemberId');\n const originalAssigneeMemberId = readStringField(\n payload,\n 'originalAssigneeMemberId',\n );\n\n if (!assigneeMemberId) {\n const candidateMemberIds = readStringArrayField(\n payload,\n 'candidateMemberIds',\n );\n\n return candidateMemberIds.length\n ? `候選簽核人:${candidateMemberIds\n .map((memberId) =>\n readMemberDisplayText(memberId, memberProfilesById),\n )\n .join('、')}`\n : null;\n }\n\n const assigneeLabel = readMemberDisplayText(\n assigneeMemberId,\n memberProfilesById,\n );\n const originalAssigneeLabel = readMemberDisplayText(\n originalAssigneeMemberId,\n memberProfilesById,\n );\n\n return originalAssigneeMemberId &&\n originalAssigneeMemberId !== assigneeMemberId\n ? `待簽人:${assigneeLabel}(原簽核人:${originalAssigneeLabel})`\n : `待簽人:${assigneeLabel}`;\n }\n\n if (activityLog.eventType === 'TASK_DECIDED') {\n const action = readStringField(payload, 'action');\n const comment = readStringField(payload, 'comment');\n const decisionLabel = action\n ? `決議:${readTaskDecisionActionLabel(action)}`\n : null;\n\n const transferToMemberId = readStringField(payload, 'transferToMemberId');\n\n return action === 'REJECTED' && comment\n ? [decisionLabel, `拒絕原因:${comment}`]\n .filter(isPresentText)\n .join(' · ')\n : action === 'TRANSFERRED'\n ? [\n decisionLabel,\n `轉派給:${readMemberDisplayText(\n transferToMemberId,\n memberProfilesById,\n )}`,\n ]\n .filter(isPresentText)\n .join(' · ')\n : decisionLabel;\n }\n\n if (activityLog.eventType === 'TOKEN_ADVANCED') {\n const action = readStringField(payload, 'action');\n\n if (action) {\n return `流程結果:${readTaskDecisionActionLabel(action)}`;\n }\n\n const arrivedCount = readNumberField(payload, 'arrivedCount');\n const requiredCount = readNumberField(payload, 'requiredCount');\n\n if (arrivedCount !== null && requiredCount !== null) {\n return `等待匯合:${arrivedCount}/${requiredCount}`;\n }\n\n const fromNodeId = readStringField(payload, 'fromNodeId');\n const toNodeId = readStringField(payload, 'toNodeId');\n\n if (fromNodeId && toNodeId) {\n return `由 ${readNodeDisplayLabel(fromNodeId, workflow)} 前進至 ${readNodeDisplayLabel(toNodeId, workflow)}`;\n }\n }\n\n if (activityLog.eventType === 'ENGINE_PROCESS_REQUESTED') {\n const state = readStringField(payload, 'state');\n\n return state ? `案件狀態:${readInstanceStateLabel(state)}` : null;\n }\n\n return null;\n}\n\nfunction readActivityDetailParts(\n activityLog: ActivityLogRecord,\n payload: Readonly<Record<string, unknown>>,\n workflow: WorkflowDefinition | null,\n taskDecisionsByTaskId: ReadonlyMap<string, TaskDecisionRecord>,\n signaturesById: ReadonlyMap<string, SignatureRecord>,\n signatureVerification: SignatureVerificationRecord | null,\n memberProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n): readonly ActivityStepDescriptionPart[] {\n if (activityLog.eventType !== 'TASK_DECIDED') {\n return [\n readTextDescriptionPart(\n readActivityDetail(\n activityLog,\n payload,\n workflow,\n memberProfilesById,\n ),\n ),\n ].filter(isActivityDescriptionPart);\n }\n\n const taskDecision = activityLog.taskId\n ? taskDecisionsByTaskId.get(activityLog.taskId)\n : null;\n const action =\n readStringField(payload, 'action') ?? taskDecision?.action ?? null;\n const comment =\n readStringField(payload, 'comment') ?? taskDecision?.comment ?? null;\n const transferToMemberId =\n readStringField(payload, 'transferToMemberId') ??\n taskDecision?.transferToMemberId ??\n null;\n const signatureId =\n readStringField(payload, 'signatureId') ??\n taskDecision?.signatureId ??\n null;\n const signature = signatureId ? signaturesById.get(signatureId) : null;\n const decisionLabel = action\n ? `決議:${readTaskDecisionActionLabel(action)}`\n : null;\n\n return [\n readTextDescriptionPart(decisionLabel),\n action === 'REJECTED'\n ? readDangerTextDescriptionPart(`拒絕原因:${comment ?? '-'}`)\n : null,\n action === 'RETURNED'\n ? readTextDescriptionPart(`退回說明:${comment ?? '-'}`)\n : null,\n action === 'TRANSFERRED'\n ? readTextDescriptionPart(\n `轉派給:${readMemberDisplayText(\n transferToMemberId,\n memberProfilesById,\n )}`,\n )\n : null,\n action === 'TRANSFERRED'\n ? readTextDescriptionPart(`轉派說明:${comment ?? '-'}`)\n : null,\n signature\n ? readTextDescriptionPart(\n signatureVerification?.valid\n ? `簽章:已驗證(${readShortHash(signature.signedPayloadHash)})`\n : `簽章:待檢查(${readShortHash(signature.signedPayloadHash)})`,\n )\n : null,\n ].filter(isActivityDescriptionPart);\n}\n\nfunction readActivityNodeLabel(\n nodeId: string | null,\n workflow: WorkflowDefinition | null,\n): string | null {\n return nodeId ? readNodeDisplayLabel(nodeId, workflow) : null;\n}\n\nfunction readNodeDisplayLabel(\n nodeId: string,\n workflow: WorkflowDefinition | null,\n): string {\n return (\n workflow?.nodes.find((node) => node.id === nodeId)?.data.label ?? nodeId\n );\n}\n\nfunction readReturnTargetOptions(\n workflow: WorkflowDefinition,\n node: WorkflowNode,\n): readonly { readonly id: string; readonly name: string }[] {\n if (node.type !== 'userTask' || !node.data.returnBehavior.allowReturn) {\n return [];\n }\n\n if (node.data.returnBehavior.allowedTargets === 'ANY') {\n return workflow.nodes\n .filter((candidate) => candidate.id !== node.id)\n .map((candidate) => ({\n id: candidate.id,\n name: `${candidate.data.label}(${readNodeKindLabel(candidate.type)})`,\n }));\n }\n\n const targetNodeId =\n node.data.returnBehavior.allowedTargets === 'INITIATOR'\n ? workflow.nodes.find((candidate) => candidate.type === 'startEvent')?.id\n : workflow.edges.find((edge) => edge.target === node.id)?.source;\n const targetNode = workflow.nodes.find(\n (candidate) => candidate.id === targetNodeId,\n );\n\n return targetNode\n ? [\n {\n id: targetNode.id,\n name: `${targetNode.data.label}(${readNodeKindLabel(\n targetNode.type,\n )})`,\n },\n ]\n : [];\n}\n\nfunction readTaskDecisionActionLabel(action: string): 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 action;\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 === 'CANCELLED') {\n return '已取消';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n return status;\n}\n\nfunction readTaskAssigneeLabel(\n task: TaskRecord,\n memberProfilesById: ReadonlyMap<string, MemberProfileRecord> = new Map(),\n): string {\n const delegationChain = readDelegationChain(task.delegationChainJson);\n\n if (!task.assigneeMemberId) {\n return task.candidateMemberIds.length\n ? `候選 ${task.candidateMemberIds\n .map((memberId) => readMemberDisplayText(memberId, memberProfilesById))\n .join('、')}`\n : '未指定';\n }\n\n const assigneeLabel = readMemberDisplayText(\n task.assigneeMemberId,\n memberProfilesById,\n );\n const originalAssigneeLabel = readMemberDisplayText(\n task.originalAssigneeMemberId,\n memberProfilesById,\n );\n\n if (\n delegationChain.length === 0 ||\n task.originalAssigneeMemberId === task.assigneeMemberId\n ) {\n return assigneeLabel;\n }\n\n return `${assigneeLabel}(原:${originalAssigneeLabel})`;\n}\n\nfunction canMemberActOnTask(\n task: TaskRecord,\n memberId: string | null,\n): boolean {\n if (!memberId) {\n return false;\n }\n\n return (\n task.assigneeMemberId === memberId ||\n task.candidateMemberIds.includes(memberId)\n );\n}\n\nfunction readInstanceStateLabel(state: string): string {\n if (state === 'APPROVED') {\n return '已同意';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n return state;\n}\n\nfunction isActivityError(\n activityLog: ActivityLogRecord,\n payload: Readonly<Record<string, unknown>>,\n): boolean {\n return (\n activityLog.eventType === 'SLA_TRIGGERED' ||\n readStringField(payload, 'action') === 'REJECTED' ||\n readStringField(payload, 'instanceState') === 'REJECTED'\n );\n}\n\nfunction formatActivityDateTime(value: string): string {\n return formatDateTime(value);\n}\n\nfunction readStringField(\n record: Readonly<Record<string, unknown>>,\n key: string,\n): string | null {\n const value = record[key];\n\n return typeof value === 'string' ? value : null;\n}\n\nfunction readStringArrayField(\n record: Readonly<Record<string, unknown>>,\n key: string,\n): readonly string[] {\n const value = record[key];\n\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : [];\n}\n\nfunction readMemberOption(profile: MemberProfileRecord): MemberOption {\n return {\n email: profile.email,\n id: profile.memberId,\n name: `${profile.name} · ${profile.email}`,\n };\n}\n\nfunction readMemberOptionFromValue(value: unknown): MemberOption | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const email = value.email;\n const id = value.id;\n const name = value.name;\n\n return typeof id === 'string' && typeof name === 'string'\n ? { email: typeof email === 'string' ? email : null, id, name }\n : null;\n}\n\nfunction readUniqueMemberOption(\n searchText: string,\n options: readonly MemberOption[],\n): MemberOption | null {\n const normalizedSearchText = searchText.trim().toLocaleLowerCase();\n\n if (!normalizedSearchText) {\n return null;\n }\n\n const matches = options.filter((option) =>\n [option.id, option.name, option.email ?? ''].some((value) =>\n value.toLocaleLowerCase().includes(normalizedSearchText),\n ),\n );\n\n return matches.length === 1 ? (matches[0] ?? null) : null;\n}\n\ninterface DelegationChainStep {\n readonly from: string;\n readonly reason: string;\n readonly ruleId: string | null;\n readonly to: string;\n}\n\nfunction readDelegationChain(value: string): readonly DelegationChainStep[] {\n try {\n const parsed = JSON.parse(value) as unknown;\n\n return Array.isArray(parsed)\n ? parsed\n .map((item): DelegationChainStep | null =>\n isRecord(item) ? readDelegationChainStep(item) : null,\n )\n .filter((item): item is DelegationChainStep => item !== null)\n : [];\n } catch {\n return [];\n }\n}\n\nfunction readDelegationChainStep(\n item: Readonly<Record<string, unknown>>,\n): DelegationChainStep | null {\n const from = readStringField(item, 'from');\n const to = readStringField(item, 'to');\n const reason = readStringField(item, 'reason');\n\n if (!from || !to || !reason) {\n return null;\n }\n\n return {\n from,\n reason,\n ruleId: readStringField(item, 'ruleId'),\n to,\n };\n}\n\nfunction readNumberField(\n record: Readonly<Record<string, unknown>>,\n key: string,\n): number | null {\n const value = record[key];\n\n return typeof value === 'number' ? value : null;\n}\n\nfunction isPresentText(value: string | null): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isPendingTask(task: TaskRecord): boolean {\n return task.status === 'PENDING' || task.status === 'IN_PROGRESS';\n}\n\nfunction WorkflowRuntimeNodeCard({\n data,\n}: NodeProps<RuntimeFlowNode>): ReactElement {\n return (\n <div style={readNodeStyle(data.tone)}>\n <Handle\n isConnectable={false}\n position={Position.Left}\n style={NODE_HANDLE_STYLE}\n type=\"target\"\n />\n <Typography\n component=\"span\"\n ellipsis\n title={data.label}\n variant=\"label-primary\"\n >\n {data.label}\n </Typography>\n <span style={readNodeStatusStyle(data.tone)}>{data.statusLabel}</span>\n <span title={data.secondaryLabel} style={NODE_SECONDARY_STYLE}>\n {data.secondaryLabel || data.kindLabel}\n </span>\n <Handle\n isConnectable={false}\n position={Position.Right}\n style={NODE_HANDLE_STYLE}\n type=\"source\"\n />\n </div>\n );\n}\n\nfunction readRuntimeFlowNodes(\n workflow: WorkflowDefinition,\n tasks: readonly TaskRecord[],\n tokens: readonly WorkflowTokenRecord[],\n instanceState: string,\n): RuntimeFlowNode[] {\n return workflow.nodes.map((node): RuntimeFlowNode => {\n const state = readNodeRuntimeState(node, tasks, tokens, instanceState);\n\n return {\n data: {\n kindLabel: readNodeKindLabel(node.type),\n label: node.data.label,\n secondaryLabel: state.secondaryLabel,\n statusLabel: state.statusLabel,\n tone: state.tone,\n },\n id: node.id,\n position: node.position,\n sourcePosition: Position.Right,\n targetPosition: Position.Left,\n type: 'workflowRuntime',\n };\n });\n}\n\nfunction layoutRuntimeWorkflowDefinition(\n workflow: WorkflowDefinition,\n): WorkflowDefinition {\n const graph = new dagre.graphlib.Graph();\n graph.setDefaultEdgeLabel(() => ({}));\n graph.setGraph({\n nodesep: 56,\n rankdir: 'LR',\n ranksep: 120,\n });\n workflow.nodes.forEach((node): void => {\n graph.setNode(node.id, {\n height: FLOW_NODE_LAYOUT_HEIGHT,\n width: FLOW_NODE_LAYOUT_WIDTH,\n });\n });\n workflow.edges.forEach((edge): void => {\n graph.setEdge(edge.source, edge.target);\n });\n dagre.layout(graph);\n\n return {\n ...workflow,\n nodes: workflow.nodes.map((node): WorkflowNode => {\n const positionedNode = graph.node(node.id) as\n | { readonly x: number; readonly y: number }\n | undefined;\n\n return positionedNode\n ? {\n ...node,\n position: {\n x: positionedNode.x - FLOW_NODE_LAYOUT_WIDTH / 2,\n y: positionedNode.y - FLOW_NODE_LAYOUT_HEIGHT / 2,\n },\n }\n : node;\n }),\n };\n}\n\nfunction readRuntimeFlowEdges(workflow: WorkflowDefinition): RuntimeFlowEdge[] {\n return workflow.edges.map((edge): RuntimeFlowEdge => {\n const label = readEdgeLabel(edge);\n\n return {\n animated: false,\n id: edge.id,\n label,\n labelBgBorderRadius: 6,\n labelBgPadding: [8, 4],\n labelBgStyle: {\n fill: edge.data.isDefault ? '#f8fafc' : '#eff6ff',\n stroke: edge.data.isDefault ? '#64748b' : '#2563eb',\n strokeWidth: 1,\n },\n labelShowBg: Boolean(label),\n labelStyle: {\n fill: edge.data.isDefault ? '#475569' : '#2563eb',\n fontSize: 12,\n fontWeight: 600,\n },\n source: edge.source,\n style: {\n stroke: '#475569',\n strokeWidth: 1.5,\n },\n target: edge.target,\n type: edge.type ?? 'smoothstep',\n };\n });\n}\n\nfunction readNodeRuntimeState(\n node: WorkflowNode,\n tasks: readonly TaskRecord[],\n tokens: readonly WorkflowTokenRecord[],\n instanceState: string,\n): Readonly<{\n secondaryLabel: string;\n statusLabel: string;\n tone: RuntimeTone;\n}> {\n const nodeTasks = tasks.filter((task) => task.nodeId === node.id);\n const pendingTask = nodeTasks.find(\n (task) => task.status === 'PENDING' || task.status === 'IN_PROGRESS',\n );\n const cancelledTask = nodeTasks.find((task) => task.status === 'CANCELLED');\n const completedTask = nodeTasks.find((task) => task.status === 'COMPLETED');\n const nodeTokens = tokens.filter((token) => token.currentNodeId === node.id);\n const activeToken = nodeTokens.find((token) => token.status === 'ACTIVE');\n const waitingToken = nodeTokens.find((token) => token.status === 'WAITING');\n\n if (pendingTask) {\n return {\n secondaryLabel: `處理者 ${readTaskAssigneeLabel(pendingTask)}`,\n statusLabel: '待處理',\n tone: 'current',\n };\n }\n\n if (cancelledTask) {\n return {\n secondaryLabel: `已取消 ${readTaskAssigneeLabel(cancelledTask)}`,\n statusLabel: '已取消',\n tone: 'cancelled',\n };\n }\n\n if (completedTask) {\n return {\n secondaryLabel: `已完成 ${readTaskAssigneeLabel(completedTask)}`,\n statusLabel: '已完成',\n tone: 'completed',\n };\n }\n\n if (activeToken) {\n return {\n secondaryLabel: `token ${activeToken.id}`,\n statusLabel: '執行中',\n tone: 'current',\n };\n }\n\n if (waitingToken) {\n return {\n secondaryLabel: `token ${waitingToken.id}`,\n statusLabel: '等待前置',\n tone: 'waiting',\n };\n }\n\n if (node.type === 'startEvent') {\n return {\n secondaryLabel: '流程已發起',\n statusLabel: '已發起',\n tone: 'completed',\n };\n }\n\n if (node.type === 'endEvent' && instanceState !== 'RUNNING') {\n return {\n secondaryLabel: instanceState,\n statusLabel: instanceState === 'REJECTED' ? '已拒絕' : '已完成',\n tone: instanceState === 'REJECTED' ? 'cancelled' : 'completed',\n };\n }\n\n return {\n secondaryLabel: readNodeKindLabel(node.type),\n statusLabel: '未抵達',\n tone: 'neutral',\n };\n}\n\nfunction readNodeKindLabel(type: WorkflowNode['type']): string {\n if (type === 'startEvent') {\n return '開始';\n }\n\n if (type === 'endEvent') {\n return '完成';\n }\n\n if (type === 'userTask') {\n return '簽核節點';\n }\n\n if (type === 'serviceTask') {\n return '知會節點';\n }\n\n if (type === 'exclusiveGateway') {\n return '條件分流';\n }\n\n return '平行處理';\n}\n\nfunction readNodeStyle(tone: RuntimeTone): CSSProperties {\n if (tone === 'current') {\n return {\n ...NODE_STYLE,\n border: '1px solid var(--mzn-color-primary, #0057ff)',\n boxShadow: '0 0 0 3px rgba(0, 87, 255, 0.14)',\n };\n }\n\n if (tone === 'completed') {\n return {\n ...NODE_STYLE,\n border: '1px solid #16a34a',\n };\n }\n\n if (tone === 'cancelled') {\n return {\n ...NODE_STYLE,\n border: '1px solid #dc2626',\n opacity: 0.72,\n };\n }\n\n if (tone === 'waiting') {\n return {\n ...NODE_STYLE,\n border: '1px dashed #64748b',\n };\n }\n\n return NODE_STYLE;\n}\n\nfunction readNodeStatusStyle(tone: RuntimeTone): CSSProperties {\n const baseStyle = NODE_STATUS_STYLE;\n\n if (tone === 'current') {\n return { ...baseStyle, background: '#eff6ff', color: '#2563eb' };\n }\n\n if (tone === 'completed') {\n return { ...baseStyle, background: '#f0fdf4', color: '#15803d' };\n }\n\n if (tone === 'cancelled') {\n return { ...baseStyle, background: '#fef2f2', color: '#dc2626' };\n }\n\n if (tone === 'waiting') {\n return { ...baseStyle, background: '#f8fafc', color: '#475569' };\n }\n\n return { ...baseStyle, background: '#f1f5f9', color: '#64748b' };\n}\n\nfunction readEdgeLabel(edge: WorkflowDefinition['edges'][number]): string {\n if (edge.data.label) {\n return edge.data.label;\n }\n\n if (edge.data.isDefault) {\n return '其他情況';\n }\n\n return edge.data.condition ?? '';\n}\n\nfunction readEdgeSummaries(workflow: WorkflowDefinition): readonly string[] {\n return workflow.edges\n .map(readEdgeLabel)\n .filter((label) => label.trim().length > 0);\n}\n"],"mappings":"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"}
|