Keep selected projects when switching hosts (#2700)

* fix(app): preserve project selection across hosts

Rendered project identity and persisted equivalence were conflated after duplicate-project handling. Keep them separate so host changes resolve selectable equivalents deterministically without resetting legacy sidebar identity.

* fix(app): restore selected clone after host round trip

Keep manual origin and current destination placements separately so switching back restores the chosen checkout while archive gaps preserve the active host selection.

* fix(app): key status icons by project view

* fix(app): preserve origin during archive gaps
This commit is contained in:
Mohamed Boudra
2026-07-31 15:42:08 +02:00
committed by GitHub
parent 87ef631ac4
commit 99eca19a76
56 changed files with 1234 additions and 428 deletions
@@ -6,6 +6,7 @@ import type {
import {
buildSidebarProjectRowModel,
resolveSidebarProjectIconTarget,
resolveSidebarProjectIconTargets,
resolveSidebarProjectLocalPath,
} from "./sidebar-project-row-model";
@@ -14,7 +15,7 @@ function workspace(overrides: Partial<SidebarWorkspaceEntry> = {}): SidebarWorks
workspaceKey: "srv:ws-root",
serverId: "srv",
workspaceId: "ws-root",
projectKey: "project-1",
projectViewKey: "project-1",
projectName: "paseo",
workspaceDirectory: "/repo",
projectKind: "git",
@@ -48,7 +49,7 @@ function project(overrides: ProjectOverrides = {}): SidebarProjectEntry {
(host) => Object.assign({}, host, { projectId: host.projectId ?? `project-${host.serverId}` }),
);
return {
projectKey: "project-1",
viewKey: "project-1",
projectName: "paseo",
projectKind,
iconWorkingDir: "/repo",
@@ -209,6 +210,22 @@ describe("buildSidebarProjectRowModel", () => {
});
});
it("keys project icon results by the rendered project view", () => {
const [iconTarget] = resolveSidebarProjectIconTargets([
project({
viewKey: '["placement","host-b","project-b"]',
hosts: [{ serverId: "host-b", iconWorkingDir: "/repo/b", canCreateWorktree: true }],
}),
]);
expect(iconTarget).toEqual({
projectViewKey: '["placement","host-b","project-b"]',
serverId: "host-b",
projectId: "project-host-b",
iconWorkingDir: "/repo/b",
});
});
it("resolves desktop file actions from the local project placement", () => {
const groupedProject = project({
iconWorkingDir: "/remote/repo",