# Dashboards

> Compose org-shared dashboards from a widget library, pick a default everyone lands on, and switch between presets and saved views.

Source: https://zop.dev/docs/zopnight/concepts/dashboards

---

Different people want different first screens. A CFO wants top-line spend and savings; an engineer wants spend by service and region; a FinOps lead wants team budgets and showback. ZopNight lets admins compose **org-shared dashboards** from a curated widget library, set one default that every member lands on, and switch between presets and saved views from a header switcher.

![ZopNight dashboard: the All Widgets default showing total-resources, spend, savings, and savings-rate stat cards above the cost-over-time trend, with a preset switcher](https://storage.googleapis.com/zopdev-blog-resources/1/files/originals/20260707/bb5fae8c-cd26-43ec-8bdc-d7e192ddb91e-dashboard.png)

*The default dashboard; stat cards and the cost-over-time trend, with the preset switcher (Executive / Engineering / FinOps / All Widgets) top-right.*

## Presets

Four system presets ship out of the box. They're read-only; clone one to customise.

**Executive**

    Leadership view: top-line spend, month-over-month delta, savings recovered, anomaly count.

**Engineering**

    By service, by region, by environment, with right-sizing potential.

**FinOps**

    By team, by tag, with budget health and showback.

**All Widgets**

    Every widget, for evaluating the library and composing your own.

New orgs need no setup; until someone sets a default, everyone lands on **All Widgets**.

## Widget library

Ten widget types are available at ship:

`stat_cards` · `cost_trend` · `cloud_spend` · `top_costly` · `recommendations` · `quick_insights` · `budget_health` · `showback` · `schedule_execution` · `upcoming_actions`.

Each widget declares a default size and the sizes it allows. Some are **singletons** (you can only add one). Every widget is permission-gated: if your role lacks the widget's required policy, it renders a "no access" placeholder so the layout stays coherent for everyone else.

## Building a dashboard

**Start from scratch or clone a preset**

  Create a new dashboard, or clone Executive / Engineering / FinOps / All Widgets and edit from there. Presets themselves can't be edited or deleted.

**Add and arrange widgets**

  Add widgets from the library drawer (already-added singletons are disabled), drag to reorder, and pick a size per widget: **Wide** (full), **Standard** (half), or **Compact** (third). Slots are fixed; there's no free-form resize in v1.

**Name it**

  Names are unique per org. A duplicate name returns a clean error rather than silently creating a second dashboard.

**Set the org default (optional)**

  Set any dashboard (a preset or a saved one) as the organisation default in one click. Everyone lands on it when they open the dashboard.

## Permissions

Dashboards use four policies: `dashboard:view`, `dashboard:create`, `dashboard:update`, `dashboard:delete`.

| Role | Can |
|---|---|
| **Viewer** | View dashboards |
| **Editor / Admin** | View, create, update, delete, and set the org default |

Setting the org default is authorised by `dashboard:update`. See [Scopes](https://zop.dev/docs/zopnight/concepts/scopes) for the RBAC model.

## Behaviour worth knowing

- **Org-shared, not per-user.** Everyone in the org sees the same dashboards; there's no per-user default in v1.
- **Per-widget error containment.** A single widget that fails to render falls back to a placeholder instead of taking down the whole dashboard.
- **Graceful upgrades.** Layouts carry a schema version; an unknown widget type (from a newer release) renders as a placeholder rather than breaking the page.
- **Audited.** Every create / update / delete / default-switch is captured in the audit trail; see [Scopes](https://zop.dev/docs/zopnight/concepts/scopes) for how RBAC and the audit trail work.
- **Caps.** Up to 50 dashboards per org and 50 widgets per dashboard; over-limit actions return a clear error.
- **Deleting the default** clears the default pointer, so the next reader falls back to All Widgets.
