Stats Banner
The Stats Banner displays rich visual statistics above List and Kanban views. It supports sparkline trends, aging breakdowns, activity heatmaps, and progress rings.
Overview
Section titled “Overview”Stats are configured as an array of stat objects, either at the view level (in the list/kanban view arch) or at the action level (in the window action’s action_ctx). Action-level stats take priority over view-level stats.
Stats load after the main view data to avoid blocking the page. The banner is hidden when there are no records.
Widget Types
Section titled “Widget Types”| Widget | Description | Visual |
|---|---|---|
trend | Sparkline area chart with value + change indicator | Metric + mini chart |
aging | Stacked horizontal bar with time-based buckets | Color-coded bar segments |
heatmap | Calendar activity density grid | GitHub-style heatmap |
progress | Ring progress showing completion rate | Ring + percentage |
Basic Configuration
Section titled “Basic Configuration”Add a stats array at the top level of your list/kanban view arch:
- data_type: UiView identifier: sale_order_list_view type: List model: SaleOrder arch: - stats: - type: stat name: total properties: widget: trend label: Revenue aggregate: sum format: currency date_field: date - type: stat properties: widget: progress label: Invoiced filter: Q(invoice_status__eq='Fully Invoiced') color: teal content: - type: field name: name # ... rest of columnsStat Object Structure
Section titled “Stat Object Structure”| Field | Type | Description |
|---|---|---|
type | string | Always "stat" |
name | string | Field name to aggregate (required for sum/avg, optional for count) |
properties | object | Widget configuration (see below) |
Trend Widget
Section titled “Trend Widget”Shows a value with sparkline chart and period-over-period change percentage.
- type: stat name: total properties: widget: trend label: Revenue aggregate: sum format: currency date_field: date filter: Q(state__eq='Posted')Trend Properties
Section titled “Trend Properties”| Property | Type | Default | Description |
|---|---|---|---|
widget | string | required | "trend" |
label | string | required | Display label (e.g., “Revenue”, “Orders”) |
aggregate | string | "sum" | Aggregation: sum, count, or avg |
format | string | "number" | Value format: "currency" or "number" |
date_field | string | required | Date/DateTime field for time series |
filter | string | — | Q-expression to scope the stat (e.g., only posted records) |
color | string | primary | Mantine color for the sparkline |
How It Works
Section titled “How It Works”- Value: Aggregates the field over the filtered dataset
- Sparkline: Groups data by day/week/month (auto-detected from date span) and plots an area chart
- Change badge: Compares current period vs. previous period of equal length, shows ↑/↓ percentage
The grouping interval is chosen automatically:
- < 60 days of data → group by day
- 60–365 days → group by week
- > 365 days → group by month
Currency Scoping
Section titled “Currency Scoping”When format: currency, the stat automatically filters to the user’s default company (cid) to ensure single-currency aggregation. The company’s currency symbol and position are included in the response.
Click Behavior
Section titled “Click Behavior”Trend cards with a filter property are clickable — clicking toggles that filter on the list/kanban view. An active filter is shown with a highlighted border.
Aging Widget
Section titled “Aging Widget”Shows a stacked horizontal bar chart with 5 standard aging buckets based on a date field.
- type: stat name: total_due properties: widget: aging label: Aging date_field: due_date filter: Q(state__eq='Posted')Aging Properties
Section titled “Aging Properties”| Property | Type | Default | Description |
|---|---|---|---|
widget | string | required | "aging" |
label | string | required | Display label |
name | string | — | Monetary field to sum per bucket. If omitted, counts records |
date_field | string | required | Date field to age from (e.g., due_date) |
filter | string | — | Q-expression to scope the stat |
Buckets
Section titled “Buckets”The aging widget uses 5 fixed buckets calculated from today’s date:
| Bucket | Color | Condition |
|---|---|---|
| Current | green | date_field >= today |
| 1-30d | yellow | today - 30 <= date_field < today |
| 31-60d | orange | today - 60 <= date_field < today - 30 |
| 61-90d | red.4 | today - 90 <= date_field < today - 60 |
| 90d+ | red.8 | date_field < today - 90 |
Hover over the bar to see per-bucket values in a tooltip.
Heatmap Widget
Section titled “Heatmap Widget”Shows a calendar-style activity density grid (like GitHub contribution graphs).
- type: stat properties: widget: heatmap label: Expected Closings aggregate: count date_field: expected_close_date months: 6Heatmap Properties
Section titled “Heatmap Properties”| Property | Type | Default | Description |
|---|---|---|---|
widget | string | required | "heatmap" |
label | string | required | Display label |
aggregate | string | "count" | "count" or "sum" |
name | string | — | Field to sum (required when aggregate is sum) |
date_field | string | required | Date field for the calendar |
months | number | 6 | Number of months to display |
Progress Widget
Section titled “Progress Widget”Shows a ring progress indicator with done/total counts.
- type: stat properties: widget: progress label: Invoiced filter: Q(invoice_status__eq='Fully Invoiced') scope: Q(state__eq='Confirmed') color: tealProgress Properties
Section titled “Progress Properties”| Property | Type | Default | Description |
|---|---|---|---|
widget | string | required | "progress" |
label | string | required | Display label |
filter | string | required | Q-expression for “done” records |
scope | string | — | Q-expression applied to both done and total counts |
color | string | primary | Ring color (Mantine color name) |
Scope vs Filter
Section titled “Scope vs Filter”filter: Defines which records count as “done” (numerator only)scope: Narrows both the total and done counts (denominator + numerator)
Example: To show what percentage of posted invoices are paid:
- type: stat properties: widget: progress label: Collected filter: Q(payment_status__eq='Paid') # done = posted + paid scope: Q(state__eq='Posted') # total = posted only color: tealWithout scope, the total would include Draft records, making the percentage misleading.
Action-Level Stats
Section titled “Action-Level Stats”When multiple menu items share the same list view (e.g., Invoices and Credit Notes use customer_invoice_list_view, Bills and Debit Notes use vendor_bill_list_view), you can define different stats per action using action_ctx.stats:
- data_type: WindowAction identifier: financial_document_customer_invoice_action name: Invoices model: FinancialDocument action_ctx: default_type: Customer Invoice stats: - type: stat name: amount_company_currency properties: widget: trend label: Revenue aggregate: sum format: currency date_field: date filter: Q(state__eq='Posted') - type: stat name: total_due properties: widget: aging label: Aging date_field: due_date filter: Q(state__eq='Posted') - type: stat properties: widget: progress label: Collected filter: Q(payment_status__eq='Paid') scope: Q(state__eq='Posted') color: teal global_filter: (Q(type__eq='Customer Invoice'))Action-level stats (action_ctx.stats) override any stats defined in the view arch.
Group Aggregates
Section titled “Group Aggregates”Alongside stats, list views support group_aggregates for showing totals in grouped rows:
arch:- group_aggregates: - field: total type: sum stats: - type: stat # ... content: - type: field # ...| Property | Description |
|---|---|
field | Field name to aggregate |
type | Aggregation type: sum |
Complete Example
Section titled “Complete Example”A sales order list view with 4 stat cards:
- data_type: UiView identifier: sale_order_list_view type: List model: SaleOrder arch: - group_aggregates: - field: total type: sum stats: - type: stat name: total properties: widget: trend label: Revenue aggregate: sum format: currency date_field: date - type: stat properties: widget: trend label: Orders aggregate: count date_field: date - type: stat name: total properties: widget: trend label: Avg Order Value aggregate: avg format: currency date_field: date - type: stat properties: widget: progress label: Invoiced filter: Q(invoice_status__eq='Fully Invoiced') color: teal content: - type: field name: name properties: widget: Text label: Number fw: 600 # ... remaining columnsNext Steps
Section titled “Next Steps”- List Views - Table views
- Kanban Views - Card-based views
- Widgets - All available widgets