Skip to content

feat: Board Autofit Toggle#330

Merged
sahil-noon merged 4 commits into
mainfrom
260708-738w-board-autofit
Jul 8, 2026
Merged

feat: Board Autofit Toggle#330
sahil-noon merged 4 commits into
mainfrom
260708-738w-board-autofit

Conversation

@sahil-noon

Copy link
Copy Markdown
Collaborator

Meta

Change ID Type Confidence Plan Review
738w feat 4.9/5.0 8/8 tasks, 21/21 acceptance ✓ ✓ 1 cycle
Impact +/− Net
raw +3207 / −63 +3144
true +2392 / −54 +2338
└ impl +1125 / −54 +1071
└ tests +1267 / −0 +1267

excludes fab/, docs/ · generated by fab-kit v2.13.5

Pipeline: intake ✓ → apply ✓ → review ✓ → hydrate ✓ → ship → review-pr

Summary

On a desktop board, panes render at explicit pixel widths, leaving unused row width on wide monitors and requiring manual per-pane drag-resizing that doesn't adapt to window resizes or pane pin/unpin. This adds a per-board autofit toggle: a pure-CSS flex layout that shares row width equally across up to 4 visible panes (floored at 25%/280px beyond that), reflowing live on resize, while leaving hand-tuned per-pane widths untouched so toggling off restores them exactly.

Changes

  • Persistence: new useBoardAutofit hook (use-board-autofit.ts), mirroring use-pane-widths.ts conventions — per-board localStorage key runkit:board-autofit:{board}, defaults to off.
  • Layout: DesktopRow autofit branch in board-page.tsxflex: 1 1 0 + gap-adjusted min-width: max(280px, calc(25% - 3px)) on BoardPane when autofit is on; resize handles hidden while on; stored per-pane widths never modified.
  • UI: board-only top-bar toggle button (mirrors FixedWidthToggle) plus a Board: Toggle Autofit command-palette action, both wired to the same state via the top-bar slot context.
  • Tests: unit tests for the persistence hook (use-board-autofit.test.ts) and a Playwright e2e spec with companion .spec.md covering equal-width fill, the 25%/280px floor with scroll, per-board persistence, and handle visibility.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the Board UX by adding a per-board desktop autofit toggle (persisted in localStorage and controllable via TopBar + command palette), and also includes substantial board pane reorder functionality (DnD + palette parity) plus a small backend fix to support cross-server neighbour resolution for reorder.

Changes:

  • Add useBoardAutofit persistence + wire a board-only TopBar toggle and Board: Toggle Autofit palette action; implement the DesktopRow/BoardPane autofit layout branch and hide resize handles while on.
  • Add board pane reorder: new reorder helpers + DnD hook + BoardPage/BoardPane wiring + palette Move Focused Pane Left/Right actions; adjust focus tracking to follow panes by key and avoid SSE-driven focus stealing.
  • Add/extend automated coverage: Vitest unit tests, Playwright e2e specs + companion .spec.md, and backend Go tests; update architecture/UI memory docs and fab change artifacts.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
