Skip to content

Range and Customization

delabrcd edited this page Jun 6, 2026 · 1 revision

Range and Customization

The cockpit drives every view — charts, the bills list, and the CSV/PDF export scope — from a single date-range pref, and lets you tune each chart in place.

One range, everywhere (lib/range.ts, PURE)

The range is one persisted pref (lib/prefs.tsx, localStorage) shaped as:

interface RangePref { preset: RangePreset; fromYm: number | null; toYm: number | null }

resolveRange() normalizes it into concrete inclusive ym bounds (YYYYMM) so any caller can filter both shapes the app speaks — MonthRow.ym (a YYYYMM int) and a Bill.statementDate (a YYYY-MM-DD string) — with a single comparison. It's pure and unit-tested (test/range.test.ts).

Presets

RangePreset = all | ytd | 12mo | 24mo | 36mo | custom. The non-custom presets resolve to a trailing-month window (all and ytd are special-cased); custom uses inclusive fromYm/toYm bounds, where null on a side means open-ended (falls back to the data's natural edge).

Visual month/year range picker

components/MonthRangePicker.tsx + RangeControl.tsx replace the native month inputs with a visual month/year picker and the preset buttons above. Because everything reads the one resolved range, picking a range (or a preset) instantly re-scopes the charts, the bills list, and what a CSV/bulk-PDF export contains — no per-view re-selection.

Paginated, customizable charts

The dashboard is a responsive single-screen cockpit: on a ≥1280px desktop it fits without page scroll (plot heights are derived from 100dvh minus the fixed chrome), and it collapses to a scrolling single/two-column layout on smaller screens and mobile.

  • Pagination: charts are shown 4 per page with prev/next arrows and a page-nav bar, so the fit-to-screen layout never has to cram every chart in at once.
  • Per-chart customization: each chart panel has a discoverable, labelled "Customize" gear (ConfigurableChart.tsx) — not a bare icon — that opens the chart's options. Charts stay declarative: their series/axes/colors come from lib/chartSpec.ts and the generic ConfigurableChart derives the menu, so there's no bespoke chart component to fork (Contributing).

Related

  • Live scrape progress — a banner (components/ScrapeProgress.tsx, lib/ngrid/progress.ts) shows phases during a scrape, which matters most on the long first run.
  • Exports follow the active range: CSV (/api/export, lib/csv.ts) and bulk-PDF (/api/export/pdfs, lib/archive.tszip for Windows/macOS, tgz for Linux).

Clone this wiki locally