summaryrefslogtreecommitdiffhomepage
path: root/src/features/tabs/tabs.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-10-15 14:38:50 +0900
committerAdam Malczewski <[email protected]>2026-10-15 14:38:50 +0900
commitc4c1d76fec972e5d902a669f0cb1953eaa528f16 (patch)
treed5d85b8500157dd690e13954216a61a6aac64a8a /src/features/tabs/tabs.ts
parent3d3c28b10de06aae7e2ad474e8931a3fdd88b41c (diff)
downloaddispatch-web-c4c1d76fec972e5d902a669f0cb1953eaa528f16.tar.gz
dispatch-web-c4c1d76fec972e5d902a669f0cb1953eaa528f16.zip
feat(tabs): 2-column tab grid with nestable subagent groups + tab menu (add/remove from group)
Diffstat (limited to 'src/features/tabs/tabs.ts')
-rw-r--r--src/features/tabs/tabs.ts27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/features/tabs/tabs.ts b/src/features/tabs/tabs.ts
index ff7bb4f..b2dad7d 100644
--- a/src/features/tabs/tabs.ts
+++ b/src/features/tabs/tabs.ts
@@ -13,6 +13,13 @@ export interface Tab {
* renamed/removed. Absent for a raw model selection.
*/
readonly snapshot?: NamedAgentSelectionSnapshot;
+ /**
+ * The EFFECTIVE tab group parent (backend `tabGroupParentId`): the
+ * conversation whose subagent group this tab is visually nested under in
+ * the tab grid. Purely presentational — distinct from the lineage
+ * `parentConversationId`. Absent = ungrouped (a top-level tab).
+ */
+ readonly tabGroupParentId?: string;
}
export interface TabsState {
@@ -120,6 +127,26 @@ export function setTitle(state: TabsState, conversationId: string, title: string
return { tabs, activeConversationId: state.activeConversationId };
}
+/**
+ * Set (string) or clear (null) a tab's tab group parent. Omits the key when
+ * cleared (`exactOptionalPropertyTypes`). No-op for an unknown tab.
+ */
+export function setTabGroupParent(
+ state: TabsState,
+ conversationId: string,
+ parentId: string | null,
+): TabsState {
+ const tabs = state.tabs.map((t) => {
+ if (t.conversationId !== conversationId) return t;
+ if (parentId !== null) return { ...t, tabGroupParentId: parentId };
+ if (!("tabGroupParentId" in t)) return t;
+ const { tabGroupParentId: _omit, ...rest } = t;
+ void _omit;
+ return rest;
+ });
+ return { tabs, activeConversationId: state.activeConversationId };
+}
+
export function setWorkspaceId(
state: TabsState,
conversationId: string,