PageSourceSearch

https://vizops360.ai/assets/employee-metrics-CXgDF0Le.js

js vizops360.ai collected 2026-10-05 13:53:22 UTC 14,448 bytes, 1 lines download raw bytes

1import{i0 as Re,i1 as Ie,r as n,j as t,bv as Pe,bw as He,bx as Ge,by as Qe,ap as B,b9 as we,ar as $e,b8 as fe,ao as ze,bB as Ve,hL as he,d3 as Be,d4 as _e,di as qe,d6 as Ke,d5 as Ue,c_ as We,dr as Ye,d7 as Je,eb as Xe,b4 as Ze,bT as et,aI as tt,cf as xe,cg as ye,ch as be,ci as ge,cj as _,ad as at,bS as st}from"./index-CpeGhXo5.js";import{u as Ne}from"./useCurrencyHelpers-D5hUvgaW.js";import{c as nt,m as rt}from"./financeMappers-CUv1G2pV.js";import{u as lt}from"./companySettingsMockApi-D8Uh5efq.js";import{F as se}from"./FinanceFormField-BQlXTOvW.js";import{F as ot}from"./FilterBar-B_jdgGzl.js";import{u as it}from"./filters-DQMtevU2.js";import{a as ct,T as ve}from"./EntityPill-btGCy98_.js";import"./currency-CACMzR5Q.js";import"./mock-Ci00pIzy.js";function mt({isOpen:r,onClose:R,employeeId:b,employeeName:I}){const{fmtConv:q}=Ne(),{data:T,refetch:A}=Re(b||"",{skip:!b||!r}),[D,{isLoading:k}]=Ie(),[h,g]=n.useState([]),[v,L]=n.useState(""),[m,j]=n.useState(""),[o,E]=n.useState(""),[w,p]=n.useState({});n.useEffect(()=>{if(T){const s=T.map(a=>({monthlySalary:Number(a.monthlySalary),effectiveFrom:a.effectiveFrom,effectiveTo:a.effectiveTo||null}));s.sort((a,d)=>new Date(a.effectiveFrom).getTime()-new Date(d.effectiveFrom).getTime()),g(s)}else g([])},[T]),n.useEffect(()=>{r||(L(""),j(""),E(""),p({}))},[r]);const P=()=>{const s={};let a=!1;const d=Number(v);if((!v||isNaN(d)||d<=0)&&(s.salary="Please enter a valid positive salary amount.",a=!0),m||(s.fromDate="Please select a start date.",a=!0),o&&m&&new Date(o)<new Date(m)&&(s.toDate="End date cannot be earlier than start date.",a=!0),a){p(s);return}const u=new Date(m),S=o?new Date(o):null;if(h.some(i=>{const C=new Date(i.effectiveFrom),F=i.effectiveTo?new Date(i.effectiveTo):null;return F===null&&S===null?!0:F===null?S>=C:S===null?F>=u:u<=F&&S>=C})){p({general:"This slab overlaps with an existing salary period. Please adjust the dates."});return}const f=[...h,{monthlySalary:d,effectiveFrom:m,effectiveTo:o||null}];f.sort((i,C)=>new Date(i.effectiveFrom).getTime()-new Date(C.effectiveFrom).getTime()),g(f),L(""),j(""),E(""),p({})},K=s=>{const a=h.filter((d,u)=>u!==s);g(a)},U=async()=>{if(!b)return;let s=[...h];if(v&&m){const a=Number(v);if(!isNaN(a)&&a>0){const d=new Date(m),u=o?new Date(o):null;h.some(N=>{const f=new Date(N.effectiveFrom),i=N.effectiveTo?new Date(N.effectiveTo):null;return i===null&&u===null?!0:i===null?u>=f:u===null?i>=d:d<=i&&u>=f})||(s.push({monthlySalary:a,effectiveFrom:m,effectiveTo:o||null}),s.sort((N,f)=>new Date(N.effectiveFrom).getTime()-new Date(f.effectiveFrom).getTime()))}}try{await D({id:b,slabs:s}).unwrap(),he({title:"Salary History Saved",description:`Successfully updated salary history and recalculated annual cost for ${I}.`}),A(),R()}catch(a){he({title:"Error saving salary history",description:a?.data?.message||a?.message||"Something went wrong",variant:"destructive"})}};return t.jsx(Pe,{open:r,onOpenChange:s=>!s&&R(),children:t.jsxs(He,{className:"max-w-2xl text-xs p-5 gap-4",children:[t.jsx(Ge,{children:t.jsxs(Qe,{className:"text-base font-bold flex flex-col",children:[t.jsx("span",{children:"Salary History & Slabs"}),t.jsxs("span",{className:"text-xs font-normal text-muted-foreground mt-0.5",children:["Employee: ",I]})]})}),t.jsx("div",{className:"border border-border rounded-lg overflow-hidden bg-muted/20",children:t.jsxs("table",{className:"w-full text-left border-collapse text-2xs",children:[t.jsx("thead",{children:t.jsxs("tr",{className:"bg-muted border-b border-border font-bold text-muted-foreground uppercase tracking-wider",children:[t.jsx("th",{className:"px-3 py-2",children:"From Date"}),t.jsx("th",{className:"px-3 py-2",children:"To Date"}),t.jsx("th",{className:"px-3 py-2 text-right",children:"Monthly Salary"}),t.jsx("th",{className:"px-3 py-2 text-center w-16",children:"Action"})]})}),t.jsx("tbody",{children:h.length===0?t.jsx("tr",{children:t.jsx("td",{colSpan:4,className:"px-3 py-6 text-center text-muted-foreground",children:"No salary slabs defined. Add a salary slab below to calculate annual cost."})}):h.map((s,a)=>t.jsxs("tr",{className:"border-b border-border hover:bg-muted/10 last:border-0 font-medium",children:[t.jsx("td",{className:"px-3 py-2 font-mono",children:s.effectiveFrom}),t.jsx("td",{className:"px-3 py-2 font-mono",children:s.effectiveTo?s.effectiveTo:t.jsx("span",{className:"text-emerald-600 font-sans font-semibold",children:"(ongoing)"})}),t.jsx("td",{className:"px-3 py-2 text-right font-mono font-semibold",children:q(s.monthlySalary)}),t.jsx("td",{className:"px-3 py-1 text-center",children:t.jsx(B,{variant:"ghost",size:"icon",className:"w-6 h-6 hover:text-destructive text-muted-foreground active:scale-95",onClick:()=>K(a),children:t.jsx(we,{className:"w-3.5 h-3.5"})})})]},a))})]})}),t.jsxs("div",{className:"border border-border rounded-lg p-3 bg-muted/5 flex flex-col gap-3",children:[t.jsx("div",{className:"font-bold text-2xs uppercase text-muted-foreground tracking-wider",children:"Add New Salary Slab"}),t.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3",children:[t.jsx(se,{label:"Monthly Salary (₹)",error:w.salary,children:t.jsxs("div",{className:"relative",children:[t.jsx("span",{className:"absolute left-2.5 top-1/2 -translate-y-1/2 font-medium text-muted-foreground",children:"₹"}
1),t.jsx($e,{type:"number",placeholder:"20000",value:v,onChange:s=>{L(s.target.value),p(a=>({...a,salary:void 0,general:void 0}))},className:"h-8 pl-6 text-xs"})]})}),t.jsx(se,{label:"Effective From",error:w.fromDate,children:t.jsx(fe,{value:m,onChange:s=>{j(s),p(a=>({...a,fromDate:void 0,general:void 0}))}})}),t.jsx(se,{label:"Effective To (Optional)",error:w.toDate,children:t.jsx(fe,{value:o,onChange:s=>{E(s),p(a=>({...a,toDate:void 0,general:void 0}))}})})]}),w.general&&t.jsx("p",{className:"text-2xs text-destructive font-medium text-center",children:w.general}),t.jsx("div",{className:"flex justify-end",children:t.jsxs(B,{type:"button",size:"sm",variant:"outline",className:"h-7 text-2xs gap-1 border-primary/30 text-primary hover:bg-primary/5 active:scale-95",onClick:P,children:[t.jsx(ze,{className:"w-3 h-3"}),"Add Slab"]})})]}),t.jsxs(Ve,{className:"mt-2",children:[t.jsx(B,{variant:"outline",size:"sm",onClick:R,disabled:k,children:"Cancel"}),t.jsx(B,{size:"sm",onClick:U,disabled:k,children:k?"Saving...":"Save Changes"})]})]})})}function jt(){const r=Be();return r||t.jsx(dt,{})}function dt(){_e();const r=it(),{fmtConvCompact:R,fmtConv:b}=Ne(),{data:I,isLoading:q,isFetching:T,refetch:A}=qe({limit:5e3},{refetchOnMountOrArgChange:!0,refetchOnFocus:!0,refetchOnReconnect:!0}),{data:D=[],isLoading:k,isFetching:h,refetch:g}=Ke(void 0,{refetchOnMountOrArgChange:!0,refetchOnFocus:!0,refetchOnReconnect:!0}),{data:v=[],isLoading:L,isFetching:m,refetch:j}=Ue(void 0,{refetchOnMountOrArgChange:!0,refetchOnFocus:!0,refetchOnReconnect:!0}),{data:o=[],refetch:E}=We(void 0,{refetchOnMountOrArgChange:!0}),{data:w=[],refetch:p}=lt(void 0,{refetchOnMountOrArgChange:!0});n.useEffect(()=>{const e=()=>{A(),g(),j(),E(),p()};window.addEventListener("focus",e);const l=()=>{document.visibilityState==="visible"&&e()};return document.addEventListener("visibilitychange",l),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",l)}},[A,g,j,E,p]);const{data:P,isLoading:K,isFetching:U,refetch:s}=Ye({limit:2e3}),{data:a,isLoading:d,isFetching:u,refetch:S}=Je({limit:2e3}),[N,f]=n.useState([]),[i,C]=n.useState(!1),F=T||h||m||U||u||i,je=q||k||L||K||d,W=I?.items??[],Y=n.useMemo(()=>(P?.items??[]).map(nt),[P]),ne=n.useMemo(()=>(a?.items??[]).map(rt),[a]),[Se,J]=n.useState(!1),[Ce,X]=n.useState(null),[De,Z]=n.useState(""),[H,re]=n.useState(""),[G,le]=n.useState("All"),[Q,oe]=n.useState("All"),ie=n.useMemo(()=>{const e=new Map;return(o||[]).forEach(l=>e.set(l.id,l.name)),(w||[]).forEach(l=>e.set(l.id,l.name)),e},[o,w]),$=n.useMemo(()=>W.map(e=>{const l=e.empCode||e.emp_code||e.employeeCode||e.raw?.["Employee Code"]||e.raw?.emp_code||"—",x=`${e.firstName||""} ${e.lastName||""}`.trim()||e.fullName||e.name||e.raw?.["Employee Name"]||e.raw?.name||e.workEmail?.split("@")[0]||l;let O=e.departmentName||e.departments?.[0]?.departmentName;const ke=e.departments?.[0]?.departmentId||D.find(c=>c.id===e.teams?.[0]?.teamId)?.departmentId,ce=v.find(c=>c.id===ke);(!O||O==="—")&&(O=ce?.name||e.department||e.raw?.Department||e.raw?.department||"—");let z=e.teamName||e.teams?.[0]?.teamName;const Le=e.teams?.[0]?.teamId,me=D.find(c=>c.id===Le);(!z||z==="—")&&(z=me?.name||e.team||e.raw?.Team||e.raw?.team||"—");const ee=e.companyName||e.company||e.raw?.Company||e.raw?.company||e.raw?.companyName,de=e.companyId||me?.companyId||ce?.companyId;let te=ee&&ee!=="—"?ee:de&&ie.get(de)||"—";if(te==="—"){const c=Y.filter(y=>y.employee&&y.employee.toLowerCase().includes((e.firstName||"").toLowerCase())),ae=ne.filter(y=>y.employee&&y.employee.toLowerCase().includes((e.firstName||"").toLowerCase()));te=c.find(y=>!!y.company)?.company||ae.find(y=>!!y.company)?.company||o[0]?.name||"Tekki Web Solutions Pvt. Ltd."}const Me=e.designation||e.raw?.Designation||e.raw?.designation||e.jobTitle||e.role||"Employee",ue=Number(e.annualCtc)>0?Number(e.annualCtc):0,V=Y.filter(c=>c.employee&&c.employee.toLowerCase()===x.toLowerCase()).reduce((c,ae)=>c+ae.net,0),pe=V-ue,Oe=V>0?pe/V*100:0;return{id:e.id,empCode:l,name:x,company:te,designation:Me,annualSalary:ue,teamName:z,deptName:O,revenue:V,profit:pe,margin:Oe}}),[W,D,v,ie,o,Y,ne]),Ee=n.useMemo(()=>$.filter(e=>{if(r.company!=="All Companies"&&e.company&&e.company!==r.company)return!1;const l=G!=="All"?G:r.department;if(l&&l!=="All"&&l!=="All Departments"&&e.deptName!==l)return!1;const M=Q!=="All"?Q:r.team;if(M&&M!=="All"&&M!=="All Teams"&&e.teamName!==M)return!1;if(H.trim()){const x=H.trim().toLowerCase();if(!((e.name||"").toLowerCase().includes(x)||(e.empCode||"").toLowerCase().includes(x)||(e.designation||"").toLowerCase().includes(x)||(e.deptName||"").toLowerCase().includes(x)||(e.teamName||"").toLowerCase().includes(x)||(e.company||"").toLowerCase().includes(x)))return!1}return!0}),[$,r.company,r.department,r.team,G,Q,H]),Fe=n.useMemo(()=>[{key:"empCode",label:"ID",width:"100px",sortable:!0},{key:"name",label:"Employee",sortable:!0,render:e=>t.jsx("button",{type:"button",onClick:()=>{X(e.id),Z(e.name),J(!0)},className:"text-primary hover:underline font-semibold text-left transition-colors",children:e.name})},{key:"company",label:"Company",width:"190px",sortable:!0,render:e=>t.jsx(ct,{name:e.company})},{key:"designation",label:"Designation",width:"160px",sortable:!0,render:e=>e.designation},{key:"deptName",label:"Department",width:"140px",sortable:!0,render:e=>t.jsx(ve,{name:e.deptName})},{key:"teamName",label:"Team",width:"140px",sortable:!0,render:e=>t.jsx(ve,{name:e.teamName})},{key:"annualSalary",label:"Annual Cost",align:"right",width:"130px",sortable:!0,render:e=>t.jsx("span",{className:"font-data font-semibold text-slate-700 dark:text-slate-300",children:e.annualSalary>0?b(e.annualSalary):t.jsx("span",{className:"text-slate-400 font-normal",children:"—"})})},{key:"revenue",label:"Revenue Contrib.",align:"right",width:"140px",sortable:!0,render:e=>t.jsx("span",{className:"font-data font-semibold",children:e.revenue>0?b(e.revenue):t.jsx("span",{className:"text-slate-400 font-normal",children:"—"})})},{key:"margin",label:"Margin %",align:"right",width:"90px",sortable:!0,render:e=>t.jsx("span",{className:"font-data font-semibold",children:e.revenue>0?Xe(e.margin):t.jsx("span",{className:"text-slate-400 font-normal",children:"—"})})},{key:"actions",label:"Action",align:"center",width:"100px",render:e=>t.jsx("button",{type:"button",onClick:()=>{X(e.id),Z(e.name),J(!0)},className:"px-2 py-0.5 text-[10px] font-bold uppercase rounded border border-primary/20 text-primary hover:bg-primary/5 active:scale-95 transition-all",children:"Set Salary"})}],[b]),Te=Array.from(new Set($.map(e=>e.deptName).filter(e=>e!=="—"))).sort(),Ae=Array.from(new Set($.map(e=>e.teamName).filter(e=>e!=="—"))).sort();return t.jsxs("div",{className:"flex flex-col flex-1 h-full min-h-0 overflow-hidden bg-slate-50/50",children:[t.jsx(Ze,{title:"Employee Metrics",subtitle:`${W.length} employees · ${D.length} teams`,accentVar:"--mod-employee",showMonthYearFilter:!1}),t.jsx("div",{className:"shrink-0 bg-surface/50 border-b border-border px-4 py-2 flex items-center justify-between flex-wrap gap-2",children:t.jsx(ot,{showMonths:!0})}),t.jsx("div",{className:"p-3 pb-3 flex-1 min-h-0 flex flex-col overflow-hidden",children:t.jsx(et,{searchSlot:t.
1jsx(st,{value:H,onChange:e=>re(e),placeholder:"Search employees…",className:"w-[300px] shrink-0"}),toolbar:t.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[t.jsxs(xe,{value:G,onValueChange:e=>le(e),children:[t.jsx(ye,{className:"h-8 px-2.5 rounded-[5px] border border-border bg-background text-xs min-w-[120px] shadow-sm",children:t.jsx(be,{placeholder:"Department"})}),t.jsxs(ge,{children:[t.jsx(_,{value:"All",children:"All Departments"}),Te.map(e=>t.jsx(_,{value:e,children:e},e))]})]}),t.jsxs(xe,{value:Q,onValueChange:e=>oe(e),children:[t.jsx(ye,{className:"h-8 px-2.5 rounded-[5px] border border-border bg-background text-xs min-w-[120px] shadow-sm",children:t.jsx(be,{placeholder:"Team"})}),t.jsxs(ge,{children:[t.jsx(_,{value:"All",children:"All Teams"}),Ae.map(e=>t.jsx(_,{value:e,children:e},e))]})]}),t.jsxs("button",{type:"button",onClick:()=>{le("All"),oe("All"),re(""),r.reset()},className:"h-8 px-3 rounded-[5px] border border-border bg-background hover:bg-accent text-xs font-medium inline-flex items-center gap-1.5 shadow-sm shrink-0",children:[t.jsx(at,{className:"w-3.5 h-3.5 text-muted-foreground"})," Clear Filters"]})]}),selectable:!0,selectedIds:N,onSelectionChange:f,bulkActions:[{id:"delete",label:"Delete",icon:t.jsx(we,{className:"w-3.5 h-3.5"}),variant:"destructive",onAction:e=>{confirm(`Delete ${e.length} selected employee metric(s)?`)&&(tt.success(`Deleted ${e.length} employee metric(s)`),f([]))}}],mode:"client",rows:Ee,columns:Fe,rowKey:e=>e.id,storageKey:"employee-metrics",initialPageSize:25,pageSizeOptions:[10,25,50,100],fetching:F||je,empty:"No employees found",fillHeight:!0,onRefresh:async()=>{C(!0),await Promise.all([A(),g(),j(),s(),S()]),setTimeout(()=>C(!1),500)}})}),t.jsx(mt,{isOpen:Se,onClose:()=>{J(!1),X(null),Z("")},employeeId:Ce,employeeName:De})]})}
1export{jt as EmployeeMetricsPage,jt 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.