@rytass/bpm-core-react 0.7.2 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/chunks/{compose-Dmp3vP-j.js → compose-B1quUa7y.js} +2 -2
  3. package/dist/chunks/{compose-Dmp3vP-j.js.map → compose-B1quUa7y.js.map} +1 -1
  4. package/dist/chunks/{compose-DYmvSyVR.cjs → compose-B6nevcwq.cjs} +2 -2
  5. package/dist/chunks/{compose-DYmvSyVR.cjs.map → compose-B6nevcwq.cjs.map} +1 -1
  6. package/dist/chunks/{designer-yYAdrQDt.js → designer-BLfz5Dk9.js} +2 -1
  7. package/dist/chunks/designer-BLfz5Dk9.js.map +1 -0
  8. package/dist/chunks/{designer-CEw0v0sY.cjs → designer-DP002lt7.cjs} +2 -2
  9. package/dist/chunks/designer-DP002lt7.cjs.map +1 -0
  10. package/dist/chunks/detail-KEmfpCtt.cjs +2 -0
  11. package/dist/chunks/{detail-Cci9tnoC.cjs.map → detail-KEmfpCtt.cjs.map} +1 -1
  12. package/dist/chunks/{detail-kyolfdBu.js → detail-fg8MTwuH.js} +3 -2
  13. package/dist/chunks/{detail-kyolfdBu.js.map → detail-fg8MTwuH.js.map} +1 -1
  14. package/dist/chunks/{orgs-DQ_wob4O.js → orgs-CrNxqlwp.js} +554 -513
  15. package/dist/chunks/orgs-CrNxqlwp.js.map +1 -0
  16. package/dist/chunks/orgs-iNJ0QEcK.cjs +2 -0
  17. package/dist/chunks/orgs-iNJ0QEcK.cjs.map +1 -0
  18. package/dist/orgs.css +1 -1
  19. package/dist/pages/admin/orgs/index.cjs +1 -1
  20. package/dist/pages/admin/orgs/index.js +1 -1
  21. package/dist/pages/instances/detail/index.cjs +1 -1
  22. package/dist/pages/instances/detail/index.js +1 -1
  23. package/dist/pages/templates/compose/index.cjs +1 -1
  24. package/dist/pages/templates/compose/index.js +1 -1
  25. package/dist/pages/templates/designer/index.cjs +1 -1
  26. package/dist/pages/templates/designer/index.js +1 -1
  27. package/dist/style.css +1 -0
  28. package/dist/views/admin/index.cjs +1 -1
  29. package/dist/views/admin/index.js +1 -1
  30. package/dist/views/admin/orgs/index.cjs +1 -1
  31. package/dist/views/admin/orgs/index.js +1 -1
  32. package/dist/views/instances/detail/index.cjs +1 -1
  33. package/dist/views/instances/detail/index.js +1 -1
  34. package/dist/views/templates/compose/index.cjs +1 -1
  35. package/dist/views/templates/compose/index.js +1 -1
  36. package/dist/views/templates/designer/index.cjs +1 -1
  37. package/dist/views/templates/designer/index.js +1 -1
  38. package/package.json +2 -2
  39. package/dist/chunks/designer-CEw0v0sY.cjs.map +0 -1
  40. package/dist/chunks/designer-yYAdrQDt.js.map +0 -1
  41. package/dist/chunks/detail-Cci9tnoC.cjs +0 -2
  42. package/dist/chunks/orgs-C1JFfk_Y.cjs +0 -2
  43. package/dist/chunks/orgs-C1JFfk_Y.cjs.map +0 -1
  44. package/dist/chunks/orgs-DQ_wob4O.js.map +0 -1
