Skip to content

Dashboard Views

Dashboard views provide a configurable home screen with KPI cards, charts, lists, and goal widgets. The system supports a Standard dashboard (read-only, defined by modules) and personal dashboards (user-created, fully editable).

The Standard dashboard is computed on-the-fly from the view architecture. It is never saved to the database and is always read-only. Each module contributes widgets via view inheritance, so the Standard dashboard automatically reflects all installed modules.

Users see only widgets matching their security groups.

Users can create personal dashboards stored in the DashboardPreference model. Personal dashboards support:

  • Drag-and-drop widget repositioning
  • Widget resizing
  • Adding/removing widgets
  • Renaming and deleting dashboards

Each user’s dashboards are private (enforced by a RecordRule).

The base dashboard is defined in the core module:

- data_type: UiView
name: Home Dashboard
identifier: home_dashboard_view
type: Dashboard
model: DashboardPreference
arch:
- type: row
anchor: dashboard_greeting
content:
- type: column
span: 12
content:
- type: widget
widget: Greeting
groups:
- core_internal
properties:
title: Welcome
showDate: true
showIcon: true
- type: row
anchor: dashboard_core_kpis
content:
- type: column
span: 3
content:
- type: widget
widget: KPICard
groups:
- core_internal
properties:
title: Contacts
model: Contact
mode: count
filter: (Q(active=True))
label: Active Contacts
icon: Users
color: blue

Dashboard arch uses rows and columns like form views:

ElementDescription
rowHorizontal container. Use anchor for stable inheritance targeting.
columnGrid column with span (1-12).
widgetDashboard widget with widget type, groups, and properties.
- type: widget
widget: KPICard # Widget type
groups: # Access control (optional)
- sales_user_group
properties: # Widget-specific configuration
model: SaleOrder
mode: count
filter: (Q(state='Confirmed'))
label: Sales Orders
icon: ShoppingCart
color: blue

Modules add widgets to the Standard dashboard using view inheritance. Always add an anchor to your rows for other modules to target.

- depends:
- ../security/security.yaml
data_type: UiView
name: Home Dashboard - Sales
identifier: home_dashboard_sales
type: Dashboard
model: DashboardPreference
inherited_view: home_dashboard_view
arch:
operations:
- action: add
target:
anchor: dashboard_core_kpis
position: after
value:
type: row
anchor: dashboard_sales_kpis
content:
- type: column
span: 3
content:
- type: widget
widget: KPICard
groups:
- sales_user_group
properties:
title: Quotations
model: SaleOrder
mode: count
filter: (Q(state='Quote') | Q(state='Sent'))
label: Active Quotes
icon: FileText
color: blue

Key points:

  • Use inherited_view: home_dashboard_view to extend the Standard dashboard
  • Target existing anchors (e.g., dashboard_core_kpis) with position: after
  • Always add an anchor to your new rows so other modules can extend after them
  • Use security groups on widgets for access control

Displays a single aggregated metric with icon, label, and formatted value.

widget: KPICard
properties:
model: SaleOrder
mode: count # count, sum, average, min, max
measure: total # Required when mode != count
filter: (Q(state='Confirmed'))
label: Sales Orders
icon: ShoppingCart # Lucide icon name
color: blue # Mantine color
format: number # number, currency, percent
action: sale_order_action # Navigate to this action on click
PropertyTypeDefaultDescription
modelStringRequiredModel to query
modeString"count"Aggregation: count, sum, average, min, max
measureString-Field to aggregate (required when mode is not count)
filterString-Q-expression filter
labelString"Count"Display label
iconString"ChartBar"Lucide icon name
colorString"blue"Mantine color
formatString"number"number, currency, percent
actionString-Action identifier to navigate to on click. The KPI’s filter is passed as global_filter.
actionMenuString-Root menu override for the action (auto-resolved from menu data if omitted)

Default size: 3×3 grid units

Displays grouped data as bar, area, line, donut, or radar chart.

widget: Chart
properties:
title: Monthly Revenue
model: SaleOrder
chartType: bar # bar, area, line, donut, radar
groupBy:
field: date
interval: month # day, week, month, quarter, year (for Date/Datetime fields)
mode: sum
measure: total # Required when mode != count
filter: (Q(state__in=['Confirmed','Done']))
PropertyTypeDefaultDescription
modelStringRequiredModel to query
chartTypeString"bar"bar, area, line, donut, radar
groupByObjectRequired{ field: "field_name", interval: "month" }. The interval key is optional and applies to Date/Datetime fields. Supported: day, week, month, quarter, year.
modeString"count"Aggregation: count, sum, average, min, max
measureString-Field to aggregate (required when mode is not count)
filterString-Q-expression filter
titleString-Chart title

Default size: 6×7 grid units (minimum height: 7)

Compact table widget for displaying records with formatted columns. Uses the same column spec format and formatting utilities as the CompactList form widget, but fetches its own data independently.

widget: List
properties:
title: Top Products
model: Product
limit: 5
order_by: total_sold DESC
columns:
- field: name
label: Product
bold: true
- field: total_sold
label: Sold
format: integer
align: right
- field: list_price
label: Price
format: currency
prefix: currency
color: blue
bold: true
PropertyTypeDefaultDescription
modelStringRequiredModel to query
titleString-Table title
columnsArrayRequiredColumn definitions (see below)
filterString-Q-expression filter
order_byString/Array-Sort order (e.g., "total DESC")
limitNumber5Max rows to display

Column Properties:

PropertyTypeDefaultDescription
fieldStringRequiredField name to display
labelStringField nameColumn header
formatString"text"text, currency, number, integer, percent
precisionNumberFormat defaultDecimal places
alignStringAutoleft, center, right (numbers default to right)
colorString-Mantine color for text
boldBooleanfalseBold text
prefixString-Static string or field name from the item data
suffixString-Static string or field name from the item data

Default size: 6×6 grid units (minimum height: 4)

Displays progress toward a target using a semi-circle progress indicator.

widget: Goal
properties:
model: SaleOrder
mode: count
filter: (Q(state='Done'))
target: 50
label: Monthly Sales Target
color: green
PropertyTypeDefaultDescription
modelStringRequiredModel to query
modeString"count"Aggregation: count, sum, average, min, max
measureString-Field to aggregate (required when mode is not count)
filterString-Q-expression filter
targetNumber100Goal target value
labelString"Goal"Display label
colorString"blue"Mantine color for filled segment
formatString"number"number, currency, percent
precisionNumber0Decimal places

Default size: 3×6 grid units (minimum height: 5)

Built-in welcome widget with date display. Typically spans the full width.

widget: Greeting
properties:
title: Welcome
showDate: true
showIcon: true

Personal dashboards are stored in the DashboardPreference model:

FieldTypeDescription
userManyToOne(User)Owner (auto-set to current user)
dashboard_idCharDashboard identifier (links to the view)
nameCharDisplay name (e.g., “My Sales Dashboard”)
sequenceIntegerSort order in dropdown
layoutJSONWidget positions for react-grid-layout
widgetsJSONWidget configurations (type, properties)

A RecordRule ensures users can only access their own dashboard preferences.