fix(dashboard): Rasterversion schuetzen, Kalender-Mindestbreite, Breiten je Breakpoint, Hintergrund

- Layout mit neuerer Rasterversion wird nie gespeichert, Bearbeiten gesperrt mit Hinweis
- Kalender minW 11 (~260 px bei lg), Breiten je Breakpoint auf Spaltenzahl begrenzt
- optimistische Ruecksetzung nur, wenn noch der gesetzte Wert steht
- Titel-Schalter mit fester Beschriftung + aria-pressed
- Hintergrund-Dialog: Fokus rein/zurueck, Tab bleibt im Dialog
- Loeschen eines Bildes setzt eine darauf zeigende Hintergrund-Wahl zurueck
- Uebersetzungen und CHANGELOG

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-30 03:20:16 +02:00
parent 071082983b
commit 12214a948e
21 changed files with 1194 additions and 205 deletions
@@ -1,5 +1,5 @@
import type { ComponentType } from 'react';
import { WIDGET_MODULE_SLUGS, type WidgetType } from '@tessera/shared';
import type { ComponentType } from 'react';
/**
* Die Typliste der Kacheln steht seit quick-260922-m1h EINMAL, in
@@ -57,11 +57,17 @@ export const WIDGET_CONSTRAINTS: Record<
// fuer Nav-Zeile + Wochentagskopf + 6 Rasterzeilen + Naechste-Termine-Block.
// Runde 3 (Design „Mosaik“): defaultH 16 statt 12 — mit 12 passte unter
// den Monat nur ein Termin.
// quick-260929-dmx: auf Nutzerwunsch (29.09.) schmaler ziehbar — minW 8 von
// 48 Spalten = rund 250 px am lg-Breakpoint (gemessen: Monatsraster,
// Ueberschrift und Terminliste sind dort noch benutzbar; bei rund 185 px
// wird die Ueberschrift abgeschnitten). defaultW 16 = unveraenderte Breite.
calendar: { minW: 8, minH: 8, defaultW: 16, defaultH: 16 },
// quick-260929-dmx: auf Nutzerwunsch (29.09.) schmaler ziehbar. Ziel sind
// rund 250 px (Monatsraster, Ueberschrift und Terminliste noch benutzbar;
// bei rund 185 px wird die Ueberschrift abgeschnitten). quick-260930: das
// damalige minW 8 ergab am lg-Breakpoint nur rund 186 px — gerechnet an
// der schmalsten lg-Breite (1200 px Raster, 48 Spalten, 12 px Abstand und
// Rand): Spalte = (1200 - 2*12 - 47*12) / 48 = 12,75 px, Kachel = w*12,75 +
// (w-1)*12. minW 11 = rund 260 px (10 waeren 235 px), auf breiteren
// Bildschirmen entsprechend mehr. defaultW 16 = unveraenderte Breite.
// Bestehende schmalere Kalender hebt dashboard-grid.tsx beim Anzeigen an,
// soweit rechts Platz ist (applyConstraintMinima).
calendar: { minW: 11, minH: 8, defaultW: 16, defaultH: 16 },
note: { minW: 8, minH: 4, defaultW: 12, defaultH: 8 },
// Phase 8 new widgets (D-01)
// minH 10, nicht 9 (260916-dyv, Browser-Messung des Orchestrators): der Rechner hat
@@ -98,6 +104,24 @@ export const WIDGET_CONSTRAINTS: Record<
reminder: { minW: 8, minH: 4, defaultW: 12, defaultH: 10 },
};
/**
* Spalten je Breakpoint (quick-260929-dmx: 48stel am lg-Breakpoint). Steht
* hier und nicht in dashboard-grid.tsx, weil auch der Store (neue Kacheln)
* die Spaltenzahl braucht und die Registry ohnehin von beiden importiert wird.
*/
export const GRID_COLS: Record<string, number> = { lg: 48, md: 40, sm: 24, xs: 16, xxs: 4 };
/**
* Begrenzt eine Breite (minW, defaultW) auf die Spaltenzahl des Breakpoints
* (quick-260930). Sonst waere z. B. die Suche (minW 12, defaultW 24) am
* xxs-Breakpoint mit 4 Spalten breiter als das ganze Raster. Unbekannte
* Breakpoints bleiben unbegrenzt.
*/
export function clampWidthToCols(width: number, breakpoint: string): number {
const cols = GRID_COLS[breakpoint];
return cols === undefined ? width : Math.min(width, cols);
}
/**
* Definition for a widget type in the catalog.
*/