Group and clear workspace status in the sidebar (#1317)

* Add status grouping to the workspace sidebar

* Mark workspaces as read from the sidebar

* Clean package builds before release checks

* Fix sidebar status follow-up checks
This commit is contained in:
Mohamed Boudra
2026-06-04 01:20:20 +08:00
committed by GitHub
parent 71ce96b913
commit 31ae545289
65 changed files with 3758 additions and 290 deletions
@@ -4,7 +4,11 @@ import type {
SidebarWorkspaceEntry,
} from "@/hooks/use-sidebar-workspaces-list";
import { buildSidebarShortcutModel, getRelativeSidebarShortcutTarget } from "./sidebar-shortcuts";
import {
buildSidebarShortcutModel,
buildStatusSidebarShortcutModel,
getRelativeSidebarShortcutTarget,
} from "./sidebar-shortcuts";
function workspace(input: {
serverId: string;
@@ -12,6 +16,8 @@ function workspace(input: {
workspaceDirectory: string;
name: string;
projectKey?: string;
statusBucket?: SidebarWorkspaceEntry["statusBucket"];
statusEnteredAt?: Date | null;
}): SidebarWorkspaceEntry {
return {
workspaceKey: `${input.serverId}:${input.workspaceId}`,
@@ -22,8 +28,9 @@ function workspace(input: {
projectKind: "git",
workspaceKind: "checkout",
name: input.name,
statusBucket: "done",
statusBucket: input.statusBucket ?? "done",
archivingAt: null,
statusEnteredAt: input.statusEnteredAt ?? null,
diffStat: null,
prHint: null,
archiveHasUncommittedChanges: null,
@@ -132,6 +139,68 @@ describe("buildSidebarShortcutModel", () => {
});
});
describe("buildStatusSidebarShortcutModel", () => {
it("builds shortcut targets in status visual order", () => {
const workspaces = [
workspace({
serverId: "s1",
workspaceId: "done-old",
workspaceDirectory: "/repo/done-old",
name: "done old",
projectKey: "p1",
statusBucket: "done",
statusEnteredAt: new Date("2026-01-01T00:00:00.000Z"),
}),
workspace({
serverId: "s1",
workspaceId: "running-new",
workspaceDirectory: "/repo/running-new",
name: "running new",
projectKey: "p2",
statusBucket: "running",
statusEnteredAt: new Date("2026-03-01T00:00:00.000Z"),
}),
workspace({
serverId: "s1",
workspaceId: "needs-input",
workspaceDirectory: "/repo/needs-input",
name: "needs input",
projectKey: "p1",
statusBucket: "needs_input",
statusEnteredAt: new Date("2026-02-01T00:00:00.000Z"),
}),
workspace({
serverId: "s1",
workspaceId: "running-old",
workspaceDirectory: "/repo/running-old",
name: "running old",
projectKey: "p2",
statusBucket: "running",
statusEnteredAt: new Date("2026-01-15T00:00:00.000Z"),
}),
];
const model = buildStatusSidebarShortcutModel({
workspaces,
projectNamesByKey: new Map([
["p1", "Project 1"],
["p2", "Project 2"],
]),
});
expect(model.shortcutTargets).toEqual([
{ serverId: "s1", workspaceId: "needs-input" },
{ serverId: "s1", workspaceId: "running-new" },
{ serverId: "s1", workspaceId: "running-old" },
{ serverId: "s1", workspaceId: "done-old" },
]);
expect(model.shortcutIndexByWorkspaceKey.get("s1:needs-input")).toBe(1);
expect(model.shortcutIndexByWorkspaceKey.get("s1:running-new")).toBe(2);
expect(model.shortcutIndexByWorkspaceKey.get("s1:running-old")).toBe(3);
expect(model.shortcutIndexByWorkspaceKey.get("s1:done-old")).toBe(4);
});
});
describe("getRelativeSidebarShortcutTarget", () => {
const targets = [
{ serverId: "s1", workspaceId: "ws-1" },