diff --git a/AgentCompany-New/src/renderer/src/pages/FilesPage.tsx b/AgentCompany-New/src/renderer/src/pages/FilesPage.tsx index a2108797..3d599cb0 100644 --- a/AgentCompany-New/src/renderer/src/pages/FilesPage.tsx +++ b/AgentCompany-New/src/renderer/src/pages/FilesPage.tsx @@ -32,7 +32,7 @@ export function FilesPage({ snapshot, actions }: PageProps) { const [view, setView] = useState("list"); const [scanFilter, setScanFilter] = useState("all"); - const departments = collectDepartments(agents); + const departments = collectDepartments(files, agents); const filesByAgent = collectAgentFiles(files, agents); const sectionFiles = filterFiles(files, section, agents); const visibleFiles = scanFilter === "all" ? sectionFiles : sectionFiles.filter((file) => file.scanState === scanFilter); diff --git a/AgentCompany-New/src/renderer/src/pages/files/FilesTree.tsx b/AgentCompany-New/src/renderer/src/pages/files/FilesTree.tsx index 529f6406..127b87af 100644 --- a/AgentCompany-New/src/renderer/src/pages/files/FilesTree.tsx +++ b/AgentCompany-New/src/renderer/src/pages/files/FilesTree.tsx @@ -91,7 +91,7 @@ function TreeItem({ }) { return ( diff --git a/AgentCompany-New/src/renderer/src/pages/files/file-helpers.ts b/AgentCompany-New/src/renderer/src/pages/files/file-helpers.ts index 44849ba0..edac1934 100644 --- a/AgentCompany-New/src/renderer/src/pages/files/file-helpers.ts +++ b/AgentCompany-New/src/renderer/src/pages/files/file-helpers.ts @@ -23,13 +23,19 @@ export const FILE_COLOR_MAP: Record = folder: { color: "#a1a1aa", label: "" }, }; -export function collectDepartments(agents: AgentRecord[]): Array<{ name: string; count: number }> { - const seen = new Map(); - for (const agent of agents) { - if (!agent.department) continue; - seen.set(agent.department, (seen.get(agent.department) ?? 0) + 1); +/** Departments shown in the file tree carry a FILE count, not an agent count: + * the badge must equal what opening the section reveals. Departments with no + * files are omitted so the tree never advertises a folder that opens empty. */ +export function collectDepartments(files: FileObjectRecord[], agents: AgentRecord[]): Array<{ name: string; count: number }> { + const departmentByAgent = new Map(agents.map((agent) => [agent.id, agent.department])); + const counts = new Map(); + for (const file of files) { + if (file.ownerType !== "agent" || !file.ownerId) continue; + const department = departmentByAgent.get(file.ownerId); + if (!department) continue; + counts.set(department, (counts.get(department) ?? 0) + 1); } - return [...seen.entries()].map(([name, count]) => ({ name, count })).sort((a, b) => a.name.localeCompare(b.name)); + return [...counts.entries()].map(([name, count]) => ({ name, count })).sort((a, b) => a.name.localeCompare(b.name)); } export function collectAgentFiles(files: FileObjectRecord[], agents: AgentRecord[]): Array<{ agent: AgentRecord; count: number }> { diff --git a/AgentCompany-New/tests/unit/file-helpers.test.ts b/AgentCompany-New/tests/unit/file-helpers.test.ts new file mode 100644 index 00000000..343ec0fc --- /dev/null +++ b/AgentCompany-New/tests/unit/file-helpers.test.ts @@ -0,0 +1,41 @@ +import { describe, expect, test } from "vitest"; +import { collectDepartments } from "../../src/renderer/src/pages/files/file-helpers"; +import type { AgentRecord, FileObjectRecord } from "../../src/shared/domain"; + +function agent(id: string, department: string): AgentRecord { + return { + id, orgId: "org", name: id, role: "engineer", department, + modelProviderId: null, modelId: null, budgetCents: 0, managerAgentId: null, + title: id, roleLevel: "ic", modelStrategy: "single", workspaceId: null, + heartbeatEnabled: false, heartbeatIntervalSec: 0, lifecycle: "active", createdAt: "2026-01-01", + }; +} + +function file(id: string, ownerType: FileObjectRecord["ownerType"], ownerId: string | null): FileObjectRecord { + return { + id, orgId: "org", name: id, kind: "doc", sizeBytes: 1, sha256: "x", storagePath: `/tmp/${id}`, + ownerType, ownerId, spaceId: null, pinned: false, scanState: "approved", scanLabelsJson: "[]", + scannedAt: null, createdAt: "2026-01-01", updatedAt: null, + }; +} + +describe("collectDepartments", () => { + test("counts files per department, not agents, and omits empty departments", () => { + const agents = [agent("a1", "Engineering"), agent("a2", "Engineering"), agent("a3", "Design"), agent("a4", "Sales")]; + const files = [ + file("f1", "agent", "a1"), + file("f2", "agent", "a1"), + file("f3", "agent", "a3"), + file("f4", "employee", "emp1"), // not owned by an agent → ignored + ]; + // Engineering has two agents but only a1 holds files (2); Design has 1; Sales has agents but no files. + expect(collectDepartments(files, agents)).toEqual([ + { name: "Design", count: 1 }, + { name: "Engineering", count: 2 }, + ]); + }); + + test("returns nothing when no agent owns a file", () => { + expect(collectDepartments([], [agent("a1", "Engineering")])).toEqual([]); + }); +});