@@ -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("react-pdf"),h=require("@mezzanine-ui/core/stepper");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`},ee=760,_=920,te=320,v=32,y=.75,b=1.75,ne=.25;function re({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),[h,re]=(0,a.useState)(ee);(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&&re(t)});return t.observe(e),()=>t.disconnect()},[]),(0,a.useEffect)(()=>{c(null),d(1),p(1)},[t]);let S=(0,a.useMemo)(()=>{let e=Math.max(te,h-v);return Math.round(Math.min(_,e)*f)},[f,h]),ie=(0,a.useCallback)(e=>{c(e.numPages),d(1)},[]),C=l>1,ae=i!==null&&l<i,w=f>y,T=f<b,E=i===null?`第 ${l} 頁`:`第 ${l} / ${i} 頁`,oe=`${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:!C,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:E}),(0,s.jsx)(o.Button,{"aria-label":`下一頁`,disabled:!ae,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:!w,icon:u.ZoomOutIcon,onClick:()=>{p(e=>Math.max(y,e-ne))},size:`minor`,variant:`base-secondary`}),(0,s.jsx)(o.Typography,{className:g.counter,component:`span`,variant:`body`,children:oe}),(0,s.jsx)(o.Button,{"aria-label":`放大`,disabled:!T,icon:u.ZoomInIcon,onClick:()=>{p(e=>Math.min(b,e+ne))},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)(m.Document,{error:(0,s.jsx)(x,{message:`PDF 無法載入。`}),file:t,loading:(0,s.jsx)(x,{message:`正在載入 PDF...`}),noData:(0,s.jsx)(x,{message:`沒有可預覽的 PDF。`}),onLoadSuccess:ie,children:(0,s.jsx)(m.Page,{className:g.page,loading:(0,s.jsx)(x,{message:`正在載入頁面...`}),pageNumber:l,renderAnnotationLayer:!0,renderTextLayer:!0,width:S})})})]})}function x({message:e}){return(0,s.jsx)(`div`,{className:g.state,children:(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:e})})}function S(e){let t=C(e,`from`),n=C(e,`to`),r=C(e,`reason`);return!t||!n||!r?null:{from:t,reason:r,ruleId:C(e,`ruleId`),to:n}}function ie(e){try{let t=JSON.parse(e);return Array.isArray(t)?t.map(e=>E(e)?S(e):null).filter(e=>e!==null):[]}catch{return[]}}function C(e,t){let n=e[t];return typeof n==`string`?n:null}function ae(e,t){let n=e[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}function w(e,t){let n=e[t];return typeof n==`number`?n:null}function T(e){return typeof e==`string`&&e.trim().length>0}function E(e){return typeof e==`object`&&!!e}function oe(e){return e.status===`PENDING`||e.status===`IN_PROGRESS`}function D(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 O(e){return e.length>16?`${e.slice(0,12)}...`:e}function ce(e){return e===`APPROVED`?`已同意`:e===`CANCELLED`?`已取消`:e===`DRAFT`?`草稿`:e===`EXPIRED`?`已逾期`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`RUNNING`?`進行中`:e}function le(e){return e===`PENDING`?`待處理`:e===`IN_PROGRESS`?`處理中`:e===`COMPLETED`?`已完成`:e===`CANCELLED`?`已取消`:e===`TRANSFERRED`?`已轉派`:e}function ue(e){return e===`APPROVED`?`同意`:e===`REJECTED`?`拒絕`:e===`RETURNED`?`退回`:e===`TRANSFERRED`?`轉派`:e}function k(e){return e===`startEvent`?`開始`:e===`endEvent`?`完成`:e===`userTask`?`簽核節點`:e===`serviceTask`?`知會節點`:e===`exclusiveGateway`?`條件分流`:`平行處理`}function A(e,t){return t?.nodes.find(t=>t.id===e)?.data.label??e}function j(e,t){if(!e)return`-`;let n=t.get(e);return n?`${n.name}(${n.email})`:e}function M(e,t=new Map){let n=ie(e.delegationChainJson);if(!e.assigneeMemberId)return e.candidateMemberIds.length?`候選 ${e.candidateMemberIds.map(e=>j(e,t)).join(`、`)}`:`未指定`;let r=j(e.assigneeMemberId,t),i=j(e.originalAssigneeMemberId,t);return n.length===0||e.originalAssigneeMemberId===e.assigneeMemberId?r:`${r}(原:${i})`}function de(e,t){return t?e.assigneeMemberId===t||e.candidateMemberIds.includes(t):!1}function fe(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}(${k(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}(${k(r.type)})`}]:[]}function N(e){return{email:e.email,id:e.memberId,name:`${e.name} · ${e.email}`}}function pe(e){if(!E(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 me(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 P(e){return T(e)?{text:e,type:`text`}:null}function he(e){return T(e)?{text:e,type:`dangerText`}:null}function F(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 I(e){return!!e}function ge(e){let t=e.findIndex(e=>e.id.startsWith(`pending-task-`)||e.id.startsWith(`future-node-`));return t===-1?e.length:t}function L(e){return e.eventType===`INSTANCE_STARTED`||e.eventType===`TASK_DECIDED`||e.eventType===`SLA_TRIGGERED`}function R(e){return e===`APPROVED`?`已同意`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`TRANSFERRED`?`已轉派`:`簽核已決議`}function _e(e,t){return e===`INSTANCE_STARTED`?`案件已發起`:e===`TOKEN_CREATED`?`流程路徑已建立`:e===`ENGINE_PROCESS_REQUESTED`?`流程引擎已處理`:e===`TOKEN_ADVANCED`?`流程已前進`:e===`TASK_CREATED`?`待簽任務已建立`:e===`TASK_DECIDED`?R(C(t,`action`)):e===`SLA_TRIGGERED`?`時限提醒已觸發`:e}function z(e){try{let t=JSON.parse(e.payloadJson);return E(t)?t:{}}catch{return{}}}function B(e,t){return e.eventType===`SLA_TRIGGERED`||C(t,`action`)===`REJECTED`||C(t,`instanceState`)===`REJECTED`}function V(e){return n.t(e)}function ve(e,t,n,r){if(e.eventType===`TASK_CREATED`){let e=C(t,`assigneeMemberId`),n=C(t,`originalAssigneeMemberId`);if(!e){let e=ae(t,`candidateMemberIds`);return e.length?`候選簽核人:${e.map(e=>j(e,r)).join(`、`)}`:null}let i=j(e,r),a=j(n,r);return n&&n!==e?`待簽人:${i}(原簽核人:${a})`:`待簽人:${i}`}if(e.eventType===`TASK_DECIDED`){let e=C(t,`action`),n=C(t,`comment`),i=e?`決議:${ue(e)}`:null,a=C(t,`transferToMemberId`);return e===`REJECTED`&&n?[i,`拒絕原因:${n}`].filter(T).join(` · `):e===`TRANSFERRED`?[i,`轉派給:${j(a,r)}`].filter(T).join(` · `):i}if(e.eventType===`TOKEN_ADVANCED`){let e=C(t,`action`);if(e)return`流程結果:${ue(e)}`;let r=w(t,`arrivedCount`),i=w(t,`requiredCount`);if(r!==null&&i!==null)return`等待匯合:${r}/${i}`;let a=C(t,`fromNodeId`),o=C(t,`toNodeId`);if(a&&o)return`由 ${A(a,n)} 前進至 ${A(o,n)}`}if(e.eventType===`ENGINE_PROCESS_REQUESTED`){let e=C(t,`state`);return e?`案件狀態:${ce(e)}`:null}return null}function ye(e,t,n,r,i,a,o){if(e.eventType!==`TASK_DECIDED`)return[P(ve(e,t,n,o))].filter(I);let s=e.taskId?r.get(e.taskId):null,c=C(t,`action`)??s?.action??null,l=C(t,`comment`)??s?.comment??null,u=C(t,`transferToMemberId`)??s?.transferToMemberId??null,d=C(t,`signatureId`)??s?.signatureId??null,f=d?i.get(d):null;return[P(c?`決議:${ue(c)}`:null),c===`REJECTED`?he(`拒絕原因:${l??`-`}`):null,c===`RETURNED`?P(`退回說明:${l??`-`}`):null,c===`TRANSFERRED`?P(`轉派給:${j(u,o)}`):null,c===`TRANSFERRED`?P(`轉派說明:${l??`-`}`):null,f?P(a?.valid?`簽章:已驗證(${O(f.signedPayloadHash)})`:`簽章:待檢查(${O(f.signedPayloadHash)})`):null].filter(I)}function be(e,t,n,r,i){if(e.type===`startEvent`||i.has(e.id))return!1;if(r===`REJECTED`)return!0;let a=we(e,t,n,r);return a.tone===`neutral`||a.tone===`waiting`}function H(e,t,n,r,i){if(r!==`RUNNING`&&r!==`REJECTED`)return[];let a=e.nodes.filter(e=>be(e,t,n,r,i)),o=U(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 U(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 W(e,n,r,i).reduce((e,t)=>xe(e,G(t,o,a)),new Map)}function W(e,t,n,r){let i=n.filter(e=>e.status===`ACTIVE`||e.status===`WAITING`).map(e=>e.currentNodeId),a=t.filter(oe).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 G(e,t,n){return K([{distance:0,nodeId:e}],t,n)}function K(e,t,n,r=new Set,i=new Map){let[a,...o]=e;if(!a)return i;if(r.has(a.nodeId))return K(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 K([...o,...(t.get(a.nodeId)??[]).map(e=>({distance:a.distance+1,nodeId:e}))],t,n,s,c)}function xe(e,t){return[...t.entries()].reduce((e,[t,n])=>new Map(e).set(t,Math.min(e.get(t)??n,n)),e)}function Se(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 Ce(e,t,n,r,i,a,o,s,c){let l=e.filter(L).map(e=>{let t=z(e),n=e.nodeId?A(e.nodeId,r):null;return{descriptionParts:[P(n?`節點:${n}`:`節點:全流程`),F(`操作者`,e.actorMemberId,a,`系統`),P(`時間:${V(e.createdAt)}`),...ye(e,t,r,o,s,c,a)].filter(I),error:B(e,t),id:e.id,title:_e(e.eventType,t)}}),u=t.filter(oe).map(e=>({descriptionParts:[P(`節點:${A(e.nodeId,r)}`),F(`處理者`,e.assigneeMemberId,a,`未指定`),P(`建立時間:${V(e.createdAt)}`)].filter(I),error:!1,id:`pending-task-${e.id}`,title:e.status===`IN_PROGRESS`?`簽核處理中`:`等待簽核處理`})),d=new Set([...e.filter(L).map(e=>e.nodeId),...t.map(e=>e.nodeId)].filter(T)),f=r?H(r,t,n,i,d).map(e=>({descriptionParts:[P(`${k(e.type)} · 尚未抵達`)].filter(I),error:!1,forcePending:!0,id:`future-node-${e.id}`,title:Se(e)})):[];return[...l,...u,...f]}function we(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:`處理者 ${M(a)}`,statusLabel:`待處理`,tone:`current`}:o?{secondaryLabel:`已取消 ${M(o)}`,statusLabel:`已取消`,tone:`cancelled`}:s?{secondaryLabel:`已完成 ${M(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:k(e.type),statusLabel:`未抵達`,tone:`neutral`}}async function q({activityLogs:e,adhocDirectives:t=[],tasks:n}){let r=[...new Set([...e.map(e=>e.actorMemberId),...n.map(e=>e.assigneeMemberId),...n.map(e=>e.originalAssigneeMemberId),...n.flatMap(e=>e.candidateMemberIds),...n.flatMap(e=>ie(e.delegationChainJson).flatMap(e=>[e.from,e.to])),...t.flatMap(e=>[e.createdByMemberId,...J(e.targetValueJson)])].filter(T))];try{return await(0,c.resolveMemberProfiles)(r)}catch{return[]}}function J(e){try{return(JSON.parse(e).memberIds??[]).filter(e=>typeof e==`string`)}catch{return[]}}async function Te(e){return(await Promise.all(e.map(e=>(0,c.listTaskDecisions)(e.id)))).flat()}function Ee(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)}var De={display:`grid`,gap:16},Y={display:`flex`,flexWrap:`wrap`,gap:8};function Oe({canResubmitInstance:e,deciding:t,error:n,instance:r,loading:a,onResubmitFormChange:c,onResubmitInstance:l,onUploadAttachment:d,resubmitFormData:f,resubmitFormErrors:p}){return(0,s.jsxs)(`div`,{style:De,children:[n?(0,s.jsx)(o.Typography,{color:`text-error`,variant:`body`,children:n}):null,a?(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:`載入中...`}):null,r?.formDefinitionSnapshot.schema&&r.formDefinitionSnapshot.uiSchema?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.t,{errors:p,onChange:e=>{c(e)},onUploadAttachment:e?d:void 0,readonly:!e,schema:r.formDefinitionSnapshot.schema,uiSchema:r.formDefinitionSnapshot.uiSchema,value:e?f:r.formData}),e?(0,s.jsx)(`div`,{style:Y,children:(0,s.jsx)(o.Button,{disabled:t,icon:u.RefreshCcwIcon,iconType:`leading`,onClick:l,variant:`base-primary`,children:`重新送出`})}):null]}):(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:`此案件沒有可顯示的表單快照。`})]})}var ke={display:`grid`,gap:16};function Ae({attachments:e,onDownload:t,onPreview:r}){let i=(0,a.useMemo)(()=>e.map(e=>({attachment:e,createdAt:e.createdAt,filename:e.filename,id:e.id,key:e.id,mimeType:e.mimeType,sizeLabel:se(Number(e.sizeBytes))})),[e]),c=(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}],[]),l=(0,a.useMemo)(()=>({render:e=>[...e.mimeType===`application/pdf`?[{icon:u.FileSearchIcon,iconType:`leading`,name:`預覽`,onClick:()=>{r(e.attachment)}}]:[],{icon:u.DownloadIcon,iconType:`leading`,name:`下載`,onClick:()=>{t(e.attachment)}}],variant:`base-secondary`,width:160}),[t,r]);return(0,s.jsxs)(`div`,{style:ke,children:[(0,s.jsx)(o.Typography,{component:`h2`,variant:`h3`,children:`附件`}),i.length>0?(0,s.jsx)(o.Table,{actions:l,columns:c,dataSource:i,fullWidth:!0}):(0,s.jsx)(o.Typography,{color:`text-neutral`,variant:`body`,children:`此案件沒有附件。`})]})}var je={display:`grid`,gap:12,width:`100%`},Me={minWidth:`100%`,width:`100%`},X={display:`grid`,gap:12,width:`100%`},Ne={marginTop:12},Pe={marginTop:24};function Fe(e){e&&(e.style.width=`100%`)}var Ie={COMPLETION_NOTIFY:`結案通知`,COUNTERSIGN:`臨時會簽`,PRE_APPROVAL:`臨時加簽`,STAGE_NOTIFY:`階段完成通知`},Le={COMPLETION_NOTIFY:`本張單到達結案狀態(核准 / 拒絕 / 取消)後,通知指定對象。`,COUNTERSIGN:`指定對象會併入下一層簽核,下一層需所有人都完成才會繼續。`,PRE_APPROVAL:`指定對象需先完成加簽,本階段才會往下一層繼續。`,STAGE_NOTIFY:`本階段完成後(不論通過與否)通知指定對象。`},Re=[{id:`REJECT_INSTANCE`,name:`加簽拒絕時整單駁回`},{id:`RETURN_TO_ORIGIN`,name:`加簽拒絕時退回給我重新處理`}],Z=[{id:`MEMBER`,name:`指定成員`},{id:`WEBHOOK`,name:`Webhook`}],ze=(0,a.forwardRef)(function({adhocDirectives:e,currentMemberId:t,instance:i,memberProfilesById:l,onChanged:u,tasks:d},f){let[p,m]=(0,a.useState)(!1),[h,g]=(0,a.useState)(null),[ee,_]=(0,a.useState)(``),[te,v]=(0,a.useState)(null),[y,b]=(0,a.useState)(!1),[ne,re]=(0,a.useState)(``),[x,S]=(0,a.useState)(!1),[ie,C]=(0,a.useState)(null),[ae,w]=(0,a.useState)(``),[T,E]=(0,a.useState)(null),[oe,se]=(0,a.useState)(!1),[O,ce]=(0,a.useState)([]),[ue,k]=(0,a.useState)(!1),[P,he]=(0,a.useState)(``),[F,I]=(0,a.useState)(null),[ge,L]=(0,a.useState)(!1),[R,_e]=(0,a.useState)([]),[z,B]=(0,a.useState)(!1),[V,ve]=(0,a.useState)(`COUNTERSIGN`),[ye,be]=(0,a.useState)(`REJECT_INSTANCE`),[H,U]=(0,a.useState)(!1),[W,G]=(0,a.useState)(`MEMBER`),[K,xe]=(0,a.useState)(``),Se=ee.trim(),Ce=ne.trim(),we=ae.trim(),q=(0,a.useMemo)(()=>d.find(e=>de(e,t)&&(e.status===`PENDING`||e.status===`IN_PROGRESS`))??null,[t,d]),J=(0,a.useMemo)(()=>q&&i?i.workflowSnapshot.nodes.find(e=>e.id===q.nodeId)??null:null,[q,i]),Te=(0,a.useMemo)(()=>J&&i?fe(i.workflowSnapshot,J):[],[J,i]),Ee=J?.type===`userTask`&&J.data.returnBehavior.allowReturn,De=J?.type===`userTask`&&J.data.allowAddSigner,Y=(0,a.useMemo)(()=>e.filter(e=>e.status===`PENDING`),[e]),Oe=Te.find(e=>e.id===ie)??Te[0]??null,ke=(0,a.useMemo)(()=>d.map(e=>({...e,assigneeLabel:M(e,l),key:e.id,nodeLabel:`${A(e.nodeId,i?.workflowSnapshot??null)}${e.isAdhoc?e.adhocType===`COUNTERSIGN`?`(臨時會簽)`:`(臨時加簽)`:``}`,statusLabel:le(e.status)})),[i,l,d]),Ae=(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}],[]),ze=(0,a.useMemo)(()=>Y.map(e=>({...e,createdByLabel:j(e.createdByMemberId,l),key:e.id,targetLabel:Be(e,l),typeLabel:Ie[e.type]})),[l,Y]),Ve=(0,a.useMemo)(()=>[{dataIndex:`typeLabel`,key:`typeLabel`,title:`類型`,width:180},{key:`targetLabel`,render:e=>(0,s.jsx)(o.Typography,{component:`span`,variant:`body`,children:e.targetLabel}),title:`對象`,width:220},{key:`createdByLabel`,render:e=>(0,s.jsx)(o.Typography,{component:`span`,variant:`body`,children:e.createdByLabel}),title:`設定者`,width:180},{key:`createdAt`,render:e=>(0,s.jsx)(o.Typography,{component:`span`,variant:`body`,children:n.t(e.createdAt)}),title:`建立時間`,width:220},{key:`actions`,render:e=>e.createdByMemberId===t?(0,s.jsx)(o.Button,{disabled:H,onClick:()=>void rt(e.id),size:`minor`,variant:`destructive-secondary`,children:`撤回`}):(0,s.jsx)(s.Fragment,{}),title:`操作`,width:100}],[H,t]);async function He({action:e,comment:n,returnToNodeId:r=null,transferToMemberId:i=null}){if(!(!t||!q)){m(!0),g(null);try{await(0,c.decideTask)({action:e,comment:n,decidedByMemberId:t,returnToNodeId:r,taskId:q.id,transferToMemberId:i}),b(!1),S(!1),k(!1),_(``),re(``),w(``),E(null),C(null),v(null),await u()}catch(e){g(D(e))}finally{m(!1)}}}function Ue(){_(``),v(null),b(!0)}function We(){p||(b(!1),_(``),v(null))}function Ge(){re(``),C(Te[0]?.id??null),S(!0)}function Ke(){p||(S(!1),re(``),C(null))}function qe(){w(``),E(null),k(!0),Ye(``)}function Je(){p||(k(!1),w(``),E(null))}async function Ye(e){se(!0);try{ce((await(0,c.searchMembers)(e)).filter(e=>e.memberId!==t).map(N))}catch(e){g(D(e))}finally{se(!1)}}async function Xe(){if(!Se){v(`請輸入拒絕原因`);return}await He({action:`REJECTED`,comment:Se})}async function Ze(){if(!T){g(`請選擇轉派對象`);return}await He({action:`TRANSFERRED`,comment:we||null,transferToMemberId:T.id})}async function Qe(){await He({action:`RETURNED`,comment:Ce||null,returnToNodeId:Oe?.id??null})}function $e(){he(``),I(null),be(`REJECT_INSTANCE`),G(`MEMBER`),xe(``)}function Q(e){ve(e),$e(),B(!0),tt(``)}function et(){H||(B(!1),$e())}async function tt(e){L(!0);try{_e((await(0,c.searchMembers)(e)).map(N))}catch(e){g(D(e))}finally{L(!1)}}async function nt(){if(!q)return;let e=(V===`STAGE_NOTIFY`||V===`COMPLETION_NOTIFY`)&&W===`WEBHOOK`,t=K.trim(),n=F;if(e&&!t){g(`請輸入 Webhook URL`);return}if(!e&&!n){g(`請選擇對象成員`);return}let r=e||!n?{kind:`WEBHOOK`,webhookUrl:t}:{kind:`MEMBER`,memberIds:[n.id]},i=P.trim()||null;U(!0),g(null);try{V===`COUNTERSIGN`?await(0,c.requestAdhocCountersign)({comment:i,target:r,taskId:q.id}):V===`PRE_APPROVAL`?await(0,c.requestAdhocPreApproval)({comment:i,onReject:ye,target:r,taskId:q.id}):V===`STAGE_NOTIFY`?await(0,c.configureAdhocStageNotification)({target:r,taskId:q.id}):await(0,c.configureAdhocCompletionNotification)({target:r,taskId:q.id}),B(!1),$e(),await u()}catch(e){g(D(e))}finally{U(!1)}}async function rt(e){U(!0),g(null);try{await(0,c.cancelAdhocDirective)(e),await u()}catch(e){g(D(e))}finally{U(!1)}}(0,a.useImperativeHandle)(f,()=>({canAddSignerCurrentTask:De,canReturnCurrentTask:Ee,deciding:p,handleApprove:()=>{He({action:`APPROVED`,comment:null})},hasCurrentTask:q!==null,openAdhocModal:Q,openRejectModal:Ue,openReturnModal:Ge,openTransferModal:qe}),[De,Ee,q,p]);let $=V===`STAGE_NOTIFY`||V===`COMPLETION_NOTIFY`,it=$&&W===`WEBHOOK`?!K.trim():!F,at=Re.find(e=>e.id===ye)??Re[0],ot=Z.find(e=>e.id===W)??Z[0];return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.Typography,{component:`h2`,variant:`h3`,children:`任務`}),h?(0,s.jsx)(o.Typography,{color:`text-error`,variant:`body`,children:h}):null,(0,s.jsx)(`div`,{style:Ne,children:(0,s.jsx)(o.Table,{columns:Ae,dataSource:ke,fullWidth:!0})}),Y.length>0?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.Typography,{component:`h3`,style:Pe,variant:`h3`,children:`待生效的臨時設定`}),(0,s.jsx)(`div`,{style:Ne,children:(0,s.jsx)(o.Table,{columns:Ve,dataSource:ze,fullWidth:!0})})]}):null,(0,s.jsx)(o.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!Se,variant:`destructive-primary`},confirmText:`送出拒絕`,loading:p,modalStatusType:`error`,modalType:`standard`,onCancel:We,onClose:We,onConfirm:()=>void Xe(),open:y,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`拒絕案件時必須留下原因,供發起人與後續追蹤查看。`,title:`拒絕原因`,children:(0,s.jsxs)(`div`,{style:je,children:[(0,s.jsx)(r.t,{label:`拒絕原因`,name:`rejectReason`,required:!0,children:(0,s.jsx)(o.Textarea,{autoFocus:!0,onChange:e=>{_(e.target.value),v(null)},placeholder:`請說明拒絕原因`,ref:Fe,resize:`vertical`,rows:4,style:Me,type:te?`error`:`default`,value:ee})}),te?(0,s.jsx)(o.Typography,{color:`text-error`,variant:`body`,children:te}):null]})}),(0,s.jsx)(o.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!T},confirmText:`送出轉派`,loading:p,modalType:`standard`,onCancel:Je,onClose:Je,onConfirm:()=>void Ze(),open:ue,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`轉派後,原任務會保留轉派紀錄,新的待簽任務會指派給指定成員。`,title:`轉派簽核`,children:(0,s.jsxs)(`div`,{style:X,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:oe,loadingText:`搜尋成員中...`,mode:`single`,onChange:e=>E(pe(e)),onSearch:Ye,onSearchTextChange:e=>E(me(e,O)),onVisibilityChange:e=>{e&&Ye(``)},options:[...O],placeholder:`搜尋姓名或信箱`,searchDebounceTime:300,value:T})}),(0,s.jsx)(r.t,{label:`轉派說明`,name:`transferComment`,children:(0,s.jsx)(o.Textarea,{onChange:e=>w(e.target.value),placeholder:`可補充轉派原因`,ref:Fe,resize:`vertical`,rows:4,style:Me,value:ae})})]})}),(0,s.jsx)(o.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!Oe},confirmText:`送出退回`,loading:p,modalType:`standard`,onCancel:Ke,onClose:Ke,onConfirm:()=>void Qe(),open:x,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`退回後,流程會回到指定節點並等待重新處理。`,title:`退回簽核`,children:(0,s.jsxs)(`div`,{style:X,children:[(0,s.jsx)(r.t,{label:`退回節點`,name:`returnTargetNodeId`,required:!0,children:(0,s.jsx)(o.Select,{clearable:!1,fullWidth:!0,onChange:e=>C(e?.id??null),options:[...Te],placeholder:`選擇退回節點`,value:Oe})}),(0,s.jsx)(r.t,{label:`退回說明`,name:`returnComment`,children:(0,s.jsx)(o.Textarea,{onChange:e=>re(e.target.value),placeholder:`可補充需要修改的內容`,ref:Fe,resize:`vertical`,rows:4,style:Me,value:ne})})]})}),(0,s.jsx)(o.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:it},confirmText:`送出`,loading:H,modalType:`standard`,onCancel:et,onClose:et,onConfirm:()=>void nt(),open:z,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:Le[V],title:Ie[V],children:(0,s.jsxs)(`div`,{style:X,children:[$?(0,s.jsx)(r.t,{label:`通知時機`,name:`adhocNotifyMode`,required:!0,children:(0,s.jsx)(o.Select,{clearable:!1,fullWidth:!0,onChange:e=>ve(e?.id===`COMPLETION_NOTIFY`?`COMPLETION_NOTIFY`:`STAGE_NOTIFY`),options:[{id:`STAGE_NOTIFY`,name:Ie.STAGE_NOTIFY},{id:`COMPLETION_NOTIFY`,name:Ie.COMPLETION_NOTIFY}],value:{id:V,name:Ie[V]}})}):null,$?(0,s.jsx)(r.t,{label:`通知對象類型`,name:`adhocTargetKind`,required:!0,children:(0,s.jsx)(o.Select,{clearable:!1,fullWidth:!0,onChange:e=>G(e?.id===`WEBHOOK`?`WEBHOOK`:`MEMBER`),options:[...Z],value:ot})}):null,$&&W===`WEBHOOK`?(0,s.jsx)(r.t,{label:`Webhook URL`,name:`adhocWebhookUrl`,required:!0,children:(0,s.jsx)(o.Input,{fullWidth:!0,onChange:e=>xe(e.target.value),placeholder:`https://example.com/webhook`,value:K})}):(0,s.jsx)(r.t,{label:$?`通知對象`:`簽核對象`,name:`adhocMemberId`,required:!0,children:(0,s.jsx)(o.AutoComplete,{asyncData:!0,disabledOptionsFilter:!0,emptyText:`沒有符合的成員`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:`adhoc-member-search`,spellCheck:!1},loading:ge,loadingText:`搜尋成員中...`,mode:`single`,onChange:e=>I(pe(e)),onSearch:tt,onSearchTextChange:e=>I(me(e,R)),onVisibilityChange:e=>{e&&tt(``)},options:[...R],placeholder:`搜尋姓名或信箱`,searchDebounceTime:300,value:F})}),V===`PRE_APPROVAL`?(0,s.jsx)(r.t,{label:`拒簽處理方式`,name:`adhocOnReject`,required:!0,children:(0,s.jsx)(o.Select,{clearable:!1,fullWidth:!0,onChange:e=>be(e?.id===`RETURN_TO_ORIGIN`?`RETURN_TO_ORIGIN`:`REJECT_INSTANCE`),options:[...Re],value:at})}):null,$?null:(0,s.jsx)(r.t,{label:`說明`,name:`adhocComment`,children:(0,s.jsx)(o.Textarea,{onChange:e=>he(e.target.value),placeholder:`可補充原因`,ref:Fe,resize:`vertical`,rows:3,style:Me,value:P})})]})})]})});function Be(e,t){try{let n=JSON.parse(e.targetValueJson);if(n.memberIds?.length)return n.memberIds.map(e=>j(e,t)).join(`、`);if(n.webhookUrl)return n.webhookUrl;if(n.positionId)return`職位 ${n.positionId}`;if(n.orgUnitId)return`部門 ${n.orgUnitId}`}catch{}return e.targetKind}var Ve={display:`grid`,gap:16};function He({signatureVerification:e,signatures:t}){let r=(0,a.useMemo)(()=>t.map(e=>({algorithm:e.algorithm,hashLabel:O(e.signedPayloadHash),key:e.id,keyVersion:e.keyVersion,signedAtLabel:n.t(e.signedAt),signerMemberId:e.signerMemberId})),[t]),i=(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}],[]);return(0,s.jsxs)(`div`,{style:Ve,children:[(0,s.jsx)(o.Typography,{component:`h2`,variant:`h3`,children:`簽章`}),(0,s.jsx)(o.Typography,{color:e?.valid?`text-success`:`text-error`,variant:`body`,children:e?e.valid?`簽章鏈已驗證,共 ${e.checkedCount} 筆。`:`簽章鏈驗證失敗:${e.errors.join(`、`)}`:`尚無簽章紀錄。`}),r.length>0?(0,s.jsx)(o.Table,{columns:i,dataSource:r,fullWidth:!0}):null]})}var Ue={display:`grid`,gap:16},We={cursor:`help`,textDecoration:`underline dotted`,textUnderlineOffset:3},Ge={color:`var(--mzn-color-text-error)`};function Ke(...e){return e.filter(e=>T(e??null)).join(` `)}var qe=(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 m=r?`pending`:l;return(0,s.jsxs)(`div`,{...f,className:Ke(h.stepClasses.host,d===`dot`?h.stepClasses.dot:null,n&&m!==`processing`?h.stepClasses.error:null,c===`horizontal`?h.stepClasses.horizontal:null,d===`number`?h.stepClasses.number:null,m===`pending`?h.stepClasses.pending:null,m===`processing`?h.stepClasses.processing:null,n&&m===`processing`?h.stepClasses.processingError:null,!n&&m===`succeeded`?h.stepClasses.succeeded:null,c===`vertical`?h.stepClasses.vertical:null,e),ref:p,children:[d===`dot`?(0,s.jsx)(`span`,{className:Ke(h.stepClasses.statusIndicator,h.stepClasses.statusIndicatorDot)}):(0,s.jsx)(`span`,{className:h.stepClasses.statusIndicator,children:i+1}),(0,s.jsxs)(`div`,{className:h.stepClasses.textContainer,children:[(0,s.jsxs)(o.Typography,{className:h.stepClasses.title,variant:`label-primary-highlight`,children:[u,(0,s.jsx)(`span`,{className:h.stepClasses.titleConnectLine})]}),t.length>0?(0,s.jsx)(o.Typography,{className:h.stepClasses.description,variant:`caption`,children:t.map((e,t)=>(0,s.jsxs)(a.Fragment,{children:[t>0?` · `:null,Je(e)]},`${e.type}-${t}`))}):null]})]})});function Je(e){return e.type===`text`?e.text:e.type===`dangerText`?(0,s.jsx)(`span`,{style:Ge,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:We,children:e.label})})]}):`${e.prefix}:${e.label}`}function Ye({activityLogs:e,instanceState:t,memberProfilesById:n,signatureVerification:r,signaturesById:i,taskDecisionsByTaskId:a,tasks:c,workflowSnapshot:l,workflowTokens:u}){let d=Ce(e,c,u,l,t,n,a,i,r),f=ge(d),p=d.map(e=>({...e,descriptionParts:e.descriptionParts.filter(I)}));return(0,s.jsxs)(`div`,{style:Ue,children:[(0,s.jsx)(o.Typography,{component:`h2`,variant:`h3`,children:`歷程`}),p.length>0?(0,s.jsx)(o.Stepper,{currentStep:f,orientation:`vertical`,type:`dot`,children:p.map(e=>(0,s.jsx)(qe,{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:`尚無歷程紀錄。`})]})}var Xe=184,Ze=96,Qe={display:`grid`,gap:16},$e={background:`#f8fafc`,border:`1px solid #e2e8f0`,borderRadius:8,height:`min(64vh, 620px)`,minHeight:440,overflow:`hidden`,width:`min(80vw, 1040px)`},Q={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},et={borderRadius:999,fontSize:12,fontWeight:600,justifySelf:`start`,lineHeight:`18px`,padding:`0 8px`},tt={color:`#64748b`,fontSize:12,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},nt={opacity:0},rt={display:`flex`,flexWrap:`wrap`,gap:8},$={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`},it={display:`grid`,gap:16},at={workflowRuntime:ht};function ot({instanceId:e,showAttachments:i=!0,showForm:p=!0,showHistory:m=!0,showSignatures:h=!0,showTasks:g=!0}){let{member:ee}=t.n(),_=ee?.memberId??null,[te,v]=(0,a.useState)([]),[y,b]=(0,a.useState)(null),[ne,x]=(0,a.useState)([]),[S,ie]=(0,a.useState)([]),[C,ae]=(0,a.useState)([]),[w,T]=(0,a.useState)(null),[E,oe]=(0,a.useState)([]),[se,O]=(0,a.useState)([]),[le,ue]=(0,a.useState)([]),[k,A]=(0,a.useState)(null),[j,M]=(0,a.useState)(!0),[fe,N]=(0,a.useState)(!1),[pe,me]=(0,a.useState)(!1),[P,he]=(0,a.useState)(``),[F,I]=(0,a.useState)(!1),[ge,L]=(0,a.useState)({}),[R,_e]=(0,a.useState)({}),[z,B]=(0,a.useState)(null),[V,ve]=(0,a.useState)(null),[ye,be]=(0,a.useState)([]),H=P.trim(),U=(0,a.useRef)(null);(0,a.useEffect)(()=>{X()},[_,e]),(0,a.useEffect)(()=>{_e(y?.formData??{})},[y]);let W=(0,a.useMemo)(()=>E.find(e=>de(e,_)&&(e.status===`PENDING`||e.status===`IN_PROGRESS`))??null,[_,E]),G=(0,a.useMemo)(()=>W&&y?y.workflowSnapshot.nodes.find(e=>e.id===W.nodeId)??null:null,[W,y]),K=G?.type===`userTask`&&G.data.returnBehavior.allowReturn,xe=G?.type===`userTask`&&G.data.allowAddSigner,Se=!!(y&&y.initiatorMemberId===_&&(y.state===`RUNNING`||y.state===`RETURNED`)),Ce=!!(y&&y.initiatorMemberId===_&&y.state===`RETURNED`),we=(0,a.useMemo)(()=>new Map(le.map(e=>[e.memberId,e])),[le]),J=(0,a.useMemo)(()=>Ee(ne),[ne]),De=(0,a.useMemo)(()=>new Map(C.map(e=>[e.id,e])),[C]),Y=(0,a.useMemo)(()=>y?dt(y.workflowSnapshot):null,[y]),ke=(0,a.useMemo)(()=>y&&Y?ut(Y,E,se,y.state):[],[y,Y,E,se]),je=(0,a.useMemo)(()=>Y?ft(Y):[],[Y]),Me=(0,a.useMemo)(()=>y?ct(y.workflowSnapshot):[],[y]);async function X(){M(!0),A(null);try{let t=await(0,c.readApprovalInstance)(e);v(t.activityLogs),b(t.instance),oe(t.tasks),O(t.workflowTokens);let n=await(0,c.listAdhocDirectives)(t.instance.id),[r,i,a,o]=await Promise.all([Te(t.tasks),q({...t,adhocDirectives:n}),(0,c.listAttachments)(t.instance.id),(0,c.readInstanceSignatures)(t.instance.id)]);x(r),ue(i),ie(a),ae(o.signatures),T(o.verification),be(n)}catch(e){A(D(e))}finally{M(!1)}}async function Ne(e,t){if(!_)throw Error(`尚未登入,無法上傳附件`);return{id:(await(0,c.uploadAttachment)({file:t,formFieldPath:`form.${e.fieldKey}`})).id}}async function Pe(e){if(!_)return;let t=await(0,c.readAttachmentDownloadUrl)({id:e.id});window.open(t,`_blank`,`noopener,noreferrer`)}async function Fe(e){if(!_)return;let t=await(0,c.readAttachmentPreviewUrl)({id:e.id});B(e),ve(t)}async function Ie(){if(!(!_||!y||!Se)){if(N(!0),A(null),L({}),y.formDefinitionSnapshot.schema&&y.formDefinitionSnapshot.uiSchema){let e=(0,d.validateFormRendererValues)({schema:y.formDefinitionSnapshot.schema,uiSchema:y.formDefinitionSnapshot.uiSchema,values:R});if(!e.valid){L(e.errors),A(`請先補齊必填欄位。`),e.firstInvalidFieldKey&&(0,d.focusFormRendererField)(e.firstInvalidFieldKey),N(!1);return}}try{await(0,c.cancelApprovalInstance)({cancelledByMemberId:_,comment:H||null,instanceId:y.id}),he(``),I(!1),await X()}catch(e){A(D(e))}finally{N(!1)}}}async function Le(){if(!(!_||!y||!Ce)){N(!0),A(null);try{await(0,c.resubmitApprovalInstance)({formData:R,initiatorMemberId:_,instanceId:y.id,title:y.title}),await X()}catch(e){A(D(e))}finally{N(!1)}}}let Re=U.current?.deciding??!1,Z=fe||Re;return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.PageHeader,{children:(0,s.jsxs)(l.default,{description:y?`${ce(y.state)} · ${n.t(y.startedAt)}`:`載入案件內容。`,title:y?.title??`簽核案件`,children:[y?(0,s.jsx)(o.Button,{"aria-label":`查看流程圖`,icon:u.ShareIcon,iconType:`icon-only`,onClick:()=>me(!0),title:`查看流程圖`,variant:`base-secondary`,children:`流程圖`}):null,Se?(0,s.jsx)(o.Button,{disabled:Z,icon:u.DangerousOutlineIcon,iconType:`leading`,onClick:()=>I(!0),variant:`destructive-secondary`,children:`取消案件`}):null,W?(0,s.jsxs)(s.Fragment,{children:[xe?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.Button,{disabled:Z,icon:u.PlusIcon,iconType:`leading`,onClick:()=>U.current?.openAdhocModal(`COUNTERSIGN`),variant:`base-secondary`,children:`會簽`},`adhoc-countersign`),(0,s.jsx)(o.Button,{disabled:Z,icon:u.PlusIcon,iconType:`leading`,onClick:()=>U.current?.openAdhocModal(`PRE_APPROVAL`),variant:`base-secondary`,children:`加簽`},`adhoc-pre-approval`)]}):null,(0,s.jsx)(o.Button,{disabled:Z,icon:u.NotificationUnreadIcon,iconType:`leading`,onClick:()=>U.current?.openAdhocModal(`STAGE_NOTIFY`),variant:`base-secondary`,children:`通知設定`},`adhoc-notify`),K?(0,s.jsx)(o.Button,{disabled:Z,icon:u.RefreshCcwIcon,iconType:`leading`,onClick:()=>U.current?.openReturnModal(),variant:`base-secondary`,children:`退回`},`task-return`):null,(0,s.jsx)(o.Button,{disabled:Z,icon:u.UserIcon,iconType:`leading`,onClick:()=>U.current?.openTransferModal(),variant:`base-secondary`,children:`轉派`},`task-transfer`),(0,s.jsx)(o.Button,{disabled:Z,icon:u.DangerousOutlineIcon,iconType:`leading`,onClick:()=>U.current?.openRejectModal(),variant:`destructive-secondary`,children:`拒絕`},`task-reject`),(0,s.jsx)(o.Button,{disabled:Z,icon:u.CheckedIcon,iconType:`leading`,onClick:()=>U.current?.handleApprove(),variant:`base-primary`,children:`同意`},`task-approve`)]}):null]})}),(0,s.jsxs)(o.SectionGroup,{children:[p?(0,s.jsx)(o.Section,{children:(0,s.jsx)(Oe,{canResubmitInstance:Ce,deciding:fe,error:k,instance:y,loading:j,onResubmitFormChange:e=>{_e(e),L({})},onResubmitInstance:()=>void Le(),onUploadAttachment:Ne,resubmitFormData:R,resubmitFormErrors:ge})}):null,i?(0,s.jsx)(o.Section,{children:(0,s.jsx)(Ae,{attachments:S,onDownload:e=>{Pe(e)},onPreview:e=>{Fe(e)}})}):null,g?(0,s.jsx)(o.Section,{children:(0,s.jsx)(ze,{adhocDirectives:ye,currentMemberId:_,instance:y,memberProfilesById:we,onChanged:X,ref:U,tasks:E})}):null,h?(0,s.jsx)(o.Section,{children:(0,s.jsx)(He,{signatureVerification:w,signatures:C})}):null,m?(0,s.jsx)(o.Section,{children:(0,s.jsx)(Ye,{activityLogs:te,instanceState:y?.state??`RUNNING`,memberProfilesById:we,signatureVerification:w,signaturesById:De,taskDecisionsByTaskId:J,tasks:E,workflowSnapshot:y?.workflowSnapshot??null,workflowTokens:se})}):null]}),y?(0,s.jsx)(o.Modal,{modalType:`standard`,onClose:()=>me(!1),open:pe,showModalHeader:!0,size:`wide`,supportingText:`${ce(y.state)} · ${n.t(y.startedAt)}`,title:`流程圖`,children:(0,s.jsxs)(`div`,{style:Qe,children:[(0,s.jsx)(`div`,{style:$e,children:(0,s.jsxs)(f.ReactFlow,{edges:je,fitView:!0,fitViewOptions:{padding:.18},maxZoom:1.2,minZoom:.2,nodes:ke,nodesDraggable:!1,nodesFocusable:!1,nodeTypes:at,panOnDrag:!0,proOptions:{hideAttribution:!0},children:[(0,s.jsx)(f.Background,{}),(0,s.jsx)(f.Controls,{showInteractive:!1})]})}),Me.length>0?(0,s.jsx)(`div`,{style:rt,children:Me.map(e=>(0,s.jsx)(`span`,{style:$,children:e},e))}):null]})}):null,(0,s.jsx)(o.Modal,{modalType:`standard`,onClose:()=>{B(null),ve(null)},open:!!(z&&V),showModalHeader:!0,size:`wide`,supportingText:z?.filename??void 0,title:`PDF 預覽`,children:V?(0,s.jsx)(re,{filename:z?.filename??`PDF 預覽`,fileUrl:V,onDownload:z?()=>void Pe(z):void 0}):null}),(0,s.jsx)(o.Modal,{cancelText:`保留案件`,confirmButtonProps:{variant:`destructive-primary`},confirmText:`確認取消`,loading:fe,modalStatusType:`error`,modalType:`standard`,onCancel:()=>I(!1),onClose:()=>I(!1),onConfirm:()=>void Ie(),open:F,showModalFooter:!0,showModalHeader:!0,supportingText:`取消後會關閉目前待簽任務與候選簽核人。`,title:`取消案件`,children:(0,s.jsxs)(`div`,{style:it,children:[(0,s.jsxs)(o.Typography,{variant:`body`,children:[`確定要取消「`,y?.title??``,`」嗎?`]}),(0,s.jsx)(r.t,{label:`取消原因`,name:`cancelComment`,children:(0,s.jsx)(o.Textarea,{onChange:e=>he(e.target.value),placeholder:`可填寫取消原因`,resize:`vertical`,rows:3,value:P})})]})})]})}function st(e){return e.data.label?e.data.label:e.data.isDefault?`其他情況`:e.data.condition??``}function ct(e){return e.edges.map(st).filter(e=>e.trim().length>0)}function lt(e){return e===`startEvent`?`開始`:e===`endEvent`?`完成`:e===`userTask`?`簽核節點`:e===`serviceTask`?`知會節點`:e===`exclusiveGateway`?`條件分流`:`平行處理`}function ut(e,t,n,r){return e.nodes.map(e=>{let i=we(e,t,n,r);return{data:{kindLabel:lt(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 dt(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:Ze,width:Xe})}),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-Xe/2,y:n.y-Ze/2}}:e})}}function ft(e){return e.edges.map(e=>{let t=st(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 pt(e){return e===`current`?{...Q,border:`1px solid var(--mzn-color-primary, #0057ff)`,boxShadow:`0 0 0 3px rgba(0, 87, 255, 0.14)`}:e===`completed`?{...Q,border:`1px solid #16a34a`}:e===`cancelled`?{...Q,border:`1px solid #dc2626`,opacity:.72}:e===`waiting`?{...Q,border:`1px dashed #64748b`}:Q}function mt(e){let t=et;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 ht({data:e}){return(0,s.jsxs)(`div`,{style:pt(e.tone),children:[(0,s.jsx)(f.Handle,{isConnectable:!1,position:f.Position.Left,style:nt,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:mt(e.tone),children:e.statusLabel}),(0,s.jsx)(`span`,{title:e.secondaryLabel,style:tt,children:e.secondaryLabel||e.kindLabel}),(0,s.jsx)(f.Handle,{isConnectable:!1,position:f.Position.Right,style:nt,type:`source`})]})}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return Ae}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return Ye}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return Oe}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return He}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return ot}});
2
- //# sourceMappingURL=detail-Cci9tnoC.cjs.map
@@ -1,2 +0,0 @@
1
- "use client";require('../orgs.css');const e=require("./chunk-CMqjfN_6.cjs"),t=require("./admin-pickers-Btvij1at.cjs"),n=require("./bpm-form-field-Bc6k4ZEO.cjs");let r=require("react"),i=require("@mezzanine-ui/react"),a=require("@rytass/bpm-core-client"),o=require("react/jsx-runtime"),s=require("@mezzanine-ui/react/ContentHeader");s=e.t(s,1);let c=require("@mezzanine-ui/core/form"),l=require("@mezzanine-ui/icons"),u=require("@rytass/bpm-core-client/organization"),d=require("@xyflow/react"),f=require("dagre");f=e.t(f,1);function p(e){return new Map(e.map(e=>[e.id,e.parentId]))}function m({orgUnitId:e,parentDraft:t,parentId:n}){let r=n===e?e:n,i=g({orgUnitId:e,parentDraft:t,parentId:r});if(i)return{message:i,parentDraft:t,status:`INVALID`};if((t.get(e)??null)===r)return{message:`父子關係沒有變更。`,parentDraft:t,status:`UNCHANGED`};let a=new Map(t);return a.set(e,r),{message:r?`已暫存新的上層組織。`:`已暫存為根節點。`,parentDraft:a,status:`UPDATED`}}function h({orgUnits:e,parentDraft:t}){return e.map(e=>{let n=t.get(e.id)??null;return n===e.parentId?null:{orgUnitId:e.id,parentId:n,previousParentId:e.parentId}}).filter(e=>!!e)}function g({orgUnitId:e,parentDraft:t,parentId:n}){return t.has(e)?n?t.has(n)?n===e?`組織不可成為自己的上層。`:_({orgUnitId:e,parentDraft:t,parentId:n})?`不可搬移到自己的下層組織。`:null:`找不到新的上層組織。`:null:`找不到要搬移的組織節點。`}function _({orgUnitId:e,parentDraft:t,parentId:n}){let r=new Set,i=n;for(;i;){if(i===e||r.has(i))return!0;r.add(i),i=t.get(i)??null}return!1}var v={orgTreeEditor:`bpm_orgTreeEditor_TMOtD`,orgTreeSummary:`bpm_orgTreeSummary_vpcV8`,orgTreeChangeList:`bpm_orgTreeChangeList_EzmOv`,orgTreeCanvas:`bpm_orgTreeCanvas_MeD7y`,orgTreeNode:`bpm_orgTreeNode_bN4FS`,orgTreeNodeRoot:`bpm_orgTreeNodeRoot_Hr2KD`,orgTreeNodeSelected:`bpm_orgTreeNodeSelected_eRwtL`,orgTreeNodeChanged:`bpm_orgTreeNodeChanged_qPJg0`,orgTreeNodeDeleted:`bpm_orgTreeNodeDeleted_Ab0cI`,orgTreeNodeHeader:`bpm_orgTreeNodeHeader_LEXl-`,orgTreeNodeBadge:`bpm_orgTreeNodeBadge_zLc7t`,orgTreeNodeActions:`bpm_orgTreeNodeActions_cMldI`},y=`__org-tree-root__`,b=232,x=118,S=232,C=86,w=320,T=1.4,E=.25,D=.005,O=250,ee=80,k=.85,te=.7,A=1200,j=600,M=60,ne=3,N={COMPANY:`公司`,DEPARTMENT:`部門`,DIVISION:`事業群`,TEAM:`小組`},P={orgUnit:re},F=(0,r.forwardRef)(function({onCreateChild:e,onCreateRoot:t,onEditOrgUnit:n,onSaveDraft:a,onStateChange:s,orgUnits:c},l){let[u,f]=(0,r.useState)(!1),[g,_]=(0,r.useState)(null),[b,x]=(0,r.useState)(null),[S,C]=(0,r.useState)(()=>p(c)),[w,M]=(0,r.useState)(()=>ie(c,p(c))),[ne,N]=(0,r.useState)([]),F=(0,r.useRef)(null),re=(0,r.useCallback)(e=>{M(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),I=(0,r.useMemo)(()=>new Map(c.map(e=>[e.id,e])),[c]),L=(0,r.useMemo)(()=>h({orgUnits:c,parentDraft:S}),[c,S]),R=(0,r.useMemo)(()=>ae({collapsedIds:w,isEditing:u,onCreateChild:n=>{n?e(n):t()},onEditOrgUnit:e=>{let t=I.get(e);t&&n(t)},onToggleCollapse:re,orgUnits:c,orgUnitsById:I,parentDraft:S,selectedOrgUnitId:b}),[w,re,u,e,t,n,c,I,S,b]),B=(0,r.useRef)(R);B.current=R;let V=L.length>0,se=(0,r.useMemo)(()=>{let e=Math.max(R.bounds.width,R.bounds.height);return e<=0?E:Math.min(E,Math.max(D,O/e))},[R.bounds.height,R.bounds.width]),ce=c.length<=ee,de=(0,r.useCallback)(()=>{let e=F.current;if(!e)return;let{bounds:t,rootCenter:n}=B.current,r=t.width>0?A/t.width:1/0,i=t.height>0?j/t.height:1/0,a=Math.min(r,i);if(!Number.isFinite(a)||a>=te){e.fitView({padding:.18});return}e.setCenter(n.x,n.y,{duration:0,zoom:k})},[]),H=(0,r.useCallback)(e=>{F.current=e,de()},[de]);(0,r.useImperativeHandle)(l,()=>({cancelEditing:me,saveDraft:he,startEditing:G})),(0,r.useEffect)(()=>{s({hasDraftChanges:V,isEditing:u})},[V,u,s]),(0,r.useEffect)(()=>{let e=p(c);C(e),M(ie(c,e)),x(null),_(null),f(!1)},[c]),(0,r.useEffect)(()=>{N(R.nodes)},[R.nodes]),(0,r.useEffect)(()=>{if(typeof window>`u`)return()=>void 0;let e=window.requestAnimationFrame(()=>{de()});return()=>window.cancelAnimationFrame(e)},[de,c]);let U=(0,r.useCallback)((e,t)=>{C(n=>{let r=m({orgUnitId:e,parentDraft:n,parentId:t});return _(r.message),r.parentDraft})},[]),W=(0,r.useCallback)(e=>{if(!u||!e.target||!e.source)return;let t=e.source===y?null:e.source;if(e.target===y){_(`根節點不能搬移到其他節點下。`);return}U(e.target,t)},[U,u]),fe=(0,r.useCallback)(e=>{u&&N(t=>(0,d.applyNodeChanges)(e,[...t]))},[u]),pe=(0,r.useCallback)((e,t,n)=>{if(!u||t.id===y)return;let r=oe(e,t.id)??z(t,n);if(r===void 0){_(`拖曳到目標父節點附近,或從父節點拉線到子節點。`);return}U(t.id,r===y?null:r)},[U,u]);function G(){f(!0),C(p(c)),_(`已進入編輯模式,拖曳節點或拉線只會更新前端草稿。`)}function me(){f(!1),C(p(c)),_(`已取消草稿變更。`)}async function he(){if(!a){_(`批次儲存 API 尚未接上,草稿仍保留在前端。`);return}await a(L),f(!1),_(`組織樹草稿已儲存。`)}return(0,o.jsxs)(`div`,{className:v.orgTreeEditor,children:[(0,o.jsxs)(`div`,{className:v.orgTreeSummary,children:[(0,o.jsx)(i.Typography,{color:`text-neutral`,variant:`caption`,children:g??(V?`目前有 ${L.length} 筆父子關係草稿變更。`:`目前沒有草稿變更。`)}),V?(0,o.jsx)(`ul`,{className:v.orgTreeChangeList,children:L.map(e=>(0,o.jsxs)(`li`,{children:[ue(e.orgUnitId,I),`:`,ue(e.previousParentId,I),` -> `,ue(e.parentId,I)]},e.orgUnitId))}):null]}),(0,o.jsx)(`div`,{className:v.orgTreeCanvas,children:(0,o.jsxs)(d.ReactFlow,{connectionMode:d.ConnectionMode.Strict,edges:[...R.edges],fitViewOptions:{minZoom:se,padding:.18},isValidConnection:e=>le({source:e.source,target:e.target},S),maxZoom:T,minZoom:se,nodeTypes:P,nodes:[...ne],nodesConnectable:u,nodesDraggable:u,onConnect:W,onInit:H,onNodeClick:(e,t)=>{x(t.id===y?null:t.id)},onNodeDoubleClick:(e,t)=>{if(t.id!==y){let e=I.get(t.id);e&&n(e)}},onNodeDragStop:pe,onNodesChange:fe,onPaneClick:()=>x(null),panOnDrag:!0,proOptions:{hideAttribution:!0},children:[(0,o.jsx)(d.Background,{}),(0,o.jsx)(d.Controls,{}),ce?(0,o.jsx)(d.MiniMap,{pannable:!0,zoomable:!0}):null]})})]})});function re({data:e,selected:t}){return(0,o.jsxs)(`div`,{className:[v.orgTreeNode,e.isSyntheticRoot?v.orgTreeNodeRoot:``,e.changed?v.orgTreeNodeChanged:``,e.deleted?v.orgTreeNodeDeleted:``,t?v.orgTreeNodeSelected:``].filter(Boolean).join(` `),children:[e.isSyntheticRoot?null:(0,o.jsx)(d.Handle,{id:`target`,isConnectable:e.isEditing,position:d.Position.Top,type:`target`}),(0,o.jsx)(d.Handle,{id:`source`,isConnectable:e.isEditing,position:d.Position.Bottom,type:`source`}),(0,o.jsxs)(`div`,{className:v.orgTreeNodeHeader,children:[(0,o.jsx)(i.Typography,{component:`span`,ellipsis:!0,title:e.name,variant:`label-primary`,children:e.name}),e.changed?(0,o.jsx)(`span`,{className:v.orgTreeNodeBadge,children:`草稿`}):null]}),(0,o.jsx)(i.Typography,{color:`text-neutral`,component:`span`,ellipsis:!0,title:e.code,variant:`caption`,children:e.isSyntheticRoot?`根節點容器`:`${e.typeLabel} · ${e.code}`}),e.isSyntheticRoot?null:(0,o.jsxs)(i.Typography,{color:`text-neutral`,component:`span`,ellipsis:!0,title:e.parentLabel,variant:`caption`,children:[`上層:`,e.parentLabel]}),(0,o.jsxs)(`div`,{className:`${v.orgTreeNodeActions} nodrag`,children:[e.childCount>0?(0,o.jsx)(i.Button,{onClick:t=>{t.stopPropagation(),e.onToggleCollapse(e.orgUnitId??y)},size:`sub`,variant:`base-secondary`,children:e.collapsed?`展開 (${e.childCount})`:`收合 (${e.childCount})`}):null,e.isSyntheticRoot?(0,o.jsx)(i.Button,{icon:l.PlusIcon,iconType:`leading`,onClick:()=>e.onCreateChild(null),size:`sub`,variant:`base-secondary`,children:`新增根節點`}):(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.Button,{icon:l.EditIcon,iconType:`leading`,onClick:()=>{e.orgUnitId&&e.onEdit(e.orgUnitId)},size:`sub`,variant:`base-secondary`,children:`編輯`}),(0,o.jsx)(i.Button,{icon:l.PlusIcon,iconType:`leading`,onClick:()=>e.onCreateChild(e.orgUnitId),size:`sub`,variant:`base-secondary`,children:`新增子節點`})]})]})]})}function I(e,t){let n=new Map;return e.forEach(e=>{let r=t.get(e.id)??y;n.set(r,[...n.get(r)??[],e.id])}),n}function L({childrenMap:e,collapsedIds:t}){let n=new Set,r=i=>{t.has(i)||(e.get(i)??[]).forEach(e=>{n.add(e),r(e)})};return r(y),n}function ie(e,t){if(e.length<=M)return new Set;let n=I(e,t),r=new Set,i=(e,t)=>{let a=n.get(e)??[];a.length!==0&&(t>=ne&&r.add(e),a.forEach(e=>i(e,t+1)))};return i(y,0),r}function ae({collapsedIds:e,isEditing:t,onCreateChild:n,onEditOrgUnit:r,onToggleCollapse:i,orgUnits:a,orgUnitsById:o,parentDraft:s,selectedOrgUnitId:c}){let l=I(a,s),u=L({childrenMap:l,collapsedIds:e}),d=a.filter(e=>u.has(e.id)),p=e=>l.get(e)?.length??0,m=new f.graphlib.Graph;m.setDefaultEdgeLabel(()=>({})),m.setGraph({marginx:36,marginy:36,nodesep:44,rankdir:`TB`}),m.setNode(y,{height:C,width:S}),d.forEach(e=>{m.setNode(e.id,{height:x,width:b})}),d.forEach(e=>{let t=s.get(e.id)??null;m.setEdge(t??y,e.id)}),f.layout(m);let h=m.graph(),g={height:h.height??0,width:h.width??0},_=m.node(y),v={x:_?.x??0,y:_?.y??0},w=R({data:{changed:!1,childCount:p(y),code:y,collapsed:e.has(y),deleted:!1,isEditing:t,isSyntheticRoot:!0,name:`組織根節點`,onCreateChild:n,onEdit:r,onToggleCollapse:i,orgUnitId:null,parentLabel:``,path:``,typeLabel:``},graph:m,height:C,id:y,selected:c===null,width:S}),T=d.map(a=>{let l=s.get(a.id)??null,u=ue(l,o);return R({data:{changed:l!==a.parentId,childCount:p(a.id),code:a.code,collapsed:e.has(a.id),deleted:!!a.deletedAt,isEditing:t,isSyntheticRoot:!1,name:a.name,onCreateChild:n,onEdit:r,onToggleCollapse:i,orgUnitId:a.id,parentLabel:u,path:a.path,typeLabel:de(a.type)},graph:m,height:x,id:a.id,selected:c===a.id,width:b})});return{bounds:g,edges:d.map(e=>{let n=s.get(e.id)??null,r=n!==e.parentId;return{animated:t&&r,data:{},id:`org-tree-edge-${n??`root`}-${e.id}`,source:n??y,sourceHandle:`source`,style:r?{stroke:`var(--mzn-color-primary, #0057ff)`,strokeWidth:2}:void 0,target:e.id,targetHandle:`target`,type:`smoothstep`}}),nodes:[w,...T],rootCenter:v}}function R({data:e,graph:t,height:n,id:r,selected:i,width:a}){let o=t.node(r);return{data:e,height:n,id:r,initialHeight:n,initialWidth:a,position:o?{x:o.x-a/2,y:o.y-n/2}:{x:0,y:0},selected:i,sourcePosition:d.Position.Bottom,targetPosition:d.Position.Top,type:`orgUnit`,width:a}}function z(e,t){let n=se(e);return t.filter(t=>t.id!==e.id).map(e=>({distance:ce(n,se(e)),id:e.id})).filter(e=>e.distance<=w).sort((e,t)=>e.distance-t.distance)[0]?.id}function oe(e,t){let n=B(e);if(n)return Array.from(document.querySelectorAll(`.react-flow__node[data-id]`)).map(e=>{let r=e.dataset.id;if(!r||r===t)return null;let i=e.getBoundingClientRect();return{distance:ce(n,{x:i.left+i.width/2,y:i.top+i.height/2}),id:r}}).filter(e=>!!e).filter(e=>e.distance<=w).sort((e,t)=>e.distance-t.distance)[0]?.id}function B(e){return V(e)?{x:e.clientX,y:e.clientY}:null}function V(e){return typeof e==`object`&&!!e&&`clientX`in e&&`clientY`in e&&typeof e.clientX==`number`&&typeof e.clientY==`number`}function se(e){return{x:e.position.x+(e.width??b)/2,y:e.position.y+(e.height??x)/2}}function ce(e,t){return Math.hypot(e.x-t.x,e.y-t.y)}function le(e,t){return!e.source||!e.target||e.target===y?!1:g({orgUnitId:e.target,parentDraft:t,parentId:e.source===y?null:e.source})===null}function ue(e,t){if(!e)return`根節點`;let n=t.get(e);return n?`${n.name} · ${n.code}`:`未知組織`}function de(e){return N[e.toUpperCase()]??`未知類型`}var H={tableIntroActions:`bpm_tableIntroActions_WO4XU`,modalFields:`bpm_modalFields_juyv6`,tableIntro:`bpm_tableIntro_u3hcm`,tableFrame:`bpm_tableFrame_IdbmB`,orgFilterArea:`bpm_orgFilterArea_Xjbbp`,membershipFilterArea:`bpm_membershipFilterArea_zob-Y`,scopeLabel:`bpm_scopeLabel_TLHMC`},U={hasDraftChanges:!1,isEditing:!1},W=[{id:`COMPANY`,name:`公司`},{id:`DIVISION`,name:`事業群`},{id:`DEPARTMENT`,name:`部門`},{id:`TEAM`,name:`小組`}],fe={id:`ALL`,name:`全部類型`},pe=[fe,...W],G=[{id:`MEMBER`,name:`指定會員`},{id:`ORG_UNIT`,name:`指定組織`},{id:`POSITION`,name:`指定職位`}],me={id:`ALL`,name:`全部範圍`},he=[me,...G],ge={activeOnly:!1,id:`ALL`,name:`全部狀態`},_e=[ge,{activeOnly:!0,id:`ACTIVE`,name:`目前有效`}],K=[{id:`true`,name:`主要歸屬`,value:!0},{id:`false`,name:`一般歸屬`,value:!1}],ve=[10,20,50],ye=1368,be=908,xe=1292,Se=1124;function Ce(){let[e,t]=(0,r.useState)(`ORG_UNITS`),[n,c]=(0,r.useState)(null),[l,d]=(0,r.useState)(null),[f,p]=(0,r.useState)(null),[m,h]=(0,r.useState)(!0),[g,_]=(0,r.useState)(null),[v,y]=(0,r.useState)(ge),[b,x]=(0,r.useState)(1),[S,C]=(0,r.useState)(10),[w,T]=(0,r.useState)(me),[E,D]=(0,r.useState)(0),[O,ee]=(0,r.useState)([]),[k,te]=(0,r.useState)(null),[A,j]=(0,r.useState)(null),[M,ne]=(0,r.useState)(null),[N,P]=(0,r.useState)(1),[F,re]=(0,r.useState)(10),[I,L]=(0,r.useState)(null),[ie,ae]=(0,r.useState)(0),[R,z]=(0,r.useState)(null),[oe,B]=(0,r.useState)(1),[V,se]=(0,r.useState)(10),[ce,le]=(0,r.useState)(``),[ue,de]=(0,r.useState)(0),[H,U]=(0,r.useState)(fe),[W,pe]=(0,r.useState)(`TABLE`),[G,he]=(0,r.useState)([]),[_e,K]=(0,r.useState)([]),[ve,ye]=(0,r.useState)([]),[be,xe]=(0,r.useState)(null),[Se,Ce]=(0,r.useState)(1),[q,Oe]=(0,r.useState)(10),[ke,Ae]=(0,r.useState)(``),[je,J]=(0,r.useState)(0),[Y,Ue]=(0,r.useState)([]),[We,Ge]=(0,r.useState)([]),[Ke,qe]=(0,r.useState)([]),[X,Je]=(0,r.useState)(!1);(0,r.useEffect)(()=>{n&&d(n)},[n]);let Ye=n??l,Xe=(0,r.useCallback)(async()=>{h(!0),p(null);try{let e=await(0,u.readOrganizationDashboard)({managerActiveOnly:v.activeOnly,managerPage:b,managerPageSize:S,managerScopeType:w.id===`ALL`?null:w.id,membershipActiveOnly:k?.activeOnly??!1,membershipOrgUnitId:M?.id??null,membershipPage:N,membershipPageSize:F,membershipPositionId:I?.id??null,orgUnitPage:oe,orgUnitPageSize:V,orgUnitSearchText:ce,orgUnitType:H.id===`ALL`?null:H.id,positionPage:Se,positionPageSize:q,positionSearchText:ke});ee(await(0,a.resolveMembers)(Ie(e.memberships,e.managerResolutions))),he(e.orgUnits),de(e.orgUnitCount),K(e.filteredOrgUnits),Ue(e.positions),J(e.positionCount),ye(e.filteredPositions),ae(e.membershipCount),qe(e.filteredMemberships),D(e.managerResolutionCount),Ge(e.filteredManagerResolutions)}catch(e){p(tt(e))}finally{h(!1)}},[v,b,S,w,k,M,N,F,I,oe,V,ce,H,Se,q,ke]);(0,r.useEffect)(()=>{Xe()},[Xe]);let Z=(0,r.useMemo)(()=>new Map(G.map(e=>[e.id,e])),[G]),Q=(0,r.useMemo)(()=>new Map(Y.map(e=>[e.id,e])),[Y]),$=(0,r.useMemo)(()=>new Map(O.map(e=>[e.memberId,e])),[O]),Qe=(0,r.useMemo)(()=>_e.map(e=>({...e,key:e.id,parentName:e.parentId?ze(Z.get(e.parentId)):`根節點`,typeLabel:Be(e.type)})),[_e,Z]),$e=(0,r.useMemo)(()=>ve.map(e=>({...e,key:e.id})),[ve]),et=(0,r.useMemo)(()=>Ke.map(e=>({...e,key:e.id,memberName:Re($.get(e.memberId)),orgUnitName:ze(Z.get(e.orgUnitId)),positionName:e.positionId?Ve(Q.get(e.positionId)):`未指定`})),[$,Ke,Z,Q]),nt=(0,r.useMemo)(()=>We.map(e=>({...e,key:e.id,managerName:Re($.get(e.managerMemberId)),scopeLabel:Le(e,{membersById:$,orgUnitsById:Z,positionsById:Q})})),[We,$,Z,Q]),rt=(0,r.useMemo)(()=>({render:e=>[{name:`編輯`,onClick:()=>z({record:e,type:`EDIT`})},{name:`停用`,onClick:()=>c({confirmText:`停用組織`,description:`停用「${e.name}」後,這個組織節點將不再出現在可用組織清單中。`,id:e.id,title:`停用組織節點`,type:`ORG_UNIT`}),variant:`destructive-secondary`}],variant:`base-secondary`,width:128}),[]),it=(0,r.useMemo)(()=>({render:e=>[{name:`編輯`,onClick:()=>xe({record:e,type:`EDIT`})}],variant:`base-secondary`,width:88}),[]),at=(0,r.useMemo)(()=>({render:e=>[{name:`編輯`,onClick:()=>j({record:e,type:`EDIT`})},{name:`刪除`,onClick:()=>c({confirmText:`刪除歸屬`,description:`刪除「${e.memberName}」在「${e.orgUnitName}」的會員歸屬。`,id:e.id,title:`刪除會員歸屬`,type:`MEMBERSHIP`}),variant:`destructive-secondary`}],variant:`base-secondary`,width:128}),[]),ot=(0,r.useMemo)(()=>({render:e=>[{name:`編輯`,onClick:()=>_({record:e,type:`EDIT`})},{name:`刪除`,onClick:()=>c({confirmText:`刪除主管規則`,description:`刪除「${e.scopeLabel}」指派給「${e.managerName}」的主管解析規則。`,id:e.id,title:`刪除主管解析規則`,type:`MANAGER_RESOLUTION`}),variant:`destructive-secondary`}],variant:`base-secondary`,width:128}),[]);function st(e){B(1),le(e)}function ct(e){B(1),U(e)}function lt(e){Ce(1),Ae(e)}function ut(e){P(1),te(e)}function dt(e){P(1),ne(e)}function ft(e){P(1),L(e)}function pt(e){x(1),y(e)}function mt(e){x(1),T(e)}function ht(){X||c(null)}async function gt(){n&&await vt(async()=>{n.type===`ORG_UNIT`&&await(0,u.deleteOrgUnit)(n.id),n.type===`MEMBERSHIP`&&await(0,u.deleteMembership)(n.id),n.type===`MANAGER_RESOLUTION`&&await(0,u.deleteManagerResolution)(n.id),c(null)})}async function _t(e){Je(!0),p(null);try{await(0,u.commitOrgUnitTreeDraft)({moves:e.map(e=>({baseUpdatedAt:Z.get(e.orgUnitId)?.updatedAt??``,id:e.orgUnitId,parentId:e.parentId}))}),await Xe()}catch(e){throw p(tt(e)),e}finally{Je(!1)}}async function vt(e){Je(!0),p(null);try{await e(),await Xe()}catch(e){p(tt(e))}finally{Je(!1)}}return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.PageHeader,{children:(0,o.jsx)(s.default,{description:`維護組織樹、職位、會員歸屬與簽核主管解析規則。`,title:`組織管理`})}),(0,o.jsx)(i.SectionGroup,{children:(0,o.jsxs)(i.Section,{tab:(0,o.jsxs)(i.Tab,{activeKey:e,onChange:e=>t(He(e)),children:[(0,o.jsx)(i.TabItem,{children:`組織樹`},`ORG_UNITS`),(0,o.jsx)(i.TabItem,{children:`職位`},`POSITIONS`),(0,o.jsx)(i.TabItem,{children:`會員歸屬`},`MEMBERSHIPS`),(0,o.jsx)(i.TabItem,{children:`簽核主管`},`MANAGERS`)]}),children:[f?(0,o.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:f}):null,e===`ORG_UNITS`?(0,o.jsx)(we,{actions:rt,loading:m,onCreate:()=>z({parentId:null,record:null,type:`CREATE`}),onCreateChild:e=>z({parentId:e,record:null,type:`CREATE`}),onEditOrgUnit:e=>z({record:e,type:`EDIT`}),onPageChange:B,onSaveDraft:_t,onPageSizeChange:e=>{B(1),se(e)},onSearchTextChange:st,onTypeFilterChange:ct,orgUnits:G,page:oe,pageSize:V,rows:Qe,searchText:ce,saving:X,total:ue,typeFilter:H,viewMode:W,onViewModeChange:pe}):null,e===`POSITIONS`?(0,o.jsx)(Te,{actions:it,loading:m,onCreate:()=>xe({record:null,type:`CREATE`}),onPageChange:Ce,onPageSizeChange:e=>{Ce(1),Oe(e)},onSearchTextChange:lt,page:Se,pageSize:q,rows:$e,searchText:ke,total:je}):null,e===`MEMBERSHIPS`?(0,o.jsx)(Ee,{actions:at,loading:m,onCreate:()=>j({record:null,type:`CREATE`}),onActiveFilterChange:ut,onOrgUnitFilterChange:dt,onPageChange:P,onPageSizeChange:e=>{P(1),re(e)},onPositionFilterChange:ft,orgUnitFilter:M,orgUnits:G,page:N,pageSize:F,positionFilter:I,positions:Y,rows:et,statusFilter:k,total:ie}):null,e===`MANAGERS`?(0,o.jsx)(De,{actions:ot,loading:m,onCreate:()=>_({record:null,type:`CREATE`}),onActiveFilterChange:pt,onPageChange:x,onPageSizeChange:e=>{x(1),C(e)},onScopeTypeFilterChange:mt,page:b,pageSize:S,rows:nt,scopeTypeFilter:w,statusFilter:v,total:E}):null]})}),(0,o.jsx)(Me,{modal:R,onClose:()=>z(null),onSubmit:e=>vt(async()=>{R?.type===`EDIT`&&R.record?await(0,u.updateOrgUnit)({...e,id:R.record.id,metadataJson:null}):await(0,u.createOrgUnit)({code:e.code??``,metadataJson:`{}`,name:e.name??``,parentId:e.parentId,type:e.type??`DEPARTMENT`}),z(null)}),orgUnits:G,saving:X}),(0,o.jsx)(Ne,{modal:be,onClose:()=>xe(null),onSubmit:e=>vt(async()=>{be?.type===`EDIT`&&be.record?await(0,u.updatePosition)({...e,id:be.record.id,metadataJson:null}):await(0,u.createPosition)({code:e.code??``,level:e.level??0,metadataJson:`{}`,name:e.name??``}),xe(null)}),saving:X}),(0,o.jsx)(Pe,{membersById:$,modal:A,onClose:()=>j(null),onSubmit:e=>vt(async()=>{A?.type===`EDIT`&&A.record?await(0,u.updateMembership)({...e,id:A.record.id}):await(0,u.createMembership)({effectiveFrom:e.effectiveFrom??Ze(),effectiveTo:e.effectiveTo,isPrimary:e.isPrimary??!1,memberId:e.memberId??``,orgUnitId:e.orgUnitId??``,positionId:e.positionId}),j(null)}),orgUnits:G,positions:Y,saving:X}),(0,o.jsx)(Fe,{membersById:$,modal:g,onClose:()=>_(null),onSubmit:e=>vt(async()=>{g?.type===`EDIT`&&g.record?await(0,u.updateManagerResolution)({...e,id:g.record.id}):await(0,u.createManagerResolution)({effectiveFrom:e.effectiveFrom??Ze(),effectiveTo:e.effectiveTo,managerMemberId:e.managerMemberId??``,priority:e.priority??0,scopeId:e.scopeId??``,scopeType:e.scopeType??`MEMBER`}),_(null)}),orgUnits:G,positions:Y,saving:X}),(0,o.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{variant:`destructive-primary`},confirmText:Ye?.confirmText??``,loading:X,modalStatusType:`error`,modalType:`standard`,onCancel:ht,onClose:ht,onConfirm:()=>void gt(),open:!!n,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`此操作會立即套用,請確認後再繼續。`,title:Ye?.title??``,children:(0,o.jsx)(i.Typography,{color:`text-neutral`,variant:`body`,children:Ye?.description??``})})]})}function we({actions:e,loading:t,onCreate:n,onCreateChild:a,onEditOrgUnit:s,onPageChange:u,onSaveDraft:d,onPageSizeChange:f,onSearchTextChange:p,onTypeFilterChange:m,onViewModeChange:h,orgUnits:g,page:_,pageSize:v,rows:y,searchText:b,saving:x,total:S,typeFilter:C,viewMode:w}){let T=(0,r.useRef)(null),[E,D]=(0,r.useState)(U),O=w===`TABLE`?`FLOW`:`TABLE`,ee=w===`TABLE`?`切換樹狀圖`:`切換表格`,k=w===`FLOW`,te=Oe({isTreeMode:k,isTreeEditing:E.isEditing}),A=ke({isTreeMode:k,isTreeEditing:E.isEditing}),j=Ae({hasDraftChanges:E.hasDraftChanges,isTreeEditing:E.isEditing,isTreeMode:k,loading:t,saving:x}),M=(0,r.useMemo)(()=>[{dataIndex:`code`,key:`code`,title:`代碼`,width:180},{dataIndex:`name`,key:`name`,title:`名稱`,width:240},{dataIndex:`typeLabel`,key:`typeLabel`,title:`類型`,width:120},{dataIndex:`parentName`,key:`parentName`,title:`上層`,width:280},{dataIndex:`path`,key:`path`,title:`Path`,width:420}],[]);return(0,r.useEffect)(()=>{w===`TABLE`&&D(U)},[w]),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(je,{actionDisabled:j,actionIcon:A,actionLabel:te,actions:(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.Button,{onClick:()=>h(O),variant:`base-secondary`,children:ee}),k&&E.isEditing?(0,o.jsx)(i.Button,{disabled:x,icon:l.CloseIcon,iconType:`leading`,onClick:()=>T.current?.cancelEditing(),variant:`base-secondary`,children:`取消`}):null]}),description:`組織節點使用 ltree path 維護階層,搬移節點會同步更新子節點 path。`,onCreate:()=>{if(!k){n();return}if(E.isEditing){T.current?.saveDraft();return}T.current?.startEditing()},title:`組織樹`}),w===`TABLE`?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.FilterArea,{className:H.orgFilterArea,size:`sub`,children:(0,o.jsxs)(i.FilterLine,{children:[(0,o.jsx)(i.Filter,{span:3,children:(0,o.jsx)(i.FormField,{fullWidth:!0,layout:c.FormFieldLayout.VERTICAL,name:`orgUnitSearchText`,children:(0,o.jsx)(i.Input,{fullWidth:!0,onChange:e=>p(e.target.value),placeholder:`搜尋組織名稱或代碼`,size:`sub`,value:b,variant:`base`})})}),(0,o.jsx)(i.Filter,{span:2,children:(0,o.jsx)(i.FormField,{fullWidth:!0,layout:c.FormFieldLayout.VERTICAL,name:`orgUnitTypeFilter`,children:(0,o.jsx)(i.Select,{clearable:!1,fullWidth:!0,onChange:e=>m(We(e)),options:[...pe],placeholder:`類型`,size:`sub`,value:C})})})]})}),(0,o.jsx)(`div`,{className:H.tableFrame,children:(0,o.jsx)(i.Table,{actions:e,columns:M,dataSource:[...y],fullWidth:!0,loading:t,pagination:q({onPageChange:u,onPageSizeChange:f,page:_,pageSize:v,total:S}),style:{minWidth:ye}})})]}):(0,o.jsx)(F,{ref:T,onCreateChild:a,onCreateRoot:n,onEditOrgUnit:s,onSaveDraft:d,onStateChange:D,orgUnits:g,saving:x})]})}function Te({actions:e,loading:t,onCreate:n,onPageChange:a,onPageSizeChange:s,onSearchTextChange:l,page:u,pageSize:d,rows:f,searchText:p,total:m}){let h=(0,r.useMemo)(()=>[{dataIndex:`code`,key:`code`,title:`代碼`,width:180},{dataIndex:`name`,key:`name`,title:`名稱`,width:280},{dataIndex:`level`,key:`level`,title:`職等`,width:96},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:220}],[]);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(je,{actionLabel:`新增職位`,description:`職位提供會員歸屬與主管解析規則使用。`,onCreate:n,title:`職位`}),(0,o.jsx)(i.FilterArea,{className:H.orgFilterArea,size:`sub`,children:(0,o.jsx)(i.FilterLine,{children:(0,o.jsx)(i.Filter,{span:3,children:(0,o.jsx)(i.FormField,{fullWidth:!0,layout:c.FormFieldLayout.VERTICAL,name:`positionSearchText`,children:(0,o.jsx)(i.Input,{fullWidth:!0,onChange:e=>l(e.target.value),placeholder:`搜尋職位名稱或代碼`,size:`sub`,value:p,variant:`base`})})})})}),(0,o.jsx)(`div`,{className:H.tableFrame,children:(0,o.jsx)(i.Table,{actions:e,columns:h,dataSource:[...f],fullWidth:!0,loading:t,pagination:q({onPageChange:a,onPageSizeChange:s,page:u,pageSize:d,total:m}),style:{minWidth:be}})})]})}function Ee({actions:e,loading:n,onCreate:a,onActiveFilterChange:s,onOrgUnitFilterChange:l,onPageChange:u,onPageSizeChange:d,onPositionFilterChange:f,orgUnitFilter:p,orgUnits:m,page:h,pageSize:g,positionFilter:_,positions:v,rows:y,statusFilter:b,total:x}){let S=(0,r.useMemo)(()=>[{dataIndex:`memberName`,key:`memberName`,title:`會員`,width:280},{dataIndex:`orgUnitName`,key:`orgUnitName`,title:`組織`,width:280},{dataIndex:`positionName`,key:`positionName`,title:`職位`,width:220},{key:`isPrimary`,render:e=>e.isPrimary?`主要`:`一般`,title:`類型`,width:104},{dataIndex:`effectiveFrom`,key:`effectiveFrom`,title:`生效日`,width:140},{dataIndex:`effectiveTo`,key:`effectiveTo`,title:`結束日`,width:140}],[]),C=(0,r.useMemo)(()=>m.map(t.a),[m]),w=(0,r.useMemo)(()=>v.map(t.o),[v]);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(je,{actionLabel:`新增歸屬`,description:`會員歸屬是 BPM 內部組織權限、主管解析與條件判斷的來源。`,onCreate:a,title:`會員歸屬`}),(0,o.jsx)(i.FilterArea,{className:[H.orgFilterArea,H.membershipFilterArea].join(` `),size:`sub`,children:(0,o.jsxs)(i.FilterLine,{children:[(0,o.jsx)(i.Filter,{span:2,children:(0,o.jsx)(i.FormField,{fullWidth:!0,layout:c.FormFieldLayout.VERTICAL,name:`membershipOrgUnitFilter`,children:(0,o.jsx)(i.AutoComplete,{disabledOptionsFilter:!0,emptyText:`沒有符合的組織`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:`membershipOrgUnitFilter`,spellCheck:!1},mode:`single`,name:`membershipOrgUnitFilter`,onChange:e=>l(Je(e)),options:[...C],placeholder:`全部組織`,size:`sub`,value:p})})}),(0,o.jsx)(i.Filter,{span:2,children:(0,o.jsx)(i.FormField,{fullWidth:!0,layout:c.FormFieldLayout.VERTICAL,name:`membershipPositionFilter`,children:(0,o.jsx)(i.AutoComplete,{disabledOptionsFilter:!0,emptyText:`沒有符合的職位`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:`membershipPositionFilter`,spellCheck:!1},mode:`single`,name:`membershipPositionFilter`,onChange:e=>f(Ye(e)),options:[...w],placeholder:`全部職位`,size:`sub`,value:_})})}),(0,o.jsx)(i.Filter,{span:2,children:(0,o.jsx)(i.FormField,{fullWidth:!0,layout:c.FormFieldLayout.VERTICAL,name:`membershipStatusFilter`,children:(0,o.jsx)(i.AutoComplete,{disabledOptionsFilter:!0,emptyText:`沒有符合的狀態`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:`membershipStatusFilter`,spellCheck:!1},mode:`single`,name:`membershipStatusFilter`,onChange:e=>s(X(e)),options:[..._e],placeholder:`全部狀態`,size:`sub`,value:b})})})]})}),(0,o.jsx)(`div`,{className:H.tableFrame,children:(0,o.jsx)(i.Table,{actions:e,columns:S,dataSource:[...y],fullWidth:!0,loading:n,pagination:q({onPageChange:u,onPageSizeChange:d,page:h,pageSize:g,total:x}),style:{minWidth:xe}})})]})}function De({actions:e,loading:t,onCreate:n,onActiveFilterChange:a,onPageChange:s,onPageSizeChange:l,onScopeTypeFilterChange:u,page:d,pageSize:f,rows:p,scopeTypeFilter:m,statusFilter:h,total:g}){let _=(0,r.useMemo)(()=>[{dataIndex:`scopeLabel`,key:`scopeLabel`,title:`套用範圍`,width:320},{dataIndex:`managerName`,key:`managerName`,title:`簽核主管`,width:300},{dataIndex:`priority`,key:`priority`,title:`優先序`,width:96},{dataIndex:`effectiveFrom`,key:`effectiveFrom`,title:`生效日`,width:140},{dataIndex:`effectiveTo`,key:`effectiveTo`,title:`結束日`,width:140}],[]);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(je,{actionLabel:`新增主管規則`,description:`簽核主管規則獨立於組織樹 parent,解析優先序為會員、組織、職位。`,onCreate:n,title:`簽核主管`}),(0,o.jsx)(i.FilterArea,{className:H.orgFilterArea,size:`sub`,children:(0,o.jsxs)(i.FilterLine,{children:[(0,o.jsx)(i.Filter,{span:3,children:(0,o.jsx)(i.FormField,{fullWidth:!0,layout:c.FormFieldLayout.VERTICAL,name:`managerScopeTypeFilter`,children:(0,o.jsx)(i.Select,{clearable:!1,fullWidth:!0,onChange:e=>u(Ke(e)),options:[...he],placeholder:`套用範圍`,size:`sub`,value:m})})}),(0,o.jsx)(i.Filter,{span:2,children:(0,o.jsx)(i.FormField,{fullWidth:!0,layout:c.FormFieldLayout.VERTICAL,name:`managerStatusFilter`,children:(0,o.jsx)(i.Select,{clearable:!1,fullWidth:!0,onChange:e=>a(qe(e)),options:[..._e],placeholder:`狀態`,size:`sub`,value:h})})})]})}),(0,o.jsx)(`div`,{className:H.tableFrame,children:(0,o.jsx)(i.Table,{actions:e,columns:_,dataSource:[...p],fullWidth:!0,loading:t,pagination:q({onPageChange:s,onPageSizeChange:l,page:d,pageSize:f,total:g}),style:{minWidth:Se}})})]})}function q({onPageChange:e,onPageSizeChange:t,page:n,pageSize:r,total:i}){return{current:n,onChange:e,onChangePageSize:t,pageSize:r,pageSizeLabel:`每頁筆數`,pageSizeOptions:[...ve],renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:i}}function Oe({isTreeEditing:e,isTreeMode:t}){return t?e?`儲存`:`開始編輯`:`新增組織`}function ke({isTreeEditing:e,isTreeMode:t}){return t?e?l.SaveIcon:l.EditIcon:l.PlusIcon}function Ae({hasDraftChanges:e,isTreeEditing:t,isTreeMode:n,loading:r,saving:i}){return n?t?!e||i:r:!1}function je({actionDisabled:e=!1,actionIcon:t=l.PlusIcon,actionLabel:n,actions:r,description:a,onCreate:s,title:c}){return(0,o.jsxs)(`div`,{className:H.tableIntro,children:[(0,o.jsxs)(`div`,{children:[(0,o.jsx)(i.Typography,{component:`h2`,variant:`h3`,children:c}),(0,o.jsx)(i.Typography,{color:`text-neutral`,variant:`body`,children:a})]}),(0,o.jsxs)(`div`,{className:H.tableIntroActions,children:[r,(0,o.jsx)(i.Button,{disabled:e,icon:t,iconType:`leading`,onClick:s,children:n})]})]})}function Me({modal:e,onClose:a,onSubmit:s,orgUnits:c,saving:l}){let[u,d]=(0,r.useState)(``),[f,p]=(0,r.useState)(``),[m,h]=(0,r.useState)(null),[g,_]=(0,r.useState)(W[2]);return(0,r.useEffect)(()=>{if(!e)return;let n=e.record,r=n?.parentId??e.parentId??null,i=r?c.find(e=>e.id===r)??null:null;d(n?.code??``),p(n?.name??``),h(i?t.a(i):null),_(W.find(e=>e.id===n?.type)??W[2])},[e,c]),(0,o.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!u||!f},confirmText:e?.type===`EDIT`?`儲存`:`建立`,loading:l,modalType:`standard`,onCancel:a,onClose:a,onConfirm:()=>void s({code:u,name:f,parentId:m?.id??null,type:g.id}),open:!!e,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:e?.type===`EDIT`?`編輯組織`:`新增組織`,children:(0,o.jsxs)(`div`,{className:H.modalFields,children:[(0,o.jsx)(J,{label:`代碼`,name:`orgCode`,onChange:d,placeholder:`例如 FIN-TW`,value:u}),(0,o.jsx)(J,{label:`名稱`,name:`orgName`,onChange:p,placeholder:`例如 財務部`,value:f}),(0,o.jsx)(n.t,{label:`類型`,name:`orgType`,children:(0,o.jsx)(i.Select,{clearable:!1,fullWidth:!0,onChange:e=>_(Ue(e)),options:[...W],placeholder:`選擇組織類型`,value:g})}),(0,o.jsx)(n.t,{label:`上層組織`,name:`parentId`,children:(0,o.jsx)(t.n,{name:`parentId`,onChange:h,orgUnits:c.filter(t=>t.id!==e?.record?.id),placeholder:`選擇上層組織`,value:m})})]})})}function Ne({modal:e,onClose:t,onSubmit:n,saving:a}){let[s,c]=(0,r.useState)(``),[l,u]=(0,r.useState)(`0`),[d,f]=(0,r.useState)(``);return(0,r.useEffect)(()=>{e&&(c(e.record?.code??``),u(String(e.record?.level??0)),f(e.record?.name??``))},[e]),(0,o.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!s||!d},confirmText:e?.type===`EDIT`?`儲存`:`建立`,loading:a,modalType:`standard`,onCancel:t,onClose:t,onConfirm:()=>void n({code:s,level:Number(l),name:d}),open:!!e,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:e?.type===`EDIT`?`編輯職位`:`新增職位`,children:(0,o.jsxs)(`div`,{className:H.modalFields,children:[(0,o.jsx)(J,{label:`代碼`,name:`positionCode`,onChange:c,placeholder:`例如 FIN-MGR`,value:s}),(0,o.jsx)(J,{label:`名稱`,name:`positionName`,onChange:f,placeholder:`例如 財務主管`,value:d}),(0,o.jsx)(J,{label:`職等`,name:`positionLevel`,onChange:u,placeholder:`例如 5`,value:l})]})})}function Pe({membersById:e,modal:a,onClose:s,onSubmit:c,orgUnits:l,positions:u,saving:d}){let[f,p]=(0,r.useState)(Ze()),[m,h]=(0,r.useState)(``),[g,_]=(0,r.useState)(K[1]),[v,y]=(0,r.useState)(null),[b,x]=(0,r.useState)(null),[S,C]=(0,r.useState)(null);return(0,r.useEffect)(()=>{if(!a)return;let n=a.record,r=n?e.get(n.memberId):null;p(n?.effectiveFrom??Ze()),h(n?.effectiveTo??``),_(K.find(e=>e.value===n?.isPrimary)??K[1]),y(r?t.i(r):null),x($(l.find(e=>e.id===n?.orgUnitId),t.a)),C($(u.find(e=>e.id===n?.positionId),t.o))},[e,a,l,u]),(0,o.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!v||!b},confirmText:a?.type===`EDIT`?`儲存`:`建立`,loading:d,modalType:`standard`,onCancel:s,onClose:s,onConfirm:()=>void c({effectiveFrom:f,effectiveTo:m||null,isPrimary:g.value,memberId:v?.id??null,orgUnitId:b?.id??null,positionId:S?.id??null}),open:!!a,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:a?.type===`EDIT`?`編輯會員歸屬`:`新增會員歸屬`,children:(0,o.jsxs)(`div`,{className:H.modalFields,children:[(0,o.jsx)(n.t,{label:`會員`,name:`memberId`,children:(0,o.jsx)(t.t,{name:`memberId`,onChange:y,placeholder:`搜尋會員姓名或信箱`,value:v})}),(0,o.jsx)(n.t,{label:`組織`,name:`orgUnitId`,children:(0,o.jsx)(t.n,{name:`orgUnitId`,onChange:x,orgUnits:l,placeholder:`選擇歸屬組織`,value:b})}),(0,o.jsx)(n.t,{label:`職位`,name:`positionId`,children:(0,o.jsx)(t.r,{name:`positionId`,onChange:C,placeholder:`選擇職位`,positions:u,value:S})}),(0,o.jsx)(n.t,{label:`歸屬類型`,name:`isPrimary`,children:(0,o.jsx)(i.Select,{clearable:!1,fullWidth:!0,onChange:e=>_(Xe(e)),options:[...K],placeholder:`選擇歸屬類型`,value:g})}),(0,o.jsx)(Y,{label:`生效日`,name:`membershipEffectiveFrom`,onChange:p,placeholder:`YYYY-MM-DD`,value:f}),(0,o.jsx)(Y,{label:`結束日`,name:`membershipEffectiveTo`,onChange:h,placeholder:`YYYY-MM-DD,未設定代表無期限`,value:m})]})})}function Fe({membersById:e,modal:a,onClose:s,onSubmit:c,orgUnits:l,positions:u,saving:d}){let[f,p]=(0,r.useState)(Ze()),[m,h]=(0,r.useState)(``),[g,_]=(0,r.useState)(null),[v,y]=(0,r.useState)(`0`),[b,x]=(0,r.useState)(null),[S,C]=(0,r.useState)(null),[w,T]=(0,r.useState)(null),[E,D]=(0,r.useState)(G[0]);(0,r.useEffect)(()=>{if(!a)return;let n=a.record,r=G.find(e=>e.id===n?.scopeType)??G[0];p(n?.effectiveFrom??Ze()),h(n?.effectiveTo??``),_($(n?e.get(n.managerMemberId):null,t.i)),y(String(n?.priority??0)),x(r.id===`MEMBER`?$(n?e.get(n.scopeId):null,t.i):null),C(r.id===`ORG_UNIT`?$(l.find(e=>e.id===n?.scopeId),t.a):null),T(r.id===`POSITION`?$(u.find(e=>e.id===n?.scopeId),t.o):null),D(r)},[e,a,l,u]);let O=E.id===`MEMBER`?b?.id:E.id===`ORG_UNIT`?S?.id:w?.id,ee=!!(E.id===`MEMBER`&&b?.id&&g?.id&&b.id===g.id);return(0,o.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!g||!O||ee},confirmText:a?.type===`EDIT`?`儲存`:`建立`,loading:d,modalType:`standard`,onCancel:s,onClose:s,onConfirm:()=>void c({effectiveFrom:f,effectiveTo:m||null,managerMemberId:g?.id??null,priority:Number(v),scopeId:O??null,scopeType:E.id}),open:!!a,showModalFooter:!0,showModalHeader:!0,size:`regular`,title:a?.type===`EDIT`?`編輯主管規則`:`新增主管規則`,children:(0,o.jsxs)(`div`,{className:H.modalFields,children:[(0,o.jsx)(n.t,{label:`套用範圍`,name:`scopeType`,children:(0,o.jsx)(i.Select,{clearable:!1,fullWidth:!0,onChange:e=>D(Ge(e)),options:[...G],placeholder:`選擇套用範圍`,value:E})}),E.id===`MEMBER`?(0,o.jsx)(n.t,{label:`會員`,name:`scopeMemberId`,children:(0,o.jsx)(t.t,{name:`scopeMemberId`,onChange:x,placeholder:`搜尋套用會員`,value:b})}):null,E.id===`ORG_UNIT`?(0,o.jsx)(n.t,{label:`組織`,name:`scopeOrgUnitId`,children:(0,o.jsx)(t.n,{name:`scopeOrgUnitId`,onChange:C,orgUnits:l,placeholder:`選擇套用組織`,value:S})}):null,E.id===`POSITION`?(0,o.jsx)(n.t,{label:`職位`,name:`scopePositionId`,children:(0,o.jsx)(t.r,{name:`scopePositionId`,onChange:T,placeholder:`選擇套用職位`,positions:u,value:w})}):null,(0,o.jsx)(n.t,{label:`簽核主管`,name:`managerMemberId`,children:(0,o.jsx)(t.t,{name:`managerMemberId`,onChange:_,placeholder:`搜尋簽核主管`,value:g})}),ee?(0,o.jsx)(i.Typography,{color:`text-error`,variant:`caption`,children:`簽核主管不可設定為套用會員本人。`}):null,(0,o.jsx)(J,{label:`優先序`,name:`managerPriority`,onChange:y,placeholder:`例如 10`,value:v}),(0,o.jsx)(Y,{label:`生效日`,name:`managerEffectiveFrom`,onChange:p,placeholder:`YYYY-MM-DD`,value:f}),(0,o.jsx)(Y,{label:`結束日`,name:`managerEffectiveTo`,onChange:h,placeholder:`YYYY-MM-DD,未設定代表無期限`,value:m})]})})}function J({label:e,name:t,onChange:r,placeholder:a,value:s}){return(0,o.jsx)(n.t,{label:e,name:t,children:(0,o.jsx)(i.Input,{fullWidth:!0,name:t,onChange:e=>r(e.target.value),placeholder:a,value:s})})}function Y({label:e,name:t,onChange:r,placeholder:a,value:s}){return(0,o.jsx)(n.t,{label:e,name:t,children:(0,o.jsx)(i.DatePicker,{format:`YYYY-MM-DD`,fullWidth:!0,inputProps:{name:t},onChange:e=>r(Qe(e)),placeholder:a,value:s.trim()?s:void 0})})}function Ie(e,t){return[...new Set([...e.map(e=>e.memberId),...t.map(e=>e.managerMemberId),...t.filter(e=>e.scopeType===`MEMBER`).map(e=>e.scopeId)])]}function Le(e,t){return e.scopeType===`MEMBER`?`會員:${Re(t.membersById.get(e.scopeId))}`:e.scopeType===`ORG_UNIT`?`組織:${ze(t.orgUnitsById.get(e.scopeId))}`:`職位:${Ve(t.positionsById.get(e.scopeId))}`}function Re(e){return e?`${e.name} · ${e.email}`:`未知會員`}function ze(e){return e?`${e.name} · ${e.code}`:`未知組織`}function Be(e){return W.find(t=>t.id.toLowerCase()===e.toLowerCase())?.name??`未知類型`}function Ve(e){return e?`${e.name} · ${e.code}`:`未指定`}function He(e){return e===`MANAGERS`||e===`MEMBERSHIPS`||e===`POSITIONS`?e:`ORG_UNITS`}function Ue(e){let t=Q(e)?e:null;if(typeof t?.id==`string`){let e=t.id;return W.find(t=>t.id.toLowerCase()===e.toLowerCase())??W[2]}return W[2]}function We(e){let t=Q(e)?e:null;if(typeof t?.id==`string`){let e=t.id;return pe.find(t=>t.id.toLowerCase()===e.toLowerCase())??fe}return fe}function Ge(e){return Z(e,G,G[0])}function Ke(e){return Z(e,he,me)}function qe(e){return Z(e,_e,ge)}function X(e){let t=Q(e)?e:null,n=typeof t?.id==`string`?t.id:null;return _e.find(e=>e.id===n)??null}function Je(e){let t=Q(e)?e:null,n=typeof t?.id==`string`?t.id:null,r=typeof t?.name==`string`?t.name:null;return n&&r?{id:n,name:r}:null}function Ye(e){let t=Q(e)?e:null,n=typeof t?.id==`string`?t.id:null,r=typeof t?.name==`string`?t.name:null;return n&&r?{id:n,name:r}:null}function Xe(e){return Z(e,K,K[1])}function Z(e,t,n){let r=Q(e)?e:null,i=typeof r?.id==`string`?r.id:null;return t.find(e=>e.id===i)??n}function Q(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function $(e,t){return e?t(e):null}function Ze(){return $e(new Date)}function Qe(e){let t=e?new Date(e):null;return t&&!Number.isNaN(t.getTime())?$e(t):``}function $e(e){return`${e.getFullYear()}-${et(e.getMonth()+1)}-${et(e.getDate())}`}function et(e){return String(e).padStart(2,`0`)}function tt(e){return e instanceof Error?e.message:`讀取組織資料失敗。`}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return Ce}});
2
- //# sourceMappingURL=orgs-C1JFfk_Y.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"orgs-C1JFfk_Y.cjs","names":[],"sources":["../../src/lib/org-tree-draft.ts","../../src/components/org-unit-tree-draft-editor.module.scss","../../src/components/org-unit-tree-draft-editor.tsx","../../src/views/admin/orgs/orgs.module.scss","../../src/views/admin/orgs/AdminOrgsView.tsx"],"sourcesContent":["import type { OrgUnitRecord } from '@rytass/bpm-core-client/organization';\n\nexport type OrgUnitParentDraftMap = ReadonlyMap<string, string | null>;\n\nexport type OrgUnitHierarchyDraftChange = Readonly<{\n orgUnitId: string;\n parentId: string | null;\n previousParentId: string | null;\n}>;\n\nexport type OrgUnitParentAssignmentResult = Readonly<{\n message: string;\n parentDraft: OrgUnitParentDraftMap;\n status: 'INVALID' | 'UNCHANGED' | 'UPDATED';\n}>;\n\nexport function createOrgUnitParentDraftMap(\n orgUnits: readonly OrgUnitRecord[],\n): OrgUnitParentDraftMap {\n return new Map(\n orgUnits.map((orgUnit): readonly [string, string | null] => [\n orgUnit.id,\n orgUnit.parentId,\n ]),\n );\n}\n\nexport function assignOrgUnitDraftParent({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string | null;\n}): OrgUnitParentAssignmentResult {\n const normalizedParentId = parentId === orgUnitId ? orgUnitId : parentId;\n const validationMessage = readOrgUnitParentValidationMessage({\n orgUnitId,\n parentDraft,\n parentId: normalizedParentId,\n });\n\n if (validationMessage) {\n return {\n message: validationMessage,\n parentDraft,\n status: 'INVALID',\n };\n }\n\n if ((parentDraft.get(orgUnitId) ?? null) === normalizedParentId) {\n return {\n message: '父子關係沒有變更。',\n parentDraft,\n status: 'UNCHANGED',\n };\n }\n\n const nextDraft = new Map(parentDraft);\n nextDraft.set(orgUnitId, normalizedParentId);\n\n return {\n message: normalizedParentId ? '已暫存新的上層組織。' : '已暫存為根節點。',\n parentDraft: nextDraft,\n status: 'UPDATED',\n };\n}\n\nexport function readOrgUnitHierarchyDraftChanges({\n orgUnits,\n parentDraft,\n}: {\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly parentDraft: OrgUnitParentDraftMap;\n}): readonly OrgUnitHierarchyDraftChange[] {\n return orgUnits\n .map((orgUnit): OrgUnitHierarchyDraftChange | null => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n\n return parentId === orgUnit.parentId\n ? null\n : {\n orgUnitId: orgUnit.id,\n parentId,\n previousParentId: orgUnit.parentId,\n };\n })\n .filter((change): change is OrgUnitHierarchyDraftChange => Boolean(change));\n}\n\nexport function readOrgUnitParentValidationMessage({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string | null;\n}): string | null {\n if (!parentDraft.has(orgUnitId)) {\n return '找不到要搬移的組織節點。';\n }\n\n if (!parentId) {\n return null;\n }\n\n if (!parentDraft.has(parentId)) {\n return '找不到新的上層組織。';\n }\n\n if (parentId === orgUnitId) {\n return '組織不可成為自己的上層。';\n }\n\n return createsOrgUnitParentCycle({ orgUnitId, parentDraft, parentId })\n ? '不可搬移到自己的下層組織。'\n : null;\n}\n\nfunction createsOrgUnitParentCycle({\n orgUnitId,\n parentDraft,\n parentId,\n}: {\n readonly orgUnitId: string;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly parentId: string;\n}): boolean {\n const visitedIds = new Set<string>();\n let currentParentId: string | null = parentId;\n\n while (currentParentId) {\n if (currentParentId === orgUnitId || visitedIds.has(currentParentId)) {\n return true;\n }\n\n visitedIds.add(currentParentId);\n currentParentId = parentDraft.get(currentParentId) ?? null;\n }\n\n return false;\n}\n",".orgTreeEditor {\n display: grid;\n gap: 12px;\n min-width: 0;\n}\n\n.orgTreeSummary {\n display: grid;\n gap: 6px;\n min-width: 0;\n padding: 10px 12px;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: var(--mzn-color-bg, #fff);\n}\n\n.orgTreeChangeList {\n display: grid;\n gap: 4px;\n max-height: 128px;\n margin: 0;\n padding-left: 18px;\n overflow: auto;\n color: var(--mzn-color-text-neutral, #5f6673);\n font-size: 13px;\n}\n\n.orgTreeCanvas {\n width: 100%;\n height: min(720px, calc(100vh - 300px));\n min-height: 520px;\n overflow: hidden;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: #f7f9fc;\n}\n\n.orgTreeNode {\n display: grid;\n gap: 6px;\n width: 232px;\n min-height: 118px;\n padding: 12px;\n border: 1px solid var(--mzn-color-border, #d9dce1);\n border-radius: 8px;\n background: #fff;\n box-shadow: 0 4px 12px rgb(20 28 44 / 8%);\n}\n\n.orgTreeNodeRoot {\n min-height: 86px;\n border-style: dashed;\n background: #eef4ff;\n}\n\n.orgTreeNodeSelected {\n border-color: var(--mzn-color-primary, #0057ff);\n box-shadow: 0 0 0 3px rgb(0 87 255 / 14%);\n}\n\n.orgTreeNodeChanged {\n border-color: var(--mzn-color-primary, #0057ff);\n}\n\n.orgTreeNodeDeleted {\n opacity: 0.58;\n}\n\n.orgTreeNodeHeader {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 8px;\n min-width: 0;\n}\n\n.orgTreeNodeHeader > :global(.mzn-typography) {\n min-width: 0;\n}\n\n.orgTreeNodeBadge {\n flex: 0 0 auto;\n padding: 2px 6px;\n border-radius: 999px;\n background: #e4f0ff;\n color: var(--mzn-color-primary, #0057ff);\n font-size: 12px;\n line-height: 18px;\n}\n\n.orgTreeNodeActions {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding-top: 2px;\n}\n","'use client';\n\nimport {\n ReactElement,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n Background,\n Connection,\n ConnectionMode,\n Controls,\n Edge,\n Handle,\n MiniMap,\n Node,\n NodeProps,\n NodeTypes,\n OnNodeDrag,\n OnNodesChange,\n Position,\n ReactFlow,\n ReactFlowInstance,\n applyNodeChanges,\n} from '@xyflow/react';\nimport * as dagre from 'dagre';\nimport { Button, Typography } from '@mezzanine-ui/react';\nimport { EditIcon, PlusIcon } from '@mezzanine-ui/icons';\nimport type { OrgUnitRecord, OrgUnitType } from '@rytass/bpm-core-client/organization';\nimport {\n OrgUnitHierarchyDraftChange,\n OrgUnitParentDraftMap,\n assignOrgUnitDraftParent,\n createOrgUnitParentDraftMap,\n readOrgUnitHierarchyDraftChanges,\n readOrgUnitParentValidationMessage,\n} from '../lib/org-tree-draft';\nimport styles from './org-unit-tree-draft-editor.module.scss';\n\ntype OrgUnitTreeFlowData = Readonly<{\n changed: boolean;\n childCount: number;\n code: string;\n collapsed: boolean;\n deleted: boolean;\n isEditing: boolean;\n isSyntheticRoot: boolean;\n name: string;\n onCreateChild: (parentId: string | null) => void;\n onEdit: (orgUnitId: string) => void;\n onToggleCollapse: (nodeId: string) => void;\n orgUnitId: string | null;\n parentLabel: string;\n path: string;\n typeLabel: string;\n}>;\n\ntype OrgUnitTreeNode = Node<OrgUnitTreeFlowData, 'orgUnit'>;\ntype OrgUnitTreeEdge = Edge<Record<string, never>>;\ntype OrgUnitTreeFlowInstance = ReactFlowInstance<\n OrgUnitTreeNode,\n OrgUnitTreeEdge\n>;\n\ntype OrgUnitTreeFlowElements = Readonly<{\n bounds: Readonly<{ height: number; width: number }>;\n edges: readonly OrgUnitTreeEdge[];\n nodes: readonly OrgUnitTreeNode[];\n rootCenter: Readonly<{ x: number; y: number }>;\n}>;\n\nexport type OrgUnitTreeDraftEditorHandle = Readonly<{\n cancelEditing: () => void;\n saveDraft: () => Promise<void>;\n startEditing: () => void;\n}>;\n\nexport type OrgUnitTreeDraftEditorState = Readonly<{\n hasDraftChanges: boolean;\n isEditing: boolean;\n}>;\n\ntype OrgUnitTreeDraftEditorProps = Readonly<{\n onCreateChild: (parentId: string) => void;\n onCreateRoot: () => void;\n onEditOrgUnit: (orgUnit: OrgUnitRecord) => void;\n onSaveDraft?: (\n changes: readonly OrgUnitHierarchyDraftChange[],\n ) => Promise<void>;\n onStateChange: (state: OrgUnitTreeDraftEditorState) => void;\n orgUnits: readonly OrgUnitRecord[];\n saving: boolean;\n}>;\n\nconst ORG_TREE_ROOT_ID = '__org-tree-root__';\nconst ORG_TREE_NODE_WIDTH = 232;\nconst ORG_TREE_NODE_HEIGHT = 118;\nconst ORG_TREE_ROOT_WIDTH = 232;\nconst ORG_TREE_ROOT_HEIGHT = 86;\nconst ORG_TREE_DROP_DISTANCE = 320;\n\n// Zoom bounds for the ReactFlow canvas. `minZoom` is computed per layout so\n// that fitView can shrink a very wide/tall tree enough to reveal the whole\n// graph; a fixed minZoom (e.g. 0.25) leaves huge trees clipped off-screen.\nconst ORG_TREE_MAX_ZOOM = 1.4;\nconst ORG_TREE_BASE_MIN_ZOOM = 0.25;\n// Absolute lowest zoom; keeps even an extremely wide tree (tens of thousands of\n// px across) fully fittable while never reaching 0.\nconst ORG_TREE_MIN_ZOOM_FLOOR = 0.005;\n// Reference viewport side (px) the fit-all zoom should still work in; minZoom is\n// derived as reference / longest-graph-side, clamped between the floor and base.\n// A small reference keeps fitView from being clamped on narrow viewports.\nconst ORG_TREE_MIN_ZOOM_REFERENCE = 250;\n// Above this node count the MiniMap turns into an unreadable black block and\n// adds render cost, so it is hidden for large trees.\nconst ORG_TREE_MINIMAP_MAX_NODES = 80;\n\n// Initial viewport strategy. A very wide/deep tree fitted to the whole graph\n// collapses into an unreadable thin line at ~0.05 zoom, so instead of fitView\n// we open large trees at a readable zoom anchored on the root node and let the\n// user pan/zoom. Small trees still open with fitView.\nconst ORG_TREE_READABLE_ZOOM = 0.85;\n// If fitView would land at or above this zoom the tree is small enough to open\n// fully; below it we switch to the readable-anchored-on-root strategy.\nconst ORG_TREE_FIT_READABLE_MIN_ZOOM = 0.7;\n// Reference viewport used to estimate the fitView zoom before the canvas is\n// measured (the real canvas is ~1000-1400 x 520-720).\nconst ORG_TREE_VIEWPORT_REF_WIDTH = 1200;\nconst ORG_TREE_VIEWPORT_REF_HEIGHT = 600;\n// Above this visible-node count a freshly loaded large tree starts collapsed to\n// `ORG_TREE_INITIAL_EXPAND_DEPTH` levels so it opens readable instead of\n// exploding into hundreds of side-by-side nodes.\nconst ORG_TREE_LARGE_NODE_COUNT = 60;\n// Depth (synthetic root = 0, top-level org units = 1) kept expanded on the\n// initial load of a large tree; nodes at or below this depth start collapsed so\n// only the root plus this many org levels show, and the user drills down.\nconst ORG_TREE_INITIAL_EXPAND_DEPTH = 3;\n\nconst ORG_UNIT_TYPE_LABELS: Readonly<Record<Uppercase<OrgUnitType>, string>> = {\n COMPANY: '公司',\n DEPARTMENT: '部門',\n DIVISION: '事業群',\n TEAM: '小組',\n};\n\nconst orgUnitTreeNodeTypes: NodeTypes = {\n orgUnit: OrgUnitTreeNodeCard,\n};\n\nexport const OrgUnitTreeDraftEditor = forwardRef<\n OrgUnitTreeDraftEditorHandle,\n OrgUnitTreeDraftEditorProps\n>(function OrgUnitTreeDraftEditor(\n {\n onCreateChild,\n onCreateRoot,\n onEditOrgUnit,\n onSaveDraft,\n onStateChange,\n orgUnits,\n },\n ref,\n): ReactElement {\n const [isEditing, setIsEditing] = useState(false);\n const [draftMessage, setDraftMessage] = useState<string | null>(null);\n const [selectedOrgUnitId, setSelectedOrgUnitId] = useState<string | null>(\n null,\n );\n const [parentDraft, setParentDraft] = useState<OrgUnitParentDraftMap>(() =>\n createOrgUnitParentDraftMap(orgUnits),\n );\n const [collapsedIds, setCollapsedIds] = useState<ReadonlySet<string>>(() =>\n createDefaultCollapsedOrgUnitIds(orgUnits, createOrgUnitParentDraftMap(orgUnits)),\n );\n const [flowNodes, setFlowNodes] = useState<readonly OrgUnitTreeNode[]>([]);\n const flowInstanceRef = useRef<OrgUnitTreeFlowInstance | null>(null);\n\n const handleToggleCollapse = useCallback((nodeId: string): void => {\n setCollapsedIds((current) => {\n const next = new Set(current);\n\n if (next.has(nodeId)) {\n next.delete(nodeId);\n } else {\n next.add(nodeId);\n }\n\n return next;\n });\n }, []);\n\n const orgUnitsById = useMemo(\n (): ReadonlyMap<string, OrgUnitRecord> =>\n new Map(orgUnits.map((orgUnit) => [orgUnit.id, orgUnit])),\n [orgUnits],\n );\n const draftChanges = useMemo(\n (): readonly OrgUnitHierarchyDraftChange[] =>\n readOrgUnitHierarchyDraftChanges({ orgUnits, parentDraft }),\n [orgUnits, parentDraft],\n );\n const flowElements = useMemo(\n (): OrgUnitTreeFlowElements =>\n createOrgUnitTreeFlowElements({\n collapsedIds,\n isEditing,\n onCreateChild: (parentId): void => {\n if (parentId) {\n onCreateChild(parentId);\n } else {\n onCreateRoot();\n }\n },\n onEditOrgUnit: (orgUnitId): void => {\n const orgUnit = orgUnitsById.get(orgUnitId);\n\n if (orgUnit) {\n onEditOrgUnit(orgUnit);\n }\n },\n onToggleCollapse: handleToggleCollapse,\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n }),\n [\n collapsedIds,\n handleToggleCollapse,\n isEditing,\n onCreateChild,\n onCreateRoot,\n onEditOrgUnit,\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n ],\n );\n const flowElementsRef = useRef(flowElements);\n flowElementsRef.current = flowElements;\n const hasDraftChanges = draftChanges.length > 0;\n const minZoom = useMemo((): number => {\n const largestSide = Math.max(\n flowElements.bounds.width,\n flowElements.bounds.height,\n );\n\n if (largestSide <= 0) {\n return ORG_TREE_BASE_MIN_ZOOM;\n }\n\n return Math.min(\n ORG_TREE_BASE_MIN_ZOOM,\n Math.max(\n ORG_TREE_MIN_ZOOM_FLOOR,\n ORG_TREE_MIN_ZOOM_REFERENCE / largestSide,\n ),\n );\n }, [flowElements.bounds.height, flowElements.bounds.width]);\n const showMiniMap = orgUnits.length <= ORG_TREE_MINIMAP_MAX_NODES;\n\n const applyInitialViewport = useCallback((): void => {\n const instance = flowInstanceRef.current;\n\n if (!instance) {\n return;\n }\n\n const { bounds, rootCenter } = flowElementsRef.current;\n const widthZoom =\n bounds.width > 0\n ? ORG_TREE_VIEWPORT_REF_WIDTH / bounds.width\n : Number.POSITIVE_INFINITY;\n const heightZoom =\n bounds.height > 0\n ? ORG_TREE_VIEWPORT_REF_HEIGHT / bounds.height\n : Number.POSITIVE_INFINITY;\n const estimatedFitZoom = Math.min(widthZoom, heightZoom);\n\n if (\n !Number.isFinite(estimatedFitZoom) ||\n estimatedFitZoom >= ORG_TREE_FIT_READABLE_MIN_ZOOM\n ) {\n instance.fitView({ padding: 0.18 });\n return;\n }\n\n instance.setCenter(rootCenter.x, rootCenter.y, {\n duration: 0,\n zoom: ORG_TREE_READABLE_ZOOM,\n });\n }, []);\n\n const handleFlowInit = useCallback(\n (instance: OrgUnitTreeFlowInstance): void => {\n flowInstanceRef.current = instance;\n applyInitialViewport();\n },\n [applyInitialViewport],\n );\n\n useImperativeHandle(\n ref,\n (): OrgUnitTreeDraftEditorHandle => ({\n cancelEditing,\n saveDraft,\n startEditing,\n }),\n );\n\n useEffect((): void => {\n onStateChange({ hasDraftChanges, isEditing });\n }, [hasDraftChanges, isEditing, onStateChange]);\n\n useEffect((): void => {\n const nextParentDraft = createOrgUnitParentDraftMap(orgUnits);\n\n setParentDraft(nextParentDraft);\n setCollapsedIds(\n createDefaultCollapsedOrgUnitIds(orgUnits, nextParentDraft),\n );\n setSelectedOrgUnitId(null);\n setDraftMessage(null);\n setIsEditing(false);\n }, [orgUnits]);\n\n useEffect((): void => {\n setFlowNodes(flowElements.nodes);\n }, [flowElements.nodes]);\n\n // Apply the opening viewport once per dataset load: fitView for small trees,\n // but a readable zoom anchored on the root node for large/very-wide trees so\n // they do not collapse into an unreadable line. Runs on dataset changes only\n // (not on collapse/selection) so the user's own pan/zoom is preserved.\n useEffect((): (() => void) => {\n if (typeof window === 'undefined') {\n return (): void => undefined;\n }\n\n const frame = window.requestAnimationFrame((): void => {\n applyInitialViewport();\n });\n\n return (): void => window.cancelAnimationFrame(frame);\n }, [applyInitialViewport, orgUnits]);\n\n const assignDraftParent = useCallback(\n (orgUnitId: string, parentId: string | null): void => {\n setParentDraft((currentDraft) => {\n const result = assignOrgUnitDraftParent({\n orgUnitId,\n parentDraft: currentDraft,\n parentId,\n });\n\n setDraftMessage(result.message);\n\n return result.parentDraft;\n });\n },\n [],\n );\n\n const handleConnect = useCallback(\n (connection: Connection): void => {\n if (!isEditing || !connection.target || !connection.source) {\n return;\n }\n\n const nextParentId =\n connection.source === ORG_TREE_ROOT_ID ? null : connection.source;\n\n if (connection.target === ORG_TREE_ROOT_ID) {\n setDraftMessage('根節點不能搬移到其他節點下。');\n return;\n }\n\n assignDraftParent(connection.target, nextParentId);\n },\n [assignDraftParent, isEditing],\n );\n\n const handleNodeChanges = useCallback<OnNodesChange<OrgUnitTreeNode>>(\n (changes): void => {\n if (!isEditing) {\n return;\n }\n\n setFlowNodes((currentNodes) =>\n applyNodeChanges(changes, [...currentNodes]),\n );\n },\n [isEditing],\n );\n\n const handleNodeDragStop = useCallback<OnNodeDrag<OrgUnitTreeNode>>(\n (event, node, nodes): void => {\n if (!isEditing || node.id === ORG_TREE_ROOT_ID) {\n return;\n }\n\n const nearestParent =\n readNearestParentNodeIdFromPointer(event, node.id) ??\n readNearestParentNodeId(node, nodes);\n\n if (nearestParent === undefined) {\n setDraftMessage('拖曳到目標父節點附近,或從父節點拉線到子節點。');\n return;\n }\n\n assignDraftParent(\n node.id,\n nearestParent === ORG_TREE_ROOT_ID ? null : nearestParent,\n );\n },\n [assignDraftParent, isEditing],\n );\n\n function startEditing(): void {\n setIsEditing(true);\n setParentDraft(createOrgUnitParentDraftMap(orgUnits));\n setDraftMessage('已進入編輯模式,拖曳節點或拉線只會更新前端草稿。');\n }\n\n function cancelEditing(): void {\n setIsEditing(false);\n setParentDraft(createOrgUnitParentDraftMap(orgUnits));\n setDraftMessage('已取消草稿變更。');\n }\n\n async function saveDraft(): Promise<void> {\n if (!onSaveDraft) {\n setDraftMessage('批次儲存 API 尚未接上,草稿仍保留在前端。');\n return;\n }\n\n await onSaveDraft(draftChanges);\n setIsEditing(false);\n setDraftMessage('組織樹草稿已儲存。');\n }\n\n return (\n <div className={styles.orgTreeEditor}>\n <div className={styles.orgTreeSummary}>\n <Typography color=\"text-neutral\" variant=\"caption\">\n {draftMessage ??\n (hasDraftChanges\n ? `目前有 ${draftChanges.length} 筆父子關係草稿變更。`\n : '目前沒有草稿變更。')}\n </Typography>\n {hasDraftChanges ? (\n <ul className={styles.orgTreeChangeList}>\n {draftChanges.map((change) => (\n <li key={change.orgUnitId}>\n {readOrgUnitName(change.orgUnitId, orgUnitsById)}\n {':'}\n {readOrgUnitName(change.previousParentId, orgUnitsById)}\n {' -> '}\n {readOrgUnitName(change.parentId, orgUnitsById)}\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n <div className={styles.orgTreeCanvas}>\n <ReactFlow\n connectionMode={ConnectionMode.Strict}\n edges={[...flowElements.edges]}\n fitViewOptions={{ minZoom, padding: 0.18 }}\n isValidConnection={(connection): boolean =>\n isOrgTreeConnectionValid(\n { source: connection.source, target: connection.target },\n parentDraft,\n )\n }\n maxZoom={ORG_TREE_MAX_ZOOM}\n minZoom={minZoom}\n nodeTypes={orgUnitTreeNodeTypes}\n nodes={[...flowNodes]}\n nodesConnectable={isEditing}\n nodesDraggable={isEditing}\n onConnect={handleConnect}\n onInit={handleFlowInit}\n onNodeClick={(_, node): void => {\n setSelectedOrgUnitId(node.id === ORG_TREE_ROOT_ID ? null : node.id);\n }}\n onNodeDoubleClick={(_, node): void => {\n if (node.id !== ORG_TREE_ROOT_ID) {\n const orgUnit = orgUnitsById.get(node.id);\n\n if (orgUnit) {\n onEditOrgUnit(orgUnit);\n }\n }\n }}\n onNodeDragStop={handleNodeDragStop}\n onNodesChange={handleNodeChanges}\n onPaneClick={(): void => setSelectedOrgUnitId(null)}\n panOnDrag\n proOptions={{ hideAttribution: true }}\n >\n <Background />\n <Controls />\n {showMiniMap ? <MiniMap pannable zoomable /> : null}\n </ReactFlow>\n </div>\n </div>\n );\n});\n\nfunction OrgUnitTreeNodeCard({\n data,\n selected,\n}: NodeProps<OrgUnitTreeNode>): ReactElement {\n return (\n <div\n className={[\n styles.orgTreeNode,\n data.isSyntheticRoot ? styles.orgTreeNodeRoot : '',\n data.changed ? styles.orgTreeNodeChanged : '',\n data.deleted ? styles.orgTreeNodeDeleted : '',\n selected ? styles.orgTreeNodeSelected : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {data.isSyntheticRoot ? null : (\n <Handle\n id=\"target\"\n isConnectable={data.isEditing}\n position={Position.Top}\n type=\"target\"\n />\n )}\n <Handle\n id=\"source\"\n isConnectable={data.isEditing}\n position={Position.Bottom}\n type=\"source\"\n />\n <div className={styles.orgTreeNodeHeader}>\n <Typography\n component=\"span\"\n ellipsis\n title={data.name}\n variant=\"label-primary\"\n >\n {data.name}\n </Typography>\n {data.changed ? (\n <span className={styles.orgTreeNodeBadge}>草稿</span>\n ) : null}\n </div>\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n title={data.code}\n variant=\"caption\"\n >\n {data.isSyntheticRoot\n ? '根節點容器'\n : `${data.typeLabel} · ${data.code}`}\n </Typography>\n {data.isSyntheticRoot ? null : (\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n title={data.parentLabel}\n variant=\"caption\"\n >\n 上層:{data.parentLabel}\n </Typography>\n )}\n <div className={`${styles.orgTreeNodeActions} nodrag`}>\n {data.childCount > 0 ? (\n <Button\n onClick={(event): void => {\n event.stopPropagation();\n data.onToggleCollapse(data.orgUnitId ?? ORG_TREE_ROOT_ID);\n }}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n {data.collapsed\n ? `展開 (${data.childCount})`\n : `收合 (${data.childCount})`}\n </Button>\n ) : null}\n {data.isSyntheticRoot ? (\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => data.onCreateChild(null)}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 新增根節點\n </Button>\n ) : (\n <>\n <Button\n icon={EditIcon}\n iconType=\"leading\"\n onClick={(): void => {\n if (data.orgUnitId) {\n data.onEdit(data.orgUnitId);\n }\n }}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 編輯\n </Button>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => data.onCreateChild(data.orgUnitId)}\n size=\"sub\"\n variant=\"base-secondary\"\n >\n 新增子節點\n </Button>\n </>\n )}\n </div>\n </div>\n );\n}\n\nfunction buildOrgUnitChildrenMap(\n orgUnits: readonly OrgUnitRecord[],\n parentDraft: OrgUnitParentDraftMap,\n): ReadonlyMap<string, readonly string[]> {\n const childrenMap = new Map<string, readonly string[]>();\n\n orgUnits.forEach((orgUnit): void => {\n const parentKey = parentDraft.get(orgUnit.id) ?? ORG_TREE_ROOT_ID;\n\n childrenMap.set(parentKey, [\n ...(childrenMap.get(parentKey) ?? []),\n orgUnit.id,\n ]);\n });\n\n return childrenMap;\n}\n\nfunction collectVisibleOrgUnitIds({\n childrenMap,\n collapsedIds,\n}: {\n readonly childrenMap: ReadonlyMap<string, readonly string[]>;\n readonly collapsedIds: ReadonlySet<string>;\n}): ReadonlySet<string> {\n const visible = new Set<string>();\n\n const visit = (nodeId: string): void => {\n if (collapsedIds.has(nodeId)) {\n return;\n }\n\n (childrenMap.get(nodeId) ?? []).forEach((childId): void => {\n visible.add(childId);\n visit(childId);\n });\n };\n\n visit(ORG_TREE_ROOT_ID);\n\n return visible;\n}\n\nfunction createDefaultCollapsedOrgUnitIds(\n orgUnits: readonly OrgUnitRecord[],\n parentDraft: OrgUnitParentDraftMap,\n): ReadonlySet<string> {\n if (orgUnits.length <= ORG_TREE_LARGE_NODE_COUNT) {\n return new Set<string>();\n }\n\n const childrenMap = buildOrgUnitChildrenMap(orgUnits, parentDraft);\n const collapsed = new Set<string>();\n\n const visit = (nodeId: string, depth: number): void => {\n const children = childrenMap.get(nodeId) ?? [];\n\n if (children.length === 0) {\n return;\n }\n\n if (depth >= ORG_TREE_INITIAL_EXPAND_DEPTH) {\n collapsed.add(nodeId);\n }\n\n children.forEach((childId): void => visit(childId, depth + 1));\n };\n\n visit(ORG_TREE_ROOT_ID, 0);\n\n return collapsed;\n}\n\nfunction createOrgUnitTreeFlowElements({\n collapsedIds,\n isEditing,\n onCreateChild,\n onEditOrgUnit,\n onToggleCollapse,\n orgUnits,\n orgUnitsById,\n parentDraft,\n selectedOrgUnitId,\n}: {\n readonly collapsedIds: ReadonlySet<string>;\n readonly isEditing: boolean;\n readonly onCreateChild: (parentId: string | null) => void;\n readonly onEditOrgUnit: (orgUnitId: string) => void;\n readonly onToggleCollapse: (nodeId: string) => void;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly orgUnitsById: ReadonlyMap<string, OrgUnitRecord>;\n readonly parentDraft: OrgUnitParentDraftMap;\n readonly selectedOrgUnitId: string | null;\n}): OrgUnitTreeFlowElements {\n const childrenMap = buildOrgUnitChildrenMap(orgUnits, parentDraft);\n const visibleIds = collectVisibleOrgUnitIds({ childrenMap, collapsedIds });\n const visibleOrgUnits = orgUnits.filter((orgUnit) =>\n visibleIds.has(orgUnit.id),\n );\n const readChildCount = (nodeId: string): number =>\n childrenMap.get(nodeId)?.length ?? 0;\n\n const graph = new dagre.graphlib.Graph();\n graph.setDefaultEdgeLabel(() => ({}));\n graph.setGraph({ marginx: 36, marginy: 36, nodesep: 44, rankdir: 'TB' });\n graph.setNode(ORG_TREE_ROOT_ID, {\n height: ORG_TREE_ROOT_HEIGHT,\n width: ORG_TREE_ROOT_WIDTH,\n });\n visibleOrgUnits.forEach((orgUnit): void => {\n graph.setNode(orgUnit.id, {\n height: ORG_TREE_NODE_HEIGHT,\n width: ORG_TREE_NODE_WIDTH,\n });\n });\n visibleOrgUnits.forEach((orgUnit): void => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n graph.setEdge(parentId ?? ORG_TREE_ROOT_ID, orgUnit.id);\n });\n dagre.layout(graph);\n\n const graphLabel = graph.graph();\n const bounds = {\n height: graphLabel.height ?? 0,\n width: graphLabel.width ?? 0,\n };\n const rootGraphNode = graph.node(ORG_TREE_ROOT_ID) as\n | Readonly<{ x: number; y: number }>\n | undefined;\n const rootCenter = {\n x: rootGraphNode?.x ?? 0,\n y: rootGraphNode?.y ?? 0,\n };\n\n const rootNode = createOrgUnitTreeNode({\n data: {\n changed: false,\n childCount: readChildCount(ORG_TREE_ROOT_ID),\n code: ORG_TREE_ROOT_ID,\n collapsed: collapsedIds.has(ORG_TREE_ROOT_ID),\n deleted: false,\n isEditing,\n isSyntheticRoot: true,\n name: '組織根節點',\n onCreateChild,\n onEdit: onEditOrgUnit,\n onToggleCollapse,\n orgUnitId: null,\n parentLabel: '',\n path: '',\n typeLabel: '',\n },\n graph,\n height: ORG_TREE_ROOT_HEIGHT,\n id: ORG_TREE_ROOT_ID,\n selected: selectedOrgUnitId === null,\n width: ORG_TREE_ROOT_WIDTH,\n });\n const orgNodes = visibleOrgUnits.map((orgUnit): OrgUnitTreeNode => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n const parentLabel = readOrgUnitName(parentId, orgUnitsById);\n\n return createOrgUnitTreeNode({\n data: {\n changed: parentId !== orgUnit.parentId,\n childCount: readChildCount(orgUnit.id),\n code: orgUnit.code,\n collapsed: collapsedIds.has(orgUnit.id),\n deleted: Boolean(orgUnit.deletedAt),\n isEditing,\n isSyntheticRoot: false,\n name: orgUnit.name,\n onCreateChild,\n onEdit: onEditOrgUnit,\n onToggleCollapse,\n orgUnitId: orgUnit.id,\n parentLabel,\n path: orgUnit.path,\n typeLabel: readOrgUnitTypeLabel(orgUnit.type),\n },\n graph,\n height: ORG_TREE_NODE_HEIGHT,\n id: orgUnit.id,\n selected: selectedOrgUnitId === orgUnit.id,\n width: ORG_TREE_NODE_WIDTH,\n });\n });\n const edges = visibleOrgUnits.map((orgUnit): OrgUnitTreeEdge => {\n const parentId = parentDraft.get(orgUnit.id) ?? null;\n const changed = parentId !== orgUnit.parentId;\n\n return {\n animated: isEditing && changed,\n data: {},\n id: `org-tree-edge-${parentId ?? 'root'}-${orgUnit.id}`,\n source: parentId ?? ORG_TREE_ROOT_ID,\n sourceHandle: 'source',\n style: changed\n ? { stroke: 'var(--mzn-color-primary, #0057ff)', strokeWidth: 2 }\n : undefined,\n target: orgUnit.id,\n targetHandle: 'target',\n type: 'smoothstep',\n };\n });\n\n return {\n bounds,\n edges,\n nodes: [rootNode, ...orgNodes],\n rootCenter,\n };\n}\n\nfunction createOrgUnitTreeNode({\n data,\n graph,\n height,\n id,\n selected,\n width,\n}: {\n readonly data: OrgUnitTreeFlowData;\n readonly graph: dagre.graphlib.Graph;\n readonly height: number;\n readonly id: string;\n readonly selected: boolean;\n readonly width: number;\n}): OrgUnitTreeNode {\n const positionedNode = graph.node(id) as\n | Readonly<{ x: number; y: number }>\n | undefined;\n\n return {\n data,\n height,\n id,\n initialHeight: height,\n initialWidth: width,\n position: positionedNode\n ? {\n x: positionedNode.x - width / 2,\n y: positionedNode.y - height / 2,\n }\n : { x: 0, y: 0 },\n selected,\n sourcePosition: Position.Bottom,\n targetPosition: Position.Top,\n type: 'orgUnit',\n width,\n };\n}\n\nfunction readNearestParentNodeId(\n draggedNode: OrgUnitTreeNode,\n nodes: readonly OrgUnitTreeNode[],\n): string | undefined {\n const draggedCenter = readNodeCenter(draggedNode);\n const candidates = nodes\n .filter((node) => node.id !== draggedNode.id)\n .map(\n (node): Readonly<{ distance: number; id: string }> => ({\n distance: readDistance(draggedCenter, readNodeCenter(node)),\n id: node.id,\n }),\n )\n .filter((candidate) => candidate.distance <= ORG_TREE_DROP_DISTANCE)\n .sort((left, right) => left.distance - right.distance);\n\n return candidates[0]?.id;\n}\n\nfunction readNearestParentNodeIdFromPointer(\n event: unknown,\n draggedNodeId: string,\n): string | undefined {\n const point = readPointerPoint(event);\n\n if (!point) {\n return undefined;\n }\n\n const candidates = Array.from(\n document.querySelectorAll<HTMLElement>('.react-flow__node[data-id]'),\n )\n .map((element): Readonly<{ distance: number; id: string }> | null => {\n const id = element.dataset['id'];\n\n if (!id || id === draggedNodeId) {\n return null;\n }\n\n const rect = element.getBoundingClientRect();\n const center = {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n\n return {\n distance: readDistance(point, center),\n id,\n };\n })\n .filter(\n (\n candidate,\n ): candidate is Readonly<{ distance: number; id: string }> =>\n Boolean(candidate),\n )\n .filter((candidate) => candidate.distance <= ORG_TREE_DROP_DISTANCE)\n .sort((left, right) => left.distance - right.distance);\n\n return candidates[0]?.id;\n}\n\nfunction readPointerPoint(\n event: unknown,\n): Readonly<{ x: number; y: number }> | null {\n if (!isPointerEventLike(event)) {\n return null;\n }\n\n return { x: event.clientX, y: event.clientY };\n}\n\nfunction isPointerEventLike(\n event: unknown,\n): event is Readonly<{ clientX: number; clientY: number }> {\n return (\n typeof event === 'object' &&\n event !== null &&\n 'clientX' in event &&\n 'clientY' in event &&\n typeof event.clientX === 'number' &&\n typeof event.clientY === 'number'\n );\n}\n\nfunction readNodeCenter(\n node: OrgUnitTreeNode,\n): Readonly<{ x: number; y: number }> {\n return {\n x: node.position.x + (node.width ?? ORG_TREE_NODE_WIDTH) / 2,\n y: node.position.y + (node.height ?? ORG_TREE_NODE_HEIGHT) / 2,\n };\n}\n\nfunction readDistance(\n source: Readonly<{ x: number; y: number }>,\n target: Readonly<{ x: number; y: number }>,\n): number {\n return Math.hypot(source.x - target.x, source.y - target.y);\n}\n\nfunction isOrgTreeConnectionValid(\n connection: Readonly<{ source: string | null; target: string | null }>,\n parentDraft: OrgUnitParentDraftMap,\n): boolean {\n if (!connection.source || !connection.target) {\n return false;\n }\n\n if (connection.target === ORG_TREE_ROOT_ID) {\n return false;\n }\n\n return (\n readOrgUnitParentValidationMessage({\n orgUnitId: connection.target,\n parentDraft,\n parentId:\n connection.source === ORG_TREE_ROOT_ID ? null : connection.source,\n }) === null\n );\n}\n\nfunction readOrgUnitName(\n orgUnitId: string | null,\n orgUnitsById: ReadonlyMap<string, OrgUnitRecord>,\n): string {\n if (!orgUnitId) {\n return '根節點';\n }\n\n const orgUnit = orgUnitsById.get(orgUnitId);\n\n return orgUnit ? `${orgUnit.name} · ${orgUnit.code}` : '未知組織';\n}\n\nfunction readOrgUnitTypeLabel(type: OrgUnitType): string {\n const normalizedType = type.toUpperCase() as Uppercase<OrgUnitType>;\n\n return ORG_UNIT_TYPE_LABELS[normalizedType] ?? '未知類型';\n}\n",".tableIntroActions {\n display: inline-flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n flex: 0 0 auto;\n max-width: 100%;\n}\n\n.tableIntroActions > :global(.mzn-button) {\n flex: 0 0 auto;\n}\n\n.modalFields {\n display: grid;\n gap: 12px;\n width: 100%;\n\n :global(.mzn-form-field--horizontal) {\n align-items: flex-start;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label-area) {\n flex: 0 0 120px;\n width: 120px;\n min-width: 120px;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label) {\n flex-wrap: nowrap;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__data-entry) {\n flex: 1 1 auto;\n align-items: stretch;\n min-width: 0;\n max-width: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-auto-complete) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-picker),\n :global(.mzn-select),\n :global(.mzn-select-trigger),\n :global(.mzn-text-field) {\n width: 100%;\n min-width: 0 !important;\n }\n\n :global(.mzn-select-trigger__input) {\n width: 100%;\n min-width: 0 !important;\n text-overflow: ellipsis;\n }\n}\n\n.tableIntro {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n min-width: 0;\n max-width: 100%;\n margin-bottom: 12px;\n}\n\n.tableIntro > div {\n min-width: 0;\n}\n\n.tableIntro > div > * {\n overflow-wrap: anywhere;\n}\n\n.tableFrame {\n width: 100%;\n min-width: 0;\n max-width: 100%;\n overflow-x: auto;\n}\n\n.orgFilterArea {\n margin-bottom: 12px;\n\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n flex-wrap: nowrap;\n }\n\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-form-field__label-area) {\n display: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n}\n\n.membershipFilterArea {\n overflow-x: auto;\n\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n align-items: center;\n flex-wrap: nowrap !important;\n min-width: 760px;\n }\n\n :global(.mzn-filter),\n :global(.mzn-filter-area__filter) {\n flex: 1 1 0;\n min-width: 0;\n }\n\n :global(.mzn-filter:nth-child(3)),\n :global(.mzn-filter-area__filter:nth-child(3)) {\n flex: 0 0 180px;\n }\n\n :global(.mzn-autocomplete) {\n width: 100%;\n min-width: 0;\n }\n}\n\n.scopeLabel {\n display: inline-flex;\n align-items: center;\n min-height: 24px;\n}\n\n@media (max-width: 960px) {\n .tableIntro {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .tableIntroActions {\n justify-content: flex-start;\n }\n\n .tableIntroActions {\n flex-wrap: wrap;\n }\n\n .orgFilterArea {\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n flex-wrap: wrap;\n }\n }\n\n .membershipFilterArea {\n :global(.mzn-filter-line),\n :global(.mzn-filter-area__line) {\n align-items: stretch;\n flex-wrap: nowrap !important;\n }\n\n :global(.mzn-form-field--horizontal) {\n align-items: center;\n }\n }\n}\n","'use client';\n\nimport {\n ChangeEvent,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n AutoComplete,\n Button,\n DatePicker,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n CloseIcon,\n EditIcon,\n PlusIcon,\n SaveIcon,\n} from '@mezzanine-ui/icons';\nimport type { IconDefinition } from '@mezzanine-ui/icons';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport {\n MemberOption,\n OrgUnitPicker,\n OrgUnitOption,\n PositionOption,\n PositionPicker,\n MemberPicker,\n readMemberOption,\n readOrgUnitOption,\n readPositionOption,\n} from '../../../components/admin-pickers';\nimport {\n commitOrgUnitTreeDraft,\n createManagerResolution,\n createMembership,\n createOrgUnit,\n createPosition,\n deleteManagerResolution,\n deleteMembership,\n deleteOrgUnit,\n ManagerResolutionRecord,\n ManagerResolutionScopeType,\n MembershipRecord,\n OrgUnitRecord,\n OrgUnitType,\n PositionRecord,\n readOrganizationDashboard,\n updateManagerResolution,\n updateMembership,\n updateOrgUnit,\n updatePosition,\n} from '@rytass/bpm-core-client/organization';\nimport { MemberProfileRecord, resolveMembers } from '@rytass/bpm-core-client';\nimport {\n OrgUnitTreeDraftEditor,\n OrgUnitTreeDraftEditorHandle,\n OrgUnitTreeDraftEditorState,\n} from '../../../components/org-unit-tree-draft-editor';\nimport type { OrgUnitHierarchyDraftChange } from '../../../lib/org-tree-draft';\nimport styles from './orgs.module.scss';\n\ntype AdminOrgTab = 'MANAGERS' | 'MEMBERSHIPS' | 'ORG_UNITS' | 'POSITIONS';\ntype OrgUnitViewMode = 'FLOW' | 'TABLE';\n\nconst INITIAL_ORG_TREE_EDITOR_STATE: OrgUnitTreeDraftEditorState = {\n hasDraftChanges: false,\n isEditing: false,\n};\n\ntype OrgUnitRow = Readonly<\n Record<string, unknown> &\n OrgUnitRecord & {\n key: string;\n parentName: string;\n typeLabel: string;\n }\n>;\n\ntype PositionRow = Readonly<\n Record<string, unknown> &\n PositionRecord & {\n key: string;\n }\n>;\n\ntype MembershipRow = Readonly<\n Record<string, unknown> &\n MembershipRecord & {\n key: string;\n memberName: string;\n orgUnitName: string;\n positionName: string;\n }\n>;\n\ntype ManagerResolutionRow = Readonly<\n Record<string, unknown> &\n ManagerResolutionRecord & {\n key: string;\n managerName: string;\n scopeLabel: string;\n }\n>;\n\ntype OrgModalState = Readonly<{\n parentId?: string | null;\n record: OrgUnitRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype PositionModalState = Readonly<{\n record: PositionRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype MembershipModalState = Readonly<{\n record: MembershipRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype ManagerModalState = Readonly<{\n record: ManagerResolutionRecord | null;\n type: 'CREATE' | 'EDIT';\n}>;\n\ntype DeleteConfirmationState = Readonly<{\n confirmText: string;\n description: string;\n id: string;\n title: string;\n type: 'MANAGER_RESOLUTION' | 'MEMBERSHIP' | 'ORG_UNIT';\n}>;\n\ntype OrgUnitTypeOption = Readonly<{\n id: OrgUnitType;\n name: string;\n}>;\n\ntype OrgUnitTypeFilterOption = Readonly<{\n id: 'ALL' | OrgUnitType;\n name: string;\n}>;\n\ntype ScopeTypeOption = Readonly<{\n id: ManagerResolutionScopeType;\n name: string;\n}>;\n\ntype ScopeTypeFilterOption = Readonly<{\n id: 'ALL' | ManagerResolutionScopeType;\n name: string;\n}>;\n\ntype ActiveFilterOption = Readonly<{\n activeOnly: boolean;\n id: 'ACTIVE' | 'ALL';\n name: string;\n}>;\n\ntype PrimaryOption = Readonly<{\n id: 'false' | 'true';\n name: string;\n value: boolean;\n}>;\n\ntype TablePaginationState = Readonly<{\n onPageChange: (page: number) => void;\n onPageSizeChange: (pageSize: number) => void;\n page: number;\n pageSize: number;\n total: number;\n}>;\n\nconst ORG_UNIT_TYPES: readonly OrgUnitTypeOption[] = [\n { id: 'COMPANY', name: '公司' },\n { id: 'DIVISION', name: '事業群' },\n { id: 'DEPARTMENT', name: '部門' },\n { id: 'TEAM', name: '小組' },\n];\nconst ALL_ORG_UNIT_TYPE_FILTER: OrgUnitTypeFilterOption = {\n id: 'ALL',\n name: '全部類型',\n};\nconst ORG_UNIT_TYPE_FILTER_OPTIONS: readonly OrgUnitTypeFilterOption[] = [\n ALL_ORG_UNIT_TYPE_FILTER,\n ...ORG_UNIT_TYPES,\n];\n\nconst SCOPE_TYPES: readonly ScopeTypeOption[] = [\n { id: 'MEMBER', name: '指定會員' },\n { id: 'ORG_UNIT', name: '指定組織' },\n { id: 'POSITION', name: '指定職位' },\n];\nconst ALL_SCOPE_TYPE_FILTER: ScopeTypeFilterOption = {\n id: 'ALL',\n name: '全部範圍',\n};\nconst SCOPE_TYPE_FILTER_OPTIONS: readonly ScopeTypeFilterOption[] = [\n ALL_SCOPE_TYPE_FILTER,\n ...SCOPE_TYPES,\n];\nconst ALL_ACTIVE_FILTER: ActiveFilterOption = {\n activeOnly: false,\n id: 'ALL',\n name: '全部狀態',\n};\nconst ACTIVE_FILTER_OPTIONS: readonly ActiveFilterOption[] = [\n ALL_ACTIVE_FILTER,\n { activeOnly: true, id: 'ACTIVE', name: '目前有效' },\n];\n\nconst PRIMARY_OPTIONS: readonly PrimaryOption[] = [\n { id: 'true', name: '主要歸屬', value: true },\n { id: 'false', name: '一般歸屬', value: false },\n];\nconst ORGANIZATION_TABLE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst ORG_UNIT_TABLE_MIN_WIDTH = 1368;\nconst POSITION_TABLE_MIN_WIDTH = 908;\nconst MEMBERSHIP_TABLE_MIN_WIDTH = 1292;\nconst MANAGER_TABLE_MIN_WIDTH = 1124;\n\n\nexport function AdminOrgsView(): ReactElement {\n const [activeTab, setActiveTab] = useState<AdminOrgTab>('ORG_UNITS');\n const [deleteConfirmation, setDeleteConfirmation] =\n useState<DeleteConfirmationState | null>(null);\n const [lastDeleteConfirmation, setLastDeleteConfirmation] =\n useState<DeleteConfirmationState | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [managerModal, setManagerModal] = useState<ManagerModalState | null>(\n null,\n );\n const [managerActiveFilter, setManagerActiveFilter] =\n useState<ActiveFilterOption>(ALL_ACTIVE_FILTER);\n const [managerPage, setManagerPage] = useState(1);\n const [managerPageSize, setManagerPageSize] = useState(10);\n const [managerScopeTypeFilter, setManagerScopeTypeFilter] =\n useState<ScopeTypeFilterOption>(ALL_SCOPE_TYPE_FILTER);\n const [managerTotalCount, setManagerTotalCount] = useState(0);\n const [memberProfiles, setMemberProfiles] = useState<\n readonly MemberProfileRecord[]\n >([]);\n const [membershipActiveFilter, setMembershipActiveFilter] =\n useState<ActiveFilterOption | null>(null);\n const [membershipModal, setMembershipModal] =\n useState<MembershipModalState | null>(null);\n const [membershipOrgUnitFilter, setMembershipOrgUnitFilter] =\n useState<OrgUnitOption | null>(null);\n const [membershipPage, setMembershipPage] = useState(1);\n const [membershipPageSize, setMembershipPageSize] = useState(10);\n const [membershipPositionFilter, setMembershipPositionFilter] =\n useState<PositionOption | null>(null);\n const [membershipTotalCount, setMembershipTotalCount] = useState(0);\n const [orgModal, setOrgModal] = useState<OrgModalState | null>(null);\n const [orgUnitPage, setOrgUnitPage] = useState(1);\n const [orgUnitPageSize, setOrgUnitPageSize] = useState(10);\n const [orgUnitSearchText, setOrgUnitSearchText] = useState('');\n const [orgUnitTotalCount, setOrgUnitTotalCount] = useState(0);\n const [orgUnitTypeFilter, setOrgUnitTypeFilter] =\n useState<OrgUnitTypeFilterOption>(ALL_ORG_UNIT_TYPE_FILTER);\n const [orgUnitViewMode, setOrgUnitViewMode] =\n useState<OrgUnitViewMode>('TABLE');\n const [orgUnits, setOrgUnits] = useState<readonly OrgUnitRecord[]>([]);\n const [visibleOrgUnits, setVisibleOrgUnits] = useState<\n readonly OrgUnitRecord[]\n >([]);\n const [visiblePositions, setVisiblePositions] = useState<\n readonly PositionRecord[]\n >([]);\n const [positionModal, setPositionModal] = useState<PositionModalState | null>(\n null,\n );\n const [positionPage, setPositionPage] = useState(1);\n const [positionPageSize, setPositionPageSize] = useState(10);\n const [positionSearchText, setPositionSearchText] = useState('');\n const [positionTotalCount, setPositionTotalCount] = useState(0);\n const [positions, setPositions] = useState<readonly PositionRecord[]>([]);\n const [visibleManagerResolutions, setVisibleManagerResolutions] = useState<\n readonly ManagerResolutionRecord[]\n >([]);\n const [visibleMemberships, setVisibleMemberships] = useState<\n readonly MembershipRecord[]\n >([]);\n const [saving, setSaving] = useState(false);\n\n useEffect((): void => {\n if (deleteConfirmation) {\n setLastDeleteConfirmation(deleteConfirmation);\n }\n }, [deleteConfirmation]);\n\n const visibleDeleteConfirmation =\n deleteConfirmation ?? lastDeleteConfirmation;\n\n const refreshOrganization = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const dashboard = await readOrganizationDashboard({\n managerActiveOnly: managerActiveFilter.activeOnly,\n managerPage,\n managerPageSize,\n managerScopeType:\n managerScopeTypeFilter.id === 'ALL'\n ? null\n : managerScopeTypeFilter.id,\n membershipActiveOnly: membershipActiveFilter?.activeOnly ?? false,\n membershipOrgUnitId: membershipOrgUnitFilter?.id ?? null,\n membershipPage,\n membershipPageSize,\n membershipPositionId: membershipPositionFilter?.id ?? null,\n orgUnitPage,\n orgUnitPageSize,\n orgUnitSearchText,\n orgUnitType:\n orgUnitTypeFilter.id === 'ALL' ? null : orgUnitTypeFilter.id,\n positionPage,\n positionPageSize,\n positionSearchText,\n });\n const memberIds = readReferencedMemberIds(\n dashboard.memberships,\n dashboard.managerResolutions,\n );\n const profiles = await resolveMembers(memberIds);\n\n setMemberProfiles(profiles);\n setOrgUnits(dashboard.orgUnits);\n setOrgUnitTotalCount(dashboard.orgUnitCount);\n setVisibleOrgUnits(dashboard.filteredOrgUnits);\n setPositions(dashboard.positions);\n setPositionTotalCount(dashboard.positionCount);\n setVisiblePositions(dashboard.filteredPositions);\n setMembershipTotalCount(dashboard.membershipCount);\n setVisibleMemberships(dashboard.filteredMemberships);\n setManagerTotalCount(dashboard.managerResolutionCount);\n setVisibleManagerResolutions(dashboard.filteredManagerResolutions);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [\n managerActiveFilter,\n managerPage,\n managerPageSize,\n managerScopeTypeFilter,\n membershipActiveFilter,\n membershipOrgUnitFilter,\n membershipPage,\n membershipPageSize,\n membershipPositionFilter,\n orgUnitPage,\n orgUnitPageSize,\n orgUnitSearchText,\n orgUnitTypeFilter,\n positionPage,\n positionPageSize,\n positionSearchText,\n ]);\n\n useEffect((): void => {\n void refreshOrganization();\n }, [refreshOrganization]);\n\n const orgUnitsById = useMemo(\n (): ReadonlyMap<string, OrgUnitRecord> =>\n new Map(orgUnits.map((orgUnit) => [orgUnit.id, orgUnit])),\n [orgUnits],\n );\n const positionsById = useMemo(\n (): ReadonlyMap<string, PositionRecord> =>\n new Map(positions.map((position) => [position.id, position])),\n [positions],\n );\n const membersById = useMemo(\n (): ReadonlyMap<string, MemberProfileRecord> =>\n new Map(memberProfiles.map((member) => [member.memberId, member])),\n [memberProfiles],\n );\n\n const orgRows = useMemo(\n (): OrgUnitRow[] =>\n visibleOrgUnits.map((orgUnit) => ({\n ...orgUnit,\n key: orgUnit.id,\n parentName: orgUnit.parentId\n ? readOrgUnitLabel(orgUnitsById.get(orgUnit.parentId))\n : '根節點',\n typeLabel: readOrgUnitTypeLabel(orgUnit.type),\n })),\n [visibleOrgUnits, orgUnitsById],\n );\n const positionRows = useMemo(\n (): PositionRow[] =>\n visiblePositions.map((position) => ({\n ...position,\n key: position.id,\n })),\n [visiblePositions],\n );\n const membershipRows = useMemo(\n (): MembershipRow[] =>\n visibleMemberships.map((membership) => ({\n ...membership,\n key: membership.id,\n memberName: readMemberLabel(membersById.get(membership.memberId)),\n orgUnitName: readOrgUnitLabel(orgUnitsById.get(membership.orgUnitId)),\n positionName: membership.positionId\n ? readPositionLabel(positionsById.get(membership.positionId))\n : '未指定',\n })),\n [membersById, visibleMemberships, orgUnitsById, positionsById],\n );\n const managerRows = useMemo(\n (): ManagerResolutionRow[] =>\n visibleManagerResolutions.map((resolution) => ({\n ...resolution,\n key: resolution.id,\n managerName: readMemberLabel(\n membersById.get(resolution.managerMemberId),\n ),\n scopeLabel: readScopeLabel(resolution, {\n membersById,\n orgUnitsById,\n positionsById,\n }),\n })),\n [visibleManagerResolutions, membersById, orgUnitsById, positionsById],\n );\n\n const orgActions = useMemo(\n (): TableActions<OrgUnitRow> => ({\n render: (record): ReturnType<TableActions<OrgUnitRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setOrgModal({ record, type: 'EDIT' }),\n },\n {\n name: '停用',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '停用組織',\n description: `停用「${record.name}」後,這個組織節點將不再出現在可用組織清單中。`,\n id: record.id,\n title: '停用組織節點',\n type: 'ORG_UNIT',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n const positionActions = useMemo(\n (): TableActions<PositionRow> => ({\n render: (record): ReturnType<TableActions<PositionRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setPositionModal({ record, type: 'EDIT' }),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [],\n );\n const membershipActions = useMemo(\n (): TableActions<MembershipRow> => ({\n render: (record): ReturnType<TableActions<MembershipRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setMembershipModal({ record, type: 'EDIT' }),\n },\n {\n name: '刪除',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '刪除歸屬',\n description: `刪除「${record.memberName}」在「${record.orgUnitName}」的會員歸屬。`,\n id: record.id,\n title: '刪除會員歸屬',\n type: 'MEMBERSHIP',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n const managerActions = useMemo(\n (): TableActions<ManagerResolutionRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ManagerResolutionRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setManagerModal({ record, type: 'EDIT' }),\n },\n {\n name: '刪除',\n onClick: (): void =>\n setDeleteConfirmation({\n confirmText: '刪除主管規則',\n description: `刪除「${record.scopeLabel}」指派給「${record.managerName}」的主管解析規則。`,\n id: record.id,\n title: '刪除主管解析規則',\n type: 'MANAGER_RESOLUTION',\n }),\n variant: 'destructive-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 128,\n }),\n [],\n );\n\n function updateOrgUnitSearchText(value: string): void {\n setOrgUnitPage(1);\n setOrgUnitSearchText(value);\n }\n\n function updateOrgUnitTypeFilter(value: OrgUnitTypeFilterOption): void {\n setOrgUnitPage(1);\n setOrgUnitTypeFilter(value);\n }\n\n function updatePositionSearchText(value: string): void {\n setPositionPage(1);\n setPositionSearchText(value);\n }\n\n function updateMembershipActiveFilter(value: ActiveFilterOption | null): void {\n setMembershipPage(1);\n setMembershipActiveFilter(value);\n }\n\n function updateMembershipOrgUnitFilter(value: OrgUnitOption | null): void {\n setMembershipPage(1);\n setMembershipOrgUnitFilter(value);\n }\n\n function updateMembershipPositionFilter(value: PositionOption | null): void {\n setMembershipPage(1);\n setMembershipPositionFilter(value);\n }\n\n function updateManagerActiveFilter(value: ActiveFilterOption): void {\n setManagerPage(1);\n setManagerActiveFilter(value);\n }\n\n function updateManagerScopeTypeFilter(value: ScopeTypeFilterOption): void {\n setManagerPage(1);\n setManagerScopeTypeFilter(value);\n }\n\n function closeDeleteConfirmation(): void {\n if (saving) {\n return;\n }\n\n setDeleteConfirmation(null);\n }\n\n async function handleConfirmDelete(): Promise<void> {\n if (!deleteConfirmation) {\n return;\n }\n\n await runMutation(async (): Promise<void> => {\n if (deleteConfirmation.type === 'ORG_UNIT') {\n await deleteOrgUnit(deleteConfirmation.id);\n }\n\n if (deleteConfirmation.type === 'MEMBERSHIP') {\n await deleteMembership(deleteConfirmation.id);\n }\n\n if (deleteConfirmation.type === 'MANAGER_RESOLUTION') {\n await deleteManagerResolution(deleteConfirmation.id);\n }\n\n setDeleteConfirmation(null);\n });\n }\n\n async function saveOrgUnitTreeDraft(\n changes: readonly OrgUnitHierarchyDraftChange[],\n ): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await commitOrgUnitTreeDraft({\n moves: changes.map((change) => {\n const orgUnit = orgUnitsById.get(change.orgUnitId);\n\n return {\n baseUpdatedAt: orgUnit?.updatedAt ?? '',\n id: change.orgUnitId,\n parentId: change.parentId,\n };\n }),\n });\n await refreshOrganization();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n throw requestError;\n } finally {\n setSaving(false);\n }\n }\n\n async function runMutation(mutation: () => Promise<void>): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await mutation();\n await refreshOrganization();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"維護組織樹、職位、會員歸屬與簽核主管解析規則。\"\n title=\"組織管理\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section\n tab={\n <Tab\n activeKey={activeTab}\n onChange={(key): void => setActiveTab(readAdminOrgTab(key))}\n >\n <TabItem key=\"ORG_UNITS\">組織樹</TabItem>\n <TabItem key=\"POSITIONS\">職位</TabItem>\n <TabItem key=\"MEMBERSHIPS\">會員歸屬</TabItem>\n <TabItem key=\"MANAGERS\">簽核主管</TabItem>\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {activeTab === 'ORG_UNITS' ? (\n <OrgUnitPanel\n actions={orgActions}\n loading={loading}\n onCreate={(): void =>\n setOrgModal({ parentId: null, record: null, type: 'CREATE' })\n }\n onCreateChild={(parentId): void =>\n setOrgModal({ parentId, record: null, type: 'CREATE' })\n }\n onEditOrgUnit={(record): void =>\n setOrgModal({ record, type: 'EDIT' })\n }\n onPageChange={setOrgUnitPage}\n onSaveDraft={saveOrgUnitTreeDraft}\n onPageSizeChange={(pageSize): void => {\n setOrgUnitPage(1);\n setOrgUnitPageSize(pageSize);\n }}\n onSearchTextChange={updateOrgUnitSearchText}\n onTypeFilterChange={updateOrgUnitTypeFilter}\n orgUnits={orgUnits}\n page={orgUnitPage}\n pageSize={orgUnitPageSize}\n rows={orgRows}\n searchText={orgUnitSearchText}\n saving={saving}\n total={orgUnitTotalCount}\n typeFilter={orgUnitTypeFilter}\n viewMode={orgUnitViewMode}\n onViewModeChange={setOrgUnitViewMode}\n />\n ) : null}\n {activeTab === 'POSITIONS' ? (\n <PositionPanel\n actions={positionActions}\n loading={loading}\n onCreate={(): void =>\n setPositionModal({ record: null, type: 'CREATE' })\n }\n onPageChange={setPositionPage}\n onPageSizeChange={(pageSize): void => {\n setPositionPage(1);\n setPositionPageSize(pageSize);\n }}\n onSearchTextChange={updatePositionSearchText}\n page={positionPage}\n pageSize={positionPageSize}\n rows={positionRows}\n searchText={positionSearchText}\n total={positionTotalCount}\n />\n ) : null}\n {activeTab === 'MEMBERSHIPS' ? (\n <MembershipPanel\n actions={membershipActions}\n loading={loading}\n onCreate={(): void =>\n setMembershipModal({ record: null, type: 'CREATE' })\n }\n onActiveFilterChange={updateMembershipActiveFilter}\n onOrgUnitFilterChange={updateMembershipOrgUnitFilter}\n onPageChange={setMembershipPage}\n onPageSizeChange={(pageSize): void => {\n setMembershipPage(1);\n setMembershipPageSize(pageSize);\n }}\n onPositionFilterChange={updateMembershipPositionFilter}\n orgUnitFilter={membershipOrgUnitFilter}\n orgUnits={orgUnits}\n page={membershipPage}\n pageSize={membershipPageSize}\n positionFilter={membershipPositionFilter}\n positions={positions}\n rows={membershipRows}\n statusFilter={membershipActiveFilter}\n total={membershipTotalCount}\n />\n ) : null}\n {activeTab === 'MANAGERS' ? (\n <ManagerPanel\n actions={managerActions}\n loading={loading}\n onCreate={(): void =>\n setManagerModal({ record: null, type: 'CREATE' })\n }\n onActiveFilterChange={updateManagerActiveFilter}\n onPageChange={setManagerPage}\n onPageSizeChange={(pageSize): void => {\n setManagerPage(1);\n setManagerPageSize(pageSize);\n }}\n onScopeTypeFilterChange={updateManagerScopeTypeFilter}\n page={managerPage}\n pageSize={managerPageSize}\n rows={managerRows}\n scopeTypeFilter={managerScopeTypeFilter}\n statusFilter={managerActiveFilter}\n total={managerTotalCount}\n />\n ) : null}\n </Section>\n </SectionGroup>\n\n <OrgUnitModal\n modal={orgModal}\n onClose={(): void => setOrgModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (orgModal?.type === 'EDIT' && orgModal.record) {\n await updateOrgUnit({\n ...input,\n id: orgModal.record.id,\n metadataJson: null,\n });\n } else {\n await createOrgUnit({\n code: input.code ?? '',\n metadataJson: '{}',\n name: input.name ?? '',\n parentId: input.parentId,\n type: input.type ?? 'DEPARTMENT',\n });\n }\n setOrgModal(null);\n })\n }\n orgUnits={orgUnits}\n saving={saving}\n />\n <PositionModal\n modal={positionModal}\n onClose={(): void => setPositionModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (positionModal?.type === 'EDIT' && positionModal.record) {\n await updatePosition({\n ...input,\n id: positionModal.record.id,\n metadataJson: null,\n });\n } else {\n await createPosition({\n code: input.code ?? '',\n level: input.level ?? 0,\n metadataJson: '{}',\n name: input.name ?? '',\n });\n }\n setPositionModal(null);\n })\n }\n saving={saving}\n />\n <MembershipModal\n membersById={membersById}\n modal={membershipModal}\n onClose={(): void => setMembershipModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (membershipModal?.type === 'EDIT' && membershipModal.record) {\n await updateMembership({\n ...input,\n id: membershipModal.record.id,\n });\n } else {\n await createMembership({\n effectiveFrom: input.effectiveFrom ?? today(),\n effectiveTo: input.effectiveTo,\n isPrimary: input.isPrimary ?? false,\n memberId: input.memberId ?? '',\n orgUnitId: input.orgUnitId ?? '',\n positionId: input.positionId,\n });\n }\n setMembershipModal(null);\n })\n }\n orgUnits={orgUnits}\n positions={positions}\n saving={saving}\n />\n <ManagerResolutionModal\n membersById={membersById}\n modal={managerModal}\n onClose={(): void => setManagerModal(null)}\n onSubmit={(input): Promise<void> =>\n runMutation(async (): Promise<void> => {\n if (managerModal?.type === 'EDIT' && managerModal.record) {\n await updateManagerResolution({\n ...input,\n id: managerModal.record.id,\n });\n } else {\n await createManagerResolution({\n effectiveFrom: input.effectiveFrom ?? today(),\n effectiveTo: input.effectiveTo,\n managerMemberId: input.managerMemberId ?? '',\n priority: input.priority ?? 0,\n scopeId: input.scopeId ?? '',\n scopeType: input.scopeType ?? 'MEMBER',\n });\n }\n setManagerModal(null);\n })\n }\n orgUnits={orgUnits}\n positions={positions}\n saving={saving}\n />\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ variant: 'destructive-primary' }}\n confirmText={visibleDeleteConfirmation?.confirmText ?? ''}\n loading={saving}\n modalStatusType=\"error\"\n modalType=\"standard\"\n onCancel={closeDeleteConfirmation}\n onClose={closeDeleteConfirmation}\n onConfirm={(): void => void handleConfirmDelete()}\n open={Boolean(deleteConfirmation)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"此操作會立即套用,請確認後再繼續。\"\n title={visibleDeleteConfirmation?.title ?? ''}\n >\n <Typography color=\"text-neutral\" variant=\"body\">\n {visibleDeleteConfirmation?.description ?? ''}\n </Typography>\n </Modal>\n </>\n );\n}\n\nfunction OrgUnitPanel({\n actions,\n loading,\n onCreate,\n onCreateChild,\n onEditOrgUnit,\n onPageChange,\n onSaveDraft,\n onPageSizeChange,\n onSearchTextChange,\n onTypeFilterChange,\n onViewModeChange,\n orgUnits,\n page,\n pageSize,\n rows,\n searchText,\n saving,\n total,\n typeFilter,\n viewMode,\n}: {\n readonly actions: TableActions<OrgUnitRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onCreateChild: (parentId: string) => void;\n readonly onEditOrgUnit: (record: OrgUnitRecord) => void;\n readonly onPageChange: (page: number) => void;\n readonly onSaveDraft: (\n changes: readonly OrgUnitHierarchyDraftChange[],\n ) => Promise<void>;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onSearchTextChange: (value: string) => void;\n readonly onTypeFilterChange: (value: OrgUnitTypeFilterOption) => void;\n readonly onViewModeChange: (mode: OrgUnitViewMode) => void;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly OrgUnitRow[];\n readonly searchText: string;\n readonly saving: boolean;\n readonly total: number;\n readonly typeFilter: OrgUnitTypeFilterOption;\n readonly viewMode: OrgUnitViewMode;\n}): ReactElement {\n const treeEditorRef = useRef<OrgUnitTreeDraftEditorHandle | null>(null);\n const [treeEditorState, setTreeEditorState] =\n useState<OrgUnitTreeDraftEditorState>(INITIAL_ORG_TREE_EDITOR_STATE);\n const nextViewMode: OrgUnitViewMode = viewMode === 'TABLE' ? 'FLOW' : 'TABLE';\n const viewModeToggleLabel = viewMode === 'TABLE' ? '切換樹狀圖' : '切換表格';\n const isTreeMode = viewMode === 'FLOW';\n const primaryActionLabel = readOrgUnitPrimaryActionLabel({\n isTreeMode,\n isTreeEditing: treeEditorState.isEditing,\n });\n const primaryActionIcon = readOrgUnitPrimaryActionIcon({\n isTreeMode,\n isTreeEditing: treeEditorState.isEditing,\n });\n const primaryActionDisabled = readOrgUnitPrimaryActionDisabled({\n hasDraftChanges: treeEditorState.hasDraftChanges,\n isTreeEditing: treeEditorState.isEditing,\n isTreeMode,\n loading,\n saving,\n });\n const columns = useMemo(\n (): TableColumn<OrgUnitRow>[] => [\n { dataIndex: 'code', key: 'code', title: '代碼', width: 180 },\n { dataIndex: 'name', key: 'name', title: '名稱', width: 240 },\n { dataIndex: 'typeLabel', key: 'typeLabel', title: '類型', width: 120 },\n { dataIndex: 'parentName', key: 'parentName', title: '上層', width: 280 },\n { dataIndex: 'path', key: 'path', title: 'Path', width: 420 },\n ],\n [],\n );\n\n useEffect((): void => {\n if (viewMode === 'TABLE') {\n setTreeEditorState(INITIAL_ORG_TREE_EDITOR_STATE);\n }\n }, [viewMode]);\n\n return (\n <>\n <PanelIntro\n actionDisabled={primaryActionDisabled}\n actionIcon={primaryActionIcon}\n actionLabel={primaryActionLabel}\n actions={\n <>\n <Button\n onClick={(): void => onViewModeChange(nextViewMode)}\n variant=\"base-secondary\"\n >\n {viewModeToggleLabel}\n </Button>\n {isTreeMode && treeEditorState.isEditing ? (\n <Button\n disabled={saving}\n icon={CloseIcon}\n iconType=\"leading\"\n onClick={(): void => treeEditorRef.current?.cancelEditing()}\n variant=\"base-secondary\"\n >\n 取消\n </Button>\n ) : null}\n </>\n }\n description=\"組織節點使用 ltree path 維護階層,搬移節點會同步更新子節點 path。\"\n onCreate={(): void => {\n if (!isTreeMode) {\n onCreate();\n return;\n }\n\n if (treeEditorState.isEditing) {\n void treeEditorRef.current?.saveDraft();\n return;\n }\n\n treeEditorRef.current?.startEditing();\n }}\n title=\"組織樹\"\n />\n {viewMode === 'TABLE' ? (\n <>\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"orgUnitSearchText\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onSearchTextChange(event.target.value)\n }\n placeholder=\"搜尋組織名稱或代碼\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"orgUnitTypeFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onTypeFilterChange(readOrgUnitTypeFilterOption(option))\n }\n options={[...ORG_UNIT_TYPE_FILTER_OPTIONS]}\n placeholder=\"類型\"\n size=\"sub\"\n value={typeFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: ORG_UNIT_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n ) : (\n <OrgUnitTreeDraftEditor\n ref={treeEditorRef}\n onCreateChild={onCreateChild}\n onCreateRoot={onCreate}\n onEditOrgUnit={onEditOrgUnit}\n onSaveDraft={onSaveDraft}\n onStateChange={setTreeEditorState}\n orgUnits={orgUnits}\n saving={saving}\n />\n )}\n </>\n );\n}\n\nfunction PositionPanel({\n actions,\n loading,\n onCreate,\n onPageChange,\n onPageSizeChange,\n onSearchTextChange,\n page,\n pageSize,\n rows,\n searchText,\n total,\n}: {\n readonly actions: TableActions<PositionRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onSearchTextChange: (value: string) => void;\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly PositionRow[];\n readonly searchText: string;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<PositionRow>[] => [\n { dataIndex: 'code', key: 'code', title: '代碼', width: 180 },\n { dataIndex: 'name', key: 'name', title: '名稱', width: 280 },\n { dataIndex: 'level', key: 'level', title: '職等', width: 96 },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增職位\"\n description=\"職位提供會員歸屬與主管解析規則使用。\"\n onCreate={onCreate}\n title=\"職位\"\n />\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"positionSearchText\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onSearchTextChange(event.target.value)\n }\n placeholder=\"搜尋職位名稱或代碼\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: POSITION_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction MembershipPanel({\n actions,\n loading,\n onCreate,\n onActiveFilterChange,\n onOrgUnitFilterChange,\n onPageChange,\n onPageSizeChange,\n onPositionFilterChange,\n orgUnitFilter,\n orgUnits,\n page,\n pageSize,\n positionFilter,\n positions,\n rows,\n statusFilter,\n total,\n}: {\n readonly actions: TableActions<MembershipRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onActiveFilterChange: (value: ActiveFilterOption | null) => void;\n readonly onOrgUnitFilterChange: (value: OrgUnitOption | null) => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onPositionFilterChange: (value: PositionOption | null) => void;\n readonly orgUnitFilter: OrgUnitOption | null;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly page: number;\n readonly pageSize: number;\n readonly positionFilter: PositionOption | null;\n readonly positions: readonly PositionRecord[];\n readonly rows: readonly MembershipRow[];\n readonly statusFilter: ActiveFilterOption | null;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<MembershipRow>[] => [\n { dataIndex: 'memberName', key: 'memberName', title: '會員', width: 280 },\n {\n dataIndex: 'orgUnitName',\n key: 'orgUnitName',\n title: '組織',\n width: 280,\n },\n {\n dataIndex: 'positionName',\n key: 'positionName',\n title: '職位',\n width: 220,\n },\n {\n key: 'isPrimary',\n render: (record: MembershipRow): string =>\n record.isPrimary ? '主要' : '一般',\n title: '類型',\n width: 104,\n },\n {\n dataIndex: 'effectiveFrom',\n key: 'effectiveFrom',\n title: '生效日',\n width: 140,\n },\n {\n dataIndex: 'effectiveTo',\n key: 'effectiveTo',\n title: '結束日',\n width: 140,\n },\n ],\n [],\n );\n const orgUnitOptions = useMemo(\n (): readonly OrgUnitOption[] => orgUnits.map(readOrgUnitOption),\n [orgUnits],\n );\n const positionOptions = useMemo(\n (): readonly PositionOption[] => positions.map(readPositionOption),\n [positions],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增歸屬\"\n description=\"會員歸屬是 BPM 內部組織權限、主管解析與條件判斷的來源。\"\n onCreate={onCreate}\n title=\"會員歸屬\"\n />\n <FilterArea\n className={[styles.orgFilterArea, styles.membershipFilterArea].join(\n ' ',\n )}\n size=\"sub\"\n >\n <FilterLine>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipOrgUnitFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的組織\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipOrgUnitFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipOrgUnitFilter\"\n onChange={(option): void =>\n onOrgUnitFilterChange(readOrgUnitOptionFromValue(option))\n }\n options={[...orgUnitOptions]}\n placeholder=\"全部組織\"\n size=\"sub\"\n value={orgUnitFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipPositionFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的職位\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipPositionFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipPositionFilter\"\n onChange={(option): void =>\n onPositionFilterChange(readPositionOptionFromValue(option))\n }\n options={[...positionOptions]}\n placeholder=\"全部職位\"\n size=\"sub\"\n value={positionFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"membershipStatusFilter\"\n >\n <AutoComplete\n disabledOptionsFilter\n emptyText=\"沒有符合的狀態\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'membershipStatusFilter',\n spellCheck: false,\n }}\n mode=\"single\"\n name=\"membershipStatusFilter\"\n onChange={(option): void =>\n onActiveFilterChange(readNullableActiveFilterOption(option))\n }\n options={[...ACTIVE_FILTER_OPTIONS]}\n placeholder=\"全部狀態\"\n size=\"sub\"\n value={statusFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: MEMBERSHIP_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction ManagerPanel({\n actions,\n loading,\n onCreate,\n onActiveFilterChange,\n onPageChange,\n onPageSizeChange,\n onScopeTypeFilterChange,\n page,\n pageSize,\n rows,\n scopeTypeFilter,\n statusFilter,\n total,\n}: {\n readonly actions: TableActions<ManagerResolutionRow>;\n readonly loading: boolean;\n readonly onCreate: () => void;\n readonly onActiveFilterChange: (value: ActiveFilterOption) => void;\n readonly onPageChange: (page: number) => void;\n readonly onPageSizeChange: (pageSize: number) => void;\n readonly onScopeTypeFilterChange: (value: ScopeTypeFilterOption) => void;\n readonly page: number;\n readonly pageSize: number;\n readonly rows: readonly ManagerResolutionRow[];\n readonly scopeTypeFilter: ScopeTypeFilterOption;\n readonly statusFilter: ActiveFilterOption;\n readonly total: number;\n}): ReactElement {\n const columns = useMemo(\n (): TableColumn<ManagerResolutionRow>[] => [\n {\n dataIndex: 'scopeLabel',\n key: 'scopeLabel',\n title: '套用範圍',\n width: 320,\n },\n {\n dataIndex: 'managerName',\n key: 'managerName',\n title: '簽核主管',\n width: 300,\n },\n { dataIndex: 'priority', key: 'priority', title: '優先序', width: 96 },\n {\n dataIndex: 'effectiveFrom',\n key: 'effectiveFrom',\n title: '生效日',\n width: 140,\n },\n {\n dataIndex: 'effectiveTo',\n key: 'effectiveTo',\n title: '結束日',\n width: 140,\n },\n ],\n [],\n );\n\n return (\n <>\n <PanelIntro\n actionLabel=\"新增主管規則\"\n description=\"簽核主管規則獨立於組織樹 parent,解析優先序為會員、組織、職位。\"\n onCreate={onCreate}\n title=\"簽核主管\"\n />\n <FilterArea className={styles.orgFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"managerScopeTypeFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onScopeTypeFilterChange(readScopeTypeFilterOption(option))\n }\n options={[...SCOPE_TYPE_FILTER_OPTIONS]}\n placeholder=\"套用範圍\"\n size=\"sub\"\n value={scopeTypeFilter}\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"managerStatusFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n onActiveFilterChange(readActiveFilterOption(option))\n }\n options={[...ACTIVE_FILTER_OPTIONS]}\n placeholder=\"狀態\"\n size=\"sub\"\n value={statusFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n <div className={styles.tableFrame}>\n <Table\n actions={actions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n })}\n style={{ minWidth: MANAGER_TABLE_MIN_WIDTH }}\n />\n </div>\n </>\n );\n}\n\nfunction createTablePagination({\n onPageChange,\n onPageSizeChange,\n page,\n pageSize,\n total,\n}: TablePaginationState): {\n current: number;\n onChange: (page: number) => void;\n onChangePageSize: (pageSize: number) => void;\n pageSize: number;\n pageSizeLabel: string;\n pageSizeOptions: number[];\n renderResultSummary: (from: number, to: number, total: number) => string;\n showPageSizeOptions: true;\n total: number;\n} {\n return {\n current: page,\n onChange: onPageChange,\n onChangePageSize: onPageSizeChange,\n pageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: [...ORGANIZATION_TABLE_PAGE_SIZE_OPTIONS],\n renderResultSummary: (from, to, resultTotal): string =>\n `顯示 ${from}-${to} 筆,共 ${resultTotal} 筆`,\n showPageSizeOptions: true,\n total,\n };\n}\n\nfunction readOrgUnitPrimaryActionLabel({\n isTreeEditing,\n isTreeMode,\n}: {\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n}): string {\n if (!isTreeMode) {\n return '新增組織';\n }\n\n return isTreeEditing ? '儲存' : '開始編輯';\n}\n\nfunction readOrgUnitPrimaryActionIcon({\n isTreeEditing,\n isTreeMode,\n}: {\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n}): IconDefinition {\n if (!isTreeMode) {\n return PlusIcon;\n }\n\n return isTreeEditing ? SaveIcon : EditIcon;\n}\n\nfunction readOrgUnitPrimaryActionDisabled({\n hasDraftChanges,\n isTreeEditing,\n isTreeMode,\n loading,\n saving,\n}: {\n readonly hasDraftChanges: boolean;\n readonly isTreeEditing: boolean;\n readonly isTreeMode: boolean;\n readonly loading: boolean;\n readonly saving: boolean;\n}): boolean {\n if (!isTreeMode) {\n return false;\n }\n\n if (!isTreeEditing) {\n return loading;\n }\n\n return !hasDraftChanges || saving;\n}\n\nfunction PanelIntro({\n actionDisabled = false,\n actionIcon = PlusIcon,\n actionLabel,\n actions,\n description,\n onCreate,\n title,\n}: {\n readonly actionDisabled?: boolean;\n readonly actionIcon?: IconDefinition;\n readonly actionLabel: string;\n readonly actions?: ReactElement;\n readonly description: string;\n readonly onCreate: () => void;\n readonly title: string;\n}): ReactElement {\n return (\n <div className={styles.tableIntro}>\n <div>\n <Typography component=\"h2\" variant=\"h3\">\n {title}\n </Typography>\n <Typography color=\"text-neutral\" variant=\"body\">\n {description}\n </Typography>\n </div>\n <div className={styles.tableIntroActions}>\n {actions}\n <Button\n disabled={actionDisabled}\n icon={actionIcon}\n iconType=\"leading\"\n onClick={onCreate}\n >\n {actionLabel}\n </Button>\n </div>\n </div>\n );\n}\n\nfunction OrgUnitModal({\n modal,\n onClose,\n onSubmit,\n orgUnits,\n saving,\n}: {\n readonly modal: OrgModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly code: string | null;\n readonly name: string | null;\n readonly parentId: string | null;\n readonly type: OrgUnitType | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [code, setCode] = useState('');\n const [name, setName] = useState('');\n const [parent, setParent] = useState<OrgUnitOption | null>(null);\n const [type, setType] = useState<OrgUnitTypeOption>(ORG_UNIT_TYPES[2]);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const parentId = record?.parentId ?? modal.parentId ?? null;\n const parentOrgUnit = parentId\n ? (orgUnits.find((orgUnit) => orgUnit.id === parentId) ?? null)\n : null;\n\n setCode(record?.code ?? '');\n setName(record?.name ?? '');\n setParent(parentOrgUnit ? readOrgUnitOption(parentOrgUnit) : null);\n setType(\n ORG_UNIT_TYPES.find((option) => option.id === record?.type) ??\n ORG_UNIT_TYPES[2],\n );\n }, [modal, orgUnits]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !code || !name }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n code,\n name,\n parentId: parent?.id ?? null,\n type: type.id,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯組織' : '新增組織'}\n >\n <div className={styles.modalFields}>\n <OrgModalTextField\n label=\"代碼\"\n name=\"orgCode\"\n onChange={setCode}\n placeholder=\"例如 FIN-TW\"\n value={code}\n />\n <OrgModalTextField\n label=\"名稱\"\n name=\"orgName\"\n onChange={setName}\n placeholder=\"例如 財務部\"\n value={name}\n />\n <BPMFormField label=\"類型\" name=\"orgType\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => setType(readOrgUnitTypeOption(option))}\n options={[...ORG_UNIT_TYPES]}\n placeholder=\"選擇組織類型\"\n value={type}\n />\n </BPMFormField>\n <BPMFormField label=\"上層組織\" name=\"parentId\">\n <OrgUnitPicker\n name=\"parentId\"\n onChange={setParent}\n orgUnits={orgUnits.filter(\n (orgUnit) => orgUnit.id !== modal?.record?.id,\n )}\n placeholder=\"選擇上層組織\"\n value={parent}\n />\n </BPMFormField>\n </div>\n </Modal>\n );\n}\n\nfunction PositionModal({\n modal,\n onClose,\n onSubmit,\n saving,\n}: {\n readonly modal: PositionModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly code: string | null;\n readonly level: number | null;\n readonly name: string | null;\n }) => Promise<void>;\n readonly saving: boolean;\n}): ReactElement {\n const [code, setCode] = useState('');\n const [level, setLevel] = useState('0');\n const [name, setName] = useState('');\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n setCode(modal.record?.code ?? '');\n setLevel(String(modal.record?.level ?? 0));\n setName(modal.record?.name ?? '');\n }, [modal]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !code || !name }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n code,\n level: Number(level),\n name,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯職位' : '新增職位'}\n >\n <div className={styles.modalFields}>\n <OrgModalTextField\n label=\"代碼\"\n name=\"positionCode\"\n onChange={setCode}\n placeholder=\"例如 FIN-MGR\"\n value={code}\n />\n <OrgModalTextField\n label=\"名稱\"\n name=\"positionName\"\n onChange={setName}\n placeholder=\"例如 財務主管\"\n value={name}\n />\n <OrgModalTextField\n label=\"職等\"\n name=\"positionLevel\"\n onChange={setLevel}\n placeholder=\"例如 5\"\n value={level}\n />\n </div>\n </Modal>\n );\n}\n\nfunction MembershipModal({\n membersById,\n modal,\n onClose,\n onSubmit,\n orgUnits,\n positions,\n saving,\n}: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly modal: MembershipModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly effectiveFrom: string | null;\n readonly effectiveTo: string | null;\n readonly isPrimary: boolean | null;\n readonly memberId: string | null;\n readonly orgUnitId: string | null;\n readonly positionId: string | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly positions: readonly PositionRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [effectiveFrom, setEffectiveFrom] = useState(today());\n const [effectiveTo, setEffectiveTo] = useState('');\n const [isPrimary, setIsPrimary] = useState<PrimaryOption>(PRIMARY_OPTIONS[1]);\n const [member, setMember] = useState<MemberOption | null>(null);\n const [orgUnit, setOrgUnit] = useState<OrgUnitOption | null>(null);\n const [position, setPosition] = useState<PositionOption | null>(null);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const profile = record ? membersById.get(record.memberId) : null;\n\n setEffectiveFrom(record?.effectiveFrom ?? today());\n setEffectiveTo(record?.effectiveTo ?? '');\n setIsPrimary(\n PRIMARY_OPTIONS.find((option) => option.value === record?.isPrimary) ??\n PRIMARY_OPTIONS[1],\n );\n setMember(profile ? readMemberOption(profile) : null);\n setOrgUnit(\n readNullableOption(\n orgUnits.find((candidate) => candidate.id === record?.orgUnitId),\n readOrgUnitOption,\n ),\n );\n setPosition(\n readNullableOption(\n positions.find((candidate) => candidate.id === record?.positionId),\n readPositionOption,\n ),\n );\n }, [membersById, modal, orgUnits, positions]);\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !member || !orgUnit }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n effectiveFrom,\n effectiveTo: effectiveTo || null,\n isPrimary: isPrimary.value,\n memberId: member?.id ?? null,\n orgUnitId: orgUnit?.id ?? null,\n positionId: position?.id ?? null,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯會員歸屬' : '新增會員歸屬'}\n >\n <div className={styles.modalFields}>\n <BPMFormField label=\"會員\" name=\"memberId\">\n <MemberPicker\n name=\"memberId\"\n onChange={setMember}\n placeholder=\"搜尋會員姓名或信箱\"\n value={member}\n />\n </BPMFormField>\n <BPMFormField label=\"組織\" name=\"orgUnitId\">\n <OrgUnitPicker\n name=\"orgUnitId\"\n onChange={setOrgUnit}\n orgUnits={orgUnits}\n placeholder=\"選擇歸屬組織\"\n value={orgUnit}\n />\n </BPMFormField>\n <BPMFormField label=\"職位\" name=\"positionId\">\n <PositionPicker\n name=\"positionId\"\n onChange={setPosition}\n placeholder=\"選擇職位\"\n positions={positions}\n value={position}\n />\n </BPMFormField>\n <BPMFormField label=\"歸屬類型\" name=\"isPrimary\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => setIsPrimary(readPrimaryOption(option))}\n options={[...PRIMARY_OPTIONS]}\n placeholder=\"選擇歸屬類型\"\n value={isPrimary}\n />\n </BPMFormField>\n <DateField\n label=\"生效日\"\n name=\"membershipEffectiveFrom\"\n onChange={setEffectiveFrom}\n placeholder=\"YYYY-MM-DD\"\n value={effectiveFrom}\n />\n <DateField\n label=\"結束日\"\n name=\"membershipEffectiveTo\"\n onChange={setEffectiveTo}\n placeholder=\"YYYY-MM-DD,未設定代表無期限\"\n value={effectiveTo}\n />\n </div>\n </Modal>\n );\n}\n\nfunction ManagerResolutionModal({\n membersById,\n modal,\n onClose,\n onSubmit,\n orgUnits,\n positions,\n saving,\n}: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly modal: ManagerModalState | null;\n readonly onClose: () => void;\n readonly onSubmit: (input: {\n readonly effectiveFrom: string | null;\n readonly effectiveTo: string | null;\n readonly managerMemberId: string | null;\n readonly priority: number | null;\n readonly scopeId: string | null;\n readonly scopeType: ManagerResolutionScopeType | null;\n }) => Promise<void>;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly positions: readonly PositionRecord[];\n readonly saving: boolean;\n}): ReactElement {\n const [effectiveFrom, setEffectiveFrom] = useState(today());\n const [effectiveTo, setEffectiveTo] = useState('');\n const [manager, setManager] = useState<MemberOption | null>(null);\n const [priority, setPriority] = useState('0');\n const [scopeMember, setScopeMember] = useState<MemberOption | null>(null);\n const [scopeOrgUnit, setScopeOrgUnit] = useState<OrgUnitOption | null>(null);\n const [scopePosition, setScopePosition] = useState<PositionOption | null>(\n null,\n );\n const [scopeType, setScopeType] = useState<ScopeTypeOption>(SCOPE_TYPES[0]);\n\n useEffect((): void => {\n if (!modal) {\n return;\n }\n\n const record = modal.record;\n const nextScopeType =\n SCOPE_TYPES.find((option) => option.id === record?.scopeType) ??\n SCOPE_TYPES[0];\n\n setEffectiveFrom(record?.effectiveFrom ?? today());\n setEffectiveTo(record?.effectiveTo ?? '');\n setManager(\n readNullableOption(\n record ? membersById.get(record.managerMemberId) : null,\n readMemberOption,\n ),\n );\n setPriority(String(record?.priority ?? 0));\n setScopeMember(\n nextScopeType.id === 'MEMBER'\n ? readNullableOption(\n record ? membersById.get(record.scopeId) : null,\n readMemberOption,\n )\n : null,\n );\n setScopeOrgUnit(\n nextScopeType.id === 'ORG_UNIT'\n ? readNullableOption(\n orgUnits.find((candidate) => candidate.id === record?.scopeId),\n readOrgUnitOption,\n )\n : null,\n );\n setScopePosition(\n nextScopeType.id === 'POSITION'\n ? readNullableOption(\n positions.find((candidate) => candidate.id === record?.scopeId),\n readPositionOption,\n )\n : null,\n );\n setScopeType(nextScopeType);\n }, [membersById, modal, orgUnits, positions]);\n\n const scopeId =\n scopeType.id === 'MEMBER'\n ? scopeMember?.id\n : scopeType.id === 'ORG_UNIT'\n ? scopeOrgUnit?.id\n : scopePosition?.id;\n const isSelfManagerResolution = Boolean(\n scopeType.id === 'MEMBER' &&\n scopeMember?.id &&\n manager?.id &&\n scopeMember.id === manager.id,\n );\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !manager || !scopeId || isSelfManagerResolution,\n }}\n confirmText={modal?.type === 'EDIT' ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void =>\n void onSubmit({\n effectiveFrom,\n effectiveTo: effectiveTo || null,\n managerMemberId: manager?.id ?? null,\n priority: Number(priority),\n scopeId: scopeId ?? null,\n scopeType: scopeType.id,\n })\n }\n open={Boolean(modal)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={modal?.type === 'EDIT' ? '編輯主管規則' : '新增主管規則'}\n >\n <div className={styles.modalFields}>\n <BPMFormField label=\"套用範圍\" name=\"scopeType\">\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n setScopeType(readScopeTypeOption(option))\n }\n options={[...SCOPE_TYPES]}\n placeholder=\"選擇套用範圍\"\n value={scopeType}\n />\n </BPMFormField>\n {scopeType.id === 'MEMBER' ? (\n <BPMFormField label=\"會員\" name=\"scopeMemberId\">\n <MemberPicker\n name=\"scopeMemberId\"\n onChange={setScopeMember}\n placeholder=\"搜尋套用會員\"\n value={scopeMember}\n />\n </BPMFormField>\n ) : null}\n {scopeType.id === 'ORG_UNIT' ? (\n <BPMFormField label=\"組織\" name=\"scopeOrgUnitId\">\n <OrgUnitPicker\n name=\"scopeOrgUnitId\"\n onChange={setScopeOrgUnit}\n orgUnits={orgUnits}\n placeholder=\"選擇套用組織\"\n value={scopeOrgUnit}\n />\n </BPMFormField>\n ) : null}\n {scopeType.id === 'POSITION' ? (\n <BPMFormField label=\"職位\" name=\"scopePositionId\">\n <PositionPicker\n name=\"scopePositionId\"\n onChange={setScopePosition}\n placeholder=\"選擇套用職位\"\n positions={positions}\n value={scopePosition}\n />\n </BPMFormField>\n ) : null}\n <BPMFormField label=\"簽核主管\" name=\"managerMemberId\">\n <MemberPicker\n name=\"managerMemberId\"\n onChange={setManager}\n placeholder=\"搜尋簽核主管\"\n value={manager}\n />\n </BPMFormField>\n {isSelfManagerResolution ? (\n <Typography color=\"text-error\" variant=\"caption\">\n 簽核主管不可設定為套用會員本人。\n </Typography>\n ) : null}\n <OrgModalTextField\n label=\"優先序\"\n name=\"managerPriority\"\n onChange={setPriority}\n placeholder=\"例如 10\"\n value={priority}\n />\n <DateField\n label=\"生效日\"\n name=\"managerEffectiveFrom\"\n onChange={setEffectiveFrom}\n placeholder=\"YYYY-MM-DD\"\n value={effectiveFrom}\n />\n <DateField\n label=\"結束日\"\n name=\"managerEffectiveTo\"\n onChange={setEffectiveTo}\n placeholder=\"YYYY-MM-DD,未設定代表無期限\"\n value={effectiveTo}\n />\n </div>\n </Modal>\n );\n}\n\nfunction OrgModalTextField({\n label,\n name,\n onChange,\n placeholder,\n value,\n}: {\n readonly label: string;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly value: string;\n}): ReactElement {\n return (\n <BPMFormField label={label} name={name}>\n <Input\n fullWidth\n name={name}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(event.target.value)\n }\n placeholder={placeholder}\n value={value}\n />\n </BPMFormField>\n );\n}\n\nfunction DateField({\n label,\n name,\n onChange,\n placeholder,\n value,\n}: {\n readonly label: string;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly value: string;\n}): ReactElement {\n return (\n <BPMFormField label={label} name={name}>\n <DatePicker\n format=\"YYYY-MM-DD\"\n fullWidth\n inputProps={{ name }}\n onChange={(nextValue): void => onChange(formatDateOnly(nextValue))}\n placeholder={placeholder}\n value={value.trim() ? value : undefined}\n />\n </BPMFormField>\n );\n}\n\nfunction readReferencedMemberIds(\n memberships: readonly MembershipRecord[],\n managerResolutions: readonly ManagerResolutionRecord[],\n): readonly string[] {\n return [\n ...new Set([\n ...memberships.map((membership) => membership.memberId),\n ...managerResolutions.map((resolution) => resolution.managerMemberId),\n ...managerResolutions\n .filter((resolution) => resolution.scopeType === 'MEMBER')\n .map((resolution) => resolution.scopeId),\n ]),\n ];\n}\n\nfunction readScopeLabel(\n resolution: ManagerResolutionRecord,\n lookup: {\n readonly membersById: ReadonlyMap<string, MemberProfileRecord>;\n readonly orgUnitsById: ReadonlyMap<string, OrgUnitRecord>;\n readonly positionsById: ReadonlyMap<string, PositionRecord>;\n },\n): string {\n if (resolution.scopeType === 'MEMBER') {\n return `會員:${readMemberLabel(lookup.membersById.get(resolution.scopeId))}`;\n }\n\n if (resolution.scopeType === 'ORG_UNIT') {\n return `組織:${readOrgUnitLabel(lookup.orgUnitsById.get(resolution.scopeId))}`;\n }\n\n return `職位:${readPositionLabel(lookup.positionsById.get(resolution.scopeId))}`;\n}\n\nfunction readMemberLabel(member: MemberProfileRecord | undefined): string {\n return member ? `${member.name} · ${member.email}` : '未知會員';\n}\n\nfunction readOrgUnitLabel(orgUnit: OrgUnitRecord | undefined): string {\n return orgUnit ? `${orgUnit.name} · ${orgUnit.code}` : '未知組織';\n}\n\nfunction readOrgUnitTypeLabel(type: OrgUnitType): string {\n return (\n ORG_UNIT_TYPES.find(\n (option) => option.id.toLowerCase() === type.toLowerCase(),\n )?.name ?? '未知類型'\n );\n}\n\nfunction readPositionLabel(position: PositionRecord | undefined): string {\n return position ? `${position.name} · ${position.code}` : '未指定';\n}\n\nfunction readAdminOrgTab(value: unknown): AdminOrgTab {\n return value === 'MANAGERS' ||\n value === 'MEMBERSHIPS' ||\n value === 'POSITIONS'\n ? value\n : 'ORG_UNITS';\n}\n\nfunction readOrgUnitTypeOption(value: unknown): OrgUnitTypeOption {\n const record = isRecord(value) ? value : null;\n\n if (typeof record?.id === 'string') {\n const id = record.id;\n\n return (\n ORG_UNIT_TYPES.find(\n (option) => option.id.toLowerCase() === id.toLowerCase(),\n ) ?? ORG_UNIT_TYPES[2]\n );\n }\n\n return ORG_UNIT_TYPES[2];\n}\n\nfunction readOrgUnitTypeFilterOption(value: unknown): OrgUnitTypeFilterOption {\n const record = isRecord(value) ? value : null;\n\n if (typeof record?.id === 'string') {\n const id = record.id;\n\n return (\n ORG_UNIT_TYPE_FILTER_OPTIONS.find(\n (option) => option.id.toLowerCase() === id.toLowerCase(),\n ) ?? ALL_ORG_UNIT_TYPE_FILTER\n );\n }\n\n return ALL_ORG_UNIT_TYPE_FILTER;\n}\n\nfunction readScopeTypeOption(value: unknown): ScopeTypeOption {\n return readOption(value, SCOPE_TYPES, SCOPE_TYPES[0]);\n}\n\nfunction readScopeTypeFilterOption(value: unknown): ScopeTypeFilterOption {\n return readOption(value, SCOPE_TYPE_FILTER_OPTIONS, ALL_SCOPE_TYPE_FILTER);\n}\n\nfunction readActiveFilterOption(value: unknown): ActiveFilterOption {\n return readOption(value, ACTIVE_FILTER_OPTIONS, ALL_ACTIVE_FILTER);\n}\n\nfunction readNullableActiveFilterOption(\n value: unknown,\n): ActiveFilterOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n\n return ACTIVE_FILTER_OPTIONS.find((option) => option.id === id) ?? null;\n}\n\nfunction readOrgUnitOptionFromValue(value: unknown): OrgUnitOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n const name = typeof record?.name === 'string' ? record.name : null;\n\n return id && name ? { id, name } : null;\n}\n\nfunction readPositionOptionFromValue(value: unknown): PositionOption | null {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n const name = typeof record?.name === 'string' ? record.name : null;\n\n return id && name ? { id, name } : null;\n}\n\nfunction readPrimaryOption(value: unknown): PrimaryOption {\n return readOption(value, PRIMARY_OPTIONS, PRIMARY_OPTIONS[1]);\n}\n\nfunction readOption<TOption extends { readonly id: string }>(\n value: unknown,\n options: readonly TOption[],\n fallback: TOption,\n): TOption {\n const record = isRecord(value) ? value : null;\n const id = typeof record?.id === 'string' ? record.id : null;\n\n return options.find((option) => option.id === id) ?? fallback;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readNullableOption<TValue, TOption>(\n value: TValue | null | undefined,\n mapper: (value: TValue) => TOption,\n): TOption | null {\n return value ? mapper(value) : null;\n}\n\nfunction today(): string {\n return formatDateParts(new Date());\n}\n\nfunction formatDateOnly(value: string | undefined): string {\n const date = value ? new Date(value) : null;\n\n return date && !Number.isNaN(date.getTime()) ? formatDateParts(date) : '';\n}\n\nfunction formatDateParts(date: Date): string {\n return `${date.getFullYear()}-${padDatePart(date.getMonth() + 1)}-${padDatePart(\n date.getDate(),\n )}`;\n}\n\nfunction padDatePart(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取組織資料失敗。';\n}\n"],"mappings":"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"}