Dashboards
A dashboard is a tile-grid layout that visualizes one or more datasets. Each tile is a configured block — a chart, a KPI card, a data table, a profile header, a comparison view. Operators build dashboards in a drag-and-drop editor and share them with a project, an organization, or the public.
Authoring
Dashboards live under a project. To create one:
- Open the project's Dashboards page.
- Click + New Dashboard, give it a name and a default audience.
- The dashboard opens in design mode — the canvas is a 12-column grid; the left rail is the block palette.
- Drag a block onto the grid. The right panel shows the block's configuration form.
- Pick a dataset as the data source. The form's other fields (column pickers, filters, formatters) populate from the dataset's schema.
- Save. The dashboard is now visible to anyone with
dashboard.read(legacy:vieweror higher).
The set of available block types is documented under the Block palette below.
Block palette
The platform ships ~30 block types across five categories. Each block has a JSON config schema; the editor renders a form against that schema.
Data display
- Chart — line, bar, area, pie, scatter. Driven by a dataset query and column mapping.
- KPI Card — single-metric tile with optional comparison delta.
- Data Table — paginated/sortable/filterable table over a dataset.
- Profile Header — name + identifying fields summary, used for entity-detail dashboards.
- Detail Card — labeled key/value list.
- Relationship List — list of related entities with link-out.
- Timeline — chronological event list.
- Comparison View — side-by-side comparison of two records.
- Status Panel — colored status indicator with description.
- Lineage Graph — embedded lineage subgraph for a dataset.
- Dashboard Embed — embed another dashboard (or an external BI tile) inside this one.
- Document Preview — preview a PDF / image stored in a managed folder.
- Badge / Tag — single-status pill.
Layout
- Hero Section — large header band.
- Page Container — section wrapper.
- Tab Container — tabbed panel — each tab holds its own sub-grid.
- Feature Grid — multi-column feature cards.
Input
- Search Bar — query input that filters downstream tiles.
- Dynamic Form — full record-edit form. Reads + writes a dataset row.
- File Tree — managed-folder browser.
- Image Upload — single-image upload tile.
- Code Editor — syntax-highlighted code editor (Monaco).
- Color Picker / Toggle Switch — small controls.
- Auth Form — login/signup, used on public-facing app pages.
Interactive
- Chat Widget — embedded chat surface against a configured agent.
Shared
- Avatar Circle / Empty State / Loading Spinner — primitives used by other blocks.
Filters and parameters
A dashboard can declare parameters that flow into every block. Common patterns:
- Date range — a single date picker at the top of the dashboard, every chart filters to that range.
- Org / project selector — for multi-tenant analytics dashboards.
- Free-text search — paired with a Search Bar block.
Parameters are referenced inside block configs as {param.name}. The dashboard renderer substitutes them at query time.
Sharing and access
Dashboards have two access tiers stored on the dashboards row:
- Audience — the default group of users who see the dashboard. Options: project members, organization members, public.
- Per-user / per-group share — additional grants or revokes via the Share modal. Three share roles: viewer, commenter, editor.
Public dashboards are reached at /public/dashboards/{slug} with no authentication. Public visibility is org-admin opt-in — there is no public path until an org admin enables it.
In the new permission layer, dashboard.read and dashboard.edit are the canonical checks. The legacy require_role("viewer") / require_role("editor") checks remain in place during the migration. See Permissions Reference.
Publishing
Dashboards can be published as part of a Honeyframe app — a bundle of pages, dashboards, APIs, and forms that becomes a customer-facing surface (e.g. a tenant-facing portal). Publishing assigns the dashboard a stable URL on the SaaS frontend and freezes its config so further edits don't immediately change the published version.
The publish lifecycle:
- Author the dashboard on the Platform (
platform.your-domain.com/dashboards). - Add it to a publishable app via Publish Manager.
- The published version lands on the SaaS surface (
app.your-domain.com/dashboards/<slug>) and is referenced from the app's navigation. - Subsequent edits on the Platform stay in draft; promote to published with the Publish action.
This author-on-PaaS, view-on-SaaS split keeps the design surface separate from the live audience surface.
Performance
Each block runs an independent query against its source dataset. Heavy dashboards (10+ tiles, large datasets) benefit from:
- Materialized intermediates — replace a
prepare → group_bychain with a single dbt-built aggregate dataset. Tile queries against the aggregate are sub-second. - Result caching — the platform caches dataset query results for 5 minutes by default. Tiles sharing the same dataset + filter share a cache hit.
- Pagination on tables — Data Table loads 100 rows by default. Push down the page size on the block config if the tile is for at-a-glance scanning rather than data exploration.
API access
| Endpoint | Description |
|---|---|
GET /api/dashboards | List dashboards visible to the caller. |
GET /api/dashboards/{id} | Full dashboard config including layout and tile blocks. |
POST /api/dashboards | Create — requires editor (legacy) or dashboard.edit (new) on the project. |
PATCH /api/dashboards/{id} | Update layout / tiles. Same auth as create. |
DELETE /api/dashboards/{id} | Delete — requires dashboard.edit on the dashboard. |
GET /api/dashboards/{id}/render?param.x=y | Render the dashboard's tiles, returning each tile's data with parameters substituted. |
The render endpoint is what the public dashboard page uses internally; embeddable dashboards (Dashboard Embed block, external BI imports) hit the same path.