docs(05-02): complete search + notes widgets + settings plan
This commit is contained in:
@@ -42,9 +42,9 @@ Requirements for initial release. Each maps to roadmap phases.
|
|||||||
- [x] **DASH-01**: Konfigurierbares Dashboard als Startseite mit Drag & Drop Grid
|
- [x] **DASH-01**: Konfigurierbares Dashboard als Startseite mit Drag & Drop Grid
|
||||||
- [x] **DASH-02**: Widgets koennen frei positioniert und in der Groesse geaendert werden
|
- [x] **DASH-02**: Widgets koennen frei positioniert und in der Groesse geaendert werden
|
||||||
- [x] **DASH-03**: Uhr-Widget (analog oder digital)
|
- [x] **DASH-03**: Uhr-Widget (analog oder digital)
|
||||||
- [ ] **DASH-04**: Suchleiste-Widget (oeffnet Google/Suchmaschine im Browser)
|
- [x] **DASH-04**: Suchleiste-Widget (oeffnet Google/Suchmaschine im Browser)
|
||||||
- [ ] **DASH-05**: Kalender-Widget mit Terminvorschau
|
- [ ] **DASH-05**: Kalender-Widget mit Terminvorschau
|
||||||
- [ ] **DASH-06**: Notiz-Widget (Freitext-Kachel)
|
- [x] **DASH-06**: Notiz-Widget (Freitext-Kachel)
|
||||||
- [x] **DASH-07**: Dashboard-Layout wird pro Benutzer gespeichert
|
- [x] **DASH-07**: Dashboard-Layout wird pro Benutzer gespeichert
|
||||||
|
|
||||||
### Kalender-Integration
|
### Kalender-Integration
|
||||||
@@ -146,9 +146,9 @@ Which phases cover which requirements. Updated during roadmap creation.
|
|||||||
| DASH-01 | Phase 5 | Complete |
|
| DASH-01 | Phase 5 | Complete |
|
||||||
| DASH-02 | Phase 5 | Complete |
|
| DASH-02 | Phase 5 | Complete |
|
||||||
| DASH-03 | Phase 5 | Complete |
|
| DASH-03 | Phase 5 | Complete |
|
||||||
| DASH-04 | Phase 5 | Pending |
|
| DASH-04 | Phase 5 | Complete |
|
||||||
| DASH-05 | Phase 5 | Pending |
|
| DASH-05 | Phase 5 | Pending |
|
||||||
| DASH-06 | Phase 5 | Pending |
|
| DASH-06 | Phase 5 | Complete |
|
||||||
| DASH-07 | Phase 5 | Complete |
|
| DASH-07 | Phase 5 | Complete |
|
||||||
| CAL-01 | Phase 5 | Pending |
|
| CAL-01 | Phase 5 | Pending |
|
||||||
| CAL-02 | Phase 5 | Pending |
|
| CAL-02 | Phase 5 | Pending |
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ Decimal phases appear between their surrounding integers in numeric order.
|
|||||||
|
|
||||||
**Wave 2** *(blocked on Wave 1 completion)*
|
**Wave 2** *(blocked on Wave 1 completion)*
|
||||||
|
|
||||||
- [ ] 05-02-PLAN.md -- Search + Notes widgets, widget settings panel, SearchProvider backend (DASH-04/06)
|
- [x] 05-02-PLAN.md -- Search + Notes widgets, widget settings panel, SearchProvider backend (DASH-04/06)
|
||||||
|
|
||||||
**Wave 3** *(blocked on Wave 2 completion)*
|
**Wave 3** *(blocked on Wave 2 completion)*
|
||||||
|
|
||||||
@@ -210,5 +210,5 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6
|
|||||||
| 2. Authentication & Multi-Tenancy | 2/5 | In Progress| |
|
| 2. Authentication & Multi-Tenancy | 2/5 | In Progress| |
|
||||||
| 3. Module System & Domaincheck | 3/4 | In Progress| |
|
| 3. Module System & Domaincheck | 3/4 | In Progress| |
|
||||||
| 4. Marketplace & Portal Navigation | 0/4 | Not started | - |
|
| 4. Marketplace & Portal Navigation | 0/4 | Not started | - |
|
||||||
| 5. Dashboard & Calendar | 1/5 | In Progress| |
|
| 5. Dashboard & Calendar | 2/5 | In Progress| |
|
||||||
| 6. Desktop Client & CI/CD | 0/TBD | Not started | - |
|
| 6. Desktop Client & CI/CD | 0/TBD | Not started | - |
|
||||||
|
|||||||
+10
-7
@@ -3,14 +3,14 @@ gsd_state_version: 1.0
|
|||||||
milestone: v1.0
|
milestone: v1.0
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: Completed 05-01-PLAN.md
|
stopped_at: Completed 05-02-PLAN.md
|
||||||
last_updated: "2026-06-24T09:27:38.939Z"
|
last_updated: "2026-06-24T13:02:42.630Z"
|
||||||
last_activity: 2026-06-24 -- Phase 05 execution started
|
last_activity: 2026-06-24 -- Phase 05 execution started
|
||||||
progress:
|
progress:
|
||||||
total_phases: 6
|
total_phases: 6
|
||||||
completed_phases: 3
|
completed_phases: 3
|
||||||
total_plans: 21
|
total_plans: 21
|
||||||
completed_plans: 16
|
completed_plans: 17
|
||||||
percent: 50
|
percent: 50
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -26,11 +26,11 @@ See: .planning/PROJECT.md (updated 2026-06-18)
|
|||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 05 (dashboard-calendar) — EXECUTING
|
Phase: 05 (dashboard-calendar) — EXECUTING
|
||||||
Plan: 2 of 5
|
Plan: 3 of 5
|
||||||
Status: Ready to execute
|
Status: Ready to execute
|
||||||
Last activity: 2026-06-24 -- Phase 05 execution started
|
Last activity: 2026-06-24 -- Phase 05 execution started
|
||||||
|
|
||||||
Progress: [██▓░░░░░░░] 25%
|
Progress: [████████░░] 81%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
@@ -55,6 +55,7 @@ Progress: [██▓░░░░░░░] 25%
|
|||||||
| Phase 02-authentication-multi-tenancy P02 | 8min | 3 tasks | 26 files |
|
| Phase 02-authentication-multi-tenancy P02 | 8min | 3 tasks | 26 files |
|
||||||
| Phase 02-authentication-multi-tenancy P03 | 5min | 2 tasks | 20 files |
|
| Phase 02-authentication-multi-tenancy P03 | 5min | 2 tasks | 20 files |
|
||||||
| Phase 05-dashboard-calendar P01 | 14min | 4 tasks | 28 files |
|
| Phase 05-dashboard-calendar P01 | 14min | 4 tasks | 28 files |
|
||||||
|
| Phase 05-dashboard-calendar P02 | 4min | 4 tasks | 16 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -76,6 +77,8 @@ Recent decisions affecting current work:
|
|||||||
- [Phase ?]: Controller-level tenant isolation for ADMIN role as defense-in-depth alongside RLS
|
- [Phase ?]: Controller-level tenant isolation for ADMIN role as defense-in-depth alongside RLS
|
||||||
- [Phase ?]: Remember-me controls cookie maxAge (30d session vs browser-session) not separate token type
|
- [Phase ?]: Remember-me controls cookie maxAge (30d session vs browser-session) not separate token type
|
||||||
- [Phase ?]: react-grid-layout v2 uses dragConfig/resizeConfig instead of isDraggable/isResizable
|
- [Phase ?]: react-grid-layout v2 uses dragConfig/resizeConfig instead of isDraggable/isResizable
|
||||||
|
- [05-02]: SearchProvider defaults as constants merged with user DB rows (no seed migration)
|
||||||
|
- [05-02]: useRef with explicit undefined initial value for React 19 strict TypeScript
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -95,6 +98,6 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-06-24T09:27:38.933Z
|
Last session: 2026-06-24T12:57:00Z
|
||||||
Stopped at: Completed 05-01-PLAN.md
|
Stopped at: Completed 05-02-PLAN.md
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
---
|
||||||
|
phase: 05-dashboard-calendar
|
||||||
|
plan: 02
|
||||||
|
subsystem: dashboard
|
||||||
|
tags: [dashboard, widgets, search, notes, markdown, settings, prisma, i18n]
|
||||||
|
dependency_graph:
|
||||||
|
requires: [DashboardModule, WidgetRegistry, SettingsLayout]
|
||||||
|
provides: [SearchWidget, NoteWidget, WidgetSettingsPanel, SearchProviderForm, SearchProviderModel]
|
||||||
|
affects: [apps/api/prisma/schema.prisma, apps/web/src/components/dashboard/widget-registry.tsx, apps/web/src/lib/dashboard-api.ts, apps/web/src/messages/en.json, apps/web/src/messages/de.json]
|
||||||
|
tech_stack:
|
||||||
|
added: ["@uiw/react-md-editor@4.1.1", rehype-sanitize]
|
||||||
|
patterns: [AbortController for in-flight request cancellation, debounced autosave, wireWidget deferred wiring, SearchProvider defaults-as-constants merged with user rows]
|
||||||
|
key_files:
|
||||||
|
created:
|
||||||
|
- apps/web/src/components/dashboard/widgets/search-widget.tsx
|
||||||
|
- apps/web/src/components/dashboard/widgets/note-widget.tsx
|
||||||
|
- apps/web/src/components/dashboard/widgets/search-widget.test.tsx
|
||||||
|
- apps/web/src/components/dashboard/widgets/note-widget.test.tsx
|
||||||
|
- apps/web/src/app/(portal)/settings/dashboard/page.tsx
|
||||||
|
- apps/web/src/components/settings/widget-settings-panel.tsx
|
||||||
|
- apps/web/src/components/settings/search-provider-form.tsx
|
||||||
|
- apps/api/src/dashboard/dto/create-search-provider.dto.ts
|
||||||
|
modified:
|
||||||
|
- apps/web/src/components/dashboard/widget-registry.tsx
|
||||||
|
- apps/web/src/lib/dashboard-api.ts
|
||||||
|
- apps/web/package.json
|
||||||
|
- apps/web/src/messages/en.json
|
||||||
|
- apps/web/src/messages/de.json
|
||||||
|
- apps/api/prisma/schema.prisma
|
||||||
|
- apps/api/src/dashboard/dashboard.controller.ts
|
||||||
|
- apps/api/src/dashboard/dashboard.service.ts
|
||||||
|
decisions:
|
||||||
|
- "useRef with explicit undefined initial value for React 19 strict TypeScript compatibility"
|
||||||
|
- "SearchProvider defaults as code constants merged with user DB rows (no seed migration needed)"
|
||||||
|
- "typeof narrowing for unknown config.title to satisfy ReactNode type constraint"
|
||||||
|
- "prisma db push via host-to-container IP (DB port not exposed to host)"
|
||||||
|
metrics:
|
||||||
|
duration: 4min
|
||||||
|
completed: 2026-06-24T12:57:00Z
|
||||||
|
tasks: 4
|
||||||
|
files_created: 8
|
||||||
|
files_modified: 8
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 05 Plan 02: Search + Notes Widgets + Widget Settings Summary
|
||||||
|
|
||||||
|
Search widget with provider dropdown and new-tab open via window.open(url, '_blank', 'noopener,noreferrer'), Notes widget with MDEditor + rehype-sanitize + debounced autosave using AbortController, SearchProvider Prisma model with defaults-as-constants CRUD, and Widget Settings panel (Settings > Dashboard) with clock timezone/date toggle, note title editor, and custom search provider management with {query} client-side validation.
|
||||||
|
|
||||||
|
## Tasks Completed
|
||||||
|
|
||||||
|
| Task | Name | Commit | Key Files |
|
||||||
|
|------|------|--------|-----------|
|
||||||
|
| 1 (RED) | Failing tests for search + note widgets | 97c1380 | search-widget.test.tsx, note-widget.test.tsx |
|
||||||
|
| 1 (GREEN) | Search + Notes widgets implementation | dd02098 | search-widget.tsx, note-widget.tsx, widget-registry.tsx, dashboard-api.ts |
|
||||||
|
| 2 | SearchProvider backend (model + CRUD + defaults) | 38dcfdf | schema.prisma, dashboard.controller.ts, dashboard.service.ts, create-search-provider.dto.ts |
|
||||||
|
| 3 | Widget settings panel (Settings > Dashboard) | 7e2592b | page.tsx, widget-settings-panel.tsx, search-provider-form.tsx, en.json, de.json |
|
||||||
|
| 4 | Prisma schema push | (no code change) | Database SearchProvider table created |
|
||||||
|
|
||||||
|
## Verification Results
|
||||||
|
|
||||||
|
- `prisma validate`: PASS
|
||||||
|
- `tsc --noEmit` (apps/api): PASS
|
||||||
|
- `tsc --noEmit` (apps/web): PASS
|
||||||
|
- `vitest run src/components/dashboard`: 14/14 PASS (4 test files)
|
||||||
|
- `prisma db push`: "database is already in sync" (second run confirms)
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 1 - Bug] useRef missing initial value for React 19 strict mode**
|
||||||
|
- **Found during:** Task 3 (tsc --noEmit verification)
|
||||||
|
- **Issue:** `useRef<ReturnType<typeof setTimeout>>()` without an argument fails in React 19 with strict TypeScript -- `Expected 1 arguments, but got 0`
|
||||||
|
- **Fix:** Changed to `useRef<ReturnType<typeof setTimeout> | undefined>(undefined)` for both timerRef and abortRef
|
||||||
|
- **Files modified:** apps/web/src/components/dashboard/widgets/note-widget.tsx
|
||||||
|
- **Commit:** 7e2592b (included in Task 3 commit)
|
||||||
|
|
||||||
|
**2. [Rule 1 - Bug] unknown type not assignable to ReactNode in JSX**
|
||||||
|
- **Found during:** Task 3 (tsc --noEmit verification)
|
||||||
|
- **Issue:** `widget.config.title` is `unknown`, and using it in a `&&` JSX chain caused TS2322: `Type 'unknown' is not assignable to type 'ReactNode'`
|
||||||
|
- **Fix:** Changed to `typeof widget.config.title === 'string' && widget.config.title !== ''` narrowing
|
||||||
|
- **Files modified:** apps/web/src/components/settings/widget-settings-panel.tsx
|
||||||
|
- **Commit:** 7e2592b (included in Task 3 commit)
|
||||||
|
|
||||||
|
**3. [Rule 2 - Missing critical] i18n keys for search provider management**
|
||||||
|
- **Found during:** Task 3 (search-provider-form.tsx creation)
|
||||||
|
- **Issue:** SearchProviderForm uses t('search.providers'), t('search.addProvider'), t('search.addProviderButton') which did not exist in the translation files
|
||||||
|
- **Fix:** Added 3 new i18n keys to both en.json and de.json
|
||||||
|
- **Files modified:** apps/web/src/messages/en.json, apps/web/src/messages/de.json
|
||||||
|
- **Commit:** 7e2592b (included in Task 3 commit)
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
| Decision | Context | Outcome |
|
||||||
|
|----------|---------|---------|
|
||||||
|
| useRef explicit undefined init | React 19 strict TS requires argument | Added `undefined` initial value with union type |
|
||||||
|
| typeof narrowing for config.title | unknown not assignable to ReactNode in JSX | Used typeof string check instead of truthiness |
|
||||||
|
| DB push via container IP | DB port not exposed to host, docker exec path doesn't have schema | Used Docker internal IP 172.22.0.2 with DATABASE_URL from host |
|
||||||
|
|
||||||
|
## Known Stubs
|
||||||
|
|
||||||
|
| File | Line | Stub | Reason |
|
||||||
|
|------|------|------|--------|
|
||||||
|
| widget-registry.tsx | calendar entry (line 181) | PlaceholderWidget for calendar | Implemented in plan 05-03 |
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
Reference in New Issue
Block a user