Fix workspace navigation regression on web (#772)

Centralize workspace navigation behind a small route-derived API so the workspace shell reads active selection from the current Expo Router route instead of a separately synchronized store.

Remove the stale layout-driven active-workspace write that regressed web after 02e5b564.
This commit is contained in:
Mohamed Boudra
2026-05-06 13:22:31 +08:00
committed by GitHub
parent 0eacc98e17
commit 868479c493
26 changed files with 221 additions and 956 deletions
@@ -1,59 +1,27 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
/**
* @vitest-environment jsdom
*/
import { renderHook } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
const { dismissToMock } = vi.hoisted(() => ({
dismissToMock: vi.fn(),
const navigateToWorkspaceMock = vi.hoisted(() => vi.fn());
vi.mock("@/stores/navigation-active-workspace-store", () => ({
navigateToWorkspace: navigateToWorkspaceMock,
}));
vi.mock("expo-router", () => ({
router: {
dismissTo: dismissToMock,
},
}));
import { navigateToWorkspace, useWorkspaceNavigation } from "@/hooks/use-workspace-navigation";
import { navigateToWorkspace } from "@/hooks/use-workspace-navigation";
import {
activateNavigationWorkspaceSelection,
getNavigationActiveWorkspaceSelection,
syncNavigationActiveWorkspace,
} from "@/stores/navigation-active-workspace-store";
describe("navigateToWorkspace", () => {
beforeEach(() => {
dismissToMock.mockReset();
syncNavigationActiveWorkspace({ current: null });
describe("useWorkspaceNavigation", () => {
it("re-exports the workspace navigation action", () => {
expect(navigateToWorkspace).toBe(navigateToWorkspaceMock);
});
it("dismisses to the workspace route from a non-workspace route even when active selection is stale", () => {
activateNavigationWorkspaceSelection({
serverId: "server-1",
workspaceId: "workspace-a",
});
it("returns a stable callback wrapper", () => {
const { result } = renderHook(() => useWorkspaceNavigation());
navigateToWorkspace("server-1", "workspace-b", {
currentPathname: "/h/server-1/sessions",
});
result.current.navigateToWorkspace("server-1", "workspace-a");
expect(dismissToMock).toHaveBeenCalledWith("/h/server-1/workspace/workspace-b");
expect(getNavigationActiveWorkspaceSelection()).toEqual({
serverId: "server-1",
workspaceId: "workspace-a",
});
});
it("keeps retained workspace switching on a workspace route", () => {
activateNavigationWorkspaceSelection({
serverId: "server-1",
workspaceId: "workspace-a",
});
navigateToWorkspace("server-1", "workspace-b", {
currentPathname: "/h/server-1/workspace/workspace-a",
});
expect(dismissToMock).not.toHaveBeenCalled();
expect(getNavigationActiveWorkspaceSelection()).toEqual({
serverId: "server-1",
workspaceId: "workspace-b",
});
expect(navigateToWorkspaceMock).toHaveBeenCalledWith("server-1", "workspace-a", undefined);
});
});