From 6965e52bf74b6cd335b8b1adda34d67b8e9ff11d Mon Sep 17 00:00:00 2001 From: Schalli Date: Wed, 24 Jun 2026 15:28:24 +0200 Subject: [PATCH] docs(05-04): complete calendar frontend plan --- .planning/REQUIREMENTS.md | 6 +- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 16 +- .../05-dashboard-calendar/05-04-SUMMARY.md | 158 ++++++++++++++++++ 4 files changed, 173 insertions(+), 11 deletions(-) create mode 100644 .planning/phases/05-dashboard-calendar/05-04-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 9ec57b2..421423d 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -43,15 +43,15 @@ Requirements for initial release. Each maps to roadmap phases. - [x] **DASH-02**: Widgets koennen frei positioniert und in der Groesse geaendert werden - [x] **DASH-03**: Uhr-Widget (analog oder digital) - [x] **DASH-04**: Suchleiste-Widget (oeffnet Google/Suchmaschine im Browser) -- [ ] **DASH-05**: Kalender-Widget mit Terminvorschau +- [x] **DASH-05**: Kalender-Widget mit Terminvorschau - [x] **DASH-06**: Notiz-Widget (Freitext-Kachel) - [x] **DASH-07**: Dashboard-Layout wird pro Benutzer gespeichert ### Kalender-Integration - [ ] **CAL-01**: In Einstellungen koennen mehrere Kalenderquellen eingebunden werden (WebDAV, Exchange, ICS-Link) -- [ ] **CAL-02**: Benutzer kann waehlen welche Kalender im Widget angezeigt werden -- [ ] **CAL-03**: Benutzer kann waehlen fuer welche Kalender Terminvorschauen angezeigt werden +- [x] **CAL-02**: Benutzer kann waehlen welche Kalender im Widget angezeigt werden +- [x] **CAL-03**: Benutzer kann waehlen fuer welche Kalender Terminvorschauen angezeigt werden ### Module System diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 160c126..3292f3b 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -177,7 +177,7 @@ Decimal phases appear between their surrounding integers in numeric order. **Wave 4** *(blocked on Wave 3 completion)* -- [ ] 05-04-PLAN.md -- Calendar frontend: calendar widget, calendar settings page, API client (CAL-01/02/03, DASH-05) +- [x] 05-04-PLAN.md -- Calendar frontend: calendar widget, calendar settings page, API client (CAL-01/02/03, DASH-05) **Wave 5** *(blocked on Wave 4 completion)* @@ -210,5 +210,5 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 | 2. Authentication & Multi-Tenancy | 2/5 | In Progress| | | 3. Module System & Domaincheck | 3/4 | In Progress| | | 4. Marketplace & Portal Navigation | 0/4 | Not started | - | -| 5. Dashboard & Calendar | 3/5 | In Progress| | +| 5. Dashboard & Calendar | 4/5 | In Progress| | | 6. Desktop Client & CI/CD | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 817c972..f3b91d0 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,14 +4,14 @@ milestone: v1.0 milestone_name: milestone status: executing stopped_at: Completed 05-03-PLAN.md -last_updated: "2026-06-24T13:16:25Z" -last_activity: 2026-06-24 -- Calendar backend complete +last_updated: "2026-06-24T13:28:10.956Z" +last_activity: 2026-06-24 -- Calendar backend complete (Plan 03) progress: total_phases: 6 completed_phases: 3 total_plans: 21 - completed_plans: 18 - percent: 86 + completed_plans: 19 + percent: 50 --- # Project State @@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-06-18) ## Current Position Phase: 05 (dashboard-calendar) — EXECUTING -Plan: 4 of 5 +Plan: 5 of 5 Status: Ready to execute Last activity: 2026-06-24 -- Calendar backend complete (Plan 03) @@ -57,6 +57,7 @@ Progress: [████████░░] 86% | Phase 05-dashboard-calendar P01 | 14min | 4 tasks | 28 files | | Phase 05-dashboard-calendar P02 | 4min | 4 tasks | 16 files | | Phase 05-dashboard-calendar P03 | 11min | 4 tasks | 14 files | +| Phase 05-dashboard-calendar PP04 | 5min | 2 tasks | 11 files | ## Accumulated Context @@ -84,6 +85,9 @@ Recent decisions affecting current work: - [05-03]: Dynamic imports for ews-javascript-api and @microsoft/microsoft-graph-client (lazy-load) - [05-03]: In-memory Map cache with 5-min TTL for calendar events (Redis not needed at current scale) - [05-03]: ews-javascript-api imported as any (no TypeScript definitions available) +- [Phase ?]: Optimistic UI for calendar visibility toggle — reverts on API error +- [Phase ?]: Auto-run testSource after adding new calendar source for immediate feedback +- [Phase ?]: URL constructor for client-side https-only validation (T-05-14) ### Pending Todos @@ -103,6 +107,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-06-24T13:16:25Z +Last session: 2026-06-24T13:27:57.769Z Stopped at: Completed 05-03-PLAN.md Resume file: None diff --git a/.planning/phases/05-dashboard-calendar/05-04-SUMMARY.md b/.planning/phases/05-dashboard-calendar/05-04-SUMMARY.md new file mode 100644 index 0000000..eaf973b --- /dev/null +++ b/.planning/phases/05-dashboard-calendar/05-04-SUMMARY.md @@ -0,0 +1,158 @@ +--- +phase: 05-dashboard-calendar +plan: 04 +subsystem: ui +tags: [calendar, frontend, widget, settings, react, next-intl, tdd, caldav, ics, exchange] + +requires: + - phase: 05-dashboard-calendar/01 + provides: Dashboard grid + widget registry + Prisma models + settings layout + i18n + - phase: 05-dashboard-calendar/02 + provides: Widget settings panel pattern + SearchProvider CRUD pattern + - phase: 05-dashboard-calendar/03 + provides: Calendar backend API (source CRUD, event aggregation, encryption, providers) +provides: + - CalendarWidget component rendering upcoming events with source color dots + - CalendarSettingsPanel for managing calendar sources with visibility toggle + - CalendarSourceForm with type-specific fields and https-only validation + - calendar-api.ts client (fetchSources/addSource/updateSource/deleteSource/testSource/fetchEvents) + - Widget registry wired with real CalendarWidget (replaces placeholder) +affects: [05-dashboard-calendar/05] + +tech-stack: + added: [] + patterns: [calendar-api-client-pattern, visibility-toggle-optimistic-update, source-form-type-conditional-fields, tdd-red-green-commit-flow] + +key-files: + created: + - apps/web/src/lib/calendar-api.ts + - apps/web/src/components/dashboard/widgets/calendar-widget.tsx + - apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx + - apps/web/src/components/settings/calendar-settings-panel.tsx + - apps/web/src/components/settings/calendar-source-form.tsx + - apps/web/src/app/(portal)/settings/dashboard/calendar/page.tsx + - apps/web/src/app/(portal)/settings/dashboard/calendar/calendar-settings.test.tsx + modified: + - apps/web/src/components/dashboard/widget-registry.tsx + - apps/web/src/app/(portal)/page.tsx + - apps/web/src/messages/de.json + - apps/web/src/messages/en.json + +key-decisions: + - "Optimistic UI update for visibility toggle — reverts on API error" + - "Auto-run testSource after adding a new source (connection test feedback)" + - "CalendarSourceForm uses URL constructor for client-side https validation (T-05-14)" + +patterns-established: + - "Calendar API client: separate module from dashboard-api following same credentials:'include' pattern" + - "Optimistic toggle: update local state immediately, revert on error for responsive UX" + - "Type-conditional form fields: Exchange-mode select only for exchange type, hide credentials for ICS" + +requirements-completed: [DASH-05, CAL-02, CAL-03] + +duration: 5min +completed: 2026-06-24 +--- + +# Phase 05 Plan 04: Calendar Frontend Summary + +**Calendar widget displaying aggregated events with source color dots, plus settings page for CalDAV/ICS/Exchange source management with visibility toggle and connection testing** + +## Performance + +- **Duration:** 5 min +- **Started:** 2026-06-24T13:21:01Z +- **Completed:** 2026-06-24T13:26:32Z +- **Tasks:** 2 +- **Files modified:** 11 + +## Accomplishments + +- Calendar widget fetches and displays upcoming events from visible sources via `/api/calendar/events` with 5-min refresh cycle +- Three distinct empty states per UI-SPEC: no sources, no events, loading +- Source management settings page at `/settings/dashboard/calendar` with visibility toggle (CAL-02), type badges, color dots, connection status indicators +- Calendar source form with conditional fields: Exchange-mode select for Exchange type, hidden credentials for ICS, 8-color palette picker +- Delete confirmation dialog per UI-SPEC destructive pattern +- Client-side https-only URL validation (T-05-14 threat mitigation) +- All 6 tests passing with TDD RED/GREEN commit flow + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Calendar API client + calendar widget (RED)** - `2d8699e` (test) +2. **Task 1: Calendar API client + calendar widget (GREEN)** - `c0f2f4c` (feat) +3. **Task 2: Calendar settings page (RED)** - `f99ff9a` (test) +4. **Task 2: Calendar settings page (GREEN)** - `24de136` (feat) + +## TDD Gate Compliance + +- RED gate: `2d8699e` (test commit) exists before `c0f2f4c` (feat commit) for Task 1 +- RED gate: `f99ff9a` (test commit) exists before `24de136` (feat commit) for Task 2 +- Both tasks follow proper RED -> GREEN sequence + +## Files Created/Modified + +- `apps/web/src/lib/calendar-api.ts` - Calendar API client with typed interfaces mirroring 05-03 backend contract +- `apps/web/src/components/dashboard/widgets/calendar-widget.tsx` - Upcoming events list widget with color dots and three empty states +- `apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx` - 3 tests: events rendering, no-events, no-sources +- `apps/web/src/components/settings/calendar-settings-panel.tsx` - Source list with visibility toggle, edit/delete, connection status +- `apps/web/src/components/settings/calendar-source-form.tsx` - Add/edit form with type-conditional fields and https validation +- `apps/web/src/app/(portal)/settings/dashboard/calendar/page.tsx` - Route page for calendar settings +- `apps/web/src/app/(portal)/settings/dashboard/calendar/calendar-settings.test.tsx` - 3 tests: source list, visibility toggle, form validation +- `apps/web/src/components/dashboard/widget-registry.tsx` - Added wireCalendarWidget() function +- `apps/web/src/app/(portal)/page.tsx` - Wired CalendarWidget into registry +- `apps/web/src/messages/de.json` - Added calendar.loading i18n key +- `apps/web/src/messages/en.json` - Added calendar.loading i18n key + +## Decisions Made + +- **Optimistic UI for visibility toggle:** Local state updated immediately on click, reverted on API error. Provides responsive UX without waiting for network roundtrip. +- **Auto-run connection test after source creation:** After addSource succeeds, testSource is called automatically and result displayed via connection status indicator (green check / error icon). +- **URL validation via URL constructor:** Uses `new URL()` with protocol check rather than regex for robust https-only client-side validation (T-05-14). Server-side DTO validation remains authoritative. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 2 - Missing Critical] Added calendar.loading i18n key** +- **Found during:** Task 1 +- **Issue:** Widget uses `t('calendar.loading')` for loading state but key was missing from i18n files +- **Fix:** Added `calendar.loading` to both de.json and en.json +- **Files modified:** de.json, en.json +- **Committed in:** c0f2f4c (Task 1 commit) + +--- + +**Total deviations:** 1 auto-fixed (1 missing critical) +**Impact on plan:** Minor i18n key addition required for correctness. No scope creep. + +## Issues Encountered + +None - all components implemented and tested without blocking issues. + +## Threat Mitigations Implemented + +| Threat ID | Mitigation | +|-----------|------------| +| T-05-14 | Client-side https-only URL validation via URL constructor before form submit | +| T-05-15 | CalendarWidget only consumes /api/calendar/events; no password fields in frontend types | + +## User Setup Required + +None - no external service configuration required. Calendar backend from 05-03 must be running with CALENDAR_ENCRYPTION_KEY configured. + +## Next Phase Readiness + +- Calendar frontend complete: widget + settings page fully wired to 05-03 backend +- Ready for Plan 05 (E2E testing / integration verification) +- Widget registry now has all four widget types wired with real components + +## Self-Check: PASSED + +- All 7 created files verified present on disk +- All 4 task commits verified in git log (2d8699e, c0f2f4c, f99ff9a, 24de136) + +--- +*Phase: 05-dashboard-calendar* +*Completed: 2026-06-24*