docs(quick-260929-dmx): feineres Raster, Kalender schmaler, Browser-Pruefung
Tessera CI/CD / Lint & Type Check (push) Successful in 51s
Tessera CI/CD / Tests (push) Successful in 1m18s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 19s
Tessera CI/CD / Build & Publish Images (push) Successful in 3m7s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 09:56:27 +02:00
parent 46ebb4e7ce
commit a435a30c34
3 changed files with 146 additions and 0 deletions
+1
View File
@@ -479,6 +479,7 @@ Gerettet aus `.continue-here.md`. Relevant fuer die noch offenen Live-Tests.
| 260928-ujj | **Design Mosaik uebernommen + Hintergrund pro Benutzer.** Merge design/mosaik (76d17fe, inkl. RESIZE_AXIS_FALLBACK), Spalte `User.dashboardBackground` JSONB (Migration 20260928120000), `PATCH /users/me/dashboard-background` mit `parseDashboardBackground` aus packages/shared (Preset-Liste, imageId nur UUID), Web liest aus Sitzung, alte localStorage-Wahl einmalig uebernommen. Browser: Duenen gewaehlt, DB-Zeile gesetzt, nach localStorage-Loeschen weiter sichtbar. api 1462, web 952 gruen; Freigabe als 1.5.0. | 2026-09-28 | 9fa0a3f,0aaa152,cb45d26 | [260928-ujj-design-mosaik-uebernehmen-und-als-1-5-0-](./quick/260928-ujj-design-mosaik-uebernehmen-und-als-1-5-0-/) | | 260928-ujj | **Design Mosaik uebernommen + Hintergrund pro Benutzer.** Merge design/mosaik (76d17fe, inkl. RESIZE_AXIS_FALLBACK), Spalte `User.dashboardBackground` JSONB (Migration 20260928120000), `PATCH /users/me/dashboard-background` mit `parseDashboardBackground` aus packages/shared (Preset-Liste, imageId nur UUID), Web liest aus Sitzung, alte localStorage-Wahl einmalig uebernommen. Browser: Duenen gewaehlt, DB-Zeile gesetzt, nach localStorage-Loeschen weiter sichtbar. api 1462, web 952 gruen; Freigabe als 1.5.0. | 2026-09-28 | 9fa0a3f,0aaa152,cb45d26 | [260928-ujj-design-mosaik-uebernehmen-und-als-1-5-0-](./quick/260928-ujj-design-mosaik-uebernehmen-und-als-1-5-0-/) |
| 260929-9wc | **Eigene Module (nur lokal, nicht gepusht).** Modell `CustomModule` + Migration 20260929120000 mit RLS (Muster ProxmoxServer), `/custom-modules` (GET alle Angemeldeten, POST/PATCH/DELETE Admin, nur https ohne Zugangsdaten), `MODULE_CATEGORIES` in packages/shared, Seitenleisten-Eintrag unter gewaehlter Kategorie, Rahmen-Seite `/modules/custom/[id]` mit XFRAME_SANDBOX + no-referrer + „In neuem Tab öffnen“, Verwaltung `/admin/custom-modules`, Zugriffsklassifikation 61/224/6. Gruppen-Beschraenkung zurueckgestellt (ModuleGrant haengt an Module). api 1495, web 992 gruen; Browser dunkel 9 Schritte bestanden. | 2026-09-29 | b9d87be,e7fc4de,e48c0de | [260929-9wc-eigene-module-admin-legt-seitenleisten-e](./quick/260929-9wc-eigene-module-admin-legt-seitenleisten-e/) | | 260929-9wc | **Eigene Module (nur lokal, nicht gepusht).** Modell `CustomModule` + Migration 20260929120000 mit RLS (Muster ProxmoxServer), `/custom-modules` (GET alle Angemeldeten, POST/PATCH/DELETE Admin, nur https ohne Zugangsdaten), `MODULE_CATEGORIES` in packages/shared, Seitenleisten-Eintrag unter gewaehlter Kategorie, Rahmen-Seite `/modules/custom/[id]` mit XFRAME_SANDBOX + no-referrer + „In neuem Tab öffnen“, Verwaltung `/admin/custom-modules`, Zugriffsklassifikation 61/224/6. Gruppen-Beschraenkung zurueckgestellt (ModuleGrant haengt an Module). api 1495, web 992 gruen; Browser dunkel 9 Schritte bestanden. | 2026-09-29 | b9d87be,e7fc4de,e48c0de | [260929-9wc-eigene-module-admin-legt-seitenleisten-e](./quick/260929-9wc-eigene-module-admin-legt-seitenleisten-e/) |
| 260929-d37 | **Desktop-App nur einmal starten.** User-Meldung Windows 11: beim Systemstart zwei Instanzen/zwei Tray-Symbole. `tauri-plugin-single-instance` 2.4.5 als erstes Plugin, zweiter Start ruft `show_main_window` (neuer Helper, ersetzt 3 Kopien) und beendet sich. cargo build/test (44)/clippy gruen. Windows-Pruefung offen (VM 8233 oder User-PC nach naechster Desktop-Version). | 2026-09-29 | c0b145a,0751198 | [260929-d37-desktop-client-nur-einmal-starten-single](./quick/260929-d37-desktop-client-nur-einmal-starten-single/) | | 260929-d37 | **Desktop-App nur einmal starten.** User-Meldung Windows 11: beim Systemstart zwei Instanzen/zwei Tray-Symbole. `tauri-plugin-single-instance` 2.4.5 als erstes Plugin, zweiter Start ruft `show_main_window` (neuer Helper, ersetzt 3 Kopien) und beendet sich. cargo build/test (44)/clippy gruen. Windows-Pruefung offen (VM 8233 oder User-PC nach naechster Desktop-Version). | 2026-09-29 | c0b145a,0751198 | [260929-d37-desktop-client-nur-einmal-starten-single](./quick/260929-d37-desktop-client-nur-einmal-starten-single/) |
| 260929-dmx | **Widget-Raster horizontal feiner + Kalender schmaler.** COLS lg 48/md 40/sm 24/xs 16/xxs 4, GRID_VERSION 3 (v2->v3 nur x/w/minW/maxW x2), alle minW/defaultW x2, Kalender minW 8 (~250 px). Browser: Anordnung pixelgleich, Kalender bis 252 px, Schritt 33 px. Auch: Hover-Anheben der Widgets entfernt (acd3c7a, Nutzerwunsch). | 2026-09-29 | 97744b5,9c9e142,46ebb4e | [260929-dmx-widget-raster-horizontal-feiner-48-spalt](./quick/260929-dmx-widget-raster-horizontal-feiner-48-spalt/) |
## Deferred Items ## Deferred Items
@@ -0,0 +1,61 @@
---
quick_id: 260929-dmx
type: quick
wave: 1
autonomous: true
---
# Quick 260929-dmx: Widget-Raster horizontal feiner (48 Spalten), Kalender schmaler
## User requests (29.09.2026)
1. "das kalender widget soll in der breite schmäler gemacht werden können."
2. "und mache das widget raster horizontal etwas feiner."
## Measurements (orchestrator, browser, lg breakpoint, grid width 1593 px, margin 12)
- Today: 24 cols → one width unit ≈ 66 px. Calendar minW 6 ≈ 383 px, default 8 ≈ 515 px.
- Calendar rendered at 251 px: fully usable (month grid, header "September 2026", event list truncates titles cleanly).
- Calendar at 185 px: header clipped, event titles reduced to one letter → too narrow.
- Target: calendar minimum ≈ 250 px.
## Decision (locked)
Double the HORIZONTAL resolution only: `COLS = { lg: 48, md: 40, sm: 24, xs: 16, xxs: 4 }` in
`apps/web/src/components/dashboard/dashboard-grid.tsx`. Row height (20) and margin (12) unchanged.
Every existing widget keeps its exact on-screen size and position.
## Task 1: Grid version 3 (horizontal x2) with migration
- files: apps/web/src/lib/grid-layout-migration.ts (+ test), apps/web/src/components/dashboard/dashboard-grid.tsx (+ test), apps/web/src/lib/stores/dashboard-store.ts (only if needed)
- action:
- Bump `GRID_VERSION` to 3. Migration becomes stepwise and cumulative:
v1 → v2: existing behavior (x,y,w,h,minW,minH,maxW,maxH × 2).
v2 → v3: NEW, horizontal only: x, w, minW, maxW × 2 (y, h, minH, maxH unchanged).
So a v1 layout gets both steps, a v2 layout only the second, a v3 layout nothing. Keep idempotence and marker semantics (marker only in persisted JSON). Update the file header comment (German, same style) to document v3.
- `COLS` as above. Check every other place that depends on column count or widget width units:
centering offset, `RESIZE_AXIS_FALLBACK`, `breakpointFor`, default positions when adding a widget
(`dashboard-grid.tsx` ~380: `defaultW ?? 4`, `minW ?? 4` fallbacks → 8), empty-dashboard suggestions,
any layout templates/seed data in apps/web or apps/api (grep `defaultW`, `w:` in dashboard code,
`layouts` defaults in apps/api/src/dashboard). Anything expressed in width units gets × 2.
- Tests: extend grid-layout-migration tests (v1→v3, v2→v3, v3 untouched, idempotence, marker 3 written), update dashboard-grid tests pinning cols.
- verify: `pnpm --filter web exec vitest run src/lib src/components/dashboard` green.
## Task 2: Widget width constraints in new units
- files: apps/web/src/components/dashboard/widget-registry.tsx (+ test)
- action: In `WIDGET_CONSTRAINTS` double every `minW` and `defaultW` (same physical size as before),
EXCEPT calendar: `minW: 8` (≈ 251 px at lg — the measured usable minimum), `defaultW: 16` (unchanged size).
minH/defaultH unchanged. Update the comment above calendar (German): narrower on user request 29.09., 8 of 48 ≈ 250 px measured usable.
Existing layouts: the existing override logic in dashboard-grid (quick-260916-dyv: stored minW/minH replaced by constants in every breakpoint) must pick up the new calendar minW so existing calendars can be shrunk — verify that path with a test.
- verify: web tests green; `pnpm turbo run type-check lint --filter web` green; biome warnings for web not above baseline 55.
## Task 3: CHANGELOG, rebuild, commit
- CHANGELOG.md under `## Unveröffentlicht` → `### Geändert` (section exists) add plain-German bullets (app text uses "Sie"):
- Dashboard: Das Raster ist in der Breite doppelt so fein – Widgets lassen sich in kleineren Schritten breiter oder schmaler ziehen und genauer platzieren. Bestehende Anordnungen bleiben unverändert.
- Dashboard: Das Kalender-Widget lässt sich deutlich schmaler ziehen als bisher.
- Rebuild local stack: `docker compose up -d --build web` (plain `up` does not rebuild).
- Commits per task, messages end with `Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>`.
- NEVER git push (orchestrator pushes after browser check).
- Browser check is done by the orchestrator (resize calendar to minimum, existing layout unchanged after migration, marker 3 persisted).
@@ -0,0 +1,84 @@
---
quick_id: 260929-dmx
status: complete
commits: 3
plan_head_before: acd3c7a05f9f01e2f5cf8ebe9aed66d8c789a055
plan_head_after: 46ebb4e7ceafa1dc782514e487ac820166279f48
completed: 2026-09-29
actuals:
tasks: 3
commits: 3
---
# Quick 260929-dmx: Widget-Raster horizontal 48 Spalten, Kalender schmaler
Grid version 3: horizontal resolution doubled (COLS lg 48 / md 40 / sm 24 / xs 16 / xxs 4), row height 20 and margin 12 unchanged. Stored layouts are migrated stepwise, so every existing widget keeps its on-screen size and position. Calendar minimum is now 8 of 48 columns (about 250 px at lg).
## Commits
- 97744b5 feat: grid v3 with stepwise migration, COLS, fallbacks
- 9c9e142 feat: widget constraints in 48-column units, calendar minW 8
- 46ebb4e docs(changelog): two bullets under "Unveröffentlicht / Geändert"
## Every place where width units changed
1. `apps/web/src/lib/grid-layout-migration.ts`: `GRID_VERSION` 2 to 3. Migration is now a step table: v1 to v2 scales x, y, w, h, minW, minH, maxW, maxH by 2; v2 to v3 scales only x, w, minW, maxW by 2. A v1 layout gets both steps, a v2 layout only the second, a v3 layout nothing. Marker semantics unchanged (marker only in the persisted JSON, stripped on load, re-added by `withGridVersion`). Header comment updated.
2. `apps/web/src/components/dashboard/dashboard-grid.tsx`:
- `COLS` is `{ lg: 48, md: 40, sm: 24, xs: 16, xxs: 4 }`.
- Fallback for a widget without a layout entry: `defaultW ?? 8` and `minW ?? 8` (was 4/4). The `?? 4` fallbacks for height stay.
- Comment block above BREAKPOINTS/COLS extended.
3. `apps/web/src/components/dashboard/widget-registry.tsx` (`WIDGET_CONSTRAINTS`, minW/defaultW doubled, heights untouched):
- clock 4/8
- search 12/24
- calendar minW 8, defaultW 16. Calendar is the only one that is not a plain doubling for minW: 8 instead of 12.
- note 8/12
- calculator 6/12
- favorites 2/12
- stopwatch 8/12
- picture-frame 8/16
- xframe 8/24
- proxmox 6/16
- Comments updated, German, including the calendar note (narrower on user request 29.09., 8 of 48 is about 250 px measured usable).
4. `dashboard-store.ts` needed no code change. `addWidget` reads `defaultW` from `WIDGET_CONSTRAINTS`, so new widgets are placed in the new units automatically. Load and save already route through `migrateGridLayouts` and `withGridVersion`.
5. `centeringOffset` needed no code change. It takes `cols` as a parameter and gets the new `COLS[breakpoint]`.
6. `breakpointFor` needed no change. It depends only on BREAKPOINTS, not on the column count.
The existing override in `applyConstraintMinima` (quick-260916-dyv) already replaces the stored minW/minH from the constants in every breakpoint, so existing calendars pick up minW 8 with no code change there. This is verified by a new test.
## Tests
- `grid-layout-migration.test.ts`: v1 to v3 (x/w/minW/maxW times 4, y/h/minH/maxH times 2), v2 to v3, v3 untouched, v1 result equals v2 result, idempotence for both paths with marker 3 written, future marker 4 untouched, string marker, foreign values.
- `dashboard-store.test.ts`: marker 3, new expected values, new-widget default of 8 wide.
- `dashboard-grid.test.tsx`: COLS pin, `centeringOffset` with 48 columns, data-grid fallbacks, minima overrides, new Test 9c (existing calendar with stored minW 12 gets minW 8 in every breakpoint, w 6 raised to 8, w 16 kept).
- `widget-registry.test.tsx`: constraints table.
- Verification: `pnpm --filter web exec vitest run src/lib src/components/dashboard` green (513). The full web suite is green (995). Type-check for `@tessera/web` is green. Biome shows 55 warnings, equal to the baseline. Note: the turbo filter name is `@tessera/web`, not `web`.
## Rebuild
`docker compose up -d --build web` ran, and the web container is up. Browser check is left to the orchestrator (calendar at minimum, existing layout unchanged after migration, marker 3 persisted).
## Found but deliberately left
- `apps/api/src/dashboard/dashboard.service.spec.ts:834` stores `__gridVersion: 2` as a passthrough fixture. The API only passes the JSON through, so the value is arbitrary, and I did not touch it.
- `RESIZE_AXIS_FALLBACK` and its tests use abstract grid numbers and are unit-independent, so nothing was changed. Its resize logic has no column dependency.
- Historical comments that mention "24 Spalten" (the quick-260922-vdk explanation in `dashboard-grid.tsx`, the quick-260916-bwo test description, the bwo header text) describe past states and were left. The vdk comment's numbers (24 columns, 50 px) describe the old bug, not the current state.
- Widget internals (calendar, favorites, calculator) use pixel-based or container-based layout, not grid units, so no change was needed.
- md/sm/xs/xxs columns are doubled proportionally with lg. Only lg was measured, and I did not check the smaller breakpoints in a browser.
- API/`seed`: no default layouts or seed data with width units exist in apps/api (empty defaults `{ lg: [], ... }` only).
- A brand-new empty v2 layout is not re-saved with marker 3 on load (`migrated` stays false for empty layouts, existing behaviour). The marker gets written on the next save.
## Deviations from Plan
None. The plan was executed as written. The SUMMARY, STATE, PLAN and ROADMAP files were not committed, as instructed.
## Self-Check: PASSED
Commits 97744b5, 9c9e142, 46ebb4e exist. Changed files exist. Working tree contains only the untracked quick-task directory.
## Browser-Pruefung (Orchestrator, 29.09., dunkel, lg 1888 px)
- Bestehende Anordnung nach Migration pixelgenau gleich (6 Widgets, left/top/width/height vor und nach identisch); DB: `__gridVersion` 3, lg-w verdoppelt.
- Kalender im Bearbeitungsmodus nach links gezogen: stoppt bei 252 px (vorher Minimum 383 px), Monatsraster, Kopf und Terminliste sauber lesbar.
- Schrittweite beim Ziehen 33 px (284/317/350), vorher 66 px.
- Kalender danach wieder auf 515 px gezogen, Testzustand zurueckgesetzt.
- Nicht im Browser geprueft: kleinere Breakpoints (md/sm/xs/xxs).