--- phase: quick-260916-k2z plan: 01 subsystem: ui tags: [react, next.js, vitest, calendar-widget, dashboard] # Dependency graph requires: - phase: quick-260916-jvj provides: "Plakette in Kalenderfarbe (badgeColor = day.events[0]?.color), Tooltip mit Farbpunkt je Zeile, sortierte Tagesgruppen in groupEventsByDate" provides: - "groupDayBySource(events) — gruppiert Tagestermine nach sourceId (nicht Farbe), Reihenfolge = erstes Auftreten" - "buildDayBadges(events, max) — baut bis zu drei Plaketten-Kreise, ab dem vierten Kalender einen grauen Restkreis mit Summe" - "Kalender-Widget rendert je Kalender am selben Tag einen kleinen farbigen Kreis statt einer einzigen Gesamt-Plakette" affects: [dashboard-calendar-widget, calendar-month-helpers] # Actuals (#2632) actuals: tokens: 4700 tasks: 2 commits: 2 # Tech tracking tech-stack: added: [] patterns: - "Reine Hilfsfunktionen ohne React/DOM in calendar-month.ts, vom Widget importiert (Muster aus resolveCalendarConfig/groupEventsByDate fortgeschrieben)" - "Ein DOM-Element traegt genau ein data-testid; mehrere gleichartige Elemente unterscheiden sich per rest-Flag im data-testid (calendar-day-count vs. calendar-day-count-rest), Positionierung wandert auf einen gemeinsamen Wrapper" key-files: created: [] modified: - apps/web/src/components/dashboard/widgets/calendar-month.ts - apps/web/src/components/dashboard/widgets/calendar-month.test.ts - apps/web/src/components/dashboard/widgets/calendar-widget.tsx - apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx - CHANGELOG.md key-decisions: - "Grau-Wahl fuer den Restkreis: text-background statt text-white, weil --muted-foreground im Dunkelmodus hell ist (oklch 0.65) und weisse Schrift dort schwach waere; text-background ist auf beiden Themes lesbar (aus PLAN uebernommen, keine eigene Abweichung)" - "Gruppierung nach sourceId, nicht nach Farbe — zwei Kalender mit identischer Farbe bleiben zwei Kreise (aus PLAN uebernommen)" patterns-established: - "buildDayBadges(events, max = CALENDAR_DAY_BADGE_MAX) als generische Kappungslogik: erste max-1 Gruppen sichtbar, Rest zu einem Summen-Eintrag gebuendelt — wiederverwendbar fuer aehnliche Kappungsfaelle" requirements-completed: [QUICK-260916-K2Z] coverage: - id: D1 description: "groupDayBySource gruppiert Tagestermine nach sourceId (nicht Farbe) in Reihenfolge des ersten Auftretens, Farbe = Farbe des ersten Termins der Gruppe" requirement: "QUICK-260916-K2Z" verification: - kind: unit ref: "apps/web/src/components/dashboard/widgets/calendar-month.test.ts#Test 8: groupDayBySource gruppiert nach sourceId in Reihenfolge des ersten Auftretens" status: pass human_judgment: false - id: D2 description: "buildDayBadges liefert 1-3 Eintraege ohne Rest, ab dem vierten Kalender max-1 Eintraege plus einen rest:true-Eintrag mit summierter Anzahl" requirement: "QUICK-260916-K2Z" verification: - kind: unit ref: "apps/web/src/components/dashboard/widgets/calendar-month.test.ts#Test 9: buildDayBadges liefert je Kalender einen Eintrag, ab dem vierten einen grauen Restkreis" status: pass human_judgment: false - id: D3 description: "Einzelplakette (ein Kalender am Tag) sieht unveraendert aus wie vor diesem Auftrag (Kalenderfarbe bzw. Akzentfarbe)" requirement: "QUICK-260916-K2Z" verification: - kind: unit ref: "apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx#Test 3: Zaehl-Plakette zeigt die korrekte Terminanzahl je Tag" status: pass - kind: unit ref: "apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx#Test 3b: Plakette traegt die Kalenderfarbe des fruehesten Termins, Tooltip-Zeilen mit Farbpunkt" status: pass - kind: unit ref: "apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx#Test 3c: Plakette ohne Kalenderfarbe behaelt bg-primary" status: pass human_judgment: false - id: D4 description: "Zwei Kalender am selben Tag zeigen zwei kleine Kreise, je eigene Farbe und Anzahl, in Startreihenfolge" requirement: "QUICK-260916-K2Z" verification: - kind: unit ref: "apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx#Test 3d: zwei Kalender am selben Tag zeigen zwei kleine Kreise in Startreihenfolge" status: pass human_judgment: false - id: D5 description: "Vier oder mehr Kalender am selben Tag zeigen zwei farbige Kreise plus einen grauen Restkreis mit der Summe der uebrigen" requirement: "QUICK-260916-K2Z" verification: - kind: unit ref: "apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx#Test 3e: vier Kalender am selben Tag zeigen zwei Kreise plus grauen Restkreis mit Summe" status: pass human_judgment: false - id: D6 description: "CHANGELOG.md-Stichpunkt erweitert; type-check und komplette Vitest-Suite gruen (52 Dateien / 354 Tests)" verification: - kind: other ref: "pnpm --filter @tessera/web type-check && pnpm --filter @tessera/web exec vitest run" status: pass human_judgment: false duration: 10min completed: 2026-09-16 status: complete --- # Quick Task 260916-k2z: Kalender-Widget mehrere Kalender am selben Tag als kleine Kreise Summary **Kalender-Widget zeigt bei mehreren Kalendern am selben Tag je einen kleinen farbigen Kreis pro Kalender (bis drei), ab dem vierten Kalender zwei Kreise plus einen grauen Restkreis mit der Summe — via neuen reinen Hilfsfunktionen `groupDayBySource`/`buildDayBadges` in calendar-month.ts.** ## Performance - **Duration:** ~10 min (zwei Task-Commits 14:34:49 und 14:37:01 Uhr; Zeiterfassung nicht exakt ab Sitzungsbeginn protokolliert) - **Tasks:** 2 - **Files modified:** 5 ## Accomplishments - `groupDayBySource(events)`: gruppiert Tagestermine nach `sourceId` (nicht Farbe) in Reihenfolge des ersten Auftretens, Gruppenfarbe = Farbe des ersten Termins der Gruppe - `buildDayBadges(events, max = 3)`: liefert 1-3 Einträge ohne Rest bzw. ab dem vierten Kalender `max - 1` Einträge plus einen `rest: true`-Eintrag mit summierter Anzahl - Kalender-Widget: Plaketten-Rendering ersetzt (Wrapper `calendar-day-badges`, Kreise `calendar-day-count`/`calendar-day-count-rest`), Einzelplakette sieht unverändert aus wie zuvor - CHANGELOG-Stichpunkt erweitert ## Task Commits Each task was committed atomically: 1. **Task 1: Hilfsfunktionen groupDayBySource / buildDayBadges in calendar-month.ts mit Unit-Tests** - `4ddadc6` (feat, TDD: RED vor Implementierung bestätigt) 2. **Task 2: Kreise je Kalender im Widget rendern, Komponententests, CHANGELOG, Gesamtlauf** - `7429c5b` (feat, TDD: RED vor Implementierung bestätigt) **Plan metadata:** committed separately by the orchestrator (per constraints, this executor did not commit SUMMARY.md/STATE.md/PLAN.md) ## Files Created/Modified - `apps/web/src/components/dashboard/widgets/calendar-month.ts` - neue Exporte `DaySourceGroup`, `DayBadge`, `CALENDAR_DAY_BADGE_MAX`, `groupDayBySource`, `buildDayBadges`; Kopfkommentar ergänzt - `apps/web/src/components/dashboard/widgets/calendar-month.test.ts` - Tests 8 (groupDayBySource) und 9 (buildDayBadges) - `apps/web/src/components/dashboard/widgets/calendar-widget.tsx` - Plaketten-IIFE durch Wrapper `calendar-day-badges` mit `buildDayBadges(day.events).map(...)` ersetzt; Import und Kopfkommentar angepasst - `apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx` - Tests 3d (zwei Kalender) und 3e (vier Kalender) ergänzt - `CHANGELOG.md` - Stichpunkt unter „Geändert“ um „mehrere Kalender am selben Tag zeigen je einen kleinen Kreis“ erweitert ## Decisions Made - Grau-Wahl für den Restkreis: `text-background` statt `text-white` — `--muted-foreground` ist im Dunkelmodus hell (oklch 0.65), `text-background` ist auf beiden Themes lesbar (aus dem Plan übernommen, keine eigene Abweichung nötig) - Gruppierung strikt nach `sourceId`, nicht nach Farbe (aus dem Plan übernommen) ## Deviations from Plan None - plan executed exactly as written. Die einzige Zahlenabweichung ist rein buchhalterisch: Der Plan nannte für `calendar-widget.test.tsx` 15 Tests, tatsächlich sind es 14 (12 bestehende + 2 neue); die im Plan als Gesamtgate genannte Summe von 354 Tests über alle 52 Dateien stimmt exakt — die einzelne Datei-Teilzahl im Plantext war ungenau, das Verhalten selbst ist unverändert zum Plan. ## Issues Encountered None. ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - Kalender-Widget-Feature ist vollständig, kein Folgeauftrag angelegt - Keine Blocker --- *Phase: quick-260916-k2z* *Completed: 2026-09-16* ## Self-Check: PASSED All 5 modified files and the SUMMARY.md file confirmed present on disk; both task commits (`4ddadc6`, `7429c5b`) confirmed present in `git log --oneline --all`.