Fix workspace tab focus from route open intent
This commit is contained in:
@@ -576,8 +576,18 @@ function WorkspaceScreenContent({
|
||||
tabs: uiTabs,
|
||||
tabOrder,
|
||||
focusedTabId,
|
||||
preferredTarget:
|
||||
openIntent?.kind === "agent"
|
||||
? { kind: "agent", agentId: openIntent.agentId }
|
||||
: openIntent?.kind === "terminal"
|
||||
? { kind: "terminal", terminalId: openIntent.terminalId }
|
||||
: openIntent?.kind === "draft"
|
||||
? { kind: "draft", draftId: openIntent.draftId }
|
||||
: openIntent?.kind === "file"
|
||||
? { kind: "file", path: openIntent.path }
|
||||
: null,
|
||||
}),
|
||||
[focusedTabId, tabOrder, terminals, uiTabs, workspaceAgents]
|
||||
[focusedTabId, openIntent, tabOrder, terminals, uiTabs, workspaceAgents]
|
||||
);
|
||||
const activeTabId = tabModel.activeTabId;
|
||||
|
||||
|
||||
@@ -151,6 +151,23 @@ describe("deriveWorkspaceTabModel", () => {
|
||||
).toBe("agent_agent-b");
|
||||
});
|
||||
|
||||
it("prefers the route-selected target over stale focused tab state", () => {
|
||||
const model = deriveWorkspaceTabModel({
|
||||
workspaceAgents: [makeAgent({ id: "agent-a" }), makeAgent({ id: "agent-b" })],
|
||||
terminals: [],
|
||||
tabs: [
|
||||
{ tabId: "agent_agent-a", target: { kind: "agent", agentId: "agent-a" }, createdAt: 1 },
|
||||
{ tabId: "agent_agent-b", target: { kind: "agent", agentId: "agent-b" }, createdAt: 2 },
|
||||
],
|
||||
tabOrder: ["agent_agent-a", "agent_agent-b"],
|
||||
focusedTabId: "agent_agent-a",
|
||||
preferredTarget: { kind: "agent", agentId: "agent-b" },
|
||||
});
|
||||
|
||||
expect(model.activeTabId).toBe("agent_agent-b");
|
||||
expect(model.activeTab?.target).toEqual({ kind: "agent", agentId: "agent-b" });
|
||||
});
|
||||
|
||||
it("re-resolves active content for a new workspace when prior focused tab is not available", () => {
|
||||
const model = deriveWorkspaceTabModel({
|
||||
workspaceAgents: [makeAgent({ id: "workspace-b-agent", title: "B" })],
|
||||
@@ -237,4 +254,24 @@ describe("deriveWorkspaceTabModel", () => {
|
||||
expect(upgradedDescriptor.label).toBe("Ready title");
|
||||
}
|
||||
});
|
||||
|
||||
it("prefers a retargeted tab when the route selects its upgraded agent target", () => {
|
||||
const model = deriveWorkspaceTabModel({
|
||||
workspaceAgents: [makeAgent({ id: "agent-1", title: "Ready title" })],
|
||||
terminals: [],
|
||||
tabs: [
|
||||
{
|
||||
tabId: "draft_abc",
|
||||
target: { kind: "agent", agentId: "agent-1" },
|
||||
createdAt: 1,
|
||||
},
|
||||
],
|
||||
tabOrder: ["draft_abc"],
|
||||
focusedTabId: "some_other_tab",
|
||||
preferredTarget: { kind: "agent", agentId: "agent-1" },
|
||||
});
|
||||
|
||||
expect(model.activeTabId).toBe("draft_abc");
|
||||
expect(model.activeTab?.descriptor.tabId).toBe("draft_abc");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,6 +26,25 @@ function trimNonEmpty(value: string | null | undefined): string | null {
|
||||
return trimmed.length > 0 ? trimmed : null;
|
||||
}
|
||||
|
||||
function tabTargetsEqual(left: WorkspaceTabTarget, right: WorkspaceTabTarget): boolean {
|
||||
if (left.kind !== right.kind) {
|
||||
return false;
|
||||
}
|
||||
if (left.kind === "draft" && right.kind === "draft") {
|
||||
return left.draftId === right.draftId;
|
||||
}
|
||||
if (left.kind === "agent" && right.kind === "agent") {
|
||||
return left.agentId === right.agentId;
|
||||
}
|
||||
if (left.kind === "terminal" && right.kind === "terminal") {
|
||||
return left.terminalId === right.terminalId;
|
||||
}
|
||||
if (left.kind === "file" && right.kind === "file") {
|
||||
return left.path === right.path;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function formatProviderLabel(provider: Agent["provider"]): string {
|
||||
if (provider === "claude") {
|
||||
return "Claude";
|
||||
@@ -130,6 +149,7 @@ export function deriveWorkspaceTabModel(input: {
|
||||
tabs: WorkspaceTab[];
|
||||
tabOrder: string[];
|
||||
focusedTabId?: string | null;
|
||||
preferredTarget?: WorkspaceTabTarget | null;
|
||||
}): WorkspaceTabModel {
|
||||
const tabsById = new Map<string, WorkspaceDerivedTab>();
|
||||
const agentsById = new Map(input.workspaceAgents.map((agent) => [agent.id, agent]));
|
||||
@@ -234,9 +254,20 @@ export function deriveWorkspaceTabModel(input: {
|
||||
|
||||
const openTabIds = new Set(tabs.map((tab) => tab.descriptor.tabId));
|
||||
const focusedTabId = trimNonEmpty(input.focusedTabId);
|
||||
const preferredTarget = input.preferredTarget ?? null;
|
||||
const preferredTabId = (() => {
|
||||
if (!preferredTarget) {
|
||||
return null;
|
||||
}
|
||||
const matchingTab =
|
||||
tabs.find((tab) => tabTargetsEqual(tab.target, preferredTarget)) ?? null;
|
||||
return matchingTab?.descriptor.tabId ?? buildWorkspaceTabId(preferredTarget);
|
||||
})();
|
||||
|
||||
const activeTabId =
|
||||
focusedTabId && openTabIds.has(focusedTabId)
|
||||
preferredTabId && openTabIds.has(preferredTabId)
|
||||
? preferredTabId
|
||||
: focusedTabId && openTabIds.has(focusedTabId)
|
||||
? focusedTabId
|
||||
: tabs[0]?.descriptor.tabId ?? null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user