History Section

Displays filtered records with date range and tag filtering.

Structure

  1. 408-date-range-picker - Preset buttons + From/To pickers
  2. 409-tag-filter - Tag toggle buttons in FlowLayout
  3. Total time display
  4. Share button (opens 410-share-export-sheet)
  5. HistoryGrid - nested grid with Period > Day > Record hierarchy

HistoryGrid

Three-level nested SwiftUI Grid structure:

Level 1: Period Grid

  • Rows grouped by year-month
  • Period label column: vertical text (rotated 90 degrees)
  • Contains Level 2 (Days Grid) for each month

Level 2: Days Grid

  • Rows grouped by day within each month
  • Day label column: large monospaced day number (01-31)
  • Contains Level 3 (Records Grid) for each day

Level 3: Records Grid

  • Individual record rows with columns:
    • Duration (compact format, monospaced, right-aligned)
    • Time range (start - end, monospaced)
    • Tag (color indicator + name) - hidden when single tag filter active
  • Comment shown on separate row when present (spans all columns)

Smart Column Hiding (HistoryVisibility)

Columns are intelligently hidden based on filtered data:

  • Period column: Hidden if all records are in current month of current year
  • Year in period label: Shown only if multiple years or non-current year
  • Day column: Hidden if all records are on the same day
  • Tag column: Hidden if exactly one tag filter is selected

This reduces visual noise when filtering to specific time periods or tags.

Sticky Labels

Period and day labels use sticky positioning:

  • Labels stay visible at top of viewport when scrolling through long lists
  • Offset is clamped to keep label within its cell bounds
  • Threshold: labels start sticking when cell Y goes below 100pt

Interactions

  • Tap row: Expand inline 406-record-editor (spans record columns)
  • Context menu: Delete option
  • Long press (iOS): Same as context menu

Filtering

Records filtered by:

  1. Date range (inclusive)
  2. Selected tags (if any)
  3. Untagged toggle

Running timers are excluded from history.

Export

Share button opens 410-share-export-sheet with:

  • Current date range
  • Current tag filters
  • All filtered records

Uses snapshot pattern to prevent sheet re-render issues.

Related