Reference → Dashboard — Reference

Dashboard — Reference

The Dashboard surface is the at-a-glance plane for SGEN operators. It owns the landing view that loads after sign-in — the grid of widgets that report sales, traffic, recent orders, low-stock alerts, pending tasks, and any custom panels the operator has added. Anything an operator sees on the SG-Admin home page traces back to a record managed here.

This page is a reference for platform engineers and integrators who need to understand the surface before extending it, scripting against it, or scoping a widget catalog. Customer-facing how-tos live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.


Overview

Dashboard lives under the Home module in SG-Admin. The module renders three primary views — the dashboard itself, the widget catalog from which an operator picks new widgets, and the per-user layout editor that arranges widgets into the grid — and exposes a small set of write operations for add widget, remove widget, reorder, resize, set refresh interval, and reset to default.

The module is paired by convention: one half renders the views and supplies widget data, the other half handles writes and returns AJAX responses. Engineers reading the SG-Admin source will see this split across two controller files; the reference below describes the combined surface as it appears to a calling integration.

Dashboard widgets are distinct from Reports. A widget renders a small, frequently-refreshed summary on the dashboard grid; a report renders a full-page, parameterized analysis. Both surfaces share underlying data sources, but the rendering model and the operator's expectations differ. Report records live under the adjacent Reports surface; this page covers dashboard widgets and per-user layout only.

Where it lives in SG-Admin:

  • Sidebar: SG-Admin → Home (the dashboard is the default landing)
  • URL prefix: /sg-admin/dashboard/
  • View templates: application/views/Admin/Dashboard/
The module surface is intentionally small. Underlying data queries, time-series storage, and the long-form report pages live in adjacent surfaces — this page covers only the widget catalog, the per-user layout record, the refresh-interval contract, and the conditional-show rule that hides widgets when the calling operator's role lacks the data capability.
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Dashboard [⚙ Customize] │├──────────────────────────────────────────────────────────────────────┤│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ││ │ Sales today │ │ Visitors today │ │ Pending orders │ ││ │ $4,820 │ │ 1,284 │ │ 7 │ ││ │ ↑ 18% vs avg │ │ ↑ 6% vs avg │ │ → 2 high pri │ ││ └─────────────────┘ └─────────────────┘ └─────────────────┘ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ Sales — last 30 days │ ││ │ ▆▆▇█▅▆▆▇█▅▆▆▇█▅▆▆▇█▅▆▆▇█▅▆▆▇█▅ │ ││ │ refresh: 5 min · source: orders + currency normalize │ ││ └───────────────────────────────────────────────────────────┘ ││ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ││ │ Low stock │ │ New customers │ │ Open tickets │ ││ │ 12 items < 5 │ │ 41 (7d) │ │ 3 │ ││ └─────────────────┘ └─────────────────┘ └─────────────────┘ │└──────────────────────────────────────────────────────────────────────┘

Actions

The Dashboard surface exposes the following operations. Each is described by what it does to the data, not by its internal method name.

Render dashboard

Returns the calling operator's saved layout — the ordered list of widget instances, each with its grid position, size, and refresh interval — and the most recent data for every widget the operator's role can see. Widgets the role cannot see are stripped from the response before render; the layout record itself is unchanged. The response also carries a layout version so the client can detect concurrent edits from another session.

List widget catalog

Returns the catalog of available widget types — the set of widget kinds the platform ships, plus any widget kinds registered by installed modules. Each entry carries a widget kind slug, display name, description, default size, default refresh interval, the data capability it requires, and a preview thumbnail. The catalog is read-only; widget kinds are registered by code, not by operator action.

Add widget

Inserts a new widget instance into the calling operator's layout. Accepts the widget kind slug, an optional initial position, an optional initial size, and an optional refresh-interval override. The surface validates that the operator's role holds the data capability for the requested widget kind, finds a free position in the grid, and persists the new instance.

Remove widget

Detaches a widget instance from the calling operator's layout. Adjacent widgets reflow to occupy the freed space. The widget kind remains available in the catalog; removal only affects the per-user layout record.

Reorder

Moves a widget instance to a new grid position within the calling operator's layout. Accepts the instance identifier and the target position. Other widgets reflow to accommodate. Reorder is the per-widget primitive; bulk layout edits are expressed as a sequence of reorder calls or as a single layout-replace.

Resize

Changes the grid size of a widget instance — small, medium, large, or full-width — within the calling operator's layout. Widget kinds declare their supported sizes; sizes outside the supported set are rejected.

Set refresh interval

Changes how often a widget instance polls for fresh data — at the widget level, overriding the kind's default. Valid intervals run from one minute to one day on a fixed step ladder. The new interval applies starting from the next poll cycle.

Set conditional show

