amaannawab923 opened a new pull request, #43769:
URL: https://github.com/apache/superset/pull/43769
### SUMMARY
Adds the ability to embed a **single chart** as an independent entity,
rather than only
whole dashboards. A chart gets its own embed UUID, its own guest token
scoped to that
chart alone, and its own allowed-domain list, and is served through the
existing
`/embedded/<uuid>` route.
This reimplements the approach from #33424 against current `master`. That PR
has been
open since May 2025 and has drifted; this branch is a fresh implementation
rather than a
rebase, and #33424 is left open and untouched for reference.
**Approach.** An embedded chart renders through the existing dashboard chart
stack —
`gridComponents/Chart`, its header controls, drill and cross-filter plumbing
— by
synthesising the minimum slice of dashboard state a single chart needs. That
is what keeps
the header menu, drill, `View query`, `View as table`, exports and
fullscreen working with
no reimplementation.
Notably this reuses `HYDRATE_DASHBOARD` rather than introducing a parallel
`HYDRATE_EMBEDDED` action, so **no dashboard reducer is modified**. `charts`,
`sliceEntities`, `dataMask`, `dashboardInfo` and `dashboardState` already
handle it;
`dashboardLayout` and `nativeFilters` handle it too but dereference their
slice without
optional chaining, so the fabricated payload carries an empty stand-in for
each.
`datasources` has no hydrate handler at all and is populated through its own
action.
**Backend**
- `EmbeddedChart` model and migration (`a1c7e4b62f18`), mirroring
`EmbeddedDashboard`
including `guest_token_revoked_before` and allowed-domain semantics
- `EmbeddedChartDAO` and `GET` / `POST` / `DELETE` on
`/api/v1/chart/<pk>/embedded`
- `/embedded/<uuid>` resolves a UUID as either an embedded dashboard or an
embedded chart
- `CHART` guest-token resource type, with `has_guest_access_to_chart`
matching on the
embed UUID
- `raise_for_access` previously gated guest datasource access entirely on a
`dashboardId`
in the form data, which a standalone chart never has. Adds a chart leg
that authorises
the datasource only when the guest token was issued for that chart and the
request
targets that chart's own datasource.
**Frontend**
- `src/embedded/embeddedChart/` — fabricated-state hydration, the
explore-data hook, and
the wrapper that renders the dashboard `Chart`
- `Embed chart` in the chart header menu, gated on `can_set_embedded` on
`Chart`
- The existing embed modal is reused, with resource-aware copy
**Two fixes that fall out of this**, both of which stand on their own:
- `superset/embedded/view.py` returned a 500 rather than a 403 for a
malformed `Referer`
(for example a host that looks like it carries a non-numeric port). Access
already
failed closed, so this is not a bypass, but any anonymous client could
turn one header
into a stack trace. **This affects embedded dashboards on `master` today**
and is
isolated in its own commit so it can be taken separately.
- `useIsMobile` matches a media query against the current viewport, which
inside an iframe
is the size the host chose for the embed rather than the size of the
device. A narrow
embed on a desktop was served the phone experience and lost its chart
controls entirely.
Gated behind `MOBILE_CONSUMPTION_MODE`, which is off by default.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Before: a chart could only be embedded by embedding the dashboard that
contained it.
After: charts embedded individually into a third-party page that Superset
knows nothing
about — no dashboard behind them, each with its own UUID and guest token,
header controls
and interactions intact. Screenshots to follow.
### TESTING INSTRUCTIONS
1. Enable `EMBEDDED_SUPERSET` and set a real `GUEST_TOKEN_JWT_SECRET`.
2. Run the migration: `superset db upgrade` (creates `embedded_charts`).
3. As an Admin, open a dashboard, pick a chart, and choose **Embed chart**
from its header
menu. Set an allowed domain and copy the UUID.
4. Mint a guest token scoped to the chart:
`POST /api/v1/security/guest_token/` with
`{"resources": [{"type": "chart", "id": "<uuid>"}], "user": {...}, "rls":
[]}`
5. From a page served on the allowed domain, embed it with
`@superset-ui/embedded-sdk`,
passing that UUID and a `fetchGuestToken` that returns the token above.
6. Confirm the chart renders with data, and that the header menu still
offers Force
refresh, Enter fullscreen, View query, View as table and Download.
Worth verifying explicitly:
- Requesting `/embedded/<uuid>` with no `Referer`, or one outside the
allow-list, returns
403; the allowed origin returns 200.
- A guest token minted for chart A is refused data for chart B (403),
including when both
charts share a datasource — the check is on the embed UUID, not the
dataset.
`hydrateEmbedded.test.ts` runs the real dashboard reducers against the real
fabricated
payload, so a slice that a `HYDRATE_DASHBOARD` handler dereferences cannot
silently go
missing again; that failure surfaces only at runtime and only in the
embedded path.
### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [x] Required feature flags: `EMBEDDED_SUPERSET`
- [x] Changes UI
- [x] Includes DB Migration (follow approval process in
[SIP-59](https://github.com/apache/superset/issues/13351))
- [x] Migration is atomic, supports rollback & is backwards-compatible
- [x] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [x] Introduces new feature or API
- [ ] Removes existing feature or API
The migration only creates a new table and adds no column to an existing
one, so it is
additive and reversible. Raising as a draft for early feedback, particularly
on the
`HYDRATE_DASHBOARD` reuse and on whether the `raise_for_access` chart leg is
scoped
tightly enough.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]