fab/changes/260708-rmiq-board-pane-reorder/plan.md Spec/plan for board pane reorder (DnD + palette parity + backend neighbour lookup fix).
fab/changes/260708-rmiq-board-pane-reorder/intake.md Intake/spec capture for board pane reorder.
fab/changes/260708-rmiq-board-pane-reorder/.status.yaml Change status/metrics for reorder change.
fab/changes/260708-rmiq-board-pane-reorder/.history.jsonl Stage history for reorder change.
fab/changes/260708-738w-board-autofit/plan.md Spec/plan for board autofit toggle (persistence, layout, UI parity, tests).
fab/changes/260708-738w-board-autofit/intake.md Intake/spec capture for board autofit toggle.
fab/changes/260708-738w-board-autofit/.status.yaml Change status/metrics for autofit change.
fab/changes/260708-738w-board-autofit/.history.jsonl Stage history for autofit change.
docs/memory/run-kit/ui-patterns.md Documents new board reorder + autofit UI patterns and invariants.
docs/memory/run-kit/log.md Memory-domain log entry for the new additions.
docs/memory/run-kit/index.md Updates memory index summary to include new board features.
docs/memory/run-kit/architecture.md Documents backend reorder neighbour resolution cross-server aggregation.
app/frontend/tests/e2e/board-reorder.spec.ts E2E coverage for reorder endpoint + SSE echo contract.
app/frontend/tests/e2e/board-reorder.spec.md Companion doc describing what the reorder e2e proves and why.
app/frontend/tests/e2e/board-autofit.spec.ts E2E coverage for autofit layout behavior + persistence + controls parity.
app/frontend/tests/e2e/board-autofit.spec.md Companion doc describing what the autofit e2e proves and why.
app/frontend/src/lib/board-reorder.ts Pure helpers for palette move neighbours + focus-by-key reconciliation + focus gating.
app/frontend/src/lib/board-reorder.test.ts Unit tests for reorder neighbour computation and focus gating helpers.
app/frontend/src/hooks/use-pin-actions.ts Makes reorder rethrow after toast so callers can roll back optimistic UI.
app/frontend/src/hooks/use-board-pane-reorder.ts New DnD reorder hook (custom MIME, override reconcile, cancel-revert, rollback-on-reject).
app/frontend/src/hooks/use-board-pane-reorder.test.ts Unit tests for the board pane reorder hook’s behaviours and edge cases.
app/frontend/src/hooks/use-board-autofit.ts New persisted per-board autofit preference hook (localStorage, per-board key).
app/frontend/src/hooks/use-board-autofit.test.ts Unit tests for autofit persistence/isolation/malformed tolerance.
app/frontend/src/contexts/top-bar-slot-context.tsx Extends TopBar slot type with optional autofit toggle fields.
app/frontend/src/components/top-bar.tsx Adds BoardAutofitToggle rendering in board mode and plumbs new props.
app/frontend/src/components/board/board-pane.tsx Adds autofit sizing behaviour + DnD handle/target props + drag-source dim support.
app/frontend/src/components/board/board-page.tsx Wires autofit state, reorder hook, palette actions, and focus-by-key reconciliation.
app/frontend/src/components/board/board-header.tsx Makes header the drag handle and prevents ✕ from initiating drags.
app/frontend/src/app.tsx Maps new slot fields into TopBar props (autofit toggle wiring).
app/backend/api/router.go Cross-server neighbour key lookup for reorder (lookupNeighbourKeys) + warning logs on per-server failures.
app/backend/api/router_test.go Go tests covering cross-server neighbour lookup and negative cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +6 to +28
import { useBoardAutofit } from "@/hooks/use-board-autofit";
import { usePinActions } from "@/hooks/use-pin-actions";
import { useOptimisticAction } from "@/hooks/use-optimistic-action";
import { useOptimisticContext } from "@/contexts/optimistic-context";
import { useSessionContext } from "@/contexts/session-context";
import { useChromeState, useChromeDispatch } from "@/contexts/chrome-context";
import { useFocusedTerminal } from "@/contexts/focused-terminal-context";
import { useToast } from "@/components/toast";
import { BottomBar } from "@/components/bottom-bar";
import { Shell } from "@/components/shell/shell";
import { Sidebar } from "@/components/sidebar";
import { HELP_URL } from "@/components/top-bar";
import { useRegisterTopBarSlot } from "@/contexts/top-bar-slot-context";
import { createSession, createWindow as createWindowApi, killServer as killServerApi, createServer } from "@/api/client";
import { setBoardOrder } from "@/api/boards";
import { computeMoveOrder } from "@/lib/palette-move";
import { Dialog } from "@/components/dialog";
import type { PaletteAction } from "@/components/command-palette";
import { ValidBoardName } from "./board-name";
import { BoardPane, type BoardPaneHandle } from "./board-pane";
import { selectLivePanes } from "./select-live-panes";
import { useBoardPaneReorder } from "@/hooks/use-board-pane-reorder";
import { computeMoveNeighbors, focusedIndexForKey, shouldFocusPane } from "@/lib/board-reorder";

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deferred — the board-pane-reorder plumbing (useBoardPaneReorder, board-reorder) is a pinned dependency for the autofit change and was intentionally cherry-picked into this branch by the operator, not an accidental co-mingling. Its own tests (use-board-pane-reorder.test.ts, board-reorder.test.ts, board-reorder.spec.ts) ship alongside. Splitting the branch at this stage is out of scope for review-pr; the observation is noted.

Comment on lines +121 to +130
if (effectiveKeys) {
const byKey = new Map(entries.map((e) => [paneKey(e.server, e.windowId), e]));
const ordered: BoardEntry[] = [];
for (const key of effectiveKeys) {
const e = byKey.get(key);
if (e) ordered.push(e);
}
for (const e of entries) {
if (!effectiveKeys.includes(paneKey(e.server, e.windowId))) ordered.push(e);
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — build a Set from effectiveKeys for the membership check in ordered-entry derivation, replacing the O(n) .includes() per entry with O(1) lookups (overall O(n) instead of O(n²)). Ordering semantics unchanged. (864d878)

Comment thread app/frontend/src/hooks/use-board-pane-reorder.ts
sahil87 added 4 commits July 8, 2026 15:39
Per-board autofit toggle for desktop board panes: panes flex to share
row width equally (up to 4 visible, 25% floor beyond), toggled via a
top-bar button and Board: Toggle Autofit palette action, persisted per
board in localStorage. Preserves hand-tuned per-pane widths when off.
Use Set-based membership checks in useBoardPaneReorder to avoid O(n^2)
scans during ordered-entry derivation (dragover) and onDrop reconcile.
Ordering semantics unchanged.
@sahil87 sahil87 force-pushed the 260708-738w-board-autofit branch from 9face17 to e6abbbc Compare July 8, 2026 12:33
@sahil-noon sahil-noon marked this pull request as ready for review July 8, 2026 14:33
@sahil-noon sahil-noon merged commit 7e4af2d into main Jul 8, 2026
5 checks passed
@sahil-noon sahil-noon deleted the 260708-738w-board-autofit branch July 8, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants