diff --git a/AgentCompany-New/src/renderer/src/pages/TeamPage.tsx b/AgentCompany-New/src/renderer/src/pages/TeamPage.tsx index 583d8eb6..d43ed0e0 100644 --- a/AgentCompany-New/src/renderer/src/pages/TeamPage.tsx +++ b/AgentCompany-New/src/renderer/src/pages/TeamPage.tsx @@ -3,6 +3,7 @@ import { Avatar, Button, Field, Icon, IconButton } from "../shared/ui"; import { TopbarActions } from "../shared/TopbarActions"; import { Dialog } from "../shared/Dialog"; import { OrgChartTree } from "./team/OrgChartTree"; +import { HiringPipeline } from "./team/HiringPipeline"; import type { AgentRecord, EmployeeRecord, ProviderRecord } from "../../../shared/domain"; import type { PageProps } from "./types"; import { activeOrgId, money } from "./types"; @@ -112,6 +113,8 @@ export function TeamPage({ snapshot, actions }: PageProps) { + a.orgId === orgId)} /> +
Roster
a.sourceEntityType === "agent" && a.sourceEntityId === agent.id && a.kind === "agent_hire", + ) ?? null; + + if (hireApproval?.state === "pending") return { agent, stage: "pending_approval", approval: hireApproval }; + if (hireApproval?.state === "declined") return { agent, stage: "rejected", approval: hireApproval }; + if (agent.lifecycle === "active") return { agent, stage: "active", approval: hireApproval }; + return { agent, stage: "approved", approval: hireApproval }; +} + +export function HiringPipeline({ agents, approvals }: { agents: AgentRecord[]; approvals: ApprovalRecord[] }) { + const entries = agents.map((a) => resolveStage(a, approvals)); + + return ( +
+
Hiring pipeline
+
+ {STAGES.map((stage) => { + const stageEntries = entries.filter((e) => e.stage === stage.id); + return ( +
+
+ + {stage.label} + {stageEntries.length} +
+
+ {stageEntries.map((entry) => ( +
+
+ +
+
{entry.agent.name}
+
{entry.agent.role} ยท {entry.agent.department}
+
+
+ {entry.approval && ( +
+ {formatRelative(entry.approval.createdAt)} +
+ )} +
+ ))} +
+
+ ); + })} +
+
+ ); +}