Files
schalli 39b1f74b56
Tessera CI/CD / Lint & Type Check (push) Successful in 53s
Tessera CI/CD / Tests (push) Successful in 1m13s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 19s
Tessera CI/CD / Build & Publish Images (push) Successful in 4m10s
docs(quick-260922-vdk): Akte - Rundgang im echten Linux-Client, Messfalle notiert
Gegenprobe lief nicht im Browser, sondern im echten 1.3.0-AppImage ueber den
WebKit-Remote-Inspektor. Gleicher Fehlerfall vorher/nachher: Kachel 469 -> 389 px
bei 1000 px Bereich, Platzhalter erreicht jetzt exakt den rechten Rand (603 px).

Dazu die Messfalle festgehalten: im Client gegen style.width/style.transform
messen, nie gegen getBoundingClientRect() - bei Fenster im Hintergrund friert
WebKitGTK die Animationsuhr ein und der width-Uebergang bleibt stehen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 22:58:17 +02:00

12 KiB
Raw Permalink Blame History

phase, plan, subsystem, tags, requires, provides, affects, actuals, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects actuals tech-stack key-files key-decisions patterns-established requirements-completed coverage duration completed status
quick-260922-vdk 01 ui
react
react-grid-layout
ref-callback
resize-observer
dashboard
vitest
Dashboard-Raster misst seine Breite auch beim Wechsel Leerzustand -> gefuellt (Ref-Rueckruf statt Einmal-Effekt)
Fenster-Horcher als Netz zusaetzlich zum ResizeObserver
dashboard-grid
dashboard
tokens tasks commits
2392 2 2
added patterns
Ref-Rueckruf (callback ref) statt useEffect mit leerer Abhaengigkeitsliste, wenn eine Messung den tatsaechlich eingehaengten Knoten ueber Aus-/Einhaengen hinweg verfolgen muss
created modified
apps/web/src/components/dashboard/dashboard-grid.tsx
apps/web/src/components/dashboard/dashboard-grid.test.tsx
CHANGELOG.md
Ref-Rueckruf measureRef ersetzt containerRef + Einmal-Effekt; misst synchron in der Commit-Phase, kein useLayoutEffect noetig
Kein Aufraeum-Rueckgabewert aus measureRef, damit React 19 den Rueckruf beim Aushaengen mit null aufruft (das ist der Aufraeumpfad)
Fenster-Horcher zusaetzlich zum ResizeObserver, nicht als Ersatz
Startwert bleibt 1200 (nur bis zur ersten Commit-Phase relevant)
FREE_PLACEMENT_COMPACTOR/preventCollision, BREAKPOINTS, COLS, rowHeight, margin, applyConstraintMinima unveraendert
quick-260922-vdk Kommentarblock in dashboard-grid.tsx erklaert das Warum der Ref-Rueckruf-Messung
QUICK-260922-VDK
id description requirement verification human_judgment rationale
D1 Dashboard-Raster misst seine Breite auch aus dem Leerzustand heraus (Ref-Rueckruf, synchrone Erstmessung, Fenster-Horcher) QUICK-260922-VDK
kind ref status
unit apps/web/src/components/dashboard/dashboard-grid.test.tsx#quick-260922-vdk Test 10: Leerzustand -> gefuellt misst die tatsaechliche Breite statt beim Startwert 1200 stehenzubleiben pass
kind ref status
unit apps/web/src/components/dashboard/dashboard-grid.test.tsx#quick-260922-vdk Test 11: Fenstergroesse aendert sich -> der Fenster-Horcher misst neu pass
true Die Unit-Tests beweisen die gemessene Breite in jsdom; ob im echten Browser rechts kein toter Streifen mehr bleibt und die Rasterbreite sichtbar der Breite des Inhaltsbereichs entspricht, verlangt einen Browser-Rundgang (Prueflliste unten).
id description verification human_judgment
D2 Ziehverhalten unveraendert: belegtes Feld bleibt blockiert, nichts wird zur Seite geschoben
kind ref status
unit apps/web/src/components/dashboard/dashboard-grid.test.tsx#quick-260916-dyv Test 7: Compactor-Pin pass
kind ref status
unit apps/web/src/components/dashboard/dashboard-grid.test.tsx#quick-260916-dyv Test 6: dragConfig-Pin pass
false
~9min 2026-09-22 complete

