kimai-plugin-heatmap/.planning/phases/07-mode-switcher-week-mode/07-CONTEXT.md

4.9 KiB

Phase 7: Mode Switcher + Week Mode - Context

Gathered: 2026-04-09 Status: Ready for planning

## Phase Boundary

Users 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 Decisions

Mode 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-group with 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.metric between '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 contract
  • assets/src/renderers/registry.ts — Renderer registration pattern
  • assets/src/renderers/year.ts — Reference renderer implementation
  • assets/src/state.ts — HeatmapState with mode, metric, weekStart fields
  • assets/src/types.ts — HeatmapMode, DisplayMetric, DayEntry types
  • assets/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 attributes
  • Resources/public/heatmap.css — Existing styles, Tabler CSS var usage

</canonical_refs>

<code_context>

Existing Code Insights

Reusable Assets

  • ModeRenderer interface: new WeekModeRenderer implements this and registers via registerRenderer()
  • buildColorScale() in shared/color-scale.ts: already metric-aware, reusable for week cells
  • createTooltip()/showTooltip()/hideTooltip() in shared/tooltip.ts: reusable for week-mode tooltips
  • getDayLabels() in shared/date-utils.ts: provides weekday labels respecting start-of-week preference

Established Patterns

  • Strategy pattern dispatch: getRenderer(state.mode).render(ctx) in doRender()
  • Module-level registration: registerRenderer(new WeekModeRenderer()) at import time
  • IIFE bundle via esbuild: KimaiHeatmap global, all modules bundled into Resources/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.ts init (or via Twig template modification)
  • state.mode and state.metric changes trigger doRender() — existing pattern in heatmap.ts
  • Filter dropdown already in header area — new controls should coordinate layout with it

</code_context>

## Specific Ideas

No specific requirements — open to standard approaches

## Deferred Ideas

None — discussion stayed within phase scope


Phase: 07-mode-switcher-week-mode Context gathered: 2026-04-09