diff --git a/packages/dashboard/app/components/TaskCard.css b/packages/dashboard/app/components/TaskCard.css index d6858f41b0..6a51240a39 100644 --- a/packages/dashboard/app/components/TaskCard.css +++ b/packages/dashboard/app/components/TaskCard.css @@ -885,17 +885,10 @@ falling through to an unstyled transparent shell. white-space: nowrap; } -@container task-card (max-width: 240px) { - .card-agent-badge-text { - display: none; - } -} - -@media (max-width: 768px) { - .card-agent-badge-text { - display: none; - } -} +/* +FNXC:TaskCardBadges 2026-07-15-00:00: +Task-card agent badges must retain their visible text label in narrow containers and on mobile. Do not hide the label into an icon-only pill; the existing ellipsis constraints preserve the card's no-wrap badge geometry for long names. +*/ .card-agent-badge--loading { animation: pulse 1.5s ease-in-out infinite; diff --git a/packages/dashboard/app/components/__tests__/TaskCard.badge-wrap.test.tsx b/packages/dashboard/app/components/__tests__/TaskCard.badge-wrap.test.tsx index f482f10b24..1b9a4e3f02 100644 --- a/packages/dashboard/app/components/__tests__/TaskCard.badge-wrap.test.tsx +++ b/packages/dashboard/app/components/__tests__/TaskCard.badge-wrap.test.tsx @@ -42,6 +42,14 @@ vi.mock("../PluginSlot", () => ({ vi.mock("../../hooks/useTaskDiffStats", () => ({ useTaskDiffStats: () => ({ stats: null, loading: false }), })); +vi.mock("../../hooks/useAgentsMapCache", () => ({ + useAgentsMapCache: () => ({ + agentsMap: new Map([["agent-ci", { name: "CI Engineer with a very long display name" }]]), + agents: [], + loading: false, + refresh: vi.fn(), + }), +})); vi.mock("../../hooks/useToast", () => ({ useToast: () => ({ addToast: vi.fn(), @@ -551,6 +559,31 @@ describe("TaskCard badge wrapping (FN-5162)", () => { expect(styles.whiteSpace).toBe("nowrap"); }); + it("keeps assigned-agent badge text visible and truncated in mobile and narrow-card CSS", () => { + const { container: assignedAgentContainer } = render( + , + ); + + const label = assignedAgentContainer.querySelector(".card-agent-badge-text") as HTMLElement; + expect(label).toBeTruthy(); + expect(label.textContent).toBe("CI Engineer ..."); + + const labelStyles = getComputedStyle(label); + expect(labelStyles.display).not.toBe("none"); + expect(labelStyles.overflow).toBe("hidden"); + expect(labelStyles.textOverflow).toBe("ellipsis"); + expect(labelStyles.whiteSpace).toBe("nowrap"); + + // jsdom does not apply media or container queries, so lock the source declaration that would otherwise hide this visible label. + const mobileSection = getCssBlocks(loadedCss, "max-width: 768px").join("\n"); + expect(mobileSection).not.toMatch(/\.card-agent-badge-text\s*\{[^}]*display\s*:\s*none/); + expect(loadedCss).not.toMatch(/@container\s+task-card\s*\(max-width:\s*240px\)\s*\{\s*\.card-agent-badge-text\s*\{[^}]*display\s*:\s*none/); + }); + it("places the agent badge in a left-aligned bottom row outside the header badge cluster", () => { const agentRow = container.querySelector(".card-agent-badge-row") as HTMLElement; const agentBadge = container.querySelector(".card-agent-created-badge") as HTMLElement;