refactor: transition to opaque workspace identifiers
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user