Attaches a conditional-show rule to a widget instance — a small expression evaluated at render time that hides the widget when the condition is false. Conditions reference operator attributes (role, last-seen, current site), time-of-day, or simple data thresholds (hide if today's sales = 0). The condition is evaluated at every render; hidden widgets do not consume grid space.

Reset to default

Replaces the calling operator's layout with the role-default layout. The role-default layout is configured at the role level and supplies a sensible widget set for that role's typical work. Reset is irreversible at the layout level — the prior custom layout is discarded — but widget instance history (creation, resize, reorder events) remains in the Activity Log.

Engineering note. Widget data fetches are cached per operator per kind per refresh-interval bucket. Two widgets of the same kind on the same dashboard share a single cache entry, even when their refresh intervals differ; the longer interval wins.

Data model

A widget-instance record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.

FieldTypeNotes
idintegerPrimary key. Stable across edits.
user_idintegerThe operator who owns this instance.
kind_slugstringReferences a widget kind in the catalog.
positionobjectGrid coordinates (row, column).
sizeenumsmall, medium, large, full_width.
refresh_interval_secondsintegerStep-ladder value: 60, 300, 900, 3600, 21600, 86400.
conditional_showexpressionOptional. Empty means always shown.
created_attimestampSet on add, immutable.
updated_attimestampTouched on any reorder, resize, or interval change.
Widget-kind catalog row: slug, display_name, description, default_size, default_interval, required_capability, preview_thumb_url, supported_sizes, registered_by (core or installed-module identifier). Catalog rows are not editable through the surface; they are produced by code registration.

Per-user layout semantics: the layout is a flat list of widget instances scoped to one operator. There is no shared "team dashboard" record at this layer — every operator carries their own layout. Role-default layouts live alongside in a separate template table; reset copies the role-default into the operator's layout in a single transaction.

Refresh-interval semantics: the operator's per-instance interval overrides the kind's default. The actual fetch frequency is the maximum of the per-instance interval and a system floor configured under Settings (defaults to one minute) — this prevents misconfigured widgets from saturating the data layer.

Conditional-show semantics: the condition is evaluated at every render, not at write time. Conditions reference operator attributes (current_role, current_site), time-of-day (hour_of_day, day_of_week), and a small set of data-summary slugs (sales_today_gt_zero, pending_orders_gt_zero). The grammar is documented under Settings → Rule Grammar.

USER jerome@sgen.com│▼LAYOUT├── widget instance 1 kind:sales_today pos: r1 c1 size: small poll: 5m├── widget instance 2 kind:visitors_today pos: r1 c2 size: small poll: 5m├── widget instance 3 kind:pending_orders pos: r1 c3 size: small poll: 1m├── widget instance 4 kind:sales_chart_30d pos: r2 c1 size: full poll: 1h├── widget instance 5 kind:low_stock pos: r3 c1 size: small poll: 1h└── widget instance 6 kind:open_tickets pos: r3 c3 size: small poll: 5mconditional_show: emptyWIDGET KIND CATALOG (read-only, registered by code)├── sales_today required_cap: orders.read├── visitors_today required_cap: analytics.read├── pending_orders required_cap: orders.read├── sales_chart_30d required_cap: orders.read├── low_stock required_cap: inventory.read├── new_customers required_cap: customers.read└── open_tickets required_cap: support.readAt render: filter operator's layout against role capability map.Stripped widgets do not appear; layout record is unchanged.

Permissions

Access to the Dashboard surface is gated at two layers — plus a per-widget data-capability check applied during render.

Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the Dashboard surface.

Layer 2 — per-action capability. Within SG-Admin, each Dashboard action checks a capability associated with the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and the capability map is:

CapabilityAdministratorEditorViewer
Render dashboard
List widget catalog
Add widget (any kind)
Remove own widget
Reorder own widgets
Resize own widget
Set refresh interval
Set conditional show
Reset own layout to default
Edit role-default layout
Force-reset another operator's layout
Custom roles defined under Settings → Roles override the default map. The capability slugs are stable; the role slugs are configurable.

Layer 3 — per-widget data capability. Each widget kind in the catalog declares a required_capability — for example, the Sales widget requires orders.read, the Stock widget requires inventory.read. The render step filters the operator's layout against the role's capability map. Widgets the role cannot read are stripped from the response, with the layout record left untouched (so the widget reappears if the operator's role gains the capability later).

Self-protection rules. An operator cannot edit another operator's layout outside the administrative force-reset path. A widget kind that the operator's role lacks the capability for cannot be added to that operator's layout — the surface returns a structured rejection at write time. The refresh-interval floor configured under Settings is enforced server-side; intervals shorter than the floor are clamped upward without rejecting the write.

Audit. Every write — add widget, remove widget, reorder, resize, set interval, set conditional show, reset — emits an Activity Log entry. The log records the acting operator, the widget instance identifier, and the change shape. Role-default edits and force-resets carry an actor and target pair, since the acting operator differs from the affected operator.

REQUEST│▼┌───────────────────────────┐│ Admin gate │ unauth → reject│ (every /sg-admin/* call) │└─────────────┬─────────────┘│ authed▼┌───────────────────────────┐│ Action capability check │ role lacks cap → reject│ (per-action) │ (custom roles override defaults)└─────────────┬─────────────┘│ allowed▼┌───────────────────────────┐│ Self-protection rules │ cross-user edit /│ │ missing data-cap on add /│ │ refresh below floor → reject or clamp└─────────────┬─────────────┘│ passes▼action executes│▼On render: per-widget data-cap filter│▼Activity Log entry

Related references

  • Reports — Reference. Long-form parameterized analyses. Many dashboard widgets are summary tiles that link through to a corresponding report. The link target is declared at the widget-kind level.
  • Settings — Reference. Owns the refresh-interval floor, the rule grammar for conditional-show expressions, and the role-default layout templates. Changes there reshape Dashboard defaults across all operators.
  • Users — Reference. Owns the operator record that a layout is scoped to. Permanent delete of an operator cascades to their layout instances; soft delete preserves them.
  • Roles — Reference. Owns the capability map referenced by the per-widget data-capability filter. Capability slug stability is documented under Roles.
  • Activity Log — Reference. Captures every dashboard write, including the force-reset path. Retention is governed by the site's general settings.
  • Modules — Reference. Installed modules can register additional widget kinds into the catalog. The registration contract — slug, display name, data fetcher, supported sizes — is documented under Modules.
  • Notifications — Reference. Some widgets surface notification counts (open tickets, low stock, pending approvals). The notification source is documented in its own reference.
For the corresponding customer-facing walkthrough — adding a widget, rearranging the layout, setting a refresh interval, resetting to defaults — see the Dashboard section of the customer docs at /docs/dashboard.
On this page