fix(workspace): stop the console remounting, and the idle polling re-renders
The Workspace page rendered `ConsoleArea` from two sites, picked by `currentLane`. Every flip of that value unmounted the whole console subtree and mounted it again at the other site: the terminal died, the run history went with it, and `LaneConsolePane`'s lane-switch effect wiped a half-typed prompt. It flipped on every page load (lanes arrive, `refreshLanes` selects `lanes[0]`), on a lane being removed, and on any refetch that re-picked the selection. `lane-detail` is now always rendered and holds the only `ConsoleArea`; the header and info block are the conditional parts. Same rule the RunConsole already followed one level down — collapse with CSS, never by unmounting — now enforced above it too. Second half: every poller fed `setState` a brand-new object graph each tick, re-rendering the lane strip, the card and the console area several times a minute on a completely idle dashboard. `keepIfSame` keeps the previous reference when the payload is value-identical, applied to the 5 s run/session poll, the lane list and counts, the `lane_update` WS branch, and LaneCard's git/runtime/locks pollers. Verified: npm run test:client (44 files / 454 tests), tsc --noEmit clean, check-headers.sh clean. The Run screen snapshot was regenerated — the diff is the added `<section>` wrapper and one indent level, no content change.
This commit is contained in:
@@ -584,6 +584,19 @@ describe("Workspace — the console is its own section", () => {
|
||||
const body = screen.getByTestId("console-body");
|
||||
expect(detail.contains(body)).toBe(true);
|
||||
});
|
||||
|
||||
// A SECOND render site for the console is what let `currentLane` flipping
|
||||
// (lanes arriving on mount, the selected lane removed, a refetch re-picking
|
||||
// the selection) unmount the terminal and wipe a half-typed prompt. It must
|
||||
// sit inside `lane-detail` in BOTH states, so React never has to move it.
|
||||
it("keeps the console at one render site whether or not a lane is selected", async () => {
|
||||
lanesToReturn = [];
|
||||
countsToReturn = { total: 0, running: 0, needs_you: 0, dead: 0 };
|
||||
await renderWorkspace();
|
||||
|
||||
const detail = screen.getByTestId("lane-detail");
|
||||
expect(detail.contains(screen.getByTestId("console-body"))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Workspace — proof gallery", () => {
|
||||
|
||||
Reference in New Issue
Block a user