refactor: transition to opaque workspace identifiers

This commit is contained in:
Mohamed Boudra
2026-04-15 17:59:09 +07:00
parent beeb315c8d
commit e6044264e2
34 changed files with 462 additions and 382 deletions
@@ -6,14 +6,20 @@ import type {
import { buildSidebarShortcutModel } from "./sidebar-shortcuts";
function workspace(serverId: string, cwd: string): SidebarWorkspaceEntry {
function workspace(input: {
serverId: string;
workspaceId: string;
workspaceDirectory: string;
name: string;
}): SidebarWorkspaceEntry {
return {
workspaceKey: `${serverId}:${cwd}`,
serverId,
workspaceId: cwd,
workspaceKey: `${input.serverId}:${input.workspaceId}`,
serverId: input.serverId,
workspaceId: input.workspaceId,
workspaceDirectory: input.workspaceDirectory,
projectKind: "git",
workspaceKind: "checkout",
name: cwd,
name: input.name,
statusBucket: "done",
diffStat: null,
scripts: [],
@@ -26,7 +32,7 @@ function project(projectKey: string, workspaces: SidebarWorkspaceEntry[]): Sideb
projectKey,
projectName: projectKey,
projectKind: "git",
iconWorkingDir: workspaces[0]?.workspaceId ?? "",
iconWorkingDir: workspaces[0]?.workspaceDirectory ?? "",
statusBucket: "done",
activeCount: 0,
totalWorkspaces: workspaces.length,
@@ -37,8 +43,34 @@ function project(projectKey: string, workspaces: SidebarWorkspaceEntry[]): Sideb
describe("buildSidebarShortcutModel", () => {
it("builds shortcut targets in visual order and excludes collapsed projects", () => {
const projects = [
project("p1", [workspace("s1", "/repo/main"), workspace("s1", "/repo/feat-a")]),
project("p2", [workspace("s1", "/repo2/main"), workspace("s1", "/repo2/feat-a")]),
project("p1", [
workspace({
serverId: "s1",
workspaceId: "ws-main",
workspaceDirectory: "/repo/main",
name: "main",
}),
workspace({
serverId: "s1",
workspaceId: "ws-feat-a",
workspaceDirectory: "/repo/feat-a",
name: "feat-a",
}),
]),
project("p2", [
workspace({
serverId: "s1",
workspaceId: "ws-repo2-main",
workspaceDirectory: "/repo2/main",
name: "main",
}),
workspace({
serverId: "s1",
workspaceId: "ws-repo2-feat-a",
workspaceDirectory: "/repo2/feat-a",
name: "feat-a",
}),
]),
];
const model = buildSidebarShortcutModel({
@@ -47,21 +79,26 @@ describe("buildSidebarShortcutModel", () => {
});
expect(model.visibleTargets).toEqual([
{ serverId: "s1", workspaceId: "/repo/main" },
{ serverId: "s1", workspaceId: "/repo/feat-a" },
{ serverId: "s1", workspaceId: "ws-main" },
{ serverId: "s1", workspaceId: "ws-feat-a" },
]);
expect(model.shortcutTargets).toEqual([
{ serverId: "s1", workspaceId: "/repo/main" },
{ serverId: "s1", workspaceId: "/repo/feat-a" },
{ serverId: "s1", workspaceId: "ws-main" },
{ serverId: "s1", workspaceId: "ws-feat-a" },
]);
expect(model.shortcutIndexByWorkspaceKey.get("s1:/repo/main")).toBe(1);
expect(model.shortcutIndexByWorkspaceKey.get("s1:/repo/feat-a")).toBe(2);
expect(model.shortcutIndexByWorkspaceKey.get("s1:/repo2/main")).toBeUndefined();
expect(model.shortcutIndexByWorkspaceKey.get("s1:ws-main")).toBe(1);
expect(model.shortcutIndexByWorkspaceKey.get("s1:ws-feat-a")).toBe(2);
expect(model.shortcutIndexByWorkspaceKey.get("s1:ws-repo2-main")).toBeUndefined();
});
it("limits shortcuts to 9", () => {
const workspaces = Array.from({ length: 20 }, (_, index) =>
workspace("s", `/repo/w${index + 1}`),
workspace({
serverId: "s",
workspaceId: `ws-${index + 1}`,
workspaceDirectory: `/repo/w${index + 1}`,
name: `w${index + 1}`,
}),
);
const projects = [project("p", workspaces)];
@@ -71,14 +108,23 @@ describe("buildSidebarShortcutModel", () => {
});
expect(model.visibleTargets).toHaveLength(20);
expect(model.visibleTargets[19]).toEqual({ serverId: "s", workspaceId: "/repo/w20" });
expect(model.visibleTargets[19]).toEqual({ serverId: "s", workspaceId: "ws-20" });
expect(model.shortcutTargets).toHaveLength(9);
expect(model.shortcutTargets[0]).toEqual({ serverId: "s", workspaceId: "/repo/w1" });
expect(model.shortcutTargets[8]).toEqual({ serverId: "s", workspaceId: "/repo/w9" });
expect(model.shortcutTargets[0]).toEqual({ serverId: "s", workspaceId: "ws-1" });
expect(model.shortcutTargets[8]).toEqual({ serverId: "s", workspaceId: "ws-9" });
});
it("still excludes collapsed single-workspace git projects because they are not flattened", () => {
const projects = [project("p1", [workspace("s1", "/repo/main")])];
const projects = [
project("p1", [
workspace({
serverId: "s1",
workspaceId: "ws-main",
workspaceDirectory: "/repo/main",
name: "main",
}),
]),
];
const model = buildSidebarShortcutModel({
projects,