diff --git a/packages/dashboard/app/components/AgentsView.css b/packages/dashboard/app/components/AgentsView.css
index cbe206e02..95d6dff5b 100644
--- a/packages/dashboard/app/components/AgentsView.css
+++ b/packages/dashboard/app/components/AgentsView.css
@@ -698,16 +698,30 @@
}
.agent-card-actions {
- display: flex;
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto;
gap: var(--space-sm);
- align-items: center;
- flex-wrap: nowrap;
+ align-items: start;
+ width: 100%;
+ min-width: 0;
container-type: inline-size;
container-name: agent-card-actions;
}
+.agent-card-actions-group {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-sm);
+ align-items: center;
+ min-width: 0;
+}
+
+.agent-card-actions-group--secondary {
+ justify-content: flex-end;
+}
+
.agent-card-actions .btn {
- flex-shrink: 0;
+ flex: 0 0 auto;
white-space: nowrap;
}
@@ -715,21 +729,29 @@
gap: var(--space-xs);
}
+.agents-split-sidebar .agent-card-actions-group {
+ gap: var(--space-xs);
+}
+
.agents-split-sidebar .agent-card-actions .btn {
gap: var(--space-xs);
padding: var(--space-xs) var(--space-sm);
}
@container agent-card-actions (max-width: calc(var(--space-2xl) * 9)) {
+ .agents-split-sidebar .agent-card-actions {
+ grid-template-columns: minmax(0, 1fr);
+ }
+
+ .agents-split-sidebar .agent-card-actions-group--secondary {
+ justify-content: flex-start;
+ }
+
.agents-split-sidebar .agent-card-actions .agent-card-action-label {
display: none;
}
}
-.agent-card-details-btn {
- margin-left: auto;
-}
-
.agent-card--clickable {
cursor: pointer;
}
diff --git a/packages/dashboard/app/components/AgentsView.tsx b/packages/dashboard/app/components/AgentsView.tsx
index bf85c43b0..e27d45197 100644
--- a/packages/dashboard/app/components/AgentsView.tsx
+++ b/packages/dashboard/app/components/AgentsView.tsx
@@ -1368,94 +1368,98 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
- {agent.state === "idle" && (
-
- )}
- {agent.state === "active" && (
- <>
+
+ {agent.state === "idle" && (
+ )}
+ {agent.state === "active" && (
+ <>
+
+
+ >
+ )}
+ {agent.state === "paused" && (
- >
- )}
- {agent.state === "paused" && (
-
- )}
- {agent.state === "running" && (
- <>
+ )}
+ {agent.state === "running" && (
+ <>
+
+
+ >
+ )}
+ {agent.state === "error" && (
-
- >
- )}
- {agent.state === "error" && (
+ )}
+
+
- )}
-
- {(agent.state === "idle" || agent.state === "paused") && (
-
- )}
+ {(agent.state === "idle" || agent.state === "paused") && (
+
+ )}
+
);
diff --git a/packages/dashboard/app/components/__tests__/AgentsView.test.tsx b/packages/dashboard/app/components/__tests__/AgentsView.test.tsx
index c3651aee3..c9e8d8876 100644
--- a/packages/dashboard/app/components/__tests__/AgentsView.test.tsx
+++ b/packages/dashboard/app/components/__tests__/AgentsView.test.tsx
@@ -651,18 +651,36 @@ describe("AgentsView", () => {
expect(screen.getAllByText("Details").length).toBeGreaterThanOrEqual(4);
});
- it("keeps a visible icon affordance on View Details buttons when labels are compacted", async () => {
- render();
+ it("keeps a visible icon affordance on split-sidebar action buttons when labels are compacted", async () => {
+ const { container } = render();
- const detailsButton = await screen.findByRole("button", { name: "View details for Test Agent 1" });
+ const sidebarCard = await waitFor(() => {
+ const card = container.querySelector(".agents-split-sidebar .agent-card");
+ expect(card).toBeTruthy();
+ return card as HTMLElement;
+ });
+ const actions = sidebarCard.querySelector(".agent-card-actions");
+ const primaryGroup = sidebarCard.querySelector(".agent-card-actions-group--primary");
+ const secondaryGroup = sidebarCard.querySelector(".agent-card-actions-group--secondary");
+ const detailsButton = within(sidebarCard).getByRole("button", { name: "View details for Test Agent 1" });
+
+ expect(actions).toBeTruthy();
+ expect(primaryGroup).toBeTruthy();
+ expect(secondaryGroup).toBeTruthy();
+ expect(primaryGroup?.querySelector("button")).toBeTruthy();
+ expect(secondaryGroup?.contains(detailsButton)).toBe(true);
expect(detailsButton.querySelector("svg")).toBeTruthy();
+ expect(sidebarCard.querySelectorAll(".agent-card-action-label").length).toBeGreaterThan(0);
});
- it("hides split-sidebar action labels only within an agent-card-actions container query", () => {
+ it("uses a grid-and-wrap containment contract for split-sidebar action rows", () => {
const css = loadAllAppCss();
+ expect(css).toMatch(/\.agent-card-actions\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*minmax\(0, 1fr\) auto;[^}]*width:\s*100%;[^}]*min-width:\s*0;[^}]*\}/);
+ expect(css).toMatch(/\.agent-card-actions-group\s*\{[^}]*display:\s*flex;[^}]*flex-wrap:\s*wrap;[^}]*min-width:\s*0;[^}]*\}/);
expect(css).not.toContain(".agents-split-sidebar .agent-card-actions .agent-card-action-label {\n display: none;\n}");
expect(css).toContain("@container agent-card-actions (max-width: calc(var(--space-2xl) * 9))");
+ expect(css).toContain(".agents-split-sidebar .agent-card-actions {\n grid-template-columns: minmax(0, 1fr);\n }");
expect(css).toContain(".agents-split-sidebar .agent-card-actions .agent-card-action-label {\n display: none;\n }");
});