Quick-Aufgabe 260922-vdk: Dashboard-Raster misst seine Breite auch aus dem Leerzustand heraus Summary

Messung an einem Ref-Rueckruf (measureRef) statt an einem Einmal-Effekt: der Beobachter folgt dem eingehaengten <div> ueber Leerzustand <-> gefuellt hinweg, misst synchron in der Commit-Phase, plus Fenster-Horcher als Netz — 20-Spalten/md-Fehlmessung nach 1200 px behoben.

Performance

  • Duration: ~9 min
  • Completed: 2026-09-22
  • Tasks: 2/2
  • Files modified: 3

Accomplishments

  • Dashboard-Raster misst jetzt in jedem Fall die tatsaechliche Breite des Inhaltsbereichs, auch wenn DashboardGrid mit null Kacheln einhaengt und die erste Kachel erst spaeter erscheint
  • Fenster-Horcher als Sicherheitsnetz zusaetzlich zum ResizeObserver
  • Zwei neue Regressionstests, nachweislich zuerst rot
  • Ziehverhalten (FREE_PLACEMENT_COMPACTOR mit preventCollision), Raster-Konstanten und Leerzustand unveraendert (per Test 4/6/7/9/9b bestaetigt)

Task Commits

Each task was committed atomically:

  1. Aufgabe 1: Messung an den Knoten haengen (Ref-Rueckruf, synchrone Erstmessung, Fenster-Horcher) - d9f2af3 (fix)
  2. Aufgabe 2: Changelog-Stichpunkt, volle Tore, Zaehler, Pruefliste - cf67c8a (docs)

Ledger: plan_head_before = 3e8c0f4 (letzter Commit vor diesem Plan — die bereits committete Akte). git rev-list --count 3e8c0f4..HEAD = 2, deckt sich mit den zwei oben genannten Commits.

Plan metadata: wird vom Orchestrator nach diesem SUMMARY committet (STATE.md/ROADMAP.md ausserhalb dieses Plans).

Rot-Nachweis (Aufgabe 1, vor der Aenderung)

Testlauf vor dem Umbau von dashboard-grid.tsx (nur die Test-Datei war schon geaendert):

FAIL src/components/dashboard/dashboard-grid.test.tsx > DashboardGrid > quick-260922-vdk Test 10: ...
AssertionError: expected 1200 to be 1000 // Object.is equality

FAIL src/components/dashboard/dashboard-grid.test.tsx > DashboardGrid > quick-260922-vdk Test 11: ...
AssertionError: expected 1000 to be 1600 // Object.is equality

10 von 12 Faellen gruen, genau die zwei neuen rot — wie erwartet: Test 10 blieb beim Startwert 1200 (der frueh zurueckspringende Leerzustand rendert den gemessenen Knoten nie, der Effekt mit leerer Abhaengigkeitsliste sieht ihn also nie), Test 11 blieb bei 1000, weil es vorher keinen Fenster-Horcher gab.

Nach dem Umbau: alle 12 Faelle gruen (pnpm --filter @tessera/web exec vitest run src/components/dashboard/dashboard-grid.test.tsx).

Gemessene Zahlen (nachher, alle Tore)

Tor Ausgangsmessung (22.09., vor der Aenderung) Nachher (gemessen)
dashboard-grid.test.tsx 10 Faelle 12 Faelle, alle gruen
Web Tests gesamt 81 Dateien / 659 Tests 81 Dateien / 661 Tests, alle gruen
pnpm type-check — 4/4 ohne Befund
pnpm lint — 5/5 ohne Befund der Stufe error
Biome web Warnungen 53 53 (unveraendert)
as unknown as in web 6 6 (unveraendert)

