4.9 KiB
4.9 KiB
Phase 7: Mode Switcher + Week Mode - Context
Gathered: 2026-04-09 Status: Ready for planning
## Phase BoundaryUsers can switch between year and week visualization modes and toggle between hours and entry-count display. This is the first visible v1.1 feature, building on the renderer architecture from Phase 6. Scope: mode switcher UI, week-mode renderer, hours/count toggle. Day-mode and combined-mode renderers belong to Phase 9.
## Implementation DecisionsMode Switcher UI
- D-01: Segmented control placed in the widget header row (Kimai Tabler card header area), next to the widget title
- D-02: Shows "Year" and "Week" as the two options for this phase (Day and Combined added in Phase 9)
- D-03: Active mode visually highlighted using Kimai/Tabler CSS conventions (e.g.,
btn-groupwith active state)
Week-Mode Visualization
- D-04: Horizontal layout — 7 cells (one per weekday), colored by aggregated metric value for that weekday
- D-05: Day labels shown alongside cells (Mon, Tue, etc.), respecting user's start-of-week preference from
state.weekStart - D-06: Aggregation is client-side — sum/average hours or count from existing
DayEntry[]data grouped by weekday (no backend changes, per STATE.md decision) - D-07: Tooltip on hover shows weekday name + aggregated value (e.g., "Monday: 42.5h (23 entries)")
Hours/Count Toggle
- D-08: Separate small segmented control (not merged into mode switcher) — "Hours" / "Count" options
- D-09: Placed adjacent to the mode switcher in the header area
- D-10: Toggles
state.metricbetween'hours'and'count', triggers re-render without re-fetching data - D-11: Affects color scale in both year and week modes — year-mode already supports this via metric-aware cell fill from Phase 6
Claude's Discretion
- Exact sizing and spacing of week-mode cells (could be larger than year cells since only 7)
- Whether week-mode cells are clickable (and what click-through would show)
- Stats row behavior when in week mode — may show week-aggregated stats or hide year-specific stats like streak
- Exact Tabler CSS classes for segmented controls
- Animation/transition when switching modes
<canonical_refs>
Canonical References
Downstream agents MUST read these before planning or implementing.
Renderer Architecture (Phase 6)
.planning/phases/06-renderer-architecture/06-01-SUMMARY.md— Type contracts, ModeRenderer interface, registry, shared utilities.planning/phases/06-renderer-architecture/06-02-SUMMARY.md— YearModeRenderer implementation, orchestrator dispatch pattern
Existing Code
assets/src/renderers/types.ts— ModeRenderer interface and RenderContext contractassets/src/renderers/registry.ts— Renderer registration patternassets/src/renderers/year.ts— Reference renderer implementationassets/src/state.ts— HeatmapState with mode, metric, weekStart fieldsassets/src/types.ts— HeatmapMode, DisplayMetric, DayEntry typesassets/src/heatmap.ts— Orchestrator with doRender() dispatch and DOM layout
Requirements
.planning/REQUIREMENTS.md— VIZ-01 (mode switcher), VIZ-02 (week-mode), VIZ-05 (hours/count toggle), TEST-01 (tests)
Widget Template
Resources/views/widget/heatmap.html.twig— Kimai card embed structure, data attributesResources/public/heatmap.css— Existing styles, Tabler CSS var usage
</canonical_refs>
<code_context>
Existing Code Insights
Reusable Assets
ModeRendererinterface: newWeekModeRendererimplements this and registers viaregisterRenderer()buildColorScale()inshared/color-scale.ts: already metric-aware, reusable for week cellscreateTooltip()/showTooltip()/hideTooltip()inshared/tooltip.ts: reusable for week-mode tooltipsgetDayLabels()inshared/date-utils.ts: provides weekday labels respecting start-of-week preference
Established Patterns
- Strategy pattern dispatch:
getRenderer(state.mode).render(ctx)indoRender() - Module-level registration:
registerRenderer(new WeekModeRenderer())at import time - IIFE bundle via esbuild:
KimaiHeatmapglobal, all modules bundled intoResources/public/heatmap.js - Kimai Tabler card layout: widget header via Twig
@theme/embeds/card.html.twig
Integration Points
- Mode switcher and metric toggle need to be injected into the DOM by
heatmap.tsinit (or via Twig template modification) state.modeandstate.metricchanges triggerdoRender()— existing pattern inheatmap.ts- Filter dropdown already in header area — new controls should coordinate layout with it
</code_context>
## Specific IdeasNo specific requirements — open to standard approaches
## Deferred IdeasNone — discussion stayed within phase scope
Phase: 07-mode-switcher-week-mode Context gathered: 2026-04-09