docs(extensions): complete the dashboards extension-point documentation

Bring the dashboards extension-point doc in line with the established
editors/chat doc conventions: add a worked Example Implementation (a
flat chart-list renderer plus its registration index.tsx, with a note
on interpreting the full layout tree via meta.chartId), a Dashboards
API Reference table covering the full namespace surface, and a Next
Steps footer. Also update the contribution-types blurb to reflect that
the built-in renderer is registered through the contribution point as
the default provider.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Claude Code
2026-07-05 14:38:02 -07:00
parent f1c7ec60ce
commit ac50d83d9d
2 changed files with 67 additions and 1 deletions

View File

@@ -131,7 +131,7 @@ See [Chat](./extension-points/chat.md) for implementation details.
### Dashboard Renderers
Extensions can replace Superset's built-in dashboard renderer with a custom implementation, changing how dashboards are displayed while reusing the host's data fetching, theming, and URL handling. The dashboard renderer is a single slot: the most recently registered renderer is active, and the built-in renderer is used when none is registered or when the dashboard enters edit mode.
Extensions can replace Superset's built-in dashboard renderer with a custom implementation, changing how dashboards are displayed while reusing the host's data fetching, theming, and URL handling. The dashboard renderer is a single slot with the built-in renderer registered through the same contribution point as the default provider (`superset.dashboard-renderer`): the most recently registered custom renderer is active, and the default renders when none is registered, when the dashboard enters edit mode, or when the extensions feature flag is off.
```tsx
import { dashboards } from '@apache-superset/core';

View File

@@ -108,6 +108,66 @@ dashboards.registerDashboardRenderer(
);
```
## Example Implementation
A minimal renderer that presents the dashboard as a flat list of chart cards, ignoring the grid layout — the kind of starting point a kiosk or mobile-style renderer might build on:
### ChartListRenderer.tsx
```tsx
import type { dashboards } from '@apache-superset/core';
export default function ChartListRenderer({
dashboard,
charts,
uiConfig,
}: dashboards.DashboardRendererProps) {
return (
<main>
{!uiConfig?.hideTitle && <h1>{dashboard.title}</h1>}
<ul>
{charts.map(chart => (
<li key={chart.id}>
<h2>{chart.slice_name}</h2>
<p>{String(chart.viz_type)}</p>
{/* Fetch and render data for this chart, e.g. by building a
query context from chart.form_data and POSTing to
/api/v1/chart/data */}
</li>
))}
</ul>
</main>
);
}
```
### index.tsx
```tsx
import { dashboards } from '@apache-superset/core';
import ChartListRenderer from './ChartListRenderer';
// Registration is a module-load side effect — no activate() call needed
dashboards.registerDashboardRenderer(
{ id: 'my-extension.chart-list', name: 'Chart List Renderer' },
ChartListRenderer,
);
```
To interpret the full grid instead, walk `dashboard.layout` from its `ROOT_ID` entry — each node's `type` (`TABS`, `TAB`, `ROW`, `COLUMN`, `CHART`, `MARKDOWN`, ...) and `children` describe the arrangement, and `CHART` nodes carry the chart id in `meta.chartId`.
## Dashboards API Reference
All methods are available on the `dashboards` namespace from `@apache-superset/core`:
| Method / Event | Description |
|----------------|-------------|
| `registerDashboardRenderer(descriptor, component)` | Register a custom dashboard renderer. Returns a `Disposable` to unregister; disposing falls back to the built-in default. |
| `getDashboardRenderer()` | Returns the active provider — the custom renderer when one is registered, otherwise the built-in default. |
| `getDefaultDashboardRenderer()` | Returns the built-in default provider (`superset.dashboard-renderer`), e.g. to wrap it. |
| `onDidRegisterDashboardRenderer(listener)` | Subscribe to registration events. Returns a `Disposable`. |
| `onDidUnregisterDashboardRenderer(listener)` | Subscribe to unregistration events (including displacement by a newer registration). Returns a `Disposable`. |
## Manifest Declaration
Declare the renderer in your extension's `Contributions` metadata (at most one per extension):
@@ -127,3 +187,9 @@ Declare the renderer in your extension's `Contributions` metadata (at most one p
- Extensions load asynchronously after startup, so a dashboard opened before your extension finishes loading renders with the built-in renderer first and swaps to yours when registration lands.
- `onDataMaskChange` and `onActiveTabsChange` are defined in the contract but not consumed by the host yet — filter state changed inside a custom renderer does not persist to permalinks.
- While a custom renderer is active the host still hydrates its internal dashboard state so permalinks and embedded behavior remain intact; this is transparent to renderers but means the built-in state bookkeeping still runs.
## Next Steps
- **[Contribution Types](../contribution-types.md)** — Explore other contribution types
- **[Editors Extension Point](./editors.md)** — Another replace-the-default contribution point
- **[Development](../development.md)** — Set up your development environment