Keine Abweichung — alle erwarteten Zahlen aus dem Plan treffen exakt zu.

Files Created/Modified

  • apps/web/src/components/dashboard/dashboard-grid.tsx - measureRef-Ref-Rueckruf ersetzt containerRef + Einmal-Effekt; applyWidth-Wächter (verwirft 0/nicht-endliche Werte); Fenster-Horcher (resize-Listener); deutscher Warum-Kommentarblock quick-260922-vdk
  • apps/web/src/components/dashboard/dashboard-grid.test.tsx - zwei neue Faelle (Test 10: Leerzustand -> gefuellt misst 1000; Test 11: resize-Ereignis misst 1600), stubResizeObserver-Import, vi.unstubAllGlobals() im afterEach
  • CHANGELOG.md - neuer Abschnitt „### Behoben" unter „## Unveroeffentlicht" mit einem Stichpunkt

Decisions Made

Keine neuen Entscheidungen — die im Plan gebundenen Entscheidungen (Ref-Rueckruf statt Einmal-Effekt, synchron vor dem ersten Zeichnen, Fenster-Horcher als Netz, Ziehverhalten unveraendert, Startwert 1200 bleibt, nur apps/web) wurden wortgleich umgesetzt.

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

None.

Pruefliste fuer den Browser-Rundgang (Orchestrator, lokal, Playwright-MCP, nicht Testserver)

Breiten werden am DOM gemessen (getBoundingClientRect der Elemente), nie per fetch aus der Seite heraus — das taeuscht in beide Richtungen.

  • (a) Dashboard eines Benutzers ohne Kacheln oeffnen (oder alle Kacheln entfernen und neu laden) -> Leerzustand mit Bildmarke erscheint
  • (b) Bearbeiten -> „Widget hinzufuegen" -> Uhr: die Kachel erscheint, und beim Ziehen reicht der Platzhalter bis an den rechten Rand des Inhaltsbereichs — kein toter Streifen
  • (c) messen: Breite von .react-grid-layout gleicht der Breite des umgebenden Inhaltsbereichs (Abweichung hoechstens der Rand von 8 px); vorher lag sie bei 1200 px unabhaengig von der Fensterbreite
  • (d) eine zweite Kachel auf ein belegtes Feld ziehen -> sie springt zurueck, nichts wird zur Seite geschoben (unveraendert gewollt); Groesse ziehen stoppt am Nachbarn
  • (e) Fenster schmaler und wieder breiter ziehen -> das Raster folgt, Kacheln bleiben heil
  • (f) Seite mit vorhandenen Kacheln neu laden -> weiterhin richtig (der bisher schon funktionierende Pfad), und beim ersten Zeichnen ist kein Sprung von schmal auf breit zu sehen
  • (g) letzte Kachel entfernen -> Leerzustand erscheint, danach eine neue Kachel hinzufuegen -> wieder volle Breite (der Beobachter wurde sauber getrennt und neu angehaengt)

Entscheidend: Punkt (b)/(c) — auf einem beim Oeffnen leeren Dashboard fuellt die erste Kachel den Inhaltsbereich bis zum rechten Rand, und die gemessene Rasterbreite stimmt mit der Breite des Inhaltsbereichs ueberein.

Threat Flags

Keine neue Vertrauensgrenze, keine neuen Pakete. Alle sechs T-VDK-Punkte aus dem Plan-Threat-Model sind mit Tests bzw. Struktur-Toren abgedeckt (siehe Rot-Nachweis und gemessene Zahlen oben); nichts Neues gefunden.

Next Phase Readiness

Kein laufender Meilenstein, keine Folge-Phase direkt abhaengig. Naechster Schritt laut STATE.md bleibt: Widget-Modul-Kopplung (WIDGET_MODULE_MAP) und danach das Proxmox-Modul — unabhaengig von dieser Quick-Aufgabe.

