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.
55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
// @vitest-environment happy-dom
|
|
import { cleanup, render, screen } from "@testing-library/react";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import type { Session } from "../../types.js";
|
|
import { PaneContainer } from "./PaneContainer.js";
|
|
|
|
vi.mock("../terminal/TerminalPane.js", () => ({
|
|
TerminalPane: ({ sessionId, focus }: { sessionId: string; focus?: boolean }) => (
|
|
<div data-testid="terminal-pane" data-session-id={sessionId} data-focus={String(focus)} />
|
|
),
|
|
}));
|
|
|
|
vi.mock("../structured/StructuredPane.js", () => ({
|
|
StructuredPane: ({ sessionId, focus }: { sessionId: string; focus?: boolean }) => (
|
|
<div data-testid="structured-pane" data-session-id={sessionId} data-focus={String(focus)} />
|
|
),
|
|
}));
|
|
|
|
afterEach(cleanup);
|
|
|
|
function session(over: Partial<Session> = {}): Session {
|
|
return {
|
|
id: "s1",
|
|
cwd: "/home/n",
|
|
command: "claude",
|
|
env: {},
|
|
metadata: {},
|
|
status: "Running",
|
|
created_at: "2026-01-01T00:00:00Z",
|
|
...over,
|
|
} as Session;
|
|
}
|
|
|
|
describe("PaneContainer", () => {
|
|
it("renders TerminalPane when the session has no view (defaults to Terminal)", () => {
|
|
render(<PaneContainer sessionId="s1" session={session()} />);
|
|
expect(screen.getByTestId("terminal-pane")).toBeTruthy();
|
|
expect(screen.queryByTestId("structured-pane")).toBeNull();
|
|
});
|
|
|
|
it("renders TerminalPane when the session isn't known yet", () => {
|
|
render(<PaneContainer sessionId="s1" />);
|
|
expect(screen.getByTestId("terminal-pane")).toBeTruthy();
|
|
});
|
|
|
|
it("renders StructuredPane for a Structured session", () => {
|
|
render(<PaneContainer sessionId="s1" session={session({ view: "Structured" })} focus={false} />);
|
|
const pane = screen.getByTestId("structured-pane");
|
|
expect(pane.dataset.sessionId).toBe("s1");
|
|
expect(pane.dataset.focus).toBe("false");
|
|
expect(screen.queryByTestId("terminal-pane")).toBeNull();
|
|
});
|
|
});
|