Keep sidebar pins visible while reopening (#2210)
* fix(app): keep sidebar pins visible while reopening Hidden sidebars stop consuming live workspace updates but retain their last rendered entries so the opening animation never exposes an empty list. * test(app): reuse sidebar pin flow
This commit is contained in:
@@ -39,6 +39,13 @@ export async function clickArchiveWorkspaceMenuItem(
|
|||||||
await archiveItem.click();
|
await archiveItem.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function pinWorkspaceFromSidebar(page: Page, workspaceId: string): Promise<void> {
|
||||||
|
const serverId = await openWorkspaceSidebarKebab(page, workspaceId);
|
||||||
|
const pinItem = page.getByTestId(`sidebar-workspace-menu-pin-${serverId}:${workspaceId}`);
|
||||||
|
await expect(pinItem).toBeVisible({ timeout: 10_000 });
|
||||||
|
await pinItem.click();
|
||||||
|
}
|
||||||
|
|
||||||
export async function archiveWorkspaceFromSidebar(page: Page, workspaceId: string): Promise<void> {
|
export async function archiveWorkspaceFromSidebar(page: Page, workspaceId: string): Promise<void> {
|
||||||
// A clean workspace archives with no prompt. Managed worktree backing may raise
|
// A clean workspace archives with no prompt. Managed worktree backing may raise
|
||||||
// a browser confirm for unsynced work, so accept it when present.
|
// a browser confirm for unsynced work, so accept it when present.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
expectMobileAgentSidebarHidden,
|
expectMobileAgentSidebarHidden,
|
||||||
expectMobileAgentSidebarVisible,
|
expectMobileAgentSidebarVisible,
|
||||||
openMobileAgentSidebar,
|
openMobileAgentSidebar,
|
||||||
|
pinWorkspaceFromSidebar,
|
||||||
} from "./helpers/sidebar";
|
} from "./helpers/sidebar";
|
||||||
import { seedWorkspace } from "./helpers/seed-client";
|
import { seedWorkspace } from "./helpers/seed-client";
|
||||||
import { expectWorkspaceHeader } from "./helpers/workspace-ui";
|
import { expectWorkspaceHeader } from "./helpers/workspace-ui";
|
||||||
@@ -168,6 +169,30 @@ test.describe("Mobile sidebar panelState transition", () => {
|
|||||||
await closeMobileAgentSidebar(page);
|
await closeMobileAgentSidebar(page);
|
||||||
await expectMobileAgentSidebarHidden(page);
|
await expectMobileAgentSidebarHidden(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("keeps a pinned workspace rendered while the retained sidebar is closed", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const workspace = await seedWorkspace({ repoPrefix: "sidebar-retained-pin-" });
|
||||||
|
|
||||||
|
try {
|
||||||
|
await gotoAppShell(page);
|
||||||
|
await openMobileAgentSidebar(page);
|
||||||
|
await expectMobileAgentSidebarVisible(page);
|
||||||
|
|
||||||
|
const row = page.getByTestId(getWorkspaceRowTestId(workspace.workspaceId));
|
||||||
|
await expect(row).toBeVisible({ timeout: 30_000 });
|
||||||
|
await pinWorkspaceFromSidebar(page, workspace.workspaceId);
|
||||||
|
await expect(page.getByTestId("sidebar-pinned-section")).toBeVisible();
|
||||||
|
|
||||||
|
await closeMobileAgentSidebar(page);
|
||||||
|
await expectMobileAgentSidebarHidden(page);
|
||||||
|
|
||||||
|
await expect(row).toHaveCount(1);
|
||||||
|
} finally {
|
||||||
|
await workspace.cleanup();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe("Half-screen desktop layout", () => {
|
test.describe("Half-screen desktop layout", () => {
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ export function useSidebarWorkspaceEntries(
|
|||||||
// subscription to structurally shared indexes, never one session-store
|
// subscription to structurally shared indexes, never one session-store
|
||||||
// subscription per mounted row.
|
// subscription per mounted row.
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (!enabled || placements.length === 0 || sessions.length === 0) {
|
if (!enabled) {
|
||||||
|
return previousEntriesRef.current;
|
||||||
|
}
|
||||||
|
if (placements.length === 0 || sessions.length === 0) {
|
||||||
previousEntriesRef.current = EMPTY_ENTRIES;
|
previousEntriesRef.current = EMPTY_ENTRIES;
|
||||||
return EMPTY_ENTRIES;
|
return EMPTY_ENTRIES;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user