fix(dashboard): t-paliad-228 — collision-aware widget placement (#70) #71

Open
mAi wants to merge 0 commits from mai/tesla/dashboard-overlap into main
Collaborator

Summary

Resolves #70. After m/paliad#69 dashboard overhaul, widgets visually overlapped on mixed-size rows.

  • Extract placement math to new pure module frontend/src/client/dashboard-grid.ts with collision-aware placeWidgets() using an occupancy bitmap.
  • No-overlap invariant: explicit positions that collide are bumped to the next free w×h block downward (preferring same column). Resize-grow + drag-drop swap now reliably produce non-overlapping layouts.
  • Clamp x+w > GRID_COLUMNS in the placer (matches the Go-side validator).
  • 14 regression tests covering mixed-width swap, resize-grow sibling shift, multi-row widgets, overflow clamp.

Acceptance (issue body)

  • 1-col + 2-col adjacent: no overlap.
  • Resize 1-col → 2-col into occupied col: sibling shifts to next free cell (recommended-(R) path).
  • Drop target on the right-half of a wide widget no longer produces an overlapping layout (placer resolves it).
  • Reload preserves the conflict-free layout (positions are persisted by materializePositions after each mutation, then re-validated by the placer on render).

Test plan

  • bun test src/client/dashboard-grid.test.ts → 14 pass
  • bun test (all frontend tests) → 99 pass
  • bun run build clean
  • go build ./... clean
  • go test ./internal/... clean
  • go test -run TestBootSmoke ./cmd/server/... clean
  • Manual: drop wide-onto-narrow + resize-into-sibling in browser
## Summary Resolves #70. After m/paliad#69 dashboard overhaul, widgets visually overlapped on mixed-size rows. - **Extract placement math** to new pure module `frontend/src/client/dashboard-grid.ts` with collision-aware `placeWidgets()` using an occupancy bitmap. - **No-overlap invariant**: explicit positions that collide are bumped to the next free w×h block downward (preferring same column). Resize-grow + drag-drop swap now reliably produce non-overlapping layouts. - **Clamp `x+w > GRID_COLUMNS`** in the placer (matches the Go-side validator). - **14 regression tests** covering mixed-width swap, resize-grow sibling shift, multi-row widgets, overflow clamp. ## Acceptance (issue body) - ✅ 1-col + 2-col adjacent: no overlap. - ✅ Resize 1-col → 2-col into occupied col: sibling shifts to next free cell (recommended-(R) path). - ✅ Drop target on the right-half of a wide widget no longer produces an overlapping layout (placer resolves it). - ✅ Reload preserves the conflict-free layout (positions are persisted by `materializePositions` after each mutation, then re-validated by the placer on render). ## Test plan - [x] `bun test src/client/dashboard-grid.test.ts` → 14 pass - [x] `bun test` (all frontend tests) → 99 pass - [x] `bun run build` clean - [x] `go build ./...` clean - [x] `go test ./internal/...` clean - [x] `go test -run TestBootSmoke ./cmd/server/...` clean - [ ] Manual: drop wide-onto-narrow + resize-into-sibling in browser
mAi added 1 commit 2026-05-21 08:48:40 +00:00
After m/paliad#69's edit-mode overhaul, widgets visually overlapped on
mixed-size rows: a 12-col + 6-col swap, an auto-flow widget landing on
an explicit blocker, or a resize-grow into a sibling all produced
layouts that ignored colspan footprints when computing occupancy.

Extracts placement math from dashboard.ts into a pure ./dashboard-grid
module and adds an occupancy bitmap. Every visible widget is placed
once; explicit-position collisions are resolved by searching downward
from the requested row for the first w×h block that fits, preferring
the requested column. Resize-grow + drag-drop swap now reliably
produce no-overlap layouts because the placer cleans up after them.

x+w > GRID_COLUMNS is clamped in the placer instead of rendered as an
overflow — matches the validator's hard rule on the wire.

Adds 14 dashboard-grid.test.ts regressions covering the mixed-width
swap, resize-grow shifting siblings, multi-row widgets, and the
overflow clamp. Pure tests — no DOM.
This branch is already included in the target branch. There is nothing to merge.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin mai/tesla/dashboard-overlap:mai/tesla/dashboard-overlap
git checkout mai/tesla/dashboard-overlap
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#71
No description provided.