-
Reports frontend — spec-driven generate form, sliceable viewer, dimension bars (#16)
released this
2026-08-21 14:16:35 +00:00 | 2 commits to main since this releaseMR: Reports frontend — spec-driven generate form, sliceable viewer, dimension bars
Branch:
cached-reporting→ Target:mainSummary
Reports UI rebuilt to treat the backend OpenAPI spec as the source of truth: the
generate-report form renders generically fromReportQuery, and the viewer displays
API-computed metrics verbatim instead of recomputing them client-side.Changes
react-openapi (library)
MultiEnumFieldrenderer for array-of-enum fields; dispatch branch in
FormFieldRendereruseFkFieldOptionshook +FKFieldConfig.value(FK options keyed by a non-PK
field — accounts resolve byname)FieldConfig.defaultValueseeding inextractFields; enum lift for
items.enumarrays; sanitize-payload bypasses FK resolution whenfk.valueis set
Reports page
- GenerateReportPanel: rewritten (~275 → ~110 lines) — fields extracted from the
servedReportQueryschema (labels, order, defaults, multi-enum, account picker);
server-side validation only - ReportViewer:
- Period groups built from cube buckets keyed by canonical
period_id; buckets
merged per period (disjoint slices), txn ids deduped - Cards/bars/metric strips read
metricsverbatim (outflows/inflows/sum/count/
avg/min/max/cadence/frequency); Net = one subtraction at render - Dimension-switchable bar strip (Period / Payees / Tags): segmented pill control
with sliding indicator; pills disabled when the report has ≤1 distinct value;
top-10 bars in a fixed view paged by chevrons (hidden scrollbar) - Active dim requests the full distribution via
payee=*/tags=*when its own
filter is unselected; explicit selections always slice normally
- Period groups built from cube buckets keyed by canonical
- TransactionList: shared component with optional
groupsprop (API periods +
metrics) used by the viewer; Expense page keeps the client-side fallback path;
group strip shows Sum · Avg · Min · Max · Cadence (or Frequency /day when
cadence < 1)
Fixes
- Strict DD-MM-YYYY parsing (
parseOccurredAt) in period merges and date ordering —
new Date()mis-read dates as MM-DD-YYYY and corrupted merged cadence
(Aug Zomato: 12.89 days displayed vs 0.76 actual) - Bar widths magnitude-based so all-outflow slices render at proper width
Reviewed-on: #16
Co-authored-by: Vishesh 'ironeagle' Bangotra aetoskia@gmail.com
Co-committed-by: Vishesh 'ironeagle' Bangotra aetoskia@gmail.comDownloads