Dashboards API
Per-option reference for dashboards. For task-oriented documentation and worked examples, see the Dashboards guide.
Options are class attributes set on the dashboard class. Any option can also be a Proc — it is evaluated through Avo::ExecutionContext, where you gain access to all its attributes plus the dashboard.
# app/avo/dashboards/dashy.rb
class Avo::Dashboards::Dashy < Avo::Dashboards::BaseDashboard
self.id = "dashy"
self.name = "Dashy"
# options listed below
def cards
# register cards here
end
endIdentity and layout
-> self.id
The dashboard's unique identifier. Used as the route param, so it must be unique across all dashboards.
self.id = "dashy"- Type: String
- Default:
nil - Required: yes
-> self.name
The title shown to the user at the top of the dashboard.
self.name = "Dashy"
# or
self.name = -> { I18n.t("avo.dashboard_titles.dashy.name", default: "Dashy") }- Type: String or Proc
- Default:
nil
To localize this, prefer the avo.dashboard_translations.<class_path>.name key — see Localization. A Proc remains the fallback and is resolved on every render in the requesting user's locale. Note the namespace: core defines avo.dashboards as a string (the sidebar heading), so nesting keys under it replaces that string with a Hash and breaks the heading. Use avo.dashboard_titles.* or any other namespace.
-> self.description
Subtitle rendered under the dashboard name for extra context.
self.description = "Key metrics at a glance"- Type: String or Proc
- Default:
nil
Like self.name, a Proc is resolved per request, so -> { I18n.t("avo.dashboard_titles.dashy.description", default: "Key metrics at a glance") } follows the user's locale. See Localization.
-> self.grid_cols
How many columns the card grid has.
self.grid_cols = 4- Type: Integer
- Default:
3 - Values:
3,4,5, or6— any other value falls back to3
Ranges
-> self.global_ranges
Renders a row of range buttons at the top of the dashboard that update every card's range at once. Each entry is a number of days; its button label comes from the avo.<days> translation key.
self.global_ranges = [7, 30, 60, 365]- Type: Array of Integers
- Default:
[](no global range bar)
-> self.refresh_button
Renders a control next to the dashboard's title that reloads every card at once. Cards reload in place, so the page never navigates and each card keeps its selected range.
self.refresh_button = true- Type: Boolean
- Default:
false
INFO
Off by default because refreshing a dashboard runs every card's query at once. The per-card control is a separate opt-in under the same name — setting one does not set the other.
Header controls
-> self.controls
avo-dashboards >= v4.3.4Declares native header controls using avo-custom_controls. The block collects controls in declaration order; its HTML return value is not rendered.
self.controls = -> {
link_to "Home", main_app.root_path
partial "avo/dashboards/controls", locals: {dashboard: dashboard}
action Avo::Actions::ClearQueue
actions_list
refresh_button
}- Type: Proc or
nil - Default:
nil - Requires:
avo-custom_controlsinstalled andenabled_feature?("avo-custom_controls")enabled on the license. - Context:
dashboard,current_user,params,request,view_context,helpers,main_app, andavoare available, including inside lists. - Inheritance: inherited; assigning
nilremoves inherited controls. - Controls:
link_to,list,divider,partial,action,actions_list,refresh_button, anddefault_controls, which adds the actions dropdown and followsself.refresh_button. Lists cannot contain partials, nested lists, the actions dropdown, or the refresh button. Default resource buttons are unavailable.
The block replaces the whole header: self.refresh_button is ignored once it runs, unless the block calls default_controls. Without the gem or the license the block never runs and self.refresh_button works as usual. Dashboard authorization runs before evaluation. See the header controls guide for forms and endpoint authorization.
-> actions
avo-dashboards >= v4.3.4Declares the actions a dashboard can run. They render in an Actions dropdown in the header, unless self.controls takes the header over.
def actions
action Avo::Actions::ClearQueue, arguments: {queue: "mailers"}
divider
action Avo::Actions::Reindex, icon: "tabler/outline/refresh"
end- Signature:
action(klass, arguments: {}, icon: nil)anddivider(label: nil) - Handle:
handlereceivesdashboard:, and no records. - Authorization: the dashboard's
self.authorizeand the action'sauthorizeboth have to pass. - Fields: every field type except
belongs_toandtrix, which need a resource.
See the actions guide.
Visibility and authorization
-> self.visible
Controls whether the dashboard appears in the sidebar and can be reached. As a Proc it is evaluated through Avo::ExecutionContext, so you have access to params, current_user, context, and dashboard.
self.visible = -> { current_user.admin? }- Type: Boolean or Proc
- Default:
true
INFO
A dashboard that fails authorize is treated as not visible regardless of this option.
-> self.authorize
Authorization gate for the dashboard. Return a falsy value to deny access. Evaluated through Avo::ExecutionContext, with access to current_user, params, request, context, and view_context.
self.authorize = -> { current_user.is_admin? }- Type: Proc
- Default:
-> { true }