fix(workspace): bind each console pane to the lane it shows
LaneConsolePane kept handle/cwd/prompt/runHistory in local state that was never reset when the laneId prop changed, so selecting another lane swapped the header and detail panel while the terminal stayed attached to the previous lane's tmux session. Reset the pane on lane switch and re-attach immediately to the new lane's live run from GET /api/run when it has one, falling back to that lane's setup form when it does not. `lanes`/`activeRuns` are read through a ref so the page's 5s poll cannot wipe a half-typed prompt.
This commit is contained in:
@@ -124,6 +124,43 @@ describe("LaneConsolePane", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("swaps to the newly selected lane's own terminal instead of keeping the old one", async () => {
|
||||
const LANE2: Lane = { ...LANE, id: 2, title: "other", cwd: "/workspace/b" };
|
||||
const run = (id: string, laneId: number) => ({
|
||||
id,
|
||||
laneId,
|
||||
status: "running" as const,
|
||||
cwd: null,
|
||||
model: null,
|
||||
permissionMode: null,
|
||||
effort: null,
|
||||
resumeSessionId: null,
|
||||
sessionId: null,
|
||||
startedAt: null,
|
||||
promptPreview: null,
|
||||
});
|
||||
const props = {
|
||||
...baseProps(),
|
||||
lanes: [LANE, LANE2],
|
||||
activeRuns: { items: [run("ccam-lane-1", 1), run("ccam-lane-2", 2)] },
|
||||
};
|
||||
|
||||
const { rerender } = render(<LaneConsolePane {...props} />);
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId("terminal-view")).toHaveAttribute("data-run-id", "ccam-lane-1")
|
||||
);
|
||||
|
||||
rerender(<LaneConsolePane {...props} laneId={2} />);
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId("terminal-view")).toHaveAttribute("data-run-id", "ccam-lane-2")
|
||||
);
|
||||
|
||||
// A lane with no live run falls back to its setup form, not the previous
|
||||
// lane's terminal.
|
||||
rerender(<LaneConsolePane {...props} lanes={[LANE, LANE2, { ...LANE, id: 3 }]} laneId={3} />);
|
||||
await waitFor(() => expect(screen.queryByTestId("terminal-view")).not.toBeInTheDocument());
|
||||
});
|
||||
|
||||
it("shows a lane dropdown only when showLaneSelector is true", () => {
|
||||
const { rerender } = render(<LaneConsolePane {...baseProps()} showLaneSelector />);
|
||||
expect(screen.getByTestId("pane-lane-select")).toBeInTheDocument();
|
||||
|
||||
Reference in New Issue
Block a user