Self-Check: PASSED

  • FOUND: apps/web/src/components/dashboard/dashboard-grid.tsx
  • FOUND: apps/web/src/components/dashboard/dashboard-grid.test.tsx
  • FOUND: CHANGELOG.md
  • FOUND: .planning/quick/260922-vdk-dashboard-raster-misst-seine-breite-nich/260922-vdk-SUMMARY.md
  • FOUND commit: d9f2af3
  • FOUND commit: cf67c8a

Phase: quick-260922-vdk Completed: 2026-09-22

Rundgang durch den Orchestrator (22.09.2026, echter Linux-Client, nicht der Browser)

Der Nutzer hat den Fehler im Linux-Client gemeldet und ausdruecklich gesagt, ein Browser-Test bringe nichts. Geprueft wurde deshalb im echten Paket: Tessera-1.3.0.AppImage aus dem Gitea-Release, auf dem Entwicklungsrechner gestartet (DISPLAY=:10, WEBKIT_INSPECTOR_HTTP_SERVER=127.0.0.1:9230), gesteuert ueber den WebKit-Remote-Inspektor (Treiber scratchpad/wk.mjs, Target-Protokoll: Target.sendMessageToTarget + Runtime.evaluate). Server: lokaler Stack.

Ausgangsmessung VOR dem Fix (gleiche Sitzung, gleicher Client):

Weg Bereich Kachel Rasterbreite laut Rechnung
Neuladen MIT Kachel 1176 px 459 px 1176 px — richtig
Seitenleiste auf/zu 1000 ↔ 1176 px folgt richtig
Leeres Dashboard, dann Kachel hinzufuegen 1000 px 469 px 1200 px — falsch

Der dritte Weg ist der Fehlerfall: DashboardGrid haengt mit null Kacheln ein, der gemessene <div> existiert nicht, der Einmal-Effekt bricht ab und laeuft nie wieder.

Nach dem Fix, derselbe Weg (Kachel entfernt, gespeichert, neu geladen -> leeres Dashboard -> Kalender hinzugefuegt):

  • width-Eigenschaft an Responsive: 1000 (= echte Bereichsbreite), Breakpoint md, 20 Spalten — aus dem React-Fiber ausgelesen, nicht geraten.
  • Kachel style.width: 389 px = 8 × 41,6 + 56, exakt der Sollwert fuer 1000 px.
  • Ziehen nach rechts (synthetische Maus-Ereignisse, jeweils mit Wartezeit, damit React dazwischen rendert): Platzhalter laeuft 8 → 107 → 256 → 405 → 554 → 603 und bleibt dort. 1000 − 8 − 389 = 603 — der Platzhalter erreicht jetzt exakt den rechten Rand. Die Kachel wird auch dort abgelegt (tileX 603).

Messfalle, dokumentiert damit sie niemanden noch einmal kostet: getBoundingClientRect() und getComputedStyle().width lieferten im Client weiter 469 px, obwohl style.width bereits 389 px war. Grund: .react-grid-item hat transition: width .2s, und das Client-Fenster lag im Hintergrund — WebKitGTK friert die Animationsuhr dann ein, der Uebergang bleibt auf dem Startwert stehen (getAnimations() meldete eine laufende CSSTransition auf width). Im Client gegen die gesetzten Werte messen (style.width, style.transform) oder gegen die React-Eigenschaften, nie gegen die gemalte Box — sonst misst man die eingefrorene Animation statt des Ergebnisses.

Nicht angefasst, wie zugesagt: belegte Plaetze bleiben gesperrt, nichts weicht aus (FREE_PLACEMENT_COMPACTOR mit preventCollision unveraendert) — ausdrueckliche Ansage des Nutzers am 22.09.

Testreste der Pruefung: lokaler Testbenutzer clienttest und die zeitweise auf NODE_ENV=development gesetzte lokale API (WebKitGTK nimmt secure-Kekse ueber http nicht an, Chromium macht fuer localhost eine Ausnahme) — beides nach der Pruefung wieder zurueckgebaut.