Dashboard Filtering and Drilldowns#
Overview#
Three dashboard widgets — Money In/Out (bar chart), Cashflow Sankey, and Outflows Donut — support both per-widget account/period filtering via URL query parameters and click-through drilldowns to a filtered transaction list. All data computation flows through PagesController and the IncomeStatement model.
Money In/Out Widget#
The Money In/Out widget displays 6 months of grouped income/expense bars and a per-month summary. It accepts two independent URL parameters:
| Parameter | Description |
|---|---|
money_flow_month | ISO 8601 date (e.g. 2026-08-01). Future months are clamped to the current month. |
money_flow_account_ids[] | Array of account IDs. Omitting it (or passing all accounts) resolves to nil — the unfiltered default. |
Both parameters are validated in money_flow_month_param and money_flow_account_ids_param on PagesController. Unknown or out-of-range values fall back to safe defaults rather than raising errors.
Account filter UI: The _money_flow partial renders a popover form with checkboxes for each account. On submit, the form issues a GET to root_path with money_flow_account_ids[] and money_flow_month in the query string, targeted at the dashboard_sections Turbo Frame so only the widget re-renders .
Drilldown links: The Income and Expenses summary rows are plain <a> tags pointing to transactions_path with pre-built query params :
q[types][]=incomeorexpenseq[status][]=confirmedq[start_date]/q[end_date]from the selected month's date rangeq[account_ids][]= the currently-selected account IDs
These links open the full transactions index (data-turbo-frame: "_top"), not a modal.
Cashflow Sankey Chart#
The Sankey chart renders income/expense category flows. Clicking a category node navigates to a filtered transaction list .
Click drilldown: sankey_chart_controller.js gates navigation with isNavigableCategoryNode(id), which allows only nodes prefixed income_ or expense_ (including _sub_ variants). Structural nodes like cash_flow_node and surplus_node are excluded. On a navigable node click, the controller calls Turbo.visit(buildCategoryTransactionsUrl(...)) .
URL construction is handled by the shared utility buildCategoryTransactionsUrl, which appends q[categories][], q[start_date], and q[end_date] to /transactions.
Account filter: Added in , the Sankey accepts a params[:account_id] URL parameter (single account) which PagesController resolves to an account_ids array passed to IncomeStatement.
Outflows Donut Chart#
The Outflows donut chart breaks down expense categories. Its drilldown pattern mirrors the Sankey: donut_chart_controller.js calls Turbo.visit(buildCategoryTransactionsUrl(...)) on segment click , using the same shared URL builder.
Segment data (including transactions_url values) is assembled server-side by build_outflows_donut_data in PagesController.
Shared URL Building Utility#
All category drilldowns in client-side JS use app/javascript/utils/transactions_filter_url.mjs, which exports two functions:
isNavigableCategoryNode(id)— returnstruefor IDs matching/^(income|expense)_/buildCategoryTransactionsUrl({ name, startDate, endDate, basePath })— builds a relative URL to/transactionswithURLSearchParams
Key Source Files#
| File | Role |
|---|---|
app/controllers/pages_controller.rb | Parameter parsing, data assembly for all three widgets |
app/views/pages/dashboard/_money_flow.html.erb | Money In/Out widget: account filter UI, drilldown links |
app/javascript/controllers/sankey_chart_controller.js | Sankey click → Turbo.visit navigation |
app/javascript/controllers/donut_chart_controller.js | Donut click → Turbo.visit navigation |
app/javascript/controllers/bar_chart_controller.js | Money In/Out bar chart renderer (display only, no click drilldown) |
app/javascript/utils/transactions_filter_url.mjs | Shared URL builder for category drilldowns |
Related Topics#
- Financial Reporting — covers
IncomeStatementmodel, Sankey data assembly, and chart data structures - Transaction Management — covers the transaction list search/filter interface that drilldowns land on