PageSourceSearch

https://alsak.ru/assets/TeamView-D2Z8bTfL.js

js alsak.ru collected 2026-10-02 11:43:06 UTC 35,607 bytes, 2 lines download raw bytes

1import{r as g,j as e}from"./vendor-CIikcnY8.js";import{u as ne,a as $e,b as pe,l as _e,I as Je,c as Te,d as Ye,A as me,f as ve,i as Ee,e as qe,P as ee,g as Fe,h as Ze,j as Qe,k as Ve,m as Be,D as Ge,S as Xe,n as Le,o as ea}from"./index-LRgHn5RP.js";import{e as aa}from"./time-C7iVqVxo.js";import{r as sa}from"./rhythm-BhyG4x_D.js";import{u as ta,C as na,T as Ae}from"./Columns-Cq-XFRJ9.js";import{S as H}from"./SortTh-C7svgVij.js";import{e as la,m as De}from"./engagement-BF18ErE1.js";function ia({personId:c,holders:t}){const d=ne(),[n,m]=g.useState(null),[w,o]=g.useState(!1);g.useEffect(()=>{m(null),o(!1)},[c]);const N=$e();if(g.useEffect(()=>{let p=!0;return pe.personStats(c).then(T=>{p&&(m(T),o(!1))},()=>p&&o(!0)),()=>{p=!1}},[c,N]),w)return e.jsx("p",{className:"hint pad",children:d("The numbers could not be read.")});if(!n)return e.jsx("p",{className:"hint pad",children:d("Counting…")});const y=n.judged?Math.round(n.onTime/n.judged*100):null,f=_e(d.lang),u=p=>new Date(`${p}-01T00:00:00`).toLocaleDateString(f,{month:"short"}),$=Math.max(1,...n.months.map(p=>p.closed)),R=[{label:"Open now",value:String(n.open)},{label:"Overdue",value:String(n.overdue),warn:n.overdue>0},{label:"Closed in total",value:String(n.closed)},{label:"Pulled into",value:String(n.pulledIn)}];return n.plannedDays>0&&R.push({label:"Person-days",value:d("{n} d",{n:n.plannedDays})}),n.avgLateDays!=null&&R.push({label:"Average delay",value:d("{n} d",{n:n.avgLateDays}),warn:!0}),n.avgDaysToClose!=null&&R.push({label:"From making to closing",value:d("{n} d",{n:n.avgDaysToClose})}),e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"panel-group",children:[e.jsx("h4",{children:d("Closing in time")}),y===null?e.jsx("p",{className:"hint pad",children:n.closed?d("Nothing to count from yet: none of the closed work had a date to meet."):d("Nothing to count from yet: nothing has been closed.")}
1):e.jsxs("div",{className:"stat-lead",children:[e.jsxs("span",{className:`stat-share ${y>=80?"good":y>=50?"soso":"bad"}`,children:[y,"%"]}),e.jsxs("span",{className:"stat-of",children:[d("{a} of {b} closed by the day they were due",{a:n.onTime,b:n.judged}),n.late>0&&` · ${d("{n} late",{n:n.late})}`]}),e.jsx("span",{className:"stat-bar","aria-hidden":"true",children:e.jsx("span",{className:`stat-fill ${y>=80?"good":y>=50?"soso":"bad"}`,style:{width:`${y}%`}})})]}),n.guessed>0&&e.jsx("p",{className:"hint pad",children:d("{n} of them are dated by the task's last change: they were closed before the history was kept.",{n:n.guessed})})]}),e.jsx("section",{className:"panel-group",children:e.jsx("div",{className:"stat-tiles",children:R.map(p=>e.jsxs("div",{className:`stat-tile ${p.warn?"warn":""}`,children:[e.jsx("span",{className:"stat-value",children:p.value}),e.jsx("span",{className:"stat-label",children:d(p.label)})]},p.label))})}),e.jsxs("section",{className:"panel-group",children:[e.jsx("h4",{children:d("The last six months")}),n.months.every(p=>!p.closed)?e.jsx("p",{className:"hint pad",children:d("Nothing closed in this time.")}):e.jsx("div",{className:"stat-months",children:n.months.map(p=>e.jsxs("div",{className:"stat-month",title:d("{a} of {b} in time",{a:p.onTime,b:p.closed}),children:[e.jsx("span",{className:"stat-col",style:{height:`${Math.round(p.closed/$*100)}%`},children:e.jsx("span",{className:"stat-col-on",style:{height:`${p.closed?Math.round(p.onTime/p.closed*100):0}%`}})}),e.jsx("span",{className:"stat-n",children:p.closed||""}),e.jsx("span",{className:"stat-when",children:u(p.month)})]},p.month))})]}),n.byHolder.length>0&&e.jsxs("section",{className:"panel-group",children:[e.jsx("h4",{children:d("Where the work is")}),n.byHolder.map(p=>{const T=t.find(z=>z.id===p.holderId);return e.jsxs("div",{className:"panel-row",children:[e.jsxs("span",{className:"panel-label",children:[T?.icon?e.jsx("span",{className:"stat-mark",style:T.color?{color:T.color}:void 0,children:e.jsx(Je,{name:T.icon,size:14})}):e.jsx("span",{className:"rail-dot",style:{background:T?.color??"var(--accent)"},"aria-hidden":"true"}),T?.name??d("Outside the projects")]}),e.jsxs("span",{className:"hint",children:[p.open>0&&d("{n} open",{n:p.open}),p.open>0&&p.done>0&&" · ",p.done>0&&d("{n} closed",{n:p.done})]})]},p.holderId)})]}),n.recurring.answered+n.recurring.skipped>0&&e.jsxs("section",{className:"panel-group",children:[e.jsx("h4",{children:d("Recurring work")}),e.jsxs("div",{className:"panel-row",children:[e.jsx("span",{className:"panel-label",children:d("Answered in time")}),e.jsxs("span",{className:"hint",children:[d("{a} of {b}",{a:n.recurring.onTime,b:n.recurring.answered}),n.recurring.skipped>0&&` · ${d("{n} skipped",{n:n.recurring.skipped})}`]})]})]})]})}const da=c=>new Date(c).toLocaleDateString(void 0,{day:"numeric",month:"long",year:"numeric"});function ra(c,t,d){const n=c.data,m=(w,o,N=!1)=>{const y=f=>f==null||f===""?t("not set"):N?d(f):String(f);return`${y(w)} → ${y(o)}`};switch(c.kind){case"created":return{what:t("Added to the map")};case"name":return{what:t("Name"),detail:m(n.from,n.to)};case"title":return{what:t("Job title"),detail:m(n.from,n.to)};case"company":return{what:t("Company"),detail:m(n.from,n.to,!0)};case"department":return{what:t("Department"),detail:m(n.from,n.to,!0)};case"email":return{what:t("Email"),detail:m(n.from,n.to)};case"started":return{what:t("Started"),detail:m(n.from,n.to)};case"managers":return{what:t("Managers"),detail:[n.added?.length?`+ ${n.added.map(d).join(", ")}`:"",n.removed?.length?`− ${n.removed.map(d).join(", ")}`:""].filter(Boolean).join("  ")};
1case"mark":return{what:n.mark==="out"?t("Possible dismissal"):t("Under review"),detail:n.on?t("set"):t("cleared")};default:return{what:c.kind}}}function ca({person:c,people:t,departments:d,companies:n}){const m=ne(),[w,o]=g.useState(null),N=$e();g.useEffect(()=>{let f=!0;return pe.personEvents(c.id).then(u=>f&&o(u),()=>f&&o([])),()=>{f=!1}},[c.id,c.title,c.departmentId,c.companyId,c.email,c.startDate,c.managerIds,N]);const y=f=>typeof f!="string"?m("not set"):t.find(u=>u.id===f)?.fullName??d.find(u=>u.id===f)?.name??n.find(u=>u.id===f)?.name??m("not set");return w?w.length?e.jsx("ol",{className:"person-history",children:w.map(f=>{const{what:u,detail:$}=ra(f,m,y);return e.jsxs("li",{children:[e.jsx("span",{className:"ph-day",children:da(f.at)}),e.jsx("span",{className:"ph-what",children:u}),$&&e.jsx("span",{className:"ph-detail",children:$}),f.byName&&e.jsx("span",{className:"ph-who",children:f.byName})]},f.id)})}):e.jsx("p",{className:"hint pad",children:m("Nothing has changed since the history was kept.")}):e.jsx("p",{className:"hint pad",children:"…"})}const Me=c=>c?c.split("-").reverse().join("."):"";function oa({personId:c,onOpenProject:t}){const d=ne(),[n,m]=g.useState(null),w=$e();return g.useEffect(()=>{let o=!0;return pe.personPast(c).then(N=>o&&m(N),()=>o&&m([])),()=>{o=!1}},[c,w]),n?.length?e.jsxs("section",{className:"panel-group",children:[e.jsxs("h4",{children:[d("Worked before"),e.jsx("span",{className:"head-count",children:n.length})]}),n.map(o=>{const N=o.projectId??o.toolId,y=[Me(o.joinedOn),Me(o.leftOn)].filter(Boolean).join(" — ");return e.jsxs("div",{className:"card-row past-row",children:[e.jsxs("div",{className:"card-row-head",children:[o.stillThere&&N?e.jsx("button",{type:"button",className:"card-title link","data-ctx":`holder:${N}`,onClick:()=>t(N),children:o.holderName}):e.jsx("span",{className:"card-title",title:d("This project no longer exists"),children:o.holderName}),e.jsx("span",{className:"hint",children:y})]}),o.role&&e.jsx("div",{className:"card-row-facts hint",children:o.role})]},o.id)})]}):null}function ha({onBack:c,onRestored:t}){const d=ne(),n=Te().can("team.delete"),[m,w]=g.useState(null),[o,N]=g.useState(null),y=()=>pe.archivedPeople().then(w,()=>w([]));g.useEffect(()=>{y()},[]),Ye(y);async function f(u){if(await ve(d("Bring {name} back to work?",{name:u.fullName}),{okLabel:"Back to work"})){N(u.id);try{await pe.unarchivePerson(u.id),await y(),t()}finally{N(null)}}}return e.jsxs("section",{className:"panel-group archived",children:[e.jsxs("h4",{children:[d("Former employees"),m&&m.length>0&&e.jsx("span",{className:"head-count",children:m.length}),e.jsx("button",{type:"button",className:"ghost-btn",onClick:c,children:d("Team")})]}),!m&&e.jsx("p",{className:"hint pad",children:"…"}),m?.length===0&&e.jsx("p",{className:"hint pad",children:d("Nobody has left yet.")}),m?.map(u=>e.jsxs("div",{className:"card-row",children:[e.jsxs("div",{className:"card-row-head",children:[e.jsx(me,{person:u,size:26}),e.jsx("span",{className:"card-title",children:u.fullName}),e.jsx("span",{className:"hint",children:u.title}),n&&e.jsx("button",{type:"button",className:"ghost-btn",disabled:o===u.id,onClick:()=>f(u),children:d("Back to work")})]}),e.jsxs("div",{className:"card-row-facts hint",children:[e.jsx("span",{children:d("Left {date}",{date:(u.archivedOn??"").split("-").reverse().join(".")})}),u.archivedBy&&e.jsx("span",{children:u.archivedBy}),u.email&&e.jsx("span",{children:u.email})]})]},u.id))]})}function ma(c,t=new Date){const d=new Date(`${c}T00:00:00Z`),n=new Date(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()));if(d.getTime()<n.getTime())return 0;let m=0;for(;n.getTime()<=d.getTime();){const w=n.getUTCDay();w!==0&&w!==6&&m++,n.setUTCDate(n.getUTCDate()+1)}return m}function We(c,t,d=new Date){const n=c.filter(N=>N.kind==="once"&&Ee(N.state)&&(N.assigneeIds??[]).includes(t)&&N.dueOn&&N.effortDays).sort((N,y)=>(N.dueOn??"").localeCompare(y.dueOn??""));let m=0,w=0,o=null;for(const N of n){m+=N.effortDays??0;const y=ma(N.dueOn,d),f=m-y;f>w&&(w=f,o=N.dueOn)}return{shortBy:Math.round(w*10)/10,on:o,planned:Math.round(m*10)/10}}const ue={core:"●",partial:"◐",advisor:"○"},Ue=c=>"leadPersonId"in c?"projects.update":"tools.update",Pe=new Date().toISOString().slice(0,10),Oe=2,He=[{key:"where",label:"Engaged in"},{key:"works",label:"Work"},{key:"days",label:"Planned"},{key:"due",label:"Due"},{key:"duties",label:"Duties"},{key:"timed",label:"Timed"},{key:"owned",label:"Areas"},{key:"email",label:"Email"},{key:"started",label:"Started"}],Ke="orgami:team-columns",Re=["where","works","due","email"];function ua(){try{const c=localStorage.getItem(Ke);if(!c)return new Set(Re);const t=JSON.parse(c);return new Set(t.filter(d=>He.some(n=>n.key===d)))}catch{return new Set(Re)}}function pa(c){try{localStorage.setItem(Ke,JSON.stringify([...c]))}catch{}}function wa({people:c,companies:t,departments:d,projects:n,tasks:m,assignments:w,actions:o,assignmentActions:N,openId:y,onOpen:f,dept:u,only:$,onShowPerson:R,onOpenProject:p,onOpenTask:T,onPatchPerson:z,onArchivePerson:je,onRestored:fe}){const h=ne(),{can:we}=Te(),F=a=>we(Ue(a)),[ae,l]=g.useState(""),[W,xe]=g.useState("all"),[L,M]=g.useState(u??"all"),[se,le]=g.useState($==="free"||$==="busy"?$:"all"),[K,ke]=g.useState("all"),[_,Se]=g.useState(null),[E,Ne]=g.useState("az"),[q,ge]=g.useState(()=>ua()),[ie,de]=g.useState(!1),k=a=>q.has(a),re=a=>ge(i=>{const b=new Set(i);return b.has(a)?b.delete(a):b.add(a),pa(b),b});g.useEffect(()=>{u&&M(u),($==="free"||$==="busy")&&le($)}
1,[u,$]);const U=a=>a&&d.find(i=>i.id===a)?.name||"",J=a=>{const i=a.parentId?n.find(b=>b.id===a.parentId):null;return i?`${i.name} › ${a.name}`:a.name},I=a=>t.find(i=>i.id===a)?.name??"",ce=a=>h(a==="core"?"Main work":a==="partial"?"Part of the time":"Advises"),Z=g.useMemo(()=>la(c,n,w),[c,n,w]),Q=g.useMemo(()=>{const a=ae.trim().toLowerCase();return c.filter(i=>i.fullName).filter(i=>W==="all"?!0:i.companyId===W).filter(i=>L==="all"?!0:i.departmentId===L).filter(i=>!a||`${i.fullName} ${i.title} ${U(i.departmentId)} ${I(i.companyId)}`.toLowerCase().includes(a)).map(i=>{const b=m.filter(O=>O.assigneeIds.includes(i.id)&&Ee(O.state)&&O.kind!=="recurring"),v=b.map(O=>O.dueOn).filter(O=>!!O).sort()[0]??null,B=b.reduce((O,s)=>O+(s.effortDays??0),0),X=We(m,i.id);return{p:i,e:Z.get(i.id),works:b.length,days:B,due:v,load:X,overdue:b.filter(O=>O.dueOn&&O.dueOn<Pe).length}}).sort((i,b)=>E==="az"?i.p.fullName.localeCompare(b.p.fullName):E==="za"?b.p.fullName.localeCompare(i.p.fullName):b.e.total-i.e.total||b.e.owned-i.e.owned||i.p.fullName.localeCompare(b.p.fullName))},[c,Z,n,m,d,t,ae,W,L,E]),V=Q.filter(a=>!a.e.idle),ye=Q.filter(a=>a.e.idle),oe=se==="busy"?V:se==="free"?ye:Q,Y=K==="all"?oe:oe.filter(a=>!!De(a.e,K)),{sorted:Ce,by:P,toggle:A}=ta(Y,{where:a=>a.e.memberships.length,works:a=>a.works,days:a=>a.days,due:a=>a.due??"",duties:a=>a.e.duties.length,timed:a=>a.e.timed.length,owned:a=>a.e.owned,email:a=>a.p.email??"",started:a=>a.p.startDate??""});async function be(a,i,b){const v=i.members.find(B=>B.personId===a.id)??null;if(b===""){if(!v)return;const B=[v.role,v.areas.length?h.n(v.areas.length,"area","areas"):""].filter(Boolean).join(" · ");if(!await ve(h("Remove {name} from “{project}”?",{name:a.fullName,project:i.name})+(B?`
2${B}`:""),{okLabel:"Remove",danger:!0}))return;await o.removeMember(i.id,v.id);return}v?await o.patchMember(i.id,v.id,{involvement:b}):await o.addMember(i.id,{personId:a.id,involvement:b})}const he=a=>[...["core","partial","advisor"].map(i=>({value:i,label:`${ue[i]}  ${ce(i)}`})),{value:"",label:h("Remove from the project"),className:"danger"}],D=c.find(a=>a.id===y)??null,G=!!D;return e.jsxs("div",{className:`team ${G?"as-page":""}`,children:[!G&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"team-tools",children:[e.jsx("input",{className:"team-search","data-find":!0,"data-help":"team-search",value:ae,onChange:a=>l(a.target.value),onKeyDown:qe(ae,()=>l("")),placeholder:h("Search a person, a job title, a department…")}),e.jsx(ee,{className:"team-filter",value:W,options:[{value:"all",label:h("All companies")},...t.map(a=>({value:a.id,label:a.name}))],onChange:xe,children:e.jsx("span",{className:W==="all"?"muted":"",children:W==="all"?h("All companies"):I(W)})}),e.jsx(ee,{className:"team-filter",value:L,options:[{value:"all",label:h("All departments")},...d.map(a=>({value:a.id,label:a.name}))],onChange:M,children:e.jsx("span",{className:L==="all"?"muted":"",children:L==="all"?h("All departments"):U(L)})}),e.jsx(ee,{className:"team-filter",value:K,options:[{value:"all",label:h("All projects")},...n.map(a=>({value:a.id,label:J(a)}))],onChange:ke,searchPlaceholder:h("Search…"),children:e.jsx("span",{className:K==="all"?"muted":"",children:K==="all"?h("All projects"):(()=>{const a=n.find(i=>i.id===K);return a?J(a):""})()})}),e.jsx("div",{className:"seg","data-help":"team-scope",children:["all","busy","free","gone"].map(a=>e.jsx("button",{type:"button",className:se===a?"on":"",onClick:()=>le(a),children:h(a==="all"?"Everyone":a==="busy"?"Engaged":a==="free"?"Free":"Former employees")},a))}),e.jsxs("div",{className:"cols-pick","data-help":"team-cols",children:[e.jsxs("button",{type:"button",className:`ghost-btn ${ie?"on":""}`,onClick:()=>de(!ie),title:h("Which columns to show"),children:["▦ ",h("Columns")]}),ie&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"cols-away",onClick:()=>de(!1)}),e.jsx("div",{className:"cols-menu",children:He.map(a=>e.jsxs("label",{className:"cols-row",children:[e.jsx("input",{type:"checkbox",checked:k(a.key),onChange:()=>re(a.key)}),e.jsx("span",{children:h(a.label)})]},a.key))})]})]}),e.jsx("span",{className:"hint team-summary",children:h("{busy} of {all} are engaged",{busy:V.length,all:Q.length})})]}),se==="gone"?e.jsx("div",{className:"team-scroll",children:e.jsx(ha,{onBack:()=>le("all"),onRestored:fe})}):e.jsx("div",{className:"team-scroll",children:e.jsxs(na,{id:"team",bare:!0,fill:!0,className:"team-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx(Ae,{k:"person",label:h("Person"),className:"team-person",children:e.jsxs("button",{type:"button",className:`s
2ort-by ${E==="az"?"":"on"}`,title:h(E==="az"?"Sort Z→A":E==="za"?"Back to the engaged first":"Sort A→Z"),onClick:()=>Ne(E==="az"?"za":E==="za"?"engaged":"az"),children:[h("Person"),e.jsx("span",{className:"sort-mark","aria-hidden":"true",children:E==="az"?"↑":E==="za"?"↓":"⇅"})]})}),k("where")&&e.jsx(H,{label:h("Engaged in"),k:"where",by:P,toggle:A,firstDir:"desc",className:"team-where"}),k("works")&&e.jsx(H,{label:h("Work"),k:"works",by:P,toggle:A,firstDir:"desc",className:"team-num"}),k("days")&&e.jsx(H,{label:h("Planned"),k:"days",by:P,toggle:A,firstDir:"desc",className:"team-num"}),k("due")&&e.jsx(H,{label:h("Due"),k:"due",by:P,toggle:A,className:"team-due"}),k("duties")&&e.jsx(H,{label:h("Duties"),k:"duties",by:P,toggle:A,firstDir:"desc",className:"team-num"}),k("timed")&&e.jsx(H,{label:h("Timed"),k:"timed",by:P,toggle:A,firstDir:"desc",className:"team-num"}),k("owned")&&e.jsx(H,{label:h("Areas"),k:"owned",by:P,toggle:A,firstDir:"desc",className:"team-num"}),k("email")&&e.jsx(H,{label:h("Email"),k:"email",by:P,toggle:A,className:"team-mail"}),k("started")&&e.jsx(H,{label:h("Started"),k:"started",by:P,toggle:A,className:"team-due"}),e.jsx(Ae,{k:"pad",filler:!0,className:"team-pad"})]})}),e.jsx("tbody",{children:Ce.map(a=>e.jsxs("tr",{className:`${a.e.idle?"idle":""} ${a.p.id===y?"on":""}`,"data-ctx":`person:${a.p.id}`,children:[e.jsx("th",{className:"team-person",children:e.jsxs("button",{type:"button",className:"team-name",onClick:()=>f(a.p.id),title:h("Open the card"),children:[e.jsx(me,{person:a.p,size:26}),e.jsxs("span",{children:[e.jsx("span",{className:"team-full",children:a.p.fullName}),e.jsx("span",{className:"team-sub",children:[a.p.title,U(a.p.departmentId)||I(a.p.companyId)].filter(Boolean).join(" · ")})]})]})}),k("where")&&e.jsx("td",{className:"team-where",children:e.jsxs("span",{className:`where-list ${_===a.p.id?"all":""}`,children:[(()=>{const i=n.map(v=>({pr:v,m:De(a.e,v.id)})).filter(({m:v})=>v),b=_===a.p.id?i:i.slice(0,Oe);return e.jsxs(e.Fragment,{children:[b.map(({pr:v,m:B})=>{const X=e.jsxs("span",{className:`where-chip inv-${B.involvement}`,"data-ctx":`holder:${v.id}`,title:[J(v),ce(B.involvement),B.role,Fe(v)===a.p.id?h("Project lead"):""].filter(Boolean).join(" · "),children:[e.jsx("span",{className:"inv-mark","aria-hidden":"true",children:ue[B.involvement]}),J(v)]});return F(v)?e.jsx(ee,{className:"where-pick",value:B.involvement,options:he(),onChange:O=>be(a.p,v,O),children:X},v.id):e.jsx("span",{className:"where-pick",children:X},v.id)}),i.length>Oe&&e.jsx("button",{type:"button",className:"where-more",title:_===a.p.id?h("show fewer"):h("show all {n}",{n:i.length}),onClick:()=>Se(_===a.p.id?null:a.p.id),children:_===a.p.id?h("fewer"):`+${i.length-Oe}`})]})})(),n.some(F)&&e.jsx(ee,{className:"where-add",value:"",options:n.filter(i=>F(i)&&!De(a.e,i.id)).map(i=>({value:i.id,label:J(i)})),onChange:i=>{const b=n.find(v=>v.id===i);b&&be(a.p,b,"core")},searchPlaceholder:h("Search…"),emptyLabel:h("Nobody matches"),title:h("Put on the project"),children:e.jsx("span",{className:"muted",children:"+"})})]})}),k("works")&&e.jsx("td",{className:`team-num ${a.overdue?"matrix-warn":""}`,children:a.works||""}),k("days")&&e.jsxs("td",{className:`team-num ${a.load.shortBy>0?"over":""}`,title:a.load.shortBy>0?h("The estimates of what is promised by {day} need {n} working days more than there are",{day:a.load.on??"",n:a.load.shortBy}):void 0,children:[a.days?h("{n} d",{n:a.days}):"",a.load.shortBy>0&&` · −${a.load.shortBy}`]}),k("due")&&e.jsxs("td",{className:`team-due ${a.due&&a.due<Pe?"matrix-warn":""}`,children:[a.due??"",a.overdue>0&&e.jsxs("span",{className:"hint",children:[" · ",h("{n} overdue",{n:a.overdue})]})]}),k("duties")&&e.jsx("td",{className:"team-num",children:a.e.duties.length||""}),k("timed")&&e.jsx("td",{className:"team-num",children:a.e.timed.length||""}),k("owned")&&e.jsx("td",{className:"team-num",children:a.e.owned||""}),k("email")&&e.jsx("td",{className:"team-mail",children:a.p.email?e.jsx("a",{href:`mailto:${a.p.email}`,children:a.p.email}):e.jsx("span",{className:"hint",children:"—"})}),k("started")&&e.jsx("td",{className:"team-due",children:a.p.startDate?a.p.startDate.split("-").reverse().join("."):""}),e.jsx("td",{className:"team-pad"})]},a.p.id))})]})})]}),D&&e.jsx(ja,{page:G,person:D,departments:d,companies:t,where:[D.title,U(D.departmentId),I(D.companyId)].filter(
2Boolean).join(" · "),company:I(D.companyId),department:U(D.departmentId),managers:D.managerIds.map(a=>c.find(i=>i.id===a)).filter(a=>!!a),reports:c.filter(a=>a.managerIds.includes(D.id)),projects:n,tasks:m,carries:Z.get(D.id),people:c,actions:o,assignmentActions:N,onClose:()=>f(null),onOpenProject:p,onOpenTask:T,onOpenPerson:f,onShowOnMap:()=>R(D.id),onArchive:async(a,i)=>{await je(D.id,a,i),f(null)},onPatch:a=>z(D.id,a)})]})}const ze=new Date().toISOString().slice(0,10);function ja({page:c,person:t,where:d,company:n,department:m,managers:w,reports:o,projects:N,tasks:y,carries:f,people:u,departments:$,companies:R,actions:p,assignmentActions:T,onClose:z,onOpenProject:je,onOpenTask:fe,onOpenPerson:h,onShowOnMap:we,onPatch:F,onArchive:ae}){const l=ne(),W=Ze(),{can:xe,mayChange:L}=Te(),M=L("team.update",t),se=L("team.delete",t),le=L("assignments.create",t),K=L("assignments.update",t),ke=L("assignments.delete",t),[_,Se]=g.useState(0),E=Qe({storageKey:"orgami:person-panel-width",range:ea,side:"left",inside:!0}),[Ne,q]=g.useState(null),[ge,ie]=g.useState(!1),[de,k]=g.useState("");g.useEffect(()=>{const s=()=>Se(document.querySelector(".bar")?.getBoundingClientRect().bottom??0);s();const r=j=>{j.key==="Escape"&&z()};return window.addEventListener("keydown",r),window.addEventListener("resize",s),()=>{window.removeEventListener("keydown",r),window.removeEventListener("resize",s)}},[z]),g.useEffect(()=>{q(null),k("")},[t.id]);const re=s=>l(s==="core"?"Main work":s==="partial"?"Part of the time":"Advises"),U=f.memberships,J=y.filter(s=>s.assigneeIds.includes(t.id)||(s.people??[]).some(r=>r.personId===t.id)).map(s=>{const r=N.find(j=>j.id===(s.projectId??s.toolId))??null;return{w:s,area:r?.areas.find(j=>s.areaIds.includes(j.id))??null,project:r,part:s.assigneeIds.includes(t.id)?"":(s.people??[]).find(j=>j.personId===t.id)?.role??""}}),I=J.filter(({w:s})=>Ee(s.state)).sort((s,r)=>(s.w.dueOn??"9999").localeCompare(r.w.dueOn??"9999")),ce=I.filter(({w:s})=>s.dueOn&&s.dueOn<ze).length,Z=y.filter(s=>s.kind==="recurring"&&(s.assigneeIds.includes(t.id)||(s.people??[]).some(r=>r.personId===t.id))),Q=I.reduce((s,{w:r})=>s+(r.effortDays??0),0),V=We(y,t.id),ye=f.duties,oe=(s,r)=>s.areas.find(j=>j.id===r)?.name??"",[Y,Ce]=g.useState("about"),P=s=>{const r=new Date(s),j=new Date;let S=(j.getFullYear()-r.getFullYear())*12+(j.getMonth()-r.getMonth());if(j.getDate()<r.getDate()&&S--,S<0)return"";const x=Math.floor(S/12),te=S%12;return[x?l("{n} y",{n:x}):"",te||!x?l("{n} mo",{n:te}):""].filter(Boolean).join(" ")};async function A(s){const r=de.trim();if(!r)return q(null);await T.add({personId:t.id,kind:s,title:r,...s==="task"?{startsOn:new Date().toISOString().slice(0,10)}:{}}),k(""),q(null)}async function be(s){await ve(l("Remove “{name}”?",{name:s.title}),{okLabel:"Remove",danger:!0})&&await T.remove(s.id)}const he=s=>e.jsxs("button",{type:"button",className:"who-chip","data-ctx":`person:${s.id}`,onClick:()=>h(s.id),title:s.title||void 0,children:[e.jsx(me,{person:s,size:22}),s.fullName]},s.id),D=s=>F({managerIds:s}),G=g.useMemo(()=>{if(!M)return[];const s=C=>R.find(Ie=>Ie.id===C)?.name??"",r=(C,Ie)=>C.fullName.localeCompare(Ie.fullName),j=u.filter(C=>C.fullName&&(t.managerIds.includes(C.id)||Ve(u,t.id,C.id))),S=j.filter(C=>C.companyId===t.companyId).sort(r),x=j.filter(C=>C.companyId!==t.companyId).sort(r),te=S.length>0&&x.length>0;return[...S,...x].map(C=>({value:C.id,label:C.fullName,sub:[C.title,C.companyId!==t.companyId?s(C.companyId):""].filter(Boolean).join(" · "),heading:te?C.companyId===t.companyId?n||l("Company"):l("Everyone else"):void 0,icon:e.jsxs(e.Fragment,{children:[e.jsx("span",{className:`tick ${t.managerIds.includes(C.id)?"on":""}`,"aria-hidden":"true"}),e.jsx(me,{person:C,size:22})]})}))},[M,u,R,t.id,t.companyId,t.managerIds,n]),a=e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"card-sheet",children:[e.jsx("h5",{className:"sheet-title",children:l("Contacts")}),e.jsxs("dl",{className:"facts",children:[e.jsxs("div",{className:"fact",children:[e.jsx("dt",{children:l("Corporate email")}),e.jsx("dd",{children:e.jsx(Be,{className:"card-mail",value:t.email??"",placeholder:l("not set"),readOnly:!M,onCommit:s=>F({email:s.trim()})})})]}),e.jsxs("div",{className:"fact",children:[e.jsx("dt",{children:l("Start date")}),e.jsxs("dd",{children:[e.jsx(Ge,{value:t.startDate??null,onChange:s=>F({startDate:s}),placeholder:l("not set"),readOnly:!M}),t.startDate&&e.jsxs("span",{className:"hint",children:["· ",l("in the group {n}",{n:P(t.startDate)})]})]})]})]})]}
2),e.jsxs("section",{className:"card-sheet",children:[e.jsx("h5",{className:"sheet-title",children:l("In the company")}),e.jsxs("dl",{className:"facts",children:[t.title&&e.jsxs("div",{className:"fact",children:[e.jsx("dt",{children:l("Job title")}),e.jsx("dd",{children:t.title})]}),e.jsxs("div",{className:"fact",children:[e.jsx("dt",{children:l("Company")}),e.jsx("dd",{children:n||e.jsx("span",{className:"hint",children:l("not set")})})]}),e.jsxs("div",{className:"fact",children:[e.jsx("dt",{children:l("Department")}),e.jsx("dd",{children:m||e.jsx("span",{className:"hint",children:l("no department")})})]}),(w.length>0||M&&G.length>0)&&e.jsxs("div",{className:"fact",children:[e.jsx("dt",{children:l("Reports to")}),e.jsxs("dd",{className:"who-list",children:[w.map(s=>M?e.jsxs("span",{className:"who-kept",children:[he(s),e.jsx("button",{type:"button",className:"who-x","aria-label":l("Stop reporting to {name}",{name:s.fullName||l("this person")}),title:l("Stop reporting to {name}",{name:s.fullName||l("this person")}),onClick:()=>D(t.managerIds.filter(r=>r!==s.id)),children:"×"})]},s.id):he(s)),M&&G.length>0&&e.jsx(ee,{className:"who-add",title:l("Add a manager"),value:"",keepOpen:!0,search:!0,searchPlaceholder:l("Search a person…"),emptyLabel:l("Nobody matches"),options:G,onChange:s=>D(t.managerIds.includes(s)?t.managerIds.filter(r=>r!==s):[...t.managerIds,s]),children:w.length?l("+ another…"):l("+ manager…")})]})]}),o.length>0&&e.jsxs("div",{className:"fact",children:[e.jsx("dt",{children:l("In their team")}),e.jsxs("dd",{className:"who-list",children:[(ge?o:o.slice(0,6)).map(he),o.length>6&&e.jsx("button",{type:"button",className:"who-more",onClick:()=>ie(s=>!s),children:ge?l("fewer"):`+${o.length-6}`})]})]})]})]}),W&&M&&e.jsxs("section",{className:"card-sheet",children:[e.jsx("h5",{className:"sheet-title",children:l("What-if")}),e.jsxs("div",{className:"card-marks",children:[e.jsxs("button",{type:"button",className:`mark-toggle ${t.plannedOut?"on out":""}`,title:t.plannedOut?l("Keep this person (clear the mark)"):l("What-if: a possible dismissal — stays on the map, out of the totals"),onClick:()=>F({plannedOut:!t.plannedOut}),children:[e.jsx("span",{"aria-hidden":"true",children:"✂"}),t.plannedOut?l("Marked as a possible dismissal"):l("Possible dism
2issal")]}),e.jsxs("button",{type:"button",className:`mark-toggle ${t.underReview?"on review":""}`,title:t.underReview?l("Decided: remove the question mark"):l("Under review: not sure yet whether this person is needed"),onClick:()=>F({underReview:!t.underReview}),children:[e.jsx("span",{"aria-hidden":"true",children:"?"}),t.underReview?l("Marked as under review"):l("Under review")]})]}),e.jsx("p",{className:"hint pad",children:l("Both are what-ifs: the person stays where they are, and the totals show what would change.")})]}),e.jsxs("div",{className:"card-foot",children:[e.jsxs("button",{type:"button",className:"card-away",onClick:we,children:[l("Show on the map"),e.jsx("span",{"aria-hidden":"true",children:"→"})]}),se&&e.jsx("button",{type:"button",className:"ghost-btn","data-help":"person-archive",onClick:v,title:l("The person leaves the company: out of the lists, kept in the history"),children:l("Send to the archive")})]})]}),i=e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"panel-group",children:[e.jsxs("h4",{children:[l("Work"),I.length>0&&e.jsx("span",{className:"head-count",children:I.length}),Q>0&&e.jsx("span",{className:"head-count",children:l("{n} person-days",{n:Q})}),ce>0&&e.jsx("span",{className:"head-warn",children:l("{n} overdue",{n:ce})}),V.shortBy>0&&e.jsx("span",{className:"head-warn",title:l("The estimates of what is promised by {day} need {n} working days more than there are",{day:V.on??"",n:V.shortBy}),children:l("overloaded: {n} days short",{n:V.shortBy})})]}),I.slice(0,12).map(({w:s,area:r,project:j,part:S})=>e.jsxs("button",{type:"button",className:"panel-row work-line","data-ctx":`task:${s.id}`,onClick:()=>fe(s.id),title:l("Open the task"),children:[e.jsxs("span",{className:"panel-label",children:[e.jsx(Xe,{state:s.state,size:12})," ",s.title]}),e.jsxs("span",{className:`hint ${s.dueOn&&s.dueOn<ze?"matrix-warn":""}`,children:[s.effortDays!=null&&`${aa(s.effortDays,l)} · `,S?`${S} · `:"",[j?.name,r?.name,s.dueOn].filter(Boolean).join(" · ")]})]},s.id)),I.length>12&&e.jsx("p",{className:"hint pad",children:l("and {n} more",{n:I.length-12})}),I.length===0&&e.jsx("p",{className:"hint pad",children:J.length?l("Everything handed to them is done."):l("Nothing is handed to them.")})]}),Z.length>0&&e.jsxs("section",{className:"panel-group",children:[e.jsxs("h4",{children:[l("Recurring"),e.jsx("span",{className:"head-count",children:Z.length})]}),Z.map(s=>e.jsxs("div",{className:"card-row","data-ctx":`task:${s.id}`,children:[e.jsx("div",{className:"card-row-head",children:e.jsx("button",{type:"button",className:"card-title link",onClick:()=>fe(s.id),children:s.title})}),e.jsxs("div",{className:"card-row-facts hint",children:[e.jsx("span",{children:sa(s,l.lang)}),s.nextDue&&e.jsx("span",{children:l("next {date}",{date:s.nextDue.split("-").reverse().join(".")})})]})]},s.id))]}),["duty"].map(s=>{const r=ye;return e.jsxs("section",{className:"panel-group",children:[e.jsxs("h4",{children:[l(s==="duty"?"Standing duties":"Timed work"),r.length>0&&e.jsx("span",{className:"head-count",children:r.length})]}),r.length===0&&Ne!==s&&e.jsx("p",{className:"hint pad",children:l("Nothing standing yet.")}),r.map(j=>e.jsxs("div",{className:"card-row",children:[e.jsxs("div",{className:"card-row-head",children:[e.jsx(Be,{className:"card-title",value:j.title,placeholder:l("What the person does"),readOnly:!K,onCommit:S=>S.trim()&&T.patch(j.id,{title:S.trim()})}),ke&&e.jsx("button",{type:"button",className:"icon-btn small",title:l("Remove"),onClick:()=>be(j),children:"×"})]}),e.jsx("div",{className:"card-row-facts hint",children:j.projectId&&e.jsx("span",{children:N.find(S=>S.id===j.projectId)?.name})})]},j.id)),le?Ne===s?e.jsx("div",{className:"card-add",children:e.jsx("input",{autoFocus:!0,value:de,onChange:j=>k(j.target.value),placeholder:l("e.g. keeps the SEO reports"),onKeyDown:j=>{j.key==="Enter"&&A(s),j.key==="Escape"&&(q(null),k(""))},onBlur:()=>A(s)})}):e.jsx("button",{type:"button",className:"panel-row add",onClick:()=>{k(""),q(s)},children:e.jsx("span",{className:"panel-label",children:l("+ Duty")})}):null]},s)})]}),b=e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"panel-group",children:[e.jsx("h4",{children:l("Projects")}),U.length===0&&e.jsx("p",{className:"hint pad",children:l("Not on any project.")}),U.map(({project:s,member:r})=>{const j=r.areas.filter(x=>x.kind==="owns").map(x=>
2oe(s,x.areaId)).filter(Boolean),S=r.areas.filter(x=>x.kind==="works").map(x=>oe(s,x.areaId)).filter(Boolean);return e.jsxs("div",{className:"card-row","data-ctx":`holder:${s.id}`,children:[e.jsxs("div",{className:"card-row-head",children:[e.jsxs("button",{type:"button",className:"link",onClick:()=>je(s.id),children:[e.jsx("span",{className:"rail-dot",style:{background:s.color??"var(--accent)"},"aria-hidden":"true"}),s.name]}),xe(Ue(s))?e.jsx(ee,{className:"panel-pick",value:r.involvement,options:["core","partial","advisor"].map(x=>({value:x,label:`${ue[x]}  ${re(x)}`})),onChange:x=>p.patchMember(s.id,r.id,{involvement:x}),children:e.jsxs("span",{className:`inv inv-${r.involvement}`,children:[e.jsx("span",{className:"inv-mark","aria-hidden":"true",children:ue[r.involvement]}),re(r.involvement)]})}):e.jsxs("span",{className:`inv inv-${r.involvement}`,children:[e.jsx("span",{className:"inv-mark","aria-hidden":"true",children:ue[r.involvement]}),re(r.involvement)]})]}),e.jsxs("div",{className:"card-row-facts hint",children:[Fe(s)===t.id&&e.jsx("span",{className:"chip",children:l("Project lead")}),r.role&&e.jsx("span",{children:r.role}),j.length>0&&e.jsxs("span",{children:[l("owns"),": ",j.join(", ")]}),S.length>0&&e.jsxs("span",{children:[l("works on"),": ",S.join(", ")]})]})]},s.id)})]}),e.jsx(oa,{personId:t.id,onOpenProject:je})]});async function v(){const s=u.filter(x=>x.id!==t.id&&x.companyId===t.companyId&&!o.some(te=>te.id===x.id)),r=x=>({value:x.id,label:x.fullName,sub:x.title||void 0});let j=null;if(o.length){const x=await Le(l("{name} has {n} reports. Who takes them over?",{name:t.fullName,n:o.length}),{label:l("Without a successor the archiving cannot finish: the reporting tree must not be broken."),options:s.map(r),okLabel:"Send to the archive"});if(!x)return;j=x}let S=null;if(I.length){const x=await Le(l("{n} open tasks are on {name}. Who takes them?",{n:I.length,name:t.fullName}),{label:l("Nobody — the tasks stay on them and will be visible as ownerless."),options:s.map(r),noneLabel:l("Nobody — leave the tasks as they are"),okLabel:"Send to the archive"});if(x===void 0)return;S=x}await ve(l("Send {name} to the archive?",{name:t.fullName}),{okLabel:"Send to the archive"})&&await ae(j,S)}const B=[{key:"about",label:"About",n:0},{key:"work",label:"Work",n:I.length+ye.length},{key:"projects",label:"Projects",n:U.length},...xe("insights.read")?[{key:"stats",label:"Numbers",n:0}]:[],{key:"history",label:"History",n:0}],X=e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"tabs card-tabs","data-help":"person-tabs",role:"tablist","aria-label":l("The card"),children:B.map(s=>e.jsxs("button",{type:"button",role:"tab","aria-selected":Y===s.key,className:Y===s.key?"on":"",onClick:()=>Ce(s.key),children:[l(s.label),s.n>0&&e.jsx("span",{className:"count",children:s.n})]},s.key))}),Y==="about"?a:Y==="work"?i:Y==="projects"?b:Y==="stats"?e.jsx(ia,{personId:t.id,holders:N}):e.jsx(ca,{person:t,people:u,departments:$,companies:R})]}),O=e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"team-name plain",children:[e.jsx(me,{person:t,size:c?48:36}),e.jsxs("span",{children:[e.jsxs("span",{className:"team-full",children:[t.fullName,t.plannedOut&&e.jsx("span",{className:"card-mark out",title:l("A possible dismissal (what-if)"),children:l("dismissal")}),t.underReview&&e.jsx("span",{className:"card-mark review",title:l("Under review: is this person needed?"),children:"?"})]}),e.jsx("span",{className:"team-sub",children:d})]})]}),!c&&e.jsx("span",{className:"head-actions",children:e.jsx("button",{type:"button",className:"icon-btn",title:l("Close"),onClick:z,children:"×"})})]});return c?e.jsxs("div",{className:"person-page",children:[e.jsxs("button",{type:"button",className:"back-link",onClick:z,children:["← ",l("Back to the team")]}),e.jsx("header",{className:"panel-head",children:O}),e.jsx("div",{className:"panel-body",children:X})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"panel-scrim",style:{top:_},onClick:z}),e.jsxs("aside",{ref:E.ref,className:"side-panel wide",style:{top:_,width:E.width??void 0},role:"dialog","aria-label":t.fullName,children:[E.edge,e.jsx("header",{className:"panel-head",children:O}),e.jsx("div",{className:"panel-body",children:X})]})]})}export{wa as TeamView};

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.