Show New Workspace isolation controls immediately (#2702)
* fix(workspaces): show isolation without checkout delay * fix(workspaces): trust hydrated project capability * fix(workspaces): resolve branch before creation * fix(workspaces): honor invalidated checkout status * fix(workspaces): preserve isolation while projects load * fix(workspaces): keep provisional project routes usable Route-derived projects do not know their worktree capability. Represent that uncertainty at the placement boundary so remembered worktree intent survives hydration without disabling the New Workspace screen indefinitely.
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
import { resetReviewDraftStore, useReviewDraftStore } from "@/review/store";
|
||||
import {
|
||||
applyCheckoutStatusUpdateFromEvent,
|
||||
ensureCheckoutStatus,
|
||||
type CheckoutPrStatusPayload,
|
||||
type CheckoutStatusPayload,
|
||||
fetchCheckoutStatus,
|
||||
@@ -122,6 +123,40 @@ describe("fetchCheckoutStatus", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("ensureCheckoutStatus", () => {
|
||||
it("awaits the canonical checkout-status query and reuses its cached result", async () => {
|
||||
const queryClient = createQueryClient();
|
||||
const fetched = checkoutStatus({ currentBranch: "feature/current" });
|
||||
const client = { getCheckoutStatus: vi.fn(async () => fetched) };
|
||||
|
||||
const first = await ensureCheckoutStatus({ queryClient, client, serverId, cwd });
|
||||
const second = await ensureCheckoutStatus({ queryClient, client, serverId, cwd });
|
||||
|
||||
expect(first).toEqual(fetched);
|
||||
expect(second).toEqual(fetched);
|
||||
expect(client.getCheckoutStatus).toHaveBeenCalledExactlyOnceWith(cwd);
|
||||
});
|
||||
|
||||
it("awaits a refetch when the canonical cached status was invalidated", async () => {
|
||||
const queryClient = createQueryClient();
|
||||
queryClient.setQueryData(
|
||||
checkoutStatusQueryKey(serverId, cwd),
|
||||
checkoutStatus({ currentBranch: "feature/stale" }),
|
||||
);
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: checkoutStatusQueryKey(serverId, cwd),
|
||||
refetchType: "none",
|
||||
});
|
||||
const fetched = checkoutStatus({ currentBranch: "feature/current" });
|
||||
const client = { getCheckoutStatus: vi.fn(async () => fetched) };
|
||||
|
||||
const result = await ensureCheckoutStatus({ queryClient, client, serverId, cwd });
|
||||
|
||||
expect(result.currentBranch).toBe("feature/current");
|
||||
expect(client.getCheckoutStatus).toHaveBeenCalledExactlyOnceWith(cwd);
|
||||
});
|
||||
});
|
||||
|
||||
describe("applyCheckoutStatusUpdateFromEvent", () => {
|
||||
it("writes the checkout status to the cache using the cwd from the payload", () => {
|
||||
const queryClient = createQueryClient();
|
||||
|
||||
@@ -35,6 +35,24 @@ export async function fetchCheckoutStatus({
|
||||
return payload;
|
||||
}
|
||||
|
||||
export async function ensureCheckoutStatus({
|
||||
queryClient,
|
||||
client,
|
||||
serverId,
|
||||
cwd,
|
||||
}: {
|
||||
queryClient: QueryClient;
|
||||
client: CheckoutStatusClient;
|
||||
serverId: string;
|
||||
cwd: string;
|
||||
}): Promise<CheckoutStatusPayload> {
|
||||
return await queryClient.fetchQuery({
|
||||
queryKey: checkoutStatusQueryKey(serverId, cwd),
|
||||
queryFn: () => fetchCheckoutStatus({ client, serverId, cwd }),
|
||||
staleTime: Infinity,
|
||||
});
|
||||
}
|
||||
|
||||
export function applyCheckoutStatusUpdateFromEvent({
|
||||
queryClient,
|
||||
serverId,
|
||||
|
||||
Reference in New Issue
Block a user