feat(FN-3902): compact sidebar agent action labels to prevent overflow
Adds compact agent action labels to the sidebar in AgentsView, with CSS improvements and tests asserting the wrapper behavior, plus a changeset to release the change as a patch. Fusion-Task-Id: FN-3902
This commit is contained in:
5
.changeset/fn-3902-agent-sidebar-button-overflow.md
Normal file
5
.changeset/fn-3902-agent-sidebar-button-overflow.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix agent sidebar action buttons (Run Now, Pause, Details) overflowing on narrow agent cards by collapsing them to icon-only controls in the sidebar context.
|
||||||
@@ -709,6 +709,19 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.agents-split-sidebar .agent-card-actions {
|
||||||
|
gap: var(--space-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.agents-split-sidebar .agent-card-actions .btn {
|
||||||
|
gap: var(--space-xs);
|
||||||
|
padding: var(--space-xs) var(--space-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.agents-split-sidebar .agent-card-actions .agent-card-action-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.agent-card-details-btn {
|
.agent-card-details-btn {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1375,7 +1375,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
disabled={transitioningAgentIds.has(agent.id)}
|
disabled={transitioningAgentIds.has(agent.id)}
|
||||||
title="Activate"
|
title="Activate"
|
||||||
>
|
>
|
||||||
<Play size={14} /> Start
|
<Play size={14} /> <span className="agent-card-action-label">Start</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{agent.state === "active" && (
|
{agent.state === "active" && (
|
||||||
@@ -1387,7 +1387,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
title="Run Now"
|
title="Run Now"
|
||||||
aria-label={`Run now for ${agent.name}`}
|
aria-label={`Run now for ${agent.name}`}
|
||||||
>
|
>
|
||||||
<Activity size={14} /> Run Now
|
<Activity size={14} /> <span className="agent-card-action-label">Run Now</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm"
|
className="btn btn-sm"
|
||||||
@@ -1395,7 +1395,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
disabled={transitioningAgentIds.has(agent.id)}
|
disabled={transitioningAgentIds.has(agent.id)}
|
||||||
title="Pause"
|
title="Pause"
|
||||||
>
|
>
|
||||||
<Pause size={14} /> Pause
|
<Pause size={14} /> <span className="agent-card-action-label">Pause</span>
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -1406,7 +1406,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
disabled={transitioningAgentIds.has(agent.id)}
|
disabled={transitioningAgentIds.has(agent.id)}
|
||||||
title="Resume"
|
title="Resume"
|
||||||
>
|
>
|
||||||
<Play size={14} /> Resume
|
<Play size={14} /> <span className="agent-card-action-label">Resume</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{agent.state === "running" && (
|
{agent.state === "running" && (
|
||||||
@@ -1417,7 +1417,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
title="View live run details"
|
title="View live run details"
|
||||||
aria-label={`View live run details for ${agent.name}`}
|
aria-label={`View live run details for ${agent.name}`}
|
||||||
>
|
>
|
||||||
<Activity size={14} /> Running
|
<Activity size={14} /> <span className="agent-card-action-label">Running</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm"
|
className="btn btn-sm"
|
||||||
@@ -1425,7 +1425,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
disabled={transitioningAgentIds.has(agent.id)}
|
disabled={transitioningAgentIds.has(agent.id)}
|
||||||
title="Pause"
|
title="Pause"
|
||||||
>
|
>
|
||||||
<Pause size={14} /> Pause
|
<Pause size={14} /> <span className="agent-card-action-label">Pause</span>
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -1436,7 +1436,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
disabled={transitioningAgentIds.has(agent.id)}
|
disabled={transitioningAgentIds.has(agent.id)}
|
||||||
title="Retry"
|
title="Retry"
|
||||||
>
|
>
|
||||||
<Play size={14} /> Retry
|
<Play size={14} /> <span className="agent-card-action-label">Retry</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
@@ -1445,7 +1445,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
title={`View details for ${agent.name}`}
|
title={`View details for ${agent.name}`}
|
||||||
aria-label={`View details for ${agent.name}`}
|
aria-label={`View details for ${agent.name}`}
|
||||||
>
|
>
|
||||||
Details
|
<span className="agent-card-action-label">Details</span>
|
||||||
</button>
|
</button>
|
||||||
{(agent.state === "idle" || agent.state === "paused") && (
|
{(agent.state === "idle" || agent.state === "paused") && (
|
||||||
<button
|
<button
|
||||||
@@ -1453,7 +1453,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
onClick={() => void handleDelete(agent.id, agent.name)}
|
onClick={() => void handleDelete(agent.id, agent.name)}
|
||||||
title="Delete"
|
title="Delete"
|
||||||
>
|
>
|
||||||
<Trash2 size={14} /> Delete
|
<Trash2 size={14} /> <span className="agent-card-action-label">Delete</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1976,6 +1976,29 @@ describe("AgentsView", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("Run Now button", () => {
|
describe("Run Now button", () => {
|
||||||
|
it("renders sidebar action labels with wrapper spans for icon-only compaction (FN-3902)", async () => {
|
||||||
|
const activeWithoutTaskId = { ...mockAgents[1] };
|
||||||
|
delete activeWithoutTaskId.taskId;
|
||||||
|
mockFetchAgents.mockResolvedValue([
|
||||||
|
mockAgents[0],
|
||||||
|
activeWithoutTaskId,
|
||||||
|
mockAgents[2],
|
||||||
|
mockAgents[3],
|
||||||
|
]);
|
||||||
|
|
||||||
|
render(<AgentsView addToast={mockAddToast} />);
|
||||||
|
|
||||||
|
const runNowButton = await screen.findByTitle("Run Now");
|
||||||
|
const pauseButton = await screen.findByTitle("Pause");
|
||||||
|
const activeCard = runNowButton.closest(".agent-card");
|
||||||
|
const detailsButton = activeCard?.querySelector('[aria-label^="View details for "]') as HTMLButtonElement | null;
|
||||||
|
|
||||||
|
expect(detailsButton).toBeTruthy();
|
||||||
|
expect(runNowButton.querySelector(".agent-card-action-label")).toBeTruthy();
|
||||||
|
expect(pauseButton.querySelector(".agent-card-action-label")).toBeTruthy();
|
||||||
|
expect(detailsButton?.querySelector(".agent-card-action-label")).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
it("shows Run Now button for active agent without taskId", async () => {
|
it("shows Run Now button for active agent without taskId", async () => {
|
||||||
const activeWithoutTaskId = { ...mockAgents[1] };
|
const activeWithoutTaskId = { ...mockAgents[1] };
|
||||||
delete activeWithoutTaskId.taskId;
|
delete activeWithoutTaskId.taskId;
|
||||||
|
|||||||
Reference in New Issue
Block a user