Make worktree archive optimistic

This commit is contained in:
Mohamed Boudra
2026-04-23 21:16:23 +07:00
parent 75b8ae640c
commit 80102753e1
5 changed files with 169 additions and 63 deletions
@@ -1,9 +1,6 @@
import type { DaemonClient } from "@server/client/daemon-client";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
buildWorkspaceArchiveRedirectRoute,
resolveWorkspaceArchiveRedirectWorkspaceId,
} from "@/utils/workspace-archive-navigation";
import { buildWorkspaceArchiveRedirectRoute } from "@/utils/workspace-archive-navigation";
import type { WorkspaceDescriptor } from "@/stores/session-store";
import { useSessionStore } from "@/stores/session-store";
import {
@@ -40,22 +37,23 @@ function workspace(
};
}
describe("resolveWorkspaceArchiveRedirectWorkspaceId", () => {
it("redirects an archived worktree to the visible local checkout for the same project", () => {
describe("buildWorkspaceArchiveRedirectRoute", () => {
it("redirects an archived worktree to the new workspace screen for the same project", () => {
const workspaces = [
workspace({ id: "/repo", workspaceKind: "checkout", name: "main" }),
workspace({ id: "/repo/.paseo/worktrees/feature", name: "feature" }),
];
expect(
resolveWorkspaceArchiveRedirectWorkspaceId({
buildWorkspaceArchiveRedirectRoute({
serverId: "server-1",
archivedWorkspaceId: "/repo/.paseo/worktrees/feature",
workspaces,
}),
).toBe("/repo");
).toBe("/h/server-1/new?dir=%2Frepo&name=Project");
});
it("falls back to the host root route when no sibling workspace target exists", () => {
it("redirects to the new workspace route when no sibling workspace target exists", () => {
const workspaces = [
workspace({
id: "/repo/.paseo/worktrees/feature",
@@ -70,10 +68,10 @@ describe("resolveWorkspaceArchiveRedirectWorkspaceId", () => {
archivedWorkspaceId: "/repo/.paseo/worktrees/feature",
workspaces,
}),
).toBe("/h/server-1");
).toBe("/h/server-1/new?dir=%2Frepo&name=Project");
});
it("falls back to the host root route when no alternate workspace target exists", () => {
it("redirects to the new workspace route instead of another workspace", () => {
const workspaces = [
workspace({
id: "/notes",
@@ -90,7 +88,7 @@ describe("resolveWorkspaceArchiveRedirectWorkspaceId", () => {
archivedWorkspaceId: "/notes",
workspaces,
}),
).toBe("/h/server-1");
).toBe("/h/server-1/new?dir=%2Fnotes&name=Project");
});
});
@@ -140,6 +138,6 @@ describe("redirectIfArchivingActiveWorkspace", () => {
}),
).toBe(true);
expect(replaceMock).toHaveBeenCalledWith("/h/server-1/workspace/main");
expect(replaceMock).toHaveBeenCalledWith("/h/server-1/new?dir=%2Frepo&name=Project");
});
});
@@ -1,55 +1,28 @@
import type { WorkspaceDescriptor } from "@/stores/session-store";
import { buildHostRootRoute, buildHostWorkspaceRoute } from "@/utils/host-routes";
import { buildHostNewWorkspaceRoute, buildHostRootRoute } from "@/utils/host-routes";
import { resolveWorkspaceRouteId } from "@/utils/workspace-execution";
export function resolveWorkspaceArchiveRedirectWorkspaceId(input: {
archivedWorkspaceId: string;
workspaces: Iterable<WorkspaceDescriptor>;
}): string | null {
const archivedWorkspaceId = resolveWorkspaceRouteId({
routeWorkspaceId: input.archivedWorkspaceId,
});
if (!archivedWorkspaceId) {
return null;
}
const workspaces = Array.from(input.workspaces);
const archivedWorkspace =
workspaces.find((workspace) => workspace.id === archivedWorkspaceId) ?? null;
if (!archivedWorkspace) {
return null;
}
const sameProjectWorkspaces = workspaces.filter(
(workspace) => workspace.projectId === archivedWorkspace.projectId,
);
const rootCheckoutWorkspace =
sameProjectWorkspaces.find(
(workspace) =>
workspace.workspaceKind === "local_checkout" && workspace.id !== archivedWorkspace.id,
) ?? null;
if (rootCheckoutWorkspace) {
return rootCheckoutWorkspace.id;
}
const siblingWorkspace =
sameProjectWorkspaces.find((workspace) => workspace.id !== archivedWorkspace.id) ?? null;
return siblingWorkspace?.id ?? null;
}
export function buildWorkspaceArchiveRedirectRoute(input: {
serverId: string;
archivedWorkspaceId: string;
workspaces: Iterable<WorkspaceDescriptor>;
}) {
const redirectWorkspaceId = resolveWorkspaceArchiveRedirectWorkspaceId({
archivedWorkspaceId: input.archivedWorkspaceId,
workspaces: input.workspaces,
const archivedWorkspaceId = resolveWorkspaceRouteId({
routeWorkspaceId: input.archivedWorkspaceId,
});
if (!redirectWorkspaceId) {
if (!archivedWorkspaceId) {
return buildHostRootRoute(input.serverId);
}
return buildHostWorkspaceRoute(input.serverId, redirectWorkspaceId);
const archivedWorkspace =
Array.from(input.workspaces).find((workspace) => workspace.id === archivedWorkspaceId) ?? null;
const sourceDirectory =
archivedWorkspace?.projectRootPath || archivedWorkspace?.workspaceDirectory;
if (!sourceDirectory) {
return buildHostRootRoute(input.serverId);
}
return buildHostNewWorkspaceRoute(input.serverId, sourceDirectory, {
displayName: archivedWorkspace.projectDisplayName,
});
}