Die Einpassung nimmt max(Leinwandhoehe, Rasterhoehe) (fitCanvasToContent).
Anlass: Dashboard des Nutzers 940 px hoch bei Leinwand 849 px, dadurch
scrollte es ueberall. Im Bearbeitungsmodus bleibt die Hoehe vom Beginn des
Bearbeitens stehen, damit der Massstab beim Ziehen nicht wandert.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Spaltenmindestbreite 76 -> 52 px (Abstand zwischen den Symbolen ~59 -> ~27 px
bei einer 373 px breiten Kachel). LauncherLabel misst den Titel einzeilig in
12 px; passt er nicht, 10 px, zweizeilig mit Silbentrennung und Auslassung.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Je Reiter wird die Flaeche des ersten Desktop-Bildschirms als __canvas im
Layout-JSON gespeichert (ohne API/DB-Aenderung, GRID_VERSION bleibt 3).
Das Raster rendert in Leinwandbreite und wird per transform: scale(min(bw/cw, bh/ch))
eingepasst, Schrift eingeschlossen, ohne Scrollen; unter 768 px wie bisher.
Ziehen/Groesse aendern unter Skalierung ueber eine eigene Positionsstrategie
(createScaledStrategy aus react-grid-layout 2.2.3 rechnet den Rasterversatz falsch).
Im Browser nachgewiesen: 1920x1080 -> 1366x768 (Faktor 0,66), Ziehen +200 px
folgt der Maus, 700 px ohne Skalierung.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- 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>
- Merkliste zusaetzlich im Arbeitsspeicher (sonst alle 10 s dieselbe Meldung)
- Aendern der Faelligkeit atomar gegen gleichzeitiges Faelligwerden, setzt Mail-Spur zurueck
- UpdateReminderDto lehnt null ab (400 statt 500)
- keine Mails an deaktivierte Benutzer
- Spaeter erinnern beschriftet heute/morgen nach dem berechneten Zeitpunkt
- Bearbeiten schickt dueAt nur bei geaenderter Zeit
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- PATCH mit null fuer name/url/category ergibt 400 statt 500
- Modulansicht unterscheidet Ladefehler von "nicht gefunden"
- Formular/Loeschdialog nennen 403 und 400 eigens
- eingeklappte Seitenleiste folgt der Gruppenreihenfolge der ausgeklappten
- neue Eintraege sind mit "Eigene Module" vorbelegt
- Verwaltung zeigt bei Ladefehler nicht zusaetzlich "keine Eintraege"
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- API: ausdrueckliche iconUrl wird nur auf Form (http/https, <= 2048) geprueft
und auch gespeichert, wenn der Server sie nicht abrufen kann; keine 422 mehr
- Erkennung: Seite mit Fehlerstatus, aber HTML mit <link rel=icon>, liefert
diesen Verweis (docuvita); og:image einer Fehlerseite zaehlt nicht
- Kachel: Proxy -> iconUrl direkt im Browser (no-referrer, nur http/https) ->
Origin-Favicon -> Buchstabe
- Meldung iconUrlUnreachable (de/en) entfernt, Hinweis zum Vorrang angepasst
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- E-Mail-Planer: Anspruch vor dem Senden (genau eine Mail je Faelligkeit, hoechstens 3 Versuche), Systemlesen nur fuer die Kandidatenabfrage
- MailService.sendReminderEmail (Berliner Zeit, nur Text), GET /reminders/email-status, Haken im Formular mit Erklaerung
- Zugriffsklassifikation und Erlaubnisliste fuer forSystem nachgezogen, Aenderungsliste und Anwenderanleitung
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- API: Aendern (409 wenn faellig), Spaeter erinnern (409 wenn nicht faellig, setzt E-Mail-Spur zurueck), Loeschen; fremde Kennungen 404
- Kachel: faellige Zeilen hervorgehoben mit Erledigt und drei Spaeter-Optionen, kuenftige mit Bearbeiten und Loeschen
- Zeit-Hilfen (morgen zur gleichen Uhrzeit), Zugriffsklassifikation nachgemessen
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Reminder-Tabelle mit Zeilenschutz (Mandant+Benutzer, Systemlesen fuer den E-Mail-Planer), API reminders (Liste, Anlegen)
- Kachel "Erinnerungen", globaler Melder im Portalrahmen (Browser und Desktop, je Faelligkeit einmal)
- Desktop: Laufzeit-Berechtigung fuer Benachrichtigungen nur fuer die gespeicherte Server-Adresse
- Zugriffsklassifikation nachgemessen
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Name- und Hinweiszeile ueber dem Rahmen entfallen (Name steht schon in der
App-Leiste, Nutzerwunsch 29.09.); der Link wandert per Portal in
HEADER_ACTIONS_SLOT_ID. Ungenutzter Schluessel customModules.embedHint weg.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Opt-out-Klasse field-plain fuer die Fluent-Unterkante; im Dunkelmodus
wirkte sie im Such-Widget wie eine weisse Linie (Nutzerwunsch 29.09.).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Die eingeklappte Seitenleiste zeigte die Kacheln in Ladefolge; ein Eintrag
aus "Eigene Module" konnte so vor einem eigenen Eintrag anderer
Kategorien stehen. Jetzt gleiche Gruppenfolge wie ausgeklappt.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
CUSTOM_MODULE_CATEGORIES = MODULE_CATEGORIES + custom-modules; API prueft
dagegen, das Formular bietet sie an. Die Seitenleiste zeigt die Gruppe wie
jede Kategorie nur mit Eintrag und stellt sie immer ans Ende. Nutzerwunsch
29.09.; ohne Migration (category ist Freitext mit IsIn-Pruefung).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Die Zentrierung der belegten Spalten (Design Mosaik, Runde 3) liess
Widgets nach dem Bearbeiten springen, z. B. ein einzelnes Widget oben
links in die Seitenmitte (Nutzer, live 29.09.). Auf Wunsch ersatzlos
entfernt: Ansicht = Bearbeitungsraster. centeringOffset, breakpointFor
und die ungenutzte Prop onInsetChange entfallen.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Liste, Anlegen, Bearbeiten und Löschen unter Verwaltung, Adresse wird im Formular geprüft
- Seitenleiste zieht nach jedem Speichern oder Löschen ohne Neuladen nach
- Texte deutsch und englisch, Eintrag in der Admin-Leiste hinter „Module“
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Tabelle CustomModule mit Zeilenschutz (tenant_isolation_policy), Migration 20260929120000
- API /custom-modules: Lesen für jeden Angemeldeten, Schreiben nur Administrator, nur https ohne Zugangsdaten
- Seitenleiste zeigt eigene Module unter ihrer Kategorie, Rahmen-Seite mit Sandbox und „In neuem Tab öffnen“
- MODULE_CATEGORIES als gemeinsame Liste, Zugriffsklassifikation nachgemessen fortgeschrieben
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Neuer Schalter im Bearbeitungsmodus (neben dem Griff) setzt hideTitle in
der Widget-Konfiguration (setWidgetConfig im Dashboard-Store, optimistisch
mit Ruecksetzen); in der Ansicht entfaellt die Titelzeile per
data-hide-title, Aktionen der Titelzeile bleiben oben rechts. Kategorien der
Seitenleiste 14 px, Moduleintraege 13 px / 32 px hoch. Version 1.5.2.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Der Knopf Bearbeiten belegte eine eigene Zeile ueber den Widgets. Die
Aktionen rendern jetzt per Portal in einen Einhaengepunkt rechts in der
Kopfzeile (HEADER_ACTIONS_SLOT_ID); in der Ansicht nur der Stift, im
Bearbeitungsmodus Hintergrund, Widget hinzufuegen und Fertig. Version 1.5.1.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Nur Formatierung und Importreihenfolge, keine Verhaltensaenderung
- Betrifft ausschliesslich Befunde, die der Merge neu eingebracht hat
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Spalte User.dashboardBackground (JSONB) samt Migration
- PATCH /users/me/dashboard-background, geprueft mit parseDashboardBackground aus @tessera/shared (Allowlist, UUID-Bildkennung)
- getMe liefert dashboardBackground normalisiert neben accentColor
- Web liest die Wahl aus dem Auth-Store, speichert ueber die Server-Aktion, alte localStorage-Wahl wird einmalig uebernommen
- Hinweistext: gilt auf jedem Geraet
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- PATCH me/dashboard-background: Allowlist, UUID-Bildkennung, Mandantenbindung
- getMe liefert dashboardBackground normalisiert
- Web: Uebernahme der alten localStorage-Wahl, Hook liest aus dem Auth-Store
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Rueckmeldung Runde 3: die Reiter in der Seitenleiste gefallen nicht -
zurueck auf den Stand vor 8532b63 (Umschalter in der Kopfzeile). Statt
dessen sitzt die Begruessung jetzt zweizeilig im sonst leeren unteren
Bereich der Seitenleiste ueber "Einklappen"; ueber den Kacheln bleibt nur
die Befehlsleiste rechts.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Dashboard-Reiter stehen in der aufgeklappten Seitenleiste als Liste
unter "Dashboard" (Ziehen sortiert senkrecht, Umbenennen/Loeschen/Neu
im Bearbeitungsmodus); eingeklappt und auf dem Handy wie bisher in der
Kopfzeile. Die Kopfzeile zeigt sonst den Namen des Dashboards.
- Begruessung einzeilig auf Hoehe der Befehlsleiste.
- Kachel-Groesse: kollidiert die gezogene Groesse mit einem Nachbarn, wird
nur die freie Achse uebernommen - vorher verwarf react-grid-layout mit
preventCollision die ganze Aenderung, sobald die Maus eine Zeile nach
unten wackelte (Favoriten liessen sich deshalb oft nicht schmaler ziehen).
- Ansicht: belegte Spalten mittig, Begruessung/Befehlsleiste ruecken mit.
- Kalender: einzeilige Terminliste mit "Heute"/"Morgen" in Akzentfarbe,
Ort im Tooltip, Standardhoehe 16 statt 12.
- Hintergrund "Bluete" im Dunkelmodus weggelassen (Farbstufen), Ersatz Nebel.
- Kacheln: Symbol-Chip in der Akzentfarbe, leichtes Anheben beim Zeigen,
gestaffeltes Einblenden beim Laden (ohne bei reduzierter Bewegung).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Begruessung nach Tageszeit mit Datum, Befehlsleiste oben rechts statt
schwebendem Knopf, einheitliche Kachel-Kopfzeilen mit Symbol, Kalender
mit Pfeilknoepfen, runden Tagen und Terminpunkten, Favoriten als
36-px-Zeilen bzw. App-Starter-Kacheln, Notiz-Kaestchen im Akzent,
leerer Zustand mit drei Vorschlaegen.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Statt bunter Modulfarben neutrale graue Kacheln; gelb (persoenliche
Akzentfarbe) nur fuer den gewaehlten Eintrag der Seitenleiste und den
Seitenkopf des Moduls. Schrift auf Akzentflaechen wird jetzt je nach
Akzentfarbe hell oder dunkel gewaehlt (readableOnAccent). Anmelde-
Mosaik und Dashboard-Hintergruende nur noch in Gelb, Grau, Graphit;
Salbei ersetzt durch Kiesel.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Einheitliche Seitenkoepfe mit Modul-Kachel, Knopf- und Linkklassen
statt gelber Schrift, Karten ohne harte Rahmen, Tabellenkoepfe ohne
Grossbuchstaben, Marktplatz mit Fluent-Reitern, Filterpillen und
Kachel-Karten, Einstellungs-/Verwaltungsnavigation mit Auswahlpille,
leere Zustaende mit Symbol im Kreis, Proxmox ohne leuchtende Schatten.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Einheitliche Kachel-Kopfzeile, ruhigere Notiz-/Kalender-/Favoriten-
Darstellung, 12 px Raster-Abstand, gestrichelte Kontur und Griff im
Bearbeitungsmodus. Neuer Knopf Hintergrund: Keiner, fuenf eingebaute
(Nebel, Salbei, Bluete, Duenen, Mosaik) oder eigenes Bild aus den
Bilderrahmen-Bildern; Prototyp speichert im localStorage je Benutzer.
Mit Hintergrund werden Kacheln Mica-artig durchscheinend (Kontrast
>= 4,5:1 auch im schlechtesten Fall).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Kopfzeile 48 px dunkel mit Seitentitel statt immer Startseite,
Dashboard-Reiter mit Akzent-Unterstrich; Seitenleiste mit
Auswahlpille, Modul-Kacheln, aufgeklappten Kategorien und gefuelltem
Suchfeld; eingeklappt nur Kacheln. Einheitlicher PageHeader.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Jedes Modul bekommt Farbe und Symbol (tender-radar Ocker, dkv-fleet
Petrol, cert-manager Violett, domaincheck Blau, proxmox Rotorange,
unbekannte stabil per Hash). Kategorien in Alltagssprache; dazu die
Texte fuer die neue Anmeldeseite.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- release-notes.ts: reine Auswahl der Versionsabschnitte aus CHANGELOG.md
- release-notice-actions.ts ('use server'): Abruf und Merken ueber die API
- ReleaseNoticeDialog: barrierefreies Fenster, Eintraege ueber ChangelogView (variant plain)
- ReleaseNoticeHost in AppShell: einmal je Seitenladung, merkt erst beim Schliessen
- Texte releaseNotice in de.json und en.json
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- selectReleaseNotice: Bereich, Deckel 3, null, unparsebar, nur Neu/Geaendert/Behoben
- Server-Aktionen: Cookie, Antwortform, Fehler still
- Fenster: role=dialog, Fokusfalle, alle Schliesswege genau einmal
- Host: merkt erst beim Schliessen, nicht auf /change-password, StrictMode
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- tenant-selector: Komponenten statisch statt im Test dynamisch importiert
(Laden zaehlte in die 5-s-Frist des ersten Tests), SUPER_ADMIN/ADMIN in
zwei it aufgetrennt
- marketplace/marketplace-filters: gleiche Umstellung; userEvent an die
falsche Uhr gekoppelt statt auf shouldAdvanceTime zu warten
- proxmox-widget: Rendern wartet das erste Laden in act() ab (81 Warnungen weg)
- Todo 2026-09-23 nach completed/
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- ProxmoxServerPicker gemeinsam fuer Kachel und Einstellungsformular
- Bearbeitungsmodus: entprelltes Titelfeld, Server auswaehlen statt Liste, sofort gespeichert
- ProxmoxWidgetConfigForm unter Einstellungen > Dashboard, Titel-Zusatz in der Kopfzeile
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Auswahl-Bauteil: Reihenfolge nach position, Produktwort, Aufraeumen geloeschter Kennungen
- Einstellungsformular: Laden, Fehler, Leer, onChange fuer Titel und Auswahl
- Einstellungsbereich: Zweig proxmox mit Titel-Zusatz in der Kopfzeile
- Kachel im Bearbeitungsmodus: entprellter Titel, Auswahl statt Liste, schliesst beim Verlassen
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Zeilen nach down, warn, ok, idle, orphan mit genau einer Kennzahl, unbekannt statt 0
- config.serverIds filtert Liste und Balken, nur geloeschte Kennungen: eigener Satz
- Ansichtsmodus Links auf /modules/proxmox, Bearbeitungsmodus ohne Links
- Groessenstufen per Container-Query, Nachladen alle 60 s, pausiert bei verborgenem Tab
- formatPercent/formatCount einmal in components/proxmox, ServerCard nutzt sie
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Typ proxmox am Ende von WIDGET_TYPES, WIDGET_MODULE_SLUGS = { proxmox: 'proxmox' }
- gemeinsame Statusteile (proxmox-status, HealthBar, status-styles) nach components/proxmox/
- HealthBar variant compact: 6 px, ohne Legende, aria-hidden
- Registry 3/4/8/8, Katalog-/Registry-/API-Tests auf die erste Modul-Kachel umgestellt
- ProxmoxWidget liest nur listServers, zeigt Lade-, Leer-, Fehlerzustand
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Kopfzeile unter 640 px nur mit Bildmarke, damit die Dashboard-Reiter
lesbar bleiben (vorher war vom Reiter nur "Das" zu sehen)
- Proxmox-Karten strecken sich nicht mehr auf gleiche Zeilenhoehe
- PBS-Pruefstatus auf Deutsch ("Pruefung fehlgeschlagen"), Rohwert als title
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Kopfzeile bekommt Einhaengepunkt header-center-slot; auf / entfaellt der Text Startseite
- DashboardTabs rendert per createPortal dorthin, eigene Zeile ueber dem Raster entfaellt
- eingelassene Spur mit erhabenem aktivem Reiter, waagrecht scrollbar mit weicher Randausblendung
- role=tablist/tab, Pfeiltasten/Pos1/Ende, sichtbarer Fokusring, aktiver Reiter wird ins Bild gescrollt
- Plus-Knopf ausserhalb der Spur, Loeschdialog am Dokumentkoerper, Ziehhinweis als sr-only/Tooltip
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bei kurzen Linknamen blieb rechts viel Leerraum; minW 3 -> 1. Der Titel
kuerzt mit Auslassungszeichen, das Symbol bleibt stehen.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dashboard-tabs.tsx: Ziehen ueber Pointer-Ereignisse (Muster
xframe-config-form.tsx, D-05 - keine neue Abhaengigkeit). Schwelle 4 px
waagerechte Auslenkung trennt Klick von Ziehen; darueber wird der Zeiger
eingefangen (jsdom-Schutzhuelle), die Leiste zeigt die Vorschau-Reihenfolge
(computeReorderedIds, Einfuegen vor dem ersten Nachbarn mit Mittelpunkt
rechts vom Zeiger), beim Loslassen geht die VOLLSTAENDIGE Kennungsliste an
onReorder. Abbruch des Zeigers verwirft die Vorschau ohne zu senden. Ein
hasDraggedRef-Merker unterdrueckt den Klick, der im echten Browser nach
einem Ziehen folgt. Ziehen ist IMMER moeglich, nicht nur im
Bearbeitungsmodus (D-09) - ein Hinweistext erklaert, dass der erste Reiter
beim Oeffnen geladen wird.
dashboard-store.ts: reorderDashboards() setzt die neue Reihenfolge SOFORT
optimistisch, sendet sie und stellt bei einem Fehler die vorherige
Reihenfolge wieder her; der aktive Reiter bleibt aktiv.
dashboard-tabs.test.tsx: 21 Tests (12 alte aus Task 3 + 9 neue fuer jeden
Punkt des Verhaltensblocks). getBoundingClientRect wird je Reiter-Wrapper
ueber data-tab-index gestubbt (Reiter i belegt 100i..100i+100 - jsdom
liefert keine echten Masse). dashboard-store.test.ts: 17 Tests (15 alte +
2 neue fuer Optimismus/Ruecknahme).
Messages: widgets.tabs.dragHint war bereits in Task 3 eingetragen
(vorausschauend) - in diesem Task keine weitere Aenderung an de.json/en.json
noetig.
Gemessene Abweichung von der Plan-Erwartung (kein Rule-1/2/3-Fall, reine
Zahlendifferenz): `grep -c "react-grid-layout|dnd|sortable"
apps/web/package.json` liefert 2 statt der im Plan erwarteten 1 - der
zweite Treffer ist `@types/react-grid-layout`, bereits vor diesem Task
vorhanden (siehe `git diff --stat apps/web/package.json`: keine Aenderung
in keinem der vier Tasks). D-05 (keine neue Zieh-Abhaengigkeit) ist damit
weiterhin erfuellt, nur an der leeren package.json-Diff nachgewiesen statt
an der im Plan vorausgesagten Zahl. Ebenso liefert `pnpm --filter
@tessera/web test` 82 statt der erwarteten 83 Dateien - Task 4 fuegt (siehe
files_modified oben) keine neue Testdatei hinzu, Task 3 hatte die
Dateizahl bereits auf 82 gebracht.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>