fix(FN-3376): close mobile agent detail when switching agent views
- Add a shared handleAgentViewChange callback to update view mode transitions - Close the selected agent detail pane on mobile when switching between list, board, and org views - Route all view-toggle buttons through the new handler for consistent behavior - Add a regression test in AgentsView.test.tsx covering mobile org-chart view switch behavior Fusion-Task-Id: FN-3376
This commit is contained in:
@@ -704,6 +704,13 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleAgentViewChange = useCallback((nextView: "list" | "board" | "org") => {
|
||||||
|
setAgentView(nextView);
|
||||||
|
if (isMobileViewport && selectedAgentId) {
|
||||||
|
handleCloseDetail();
|
||||||
|
}
|
||||||
|
}, [handleCloseDetail, isMobileViewport, selectedAgentId]);
|
||||||
|
|
||||||
const getRoleLabel = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.label ?? role;
|
const getRoleLabel = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.label ?? role;
|
||||||
const getRoleIcon = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.icon ?? "◆";
|
const getRoleIcon = (role: AgentCapability) => AGENT_ROLES.find(r => r.value === role)?.icon ?? "◆";
|
||||||
const selectedAgent = selectedAgentId ? displayAgents.find((agent) => agent.id === selectedAgentId) ?? null : null;
|
const selectedAgent = selectedAgentId ? displayAgents.find((agent) => agent.id === selectedAgentId) ?? null : null;
|
||||||
@@ -742,7 +749,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
<div className="view-toggle">
|
<div className="view-toggle">
|
||||||
<button
|
<button
|
||||||
className={`view-toggle-btn${agentView === "list" ? " active" : ""}`}
|
className={`view-toggle-btn${agentView === "list" ? " active" : ""}`}
|
||||||
onClick={() => setAgentView("list")}
|
onClick={() => handleAgentViewChange("list")}
|
||||||
title="List view"
|
title="List view"
|
||||||
aria-label="List view"
|
aria-label="List view"
|
||||||
aria-pressed={agentView === "list"}
|
aria-pressed={agentView === "list"}
|
||||||
@@ -751,7 +758,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`view-toggle-btn${agentView === "board" ? " active" : ""}`}
|
className={`view-toggle-btn${agentView === "board" ? " active" : ""}`}
|
||||||
onClick={() => setAgentView("board")}
|
onClick={() => handleAgentViewChange("board")}
|
||||||
title="Board view"
|
title="Board view"
|
||||||
aria-label="Board view"
|
aria-label="Board view"
|
||||||
aria-pressed={agentView === "board"}
|
aria-pressed={agentView === "board"}
|
||||||
@@ -760,7 +767,7 @@ export function AgentsView({ addToast, projectId, onOpenTaskLogs, agentOnboardin
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`view-toggle-btn${agentView === "org" ? " active" : ""}`}
|
className={`view-toggle-btn${agentView === "org" ? " active" : ""}`}
|
||||||
onClick={() => setAgentView("org")}
|
onClick={() => handleAgentViewChange("org")}
|
||||||
title="Org Chart view"
|
title="Org Chart view"
|
||||||
aria-label="Org Chart view"
|
aria-label="Org Chart view"
|
||||||
aria-pressed={agentView === "org"}
|
aria-pressed={agentView === "org"}
|
||||||
|
|||||||
@@ -340,6 +340,39 @@ describe("AgentsView", () => {
|
|||||||
expect(container.querySelector(".agents-split-detail--hidden-mobile")).toBeTruthy();
|
expect(container.querySelector(".agents-split-detail--hidden-mobile")).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("closes mobile detail and shows org chart when switching views", async () => {
|
||||||
|
mockViewportMode.mockReturnValue("mobile");
|
||||||
|
mockFetchOrgTree.mockResolvedValue([
|
||||||
|
{
|
||||||
|
agent: {
|
||||||
|
id: "agent-org-1",
|
||||||
|
name: "Org Lead",
|
||||||
|
role: "scheduler",
|
||||||
|
state: "active",
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
metadata: {},
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
render(<AgentsView addToast={mockAddToast} />);
|
||||||
|
|
||||||
|
fireEvent.click(await screen.findByRole("button", { name: "View details for Test Agent 1" }));
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByTestId("agent-detail-view")).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByRole("button", { name: "Org Chart view" }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.queryByTestId("agent-detail-view")).toBeNull();
|
||||||
|
expect(screen.getByTestId("agent-org-chart")).toBeTruthy();
|
||||||
|
expect(screen.getByText("Org Lead")).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("collapses mobile overview after selecting an active agent card", async () => {
|
it("collapses mobile overview after selecting an active agent card", async () => {
|
||||||
mockViewportMode.mockReturnValue("mobile");
|
mockViewportMode.mockReturnValue("mobile");
|
||||||
render(<AgentsView addToast={mockAddToast} />);
|
render(<AgentsView addToast={mockAddToast} />);
|
||||||
|
|||||||
Reference in New Issue
Block a user