fix(dashboard): hidden widgets render at proper size in edit mode (t-paliad-238) #74

Closed
mAi wants to merge 0 commits from mai/tesla/dashboard-resize-clamp into main
Collaborator

Symptom

m 2026-05-22 15:41: "Resizing my dashboard layout lead to an error where now I have some super slim columns which I can move but not resize - and they seem greyed out."

No Gitea issue filed yet — head dispatched this as task t-paliad-238 directly. Filing an issue retro-actively if needed.

Root cause

Hidden widgets in edit mode were rendering as 1×1 slivers because applyLayout left their inline grid-column empty — placeWidgets skipped non-visible entries entirely, so CSS Grid auto-flowed them into the next free cell at 1/12 width.

  • Super slim — 1/12 of the grid (no grid-column inline → auto-flow as 1×1).
  • Can move but not resizerebuildEditChrome correctly omits the resize handle for hidden widgets (line 940-943); this is intentional UX (un-hide before resizing).
  • Greyed outdashboard-widget--hidden class adds opacity: 0.45.

The last two are correct signals that a widget is hidden. The slim rendering was the bug. Resize itself never changed visibility — the user likely hit × at some point (deliberately or accidentally) and saw the result on the next edit-mode entry.

Fix

Frontend (frontend/src/client/dashboard-grid.ts)

  • placeWidgets() gains a {includeHidden} option.
  • When true, a second pass places hidden widgets after the visible pass — collision-aware + cursor-aware so the hidden tray stacks below the active layout. Visible widgets always claim their cells first.
  • applyLayout() passes includeHidden: editMode.
  • materializePositions() keeps the default (hidden widgets retain stored coordinates so un-hiding restores them in place).

Backend (internal/services/dashboard_layout_spec.go)

  • SanitizeForRead now also clamps each widget's W/H/X against the catalog MinW/MaxW/MinH/MaxH + grid bounds on load. Stale rows with W below MinW (or above MaxW, or X+W overflowing the grid) heal on the next GET /api/me/dashboard-layout and the cleaned spec is persisted back.
  • W=0 stays 0 (auto/default sentinel — the placer expands it).
  • The validator stays strict on write; the read-path sanitiser only exists to recover users who got into a bad state under earlier rules.

Recovery for m

If m's saved layout already has out-of-range sizes, the next /api/me/dashboard-layout GET will heal them and persist the cleaned spec back. He should see proper rendering on reload.

Tests

  • bun (frontend): 4 new cases in dashboard-grid.test.ts pin includeHidden behaviour. All 103 frontend tests pass.
  • go (backend): 7 sub-tests in dashboard_layout_spec_test.go cover each SanitizeForRead clamp plus a round-trip Validate guarantee. All ./internal/... tests pass.
  • boot smoke: go test ./cmd/server/... clean.
  • builds: go build ./... + bun run build clean.

Test plan

  • bun test 103/103
  • go test ./internal/... ./cmd/server/... clean
  • go build ./... + bun run build clean
  • Manual: hide a widget, reload in edit mode, confirm hidden widget renders at proper size in the hidden tray below the active layout
## Symptom m 2026-05-22 15:41: *"Resizing my dashboard layout lead to an error where now I have some super slim columns which I can move but not resize - and they seem greyed out."* No Gitea issue filed yet — head dispatched this as task t-paliad-238 directly. Filing an issue retro-actively if needed. ## Root cause Hidden widgets in edit mode were rendering as 1×1 slivers because `applyLayout` left their inline `grid-column` empty — `placeWidgets` skipped non-visible entries entirely, so CSS Grid auto-flowed them into the next free cell at 1/12 width. - **Super slim** — 1/12 of the grid (no grid-column inline → auto-flow as 1×1). - **Can move but not resize** — `rebuildEditChrome` correctly omits the resize handle for hidden widgets (line 940-943); this is intentional UX (un-hide before resizing). - **Greyed out** — `dashboard-widget--hidden` class adds `opacity: 0.45`. The last two are correct signals that a widget is hidden. The slim rendering was the bug. Resize itself never changed visibility — the user likely hit × at some point (deliberately or accidentally) and saw the result on the next edit-mode entry. ## Fix ### Frontend (`frontend/src/client/dashboard-grid.ts`) - `placeWidgets()` gains a `{includeHidden}` option. - When true, a **second pass** places hidden widgets after the visible pass — collision-aware + cursor-aware so the hidden tray stacks below the active layout. Visible widgets always claim their cells first. - `applyLayout()` passes `includeHidden: editMode`. - `materializePositions()` keeps the default (hidden widgets retain stored coordinates so un-hiding restores them in place). ### Backend (`internal/services/dashboard_layout_spec.go`) - `SanitizeForRead` now also clamps each widget's `W`/`H`/`X` against the catalog `MinW`/`MaxW`/`MinH`/`MaxH` + grid bounds on load. Stale rows with `W` below `MinW` (or above `MaxW`, or `X+W` overflowing the grid) heal on the next `GET /api/me/dashboard-layout` and the cleaned spec is persisted back. - `W=0` stays `0` (auto/default sentinel — the placer expands it). - The validator stays strict on write; the read-path sanitiser only exists to recover users who got into a bad state under earlier rules. ### Recovery for m If m's saved layout already has out-of-range sizes, the next `/api/me/dashboard-layout` GET will heal them and persist the cleaned spec back. He should see proper rendering on reload. ## Tests - **bun (frontend)**: 4 new cases in `dashboard-grid.test.ts` pin `includeHidden` behaviour. All 103 frontend tests pass. - **go (backend)**: 7 sub-tests in `dashboard_layout_spec_test.go` cover each `SanitizeForRead` clamp plus a round-trip `Validate` guarantee. All `./internal/...` tests pass. - **boot smoke**: `go test ./cmd/server/...` clean. - **builds**: `go build ./...` + `bun run build` clean. ## Test plan - [x] `bun test` 103/103 - [x] `go test ./internal/... ./cmd/server/...` clean - [x] `go build ./...` + `bun run build` clean - [ ] Manual: hide a widget, reload in edit mode, confirm hidden widget renders at proper size in the hidden tray below the active layout
mAi changed title from fix(dashboard): t-paliad-238 — hidden widgets render at proper size in edit mode to fix(dashboard): hidden widgets render at proper size in edit mode (t-paliad-238) 2026-05-22 13:52:57 +00:00
m force-pushed mai/tesla/dashboard-resize-clamp from d5b3652963 to 4cd2f05d33 2026-05-22 13:53:22 +00:00 Compare
m closed this pull request 2026-07-06 22:50:18 +00:00
m deleted branch mai/tesla/dashboard-resize-clamp 2026-07-06 22:50:18 +00:00

Pull request closed

Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#74
No description provided.