feat: add terminal tabs and split pane controls to workspace UI

This commit is contained in:
Mohamed Boudra
2026-03-18 19:55:04 +07:00
parent 5f2d4ac122
commit b763d4358e
6 changed files with 267 additions and 17 deletions
@@ -26,6 +26,7 @@ import {
reorderFocusedPaneTabsInLayout,
reorderPaneTabsInLayout,
retargetTabInLayout,
splitPaneEmptyInLayout,
splitPaneInLayout,
type SplitGroup,
type SplitNode,
@@ -66,6 +67,13 @@ interface WorkspaceLayoutStore {
position: "left" | "right" | "top" | "bottom";
}
) => string | null;
splitPaneEmpty: (
workspaceKey: string,
input: {
targetPaneId: string;
position: "left" | "right" | "top" | "bottom";
}
) => string | null;
moveTabToPane: (workspaceKey: string, tabId: string, toPaneId: string) => void;
focusPane: (workspaceKey: string, paneId: string) => void;
resizeSplit: (workspaceKey: string, groupId: string, sizes: number[]) => void;
@@ -252,6 +260,39 @@ export const useWorkspaceLayoutStore = create<WorkspaceLayoutStore>()(
return result.paneId;
},
splitPaneEmpty: (workspaceKey, input) => {
const normalizedWorkspaceKey = trimNonEmpty(workspaceKey);
const normalizedTargetPaneId = trimNonEmpty(input.targetPaneId);
if (!normalizedWorkspaceKey || !normalizedTargetPaneId) {
return null;
}
const result = splitPaneEmptyInLayout({
layout: getWorkspaceLayout(get().layoutByWorkspace, normalizedWorkspaceKey),
targetPaneId: normalizedTargetPaneId,
position: input.position,
maxTreeDepth: MAX_TREE_DEPTH,
createNodeId: (prefix) => {
const randomValue =
typeof globalThis.crypto?.randomUUID === "function"
? globalThis.crypto.randomUUID()
: `${Date.now()}-${Math.random().toString(16).slice(2)}`;
return `${prefix}_${randomValue}`;
},
});
if (!result) {
return null;
}
set((state) => ({
layoutByWorkspace: {
...state.layoutByWorkspace,
[normalizedWorkspaceKey]: result.layout,
},
}));
return result.paneId;
},
moveTabToPane: (workspaceKey, tabId, toPaneId) => {
const normalizedWorkspaceKey = trimNonEmpty(workspaceKey);
const normalizedTabId = trimNonEmpty(tabId);