mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-30 03:00:41 -04:00
fix(frontend/copilot): close artifact panel on copilot page unmount
The artifact panel lived in the Zustand store, so its `isOpen` state survived copilot page unmounts. Navigating to /profile, /home, or a new chat and coming back would re-render the panel open with the prior session's artifact. Tickets SECRT-2254, SECRT-2223, SECRT-2220 all trace to this. Reset the panel in a useAutoOpenArtifacts unmount cleanup so leaving the copilot page (or session-less limbo) always returns users to a clean default-closed panel. Session-change reset was already handled; this covers the nav-away → nav-back case. Two new failing-first tests drive it: - SECRT-2254 repro: open panel → unmount hook → panel must be closed. - SECRT-2220 repro: seed store with a stale `isOpen: true`, mount+unmount, remount → panel must be closed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -88,4 +88,53 @@ describe("useAutoOpenArtifacts", () => {
|
||||
expect(s.activeArtifact?.id).toBe("c");
|
||||
expect(s.history).toEqual([]);
|
||||
});
|
||||
|
||||
// SECRT-2254: "had agent panel open then went to profile then went to home
|
||||
// and agent panel was still open". Nav-away unmounts the copilot page; if
|
||||
// the panel state persists in the store, coming back re-renders it open.
|
||||
it("closes the panel on unmount so nav-away → nav-back doesn't resurrect it (SECRT-2254)", () => {
|
||||
useCopilotUIStore.getState().openArtifact(makeArtifact(A_ID, "a.txt"));
|
||||
expect(useCopilotUIStore.getState().artifactPanel.isOpen).toBe(true);
|
||||
|
||||
const { unmount } = renderHook(() =>
|
||||
useAutoOpenArtifacts({ sessionId: "s1" }),
|
||||
);
|
||||
|
||||
act(() => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
const s = useCopilotUIStore.getState().artifactPanel;
|
||||
expect(s.isOpen).toBe(false);
|
||||
expect(s.activeArtifact).toBeNull();
|
||||
expect(s.history).toEqual([]);
|
||||
});
|
||||
|
||||
// SECRT-2220: "keep closed by default" — a fresh mount (e.g. user returns to
|
||||
// /copilot) must start with a closed panel even if the store somehow carries
|
||||
// stale state from a prior life.
|
||||
it("does not re-open a panel whose store state is stale on fresh mount (SECRT-2220)", () => {
|
||||
// Simulate the store being left in an open state by a previous page life.
|
||||
useCopilotUIStore.setState({
|
||||
artifactPanel: {
|
||||
isOpen: true,
|
||||
isMinimized: false,
|
||||
isMaximized: false,
|
||||
width: 600,
|
||||
activeArtifact: makeArtifact(A_ID, "stale.txt"),
|
||||
history: [],
|
||||
},
|
||||
});
|
||||
|
||||
const { unmount } = renderHook(() =>
|
||||
useAutoOpenArtifacts({ sessionId: "s1" }),
|
||||
);
|
||||
act(() => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
// Next mount of the page should see a clean store.
|
||||
renderHook(() => useAutoOpenArtifacts({ sessionId: "s1" }));
|
||||
expect(useCopilotUIStore.getState().artifactPanel.isOpen).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,4 +26,13 @@ export function useAutoOpenArtifacts({
|
||||
resetArtifactPanel();
|
||||
}
|
||||
}, [sessionId, resetArtifactPanel]);
|
||||
|
||||
// Reset on unmount so navigating away from /copilot (to /profile, /home,
|
||||
// etc.) can't leave the panel open in the Zustand store, which would then
|
||||
// render the panel re-open when the user returns. See SECRT-2254/2220.
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
resetArtifactPanel();
|
||||
};
|
||||
}, [resetArtifactPanel]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user