• 1.2.0 2add23efe7

    Reports frontend — spec-driven generate form, sliceable viewer, dimension bars (#16)

    aetos released this 2026-08-21 14:16:35 +00:00 | 2 commits to main since this release

    MR: Reports frontend — spec-driven generate form, sliceable viewer, dimension bars

    Branch: cached-reportingTarget: main

    Summary

    Reports UI rebuilt to treat the backend OpenAPI spec as the source of truth: the
    generate-report form renders generically from ReportQuery, and the viewer displays
    API-computed metrics verbatim instead of recomputing them client-side.

    Changes

    react-openapi (library)

    • MultiEnumField renderer for array-of-enum fields; dispatch branch in
      FormFieldRenderer
    • useFkFieldOptions hook + FKFieldConfig.value (FK options keyed by a non-PK
      field — accounts resolve by name)
    • FieldConfig.defaultValue seeding in extractFields; enum lift for
      items.enum arrays; sanitize-payload bypasses FK resolution when fk.value is set

    Reports page

    • GenerateReportPanel: rewritten (~275 → ~110 lines) — fields extracted from the
      served ReportQuery schema (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 metrics verbatim (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
    • TransactionList: shared component with optional groups prop (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.com

    Downloads