From 55acae8c8b98229a21e28ba443dba476013fb44e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Wed, 8 Apr 2026 15:04:19 +0200 Subject: [PATCH] docs(04): smart discuss context --- .planning/phases/phase-4/04-CONTEXT.md | 75 ++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 .planning/phases/phase-4/04-CONTEXT.md diff --git a/.planning/phases/phase-4/04-CONTEXT.md b/.planning/phases/phase-4/04-CONTEXT.md new file mode 100644 index 0000000..5c387f3 --- /dev/null +++ b/.planning/phases/phase-4/04-CONTEXT.md @@ -0,0 +1,75 @@ +# Phase 4: Heatmap Interaction - Context + +**Gathered:** 2026-04-08 +**Status:** Ready for planning + + +## Phase Boundary + +Add click-through navigation from heatmap day cells to Kimai's timesheet view, and a project filter dropdown that re-fetches and re-renders the heatmap without page reload. + + + + +## Implementation Decisions + +### Click Navigation +- Clicking any day cell navigates to Kimai's timesheet list filtered by that date (`/en/timesheet/?daterange=YYYY-MM-DD`) +- Empty cells (no data) are clickable too — user may want to add time for that day +- Pointer cursor + subtle hover highlight (opacity change) on all cells as click affordance +- If a project filter is active, preserve it in the timesheet URL (`&projects[]=N`) + +### Project Filter +- Filter dropdown positioned next to the heatmap SVG (right side), using the spare horizontal space since the heatmap isn't full card width +- Projects only — no activity filter (API already supports `?project=N`) +- Default state: "All Projects" selected, no filter applied +- Selecting a project fetches from API with `?project=N`, re-renders heatmap in place; color scale recalculates for filtered data + +### Testing Strategy +- Vitest tests for click navigation: verify click handler sets `window.location.href` to correct Kimai URL pattern +- Vitest tests for filter dropdown: verify dropdown renders, selecting fires fetch with correct query param, heatmap re-renders with new data +- Fixture data matching existing HeatmapData shape from prior tests + +### Claude's Discretion +- Exact Kimai timesheet URL format (verify against Kimai source) +- Filter dropdown styling details (should use Tabler/Kimai form classes) +- How to populate the project list (new API endpoint or extend existing one) + + + + +## Existing Code Insights + +### Reusable Assets +- `renderHeatmap(container, data, config)` in `assets/src/heatmap.ts` — main rendering function, can be called again with new data for filter updates +- `HeatmapData` / `DayEntry` types in `assets/src/types.ts` — shared data shape +- `HeatmapController::data()` already accepts `?project` query parameter +- `HeatmapService::getDailyAggregation()` already supports `?int $projectId` parameter + +### Established Patterns +- d3 selections for SVG rendering with data binding +- Tooltip positioning via fixed-position div (mouseenter/mouseleave) +- IIFE format with `KimaiHeatmap` global, `kimai.initialized` event for deferred init +- Tabler CSS variables for theming (`--tblr-bg-surface`, `--tblr-body-color`, etc.) + +### Integration Points +- `data-url` attribute on container div passes API endpoint to JS +- Widget template at `Resources/views/widget/heatmap.html.twig` with Tabler card embed +- CSS at `Resources/public/heatmap.css` +- Route `heatmap_data` resolves to `/heatmap/data` + + + + +## Specific Ideas + +- User wants filter next to the heatmap (not in header or below) since the SVG doesn't fill the full card width — use the horizontal space to the right + + + + +## Deferred Ideas + +None — discussion stayed within phase scope. + +