Closes #249: layoutStore.ts wraps the existing layout.ts tree model in Zustand, persisting to localStorage on a 400ms debounce and adding boot reconciliation to prune leaves for sessions no longer live. MultiView/TabBar/PaneContainer/PaneTitle render tabs, nested splits with draggable dividers, drag-and-drop tab reordering, and dispatch each pane to TerminalPane or StructuredPane by session view. Preview mode (#251) and sidebar drag-to-dock stay out of scope here.
50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
// Dispatches a leaf's session to the right body — TerminalPane for a PTY
|
|
// session, StructuredPane for an ACP one (session.view, #133/#140/#249).
|
|
|
|
import { forwardRef, useImperativeHandle, useRef } from "react";
|
|
|
|
import type { Session, Uuid } from "../../types.js";
|
|
import { StructuredPane, type StructuredPaneHandle } from "../structured/StructuredPane.js";
|
|
import { TerminalPane, type TerminalPaneHandle } from "../terminal/TerminalPane.js";
|
|
|
|
export interface PaneContainerHandle {
|
|
focusTerminal(): void;
|
|
/** No-op for a structured pane — it has no PTY (pane.ts's PaneConnection contract). */
|
|
sendInput(data: string): void;
|
|
}
|
|
|
|
export interface PaneContainerProps {
|
|
sessionId: Uuid;
|
|
session?: Session;
|
|
/** Grabs the keyboard once connected. A sidebar preview passes `false`. */
|
|
focus?: boolean;
|
|
onClosed?: () => void;
|
|
className?: string;
|
|
}
|
|
|
|
export const PaneContainer = forwardRef<PaneContainerHandle, PaneContainerProps>(function PaneContainer(
|
|
{ sessionId, session, focus, onClosed, className },
|
|
ref,
|
|
) {
|
|
const terminalRef = useRef<TerminalPaneHandle>(null);
|
|
const structuredRef = useRef<StructuredPaneHandle>(null);
|
|
|
|
useImperativeHandle(
|
|
ref,
|
|
() => ({
|
|
focusTerminal: () => {
|
|
terminalRef.current?.focusTerminal();
|
|
structuredRef.current?.focusComposer();
|
|
},
|
|
sendInput: (data: string) => terminalRef.current?.sendInput(data),
|
|
}),
|
|
[],
|
|
);
|
|
|
|
return session?.view === "Structured" ? (
|
|
<StructuredPane ref={structuredRef} sessionId={sessionId} focus={focus} onClosed={onClosed} className={className} />
|
|
) : (
|
|
<TerminalPane ref={terminalRef} sessionId={sessionId} focus={focus} onClosed={onClosed} className={className} />
|
|
);
|
|
});
|