PageSourceSearch

https://os.sosme.ai/assets/ApprovalMatricesPage-DRZnrPlK.js

js sosme.ai collected 2026-10-05 15:11:37 UTC 16,182 bytes, 1 lines download raw bytes

1import{p as Z,r,v as ee,z as i,j as e,av as ae,t as se,aB as le,ai as te,X as re,y as N}from"./index-DelWp-6b.js";import{n as x,m as ie}from"./api.service-Lf-HmAnC.js";import{M as ne}from"./Modal-XqSNGlu3.js";import{C as de}from"./ConfirmDialog-DIYc6JNE.js";import{G as C}from"./git-branch-Bc1hcnOF.js";import{P as R}from"./plus-BjX2r5pd.js";import{C as ce}from"./chevron-down-B145rEUg.js";import{P as oe}from"./pencil-D8nokcWq.js";import{L as me}from"./link-2-DFgdE0-m.js";import"./unwrap-CuJafpqD.js";import"./crud.service-B2C_PX1U.js";import"./circle-check-big-BNy0DKH2.js";const ue=["Small","Medium","Large"],D=a=>Array.isArray(a)?a:Array.isArray(a==null?void 0:a.items)?a.items:Array.isArray(a==null?void 0:a.data)?a.data:Array.isArray(a==null?void 0:a.$values)?a.$values:[],Le=()=>{const{t:a}=Z(),[E,F]=r.useState([]),[B,P]=r.useState([]),[O,S]=r.useState(!0),[f,T]=r.useState(""),[$,U]=r.useState(null),[G,h]=r.useState(!1),[m,M]=r.useState(null),[u,A]=r.useState(null),[V,b]=r.useState(!1),[q,L]=r.useState(null),[c,j]=r.useState({approvalLevelId:"",sequence:1,isMandatory:!0}),[k,I]=r.useState(!1),{register:p,handleSubmit:X,reset:z,formState:{errors:d}}=ee(),o=r.useCallback(async()=>{S(!0);try{const[s,t]=await Promise.all([x.getAll(),ie.getAll()]);F(D(s)),P(D(t))}catch{i.error(a("approvals.matrices.fetchFailed",{defaultValue:"Failed to load approval matrices"}))}finally{S(!1)}},[]);r.useEffect(()=>{o()},[o]);const _=()=>{M(null),z({name:"",description:"",bidClass:"",minAmount:0,maxAmount:void 0,requiredApprovalLevels:1}),h(!0)},H=s=>{M(s),z({name:s.name,description:s.description||"",bidClass:s.bidClass||"",minAmount:s.minAmount,maxAmount:s.maxAmount,requiredApprovalLevels:s.requiredApprovalLevels}),h(!0)},J=async s=>{b(!0);try{const t={...s,bidClass:s.bidClass||void 0,maxAmount:s.maxAmount||void 0};if(m){const v={...t,id:m.id,isActive:m.isActive};await x.update(m.id,v),i.success(a("approvals.matrices.updateSuccess",{defaultValue:"Approval matrix updated successfully"}))}else await x.create(t),i.success(a("approvals.matrices.createSuccess",{defaultValue:"Approval matrix created successfully"}));h(!1),o()}catch(t){i.error(N(t,a("common.operationFailed",{defaultValue:"Operation failed"})))}finally{b(!1)}},K=async()=>{if(u){b(!0);try{await x.delete(u.id),i.success(a("approvals.matrices.deleteSuccess",{defaultValue:"Approval matrix deleted successfully"})),A(null),o()}catch(s){i.error(N(s,a("common.deleteFailed",{defaultValue:"Delete failed"})))}finally{b(!1)}}},Q=async s=>{if(!c.approvalLevelId)return i.error(a("approvals.matrices.selectLevel",{defaultValue:"Select an approval level"}));I(!0);try{const t={approvalMatrixId:s,approvalLevelId:c.approvalLevelId,sequence:c.sequence,isMandatory:c.isMandatory};await x.addLevel(t),i.success(a("approvals.matrices.levelAdded",{defaultValue:"Level added to matrix"})),L(null),j({approvalLevelId:"",sequence:1,isMandatory:!0}),o()}catch(t){i.error(N(t,a("approvals.matrices.addLevelFailed",{defaultValue:"Failed to add level"})))}finally{I(!1)}},W=async(s,t,v)=>{try{await x.removeLevel(s,t),i.success(a("approvals.matrices.levelRemoved",{defaultValue:'Removed "{{levelName}}" from matrix',levelName:v})),o()}catch(y){i.error(N(y,a("approvals.matrices.removeLevelFailed",{defaultValue:"Failed to remove level"})))}},g=E.filter(s=>(s.name??"").toLowerCase().includes(f.toLowerCase())||(s.bidClass??"").toLowerCase().includes(f.toLowerCase())||(s.description??"").toLowerCase().includes(f.toLowerCase())),w=s=>s!=null?`SAR ${s.toLocaleString()}`:"—";return e.jsxs("div",{className:"page-container",children:[e.jsxs("div",{className:"page-header",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-10 h-10 rounded-xl bg-[var(--primary-500)] flex items-center justify-center",children:e.jsx(C,{size:20,className:"text-white"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"page-title",children:a("approvals.matrices.title",{defaultValue:"Approval Matrices"})}),e.jsx("p",{className:"page-subtitle",children:a("approvals.matrices.subtitle",{defaultValue:"Configure multi-level approval workflows by bid class and amount"})})]})]}),e.jsxs("button",{onClick:_,className:"btn-primary",children:[e.jsx(R,{size:18}),a("approvals.matrices.addMatrix",{defaultValue:"Add Matrix"})]})]}),e.jsx("div",{className:"card",children:e.jsxs("div",{className:"px-5 py-4 flex items-center gap-4",children:[e.jsxs("div",{className:"relative flex-1 max-w-sm",children:[e.jsx(ae,{size:16,className:"absolute start-3 top-1/2 -translate-y-1/2 text-gray-400"}),e.jsx("input",{type:"text",placeholder:a("approvals.matrices.searchPlaceholder",{defaultValue:"Search matrices..."}),value:f,onChange:s=>T(s.target.value),className:"input ps-9"})]}),e.jsx("button",{onClick:o,className:"btn-ghost",title:a("common.refresh",{defaultValue:"Refresh"}),children:e.jsx(se,{size:16})}),e.jsxs("span",{className:"text-sm text-gray-500 ms-auto",children:[g.length," ",g.length===1?a("approvals.matrices.matrix",{defaultValue:"matrix"}):a("approvals.matrices.matrices",{defaultValue:"matrices"})]})]})}),e.jsx("div",{className:"card",children:O?e.jsx("div",{className:"flex items-center justify-center py-20",children:e.jsx("div",{className:"w-8 h-8 border-4 border-[var(--primary-500)] border-t-transparent roun
1ded-full animate-spin"})}):g.length===0?e.jsxs("div",{className:"text-center py-20",children:[e.jsx(C,{size:40,className:"mx-auto text-gray-200 mb-3"}),e.jsx("p",{className:"text-gray-400 text-sm",children:f?a("approvals.matrices.noMatch",{defaultValue:"No matching approval matrices found"}):a("approvals.matrices.noMatrices",{defaultValue:"No approval matrices yet"})})]}):e.jsx("div",{className:"divide-y divide-gray-100",children:g.map(s=>{var v,y;const t=$===s.id;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-4 px-5 py-4 hover:bg-gray-50 transition-colors",children:[e.jsx("button",{onClick:()=>U(t?null:s.id),className:"flex-shrink-0 text-gray-400 hover:text-[var(--primary-600)] transition-colors",children:t?e.jsx(le,{size:16}):e.jsx(ce,{size:16})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"font-medium text-gray-900",children:s.name}),s.bidClass&&e.jsx("span",{className:"badge-info text-xs",children:a(`enums.BidClass.${s.bidClass}`,{defaultValue:s.bidClass})}),e.jsx("span",{className:s.isActive?"badge-success text-xs":"badge-danger text-xs",children:s.isActive?a("common.active",{defaultValue:"Active"}):a("common.inactive",{defaultValue:"Inactive"})})]}),s.description&&e.jsx("p",{className:"text-xs text-gray-400 mt-0.5 truncate",children:s.description})]}),e.jsxs("div",{className:"hidden md:flex items-center gap-6 text-sm text-gray-600 flex-shrink-0",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"text-xs text-gray-400",children:a("approvals.matrices.amtRange",{defaultValue:"Amount Range"})}),e.jsxs("div",{children:[w(s.minAmount)," – ",s.maxAmount?w(s.maxAmount):"+"]})]}),e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"text-xs text-gray-400",children:a("approvals.matrices.reqLevels",{defaultValue:"Required Levels"})}),e.jsx("div",{className:"font-medium text-gray-900",children:s.requiredApprovalLevels})]}),e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"text-xs text-gray-400",children:a("approvals.matrices.assignedLevels",{defaultValue:"Assigned Levels"})}),e.jsx("div",{className:"font-medium text-gray-900",children:((v=s.levels)==null?void 0:v.length)??0})]})]}),e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[e.jsx("button",{onClick:()=>H(s),className:"btn-ghost btn-sm",title:a("common.edit",{defaultValue:"Edit"}),children:e.jsx(oe,{size:14})}),e.jsx("button",{onClick:()=>A(s),className:"btn-ghost btn-sm text-red-500 hover:bg-red-50",title:a("common.delete",{defaultValue:"Delete"}),children:e.jsx(te,{size:14})})]})]}),t&&e.jsxs("div",{className:"bg-gray-50 border-t border-gray-100 px-5 py-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsxs("h4",{className:"text-sm font-semibold text-gray-900 flex items-center gap-2",children:[e.jsx(me,{size:14}),a("approvals.matrices.assignedApprovalLevels",{defaultValue:"Assigned Approval Levels"})]}),q!==s.id?e.jsxs("button",{onClick:()=>{var l;L(s.id),j({approvalLevelId:"",sequence:(((l=s.levels)==null?void 0:l.length)??0)+1,isMandatory:!0})},className:"btn-ghost btn-sm text-[var(--primary-600)]",children:[e.jsx(R,{size:14}),a("approvals.matrices.addLevel",{defaultValue:"Add Level"})]}):null]}),s.levels&&s.levels.length>0?e.jsx("div",{className:"space-y-2 mb-3",children:(y=s.levels)==null?void 0:y.slice().sort((l,n)=>l.sequence-n.sequence).map(l=>e.jsxs("div",{className:"flex items-center gap-3 bg-white rounded-lg px-3 py-2 border border-gray-200",children:[e.jsx("span",{className:"inline-flex items-center justify-center w-6 h-6 rounded-full bg-[var(--primary-100)] text-[var(--primary-700)] text-xs font-bold",children:l.sequence}),e.jsx("span",{className:"text-sm font-medium text-gray-900 flex-1",children:l.levelName}),l.isMandatory&&e.jsx("span",{className:"text-xs text-[var(--primary-600)] bg-[var(--primary-50)] px-2 py-0.5 rounded-full",children:a("approvals.matrices.mandatory",{defaultValue:"Mandatory"})}),e.jsx("button",{onClick:()=>W(s.id,l.id,l.levelName),className:"text-red-400 hover:text-red-600 transition-colors",title:a("common.remove",{defaultValue:"Remove"}),children:e.jsx(re,{size:14})})]},l.id))}):e.jsx("p",{className:"text-xs text-gray-400 mb-3",children:a("approvals.matrices.noLevelsAssigned",{defaultValue:"No approval levels assigned yet."})}),q===s.id&&e.jsxs("div",{className:"bg-white rounded-lg border border-[var(--primary-200)] p-3 space-y-3",children:[e.jsx("p",{className:"text-xs font-semibold text-gray-900",children:a("approvals.matrices.addApprovalLevel",{defaultValue:"Add Approval Level"})}),e.jsxs("div",{className:"grid grid-cols-3 gap-3",children:[e.jsxs("div",{className:"col-span-3 md:col-span-1",children:[e.jsx("label",{className:"text-xs text-gray-500 mb-1 block",children:a("approvals.matrices.level",{defaultValue:"Level"})}),e.jsxs("select",{className:"input text-sm",value:c.approvalLevelId,onChange:l=>j(n=>({...n,approvalLevelId:l.target.value})),children:[e.jsx("option",{value:"",children:a("approvals.matrices.selectLevelEllipsis",{defaultValue:"Select level..."})}),B.filter(l=>{var n;return!((n=s.levels)!=null&&n.some(Y=>Y.approvalLevelId===l.id))}).map(l=>e.jsxs("option",{value:l.id,children:[l.name,"  ",a("common.l",{defaultValue:"(L"}),l.level,")"]},l.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500 mb-1 block",children:a("common.sequence",{defaultValue:"Sequence"})}
1),e.jsx("input",{type:"number",min:1,className:"input text-sm",value:c.sequence,onChange:l=>j(n=>({...n,sequence:parseInt(l.target.value)||1}))})]}),e.jsx("div",{className:"flex items-end pb-1",children:e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",className:"rounded text-[var(--primary-600)] focus:ring-[var(--primary-500)]",checked:c.isMandatory,onChange:l=>j(n=>({...n,isMandatory:l.target.checked}))}),e.jsx("span",{className:"text-xs text-gray-600",children:a("approvals.matrices.mandatory",{defaultValue:"Mandatory"})})]})})]}),e.jsxs("div",{className:"flex gap-2 justify-end",children:[e.jsx("button",{type:"button",onClick:()=>L(null),className:"btn-ghost btn-sm",children:a("common.cancel",{defaultValue:"Cancel"})}),e.jsx("button",{type:"button",disabled:k,onClick:()=>Q(s.id),className:"btn-primary btn-sm",children:k?e.jsx("div",{className:"w-3 h-3 border-2 border-white border-t-transparent rounded-full animate-spin"}):a("common.add",{defaultValue:"Add"})})]})]})]})]},s.id)})})}),e.jsx(ne,{isOpen:G,icon:e.jsx(C,{}),subtitle:"Map approval workflows to bid classes and value thresholds",title:m?a("approvals.matrices.editMatrix",{defaultValue:"Edit Approval Matrix"}):a("approvals.matrices.addMatrix",{defaultValue:"Add Approval Matrix"}),onClose:()=>h(!1),size:"lg",children:e.jsxs("form",{onSubmit:X(J),className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"col-span-2",children:[e.jsx("label",{className:"label",children:a("common.name",{defaultValue:"Name"})}),e.jsx("input",{className:d.name?"input-error":"input",placeholder:a("approvals.matrices.namePlaceholder",{defaultValue:"e.g. Large Bid Approval"}),...p("name",{required:a("validation.required",{defaultValue:"This field is required"})})}),d.name&&e.jsx("p",{className:"error-text",children:d.name.message})]}),e.jsxs("div",{children:[e.jsxs("label",{className:"label",children:[a("approvals.matrices.bidClass",{defaultValue:"Bid Class"}),e.jsx("span",{className:"text-gray-400 font-normal ms-1",children:a("common.optional",{defaultValue:"(Optional)"})})]}),e.jsxs("select",{className:"input",...p("bidClass"),children:[e.jsx("option",{value:"",children:a("approvals.matrices.anyBidClass",{defaultValue:"Any bid class"})}),ue.map(s=>e.jsx("option",{value:s,children:a(`enums.BidClass.${s}`,{defaultValue:s})},s))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"label",children:a("approvals.matrices.reqLevelsNum",{defaultValue:"Required Approval Levels"})}),e.jsx("input",{type:"number",min:1,className:d.requiredApprovalLevels?"input-error":"input",placeholder:"1",...p("requiredApprovalLevels",{required:a("validation.required",{defaultValue:"This field is required"}),valueAsNumber:!0,min:{value:1,message:a("validation.min1",{defaultValue:"Must be at least 1"})}})}),d.requiredApprovalLevels&&e.jsx("p",{className:"error-text",children:d.requiredApprovalLevels.message})]}),e.jsxs("div",{children:[e.jsx("label",{className:"label",children:a("approvals.matrices.minAmount",{defaultValue:"Min Amount (SAR)"})}),e.jsx("input",{type:"number",min:0,className:d.minAmount?"input-error":"input",placeholder:"0",...p("minAmount",{required:a("validation.required",{defaultValue:"This field is required"}),valueAsNumber:!0,min:{value:0,message:a("validation.min0",{defaultValue:"Must be 0 or more"})}})}),d.minAmount&&e.jsx("p",{className:"error-text",children:d.minAmount.message})]}),e.jsxs("div",{children:[e.jsxs("label",{className:"label",children:[a("approvals.matrices.maxAmount",{defaultValue:"Max Amount (SAR)"}),e.jsxs("span",{className:"text-gray-400 font-normal ms-1",children:["(",a("approvals.matrices.blankUnlimited",{defaultValue:"blank = unlimited"}),")"]})]}),e.jsx("input",{type:"number",min:0,className:"input",placeholder:a("approvals.levels.unlimited",{defaultValue:"Unlimited"}),...p("maxAmount",{valueAsNumber:!0})})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsxs("label",{className:"label",children:[a("common.description",{defaultValue:"Description"}),e.jsx("span",{className:"text-gray-400 font-normal ms-1",children:a("common.optional",{defaultValue:"(Optional)"})})]}),e.jsx("textarea",{rows:2,className:"input resize-none",placeholder:a("common.descPlaceholder",{defaultValue:"Brief description..."}),...p("description")})]})]}),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx("button",{type:"button",onClick:()=>h(!1),className:"btn-secondary",children:a("common.cancel",{defaultValue:"Cancel"})}),e.jsx("button",{type:"submit",disabled:V,className:"btn-primary",children:V?e.jsx("div",{className:"w-4 h-4 border-2 border-white border-t-transparent roun
1ded-full animate-spin"}):m?a("common.update",{defaultValue:"Update"}):a("common.create",{defaultValue:"Create"})})]})]})}),e.jsx(de,{isOpen:!!u,title:a("approvals.matrices.deleteTitle",{defaultValue:"Delete Approval Matrix"}),message:a("approvals.matrices.deleteConfirm",{defaultValue:'Are you sure you want to delete "{{name}}"? This may affect active approval requests.',name:u==null?void 0:u.name}),confirmLabel:a("common.delete",{defaultValue:"Delete"}),cancelLabel:a("common.cancel",{defaultValue:"Cancel"}),variant:"danger",isLoading:V,onConfirm:K,onCancel:()=>A(null)})]})};export{Le as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.