fix(webui): persist large sidebar ordering state

This commit is contained in:
Xubin Ren
2026-08-06 19:11:05 +08:00
parent 1d290614c9
commit c2fd41b44d
7 changed files with 110 additions and 33 deletions
+8 -13
View File
@@ -13,6 +13,7 @@ const getSessionAutomationsSpy = vi.fn<(key: string) => Promise<SessionAutomatio
const toggleThemeSpy = vi.fn();
const updateUrlSpy = vi.fn();
const attachSpy = vi.fn();
const setSidebarStateSpy = vi.fn();
const runStatusHandlers = new Set<(chatId: string, startedAt: number | null) => void>();
const sessionUpdateHandlers = new Set<(chatId: string, scope?: string) => void>();
let mockSessions: ChatSummary[] = [];
@@ -218,6 +219,7 @@ vi.mock("@/lib/nanobot-client", () => {
sendMessage = vi.fn();
newChat = vi.fn();
attach = attachSpy;
setSidebarState = setSidebarStateSpy;
close = vi.fn();
updateUrl = updateUrlSpy;
updateMaxFrameBytes = vi.fn();
@@ -245,6 +247,7 @@ describe("App layout", () => {
getSessionAutomationsSpy.mockReset().mockResolvedValue([]);
toggleThemeSpy.mockReset();
attachSpy.mockReset();
setSidebarStateSpy.mockReset();
runStatusHandlers.clear();
sessionUpdateHandlers.clear();
window.history.replaceState(null, "", "/");
@@ -1403,13 +1406,6 @@ describe("App layout", () => {
if (href === "/api/webui/sidebar-state") {
return { ok: true, json: async () => initialState };
}
if (href.startsWith("/api/webui/sidebar-state/update?")) {
const encoded = new URLSearchParams(href.split("?", 2)[1]).get("state");
return {
ok: true,
json: async () => JSON.parse(encoded ?? "{}"),
};
}
return { ok: false, status: 404 };
}),
);
@@ -1429,12 +1425,11 @@ describe("App layout", () => {
expect(within(sidebar).getByText("Archived")).toBeInTheDocument(),
);
expect(within(sidebar).getByRole("button", { name: /^First chat$/ })).toBeInTheDocument();
const updateUrl = vi.mocked(fetch).mock.calls
.map(([url]) => String(url))
.find((url) => url.startsWith("/api/webui/sidebar-state/update?"));
expect(updateUrl).toBeTruthy();
const encoded = new URLSearchParams(updateUrl?.split("?", 2)[1]).get("state");
expect(JSON.parse(encoded ?? "{}").view.show_archived).toBe(true);
expect(setSidebarStateSpy).toHaveBeenCalledWith(
expect.objectContaining({
view: expect.objectContaining({ show_archived: true }),
}),
);
expect(within(sidebar).queryByRole("button", { name: "View" })).not.toBeInTheDocument();
});