Skip to content

feat(embedded): embed a single chart as an independent entity [SIP-145] - #43769

Open
amaannawab923 wants to merge 21 commits into
masterfrom
feat/embedded-chart
Open

feat(embedded): embed a single chart as an independent entity [SIP-145]#43769
amaannawab923 wants to merge 21 commits into
masterfrom
feat/embedded-chart

Conversation

@amaannawab923

@amaannawab923 amaannawab923 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Screen.Recording.2026-09-01.at.9.38.38.PM.mov

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:
  • Required feature flags: EMBEDDED_SUPERSET
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • 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.

@github-actions github-actions Bot added risk:db-migration PRs that require a DB migration api Related to the REST API labels Sep 1, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.10.

Benchmark suite Current: a658e8b Previous: 4a18556 Ratio
embedded entrypoint (JS) 9322462 bytes 7968217 bytes 1.17

This comment was automatically generated by workflow using github-action-benchmark.

@netlify

netlify Bot commented Sep 1, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit a658e8b
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a9917e71f84fa00083b802e
😎 Deploy Preview https://deploy-preview-43769--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 45.75472% with 115 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.34%. Comparing base (4a18556) to head (a658e8b).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
...rset-frontend/src/embedded/embeddedChart/index.tsx 6.97% 40 Missing ⚠️
superset/charts/api.py 51.85% 26 Missing ⚠️
...ntend/src/embedded/embeddedChart/useExploreData.ts 0.00% 19 Missing ⚠️
superset/security/manager.py 28.57% 9 Missing and 1 partial ⚠️
...dashboard/components/SliceHeaderControls/index.tsx 41.66% 7 Missing ⚠️
superset/daos/chart.py 66.66% 4 Missing ⚠️
superset-frontend/src/embedded/index.tsx 25.00% 3 Missing ⚠️
...d/src/dashboard/components/EmbeddedModal/index.tsx 75.00% 2 Missing ⚠️
superset/embedded/view.py 83.33% 2 Missing ⚠️
...tend/src/embedded/embeddedChart/hydrateEmbedded.ts 83.33% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #43769      +/-   ##
==========================================
- Coverage   79.39%   79.34%   -0.05%     
==========================================
  Files        2894     2898       +4     
  Lines      167749   167949     +200     
  Branches    38853    38892      +39     
==========================================
+ Hits       133182   133267      +85     
- Misses      32066    32180     +114     
- Partials     2501     2502       +1     
Flag Coverage Δ
hive 37.80% <52.94%> (+0.01%) ⬆️
javascript 74.84% <22.58%> (-0.06%) ⬇️
mysql 57.48% <63.86%> (+<0.01%) ⬆️
postgres 57.52% <63.86%> (+<0.01%) ⬆️
presto 39.68% <53.78%> (+0.01%) ⬆️
python 83.81% <63.86%> (-0.04%) ⬇️
sqlite 57.21% <63.86%> (+<0.01%) ⬆️
unit 74.31% <56.30%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Mirrors EmbeddedDashboard so both embeddable resource types share the same
guest-token and allowed-domain semantics, including
guest_token_revoked_before.
…oints

Adds GET/POST/PUT/DELETE on /api/v1/chart/<pk>/embedded, mirroring the
dashboard embedded endpoints, with a set_embedded permission for writes.
The embed view now falls back to EmbeddedChartDAO and passes resource_type
plus chart_id into the bootstrap payload.
Builds the minimum slice of dashboard state a single chart needs and renders
the existing dashboard Chart component against it, so cross-filtering, drill
and the header controls work without reimplementation.

Reuses HYDRATE_DASHBOARD rather than adding a parallel action, so no
dashboard reducer changes are required; datasources is populated through its
own setDatasources action.
Generalises the embed modal with an optional resourceType (defaulting to
dashboard, so existing call sites are unchanged) and adds an Embed chart
item to the chart header menu, gated on EMBEDDED_SUPERSET and the
can_set_embedded permission on Chart.
t moved to @apache-superset/core/translation, css/styled to
@apache-superset/core/theme, and ErrorBoundary is a named export.
Adds a CHART guest token resource type, validates it against the embedded
chart uuid, and lets a directly-embedded chart satisfy the guest branch of
raise_for_access without belonging to a dashboard.
Two gaps surfaced once a chart was actually rendered on its own:

- The nativeFilters and dashboardLayout reducers dereference their slice
  unconditionally on HYDRATE_DASHBOARD, so the fabricated state has to carry
  both even though a lone chart has no layout tree and no native filters.

- raise_for_access gates guest datasource access entirely on a dashboardId in
  the form data, which a standalone chart never has. Added a chart leg that
  authorizes the datasource when the guest token was issued for that chart and
  the request targets the chart's own datasource.
The modal is shared with the dashboard flow and its copy was hardcoded to
'dashboard', so a chart embed read 'This dashboard is ready to embed'.
same_origin parses the referrer eagerly, so an attacker-controlled value whose
authority looks like it carries a non-numeric port (for example
http://localhost:3007.evil.com/) raised ValueError instead of returning False.
Access already failed closed, but any anonymous client could turn one header
into a stack trace. This is not specific to embedded charts: the same path
serves embedded dashboards today.
The dashboard gives every chart a holder element that owns two things the
header controls reach for: the node handed to requestFullscreen, and the
dashboard-chart-id-<id> class the jpeg and PDF exports select on. Rendering
Chart directly meant neither existed, so fullscreen always reported
'not supported in this browser' and the image exports silently produced
nothing. The embed now supplies its own holder rather than adopting
ChartHolder, which would drag in drag-and-drop, resize and edit-mode logic an
iframe has no use for.

Popups are portaled into the fullscreen element for the same reason the
dashboard does it: only that subtree is painted, so the header menu would
otherwise be unreachable while fullscreen.
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 therefore treated as a phone and lost
its chart controls entirely, since SliceHeader hides them when isMobile. Mobile
consumption mode is a whole-app experience (route guarding, drawer navigation)
that an embed does not have to begin with.
Runs the real dashboard reducers against the real payload, so a slice that a
HYDRATE_DASHBOARD handler dereferences without optional chaining cannot go
missing again. That failure only surfaces at runtime and only in the embedded
path, which is why it went unnoticed. Also fills in dashboardLayout and
nativeFilters on HydrateEmbeddedAction, which had gone stale.
The chart title and the header menu rendered flush against the iframe edge,
because on a dashboard that breathing room comes from the grid gutter and an
embed has no grid. The holder supplies it instead.

Sizing moved from the viewport to the holder's content box, so the chart lays
out inside that padding rather than overflowing it, and the holder also carries
dashboard-component-chart-holder, which is the class the fullscreen styles
select on.
Import ordering and formatting from ruff, and dropping an unused alembic op
import from the migration, which builds its table through the shared helpers.
tsc rejected passing the loosely typed dataset to setDatasources, which stores
it as a Datasource. The explore endpoint returns the full datasource, so the
field is declared as one rather than cast at the call site. Also applies oxfmt
formatting the frontend hook expects.
The purge registry requires every inbound foreign key to a supported model to
be declared, so adding embedded_charts.slice_id left Slice with an incomplete
policy. Declared as OWNED with its three outbound keys, mirroring how
embedded_dashboards is declared against Dashboard, which matches the cascade
already on the relationship and the migration.
…mission

set_embedded is exposed for POST and PUT but only documented post, so the
generated spec carried a put operation with no responses and failed OpenAPI
validation. The chart info permission set also needed can_set_embedded, which
the dashboard equivalent already lists.
Two unit test failures, one real and one a fixture gap.

has_embedded_chart_access queried the slice before establishing that a guest
user exists, so it issued a database lookup on every datasource check that
reached it, including paths where the grant could never hold. Resolving the
guest user first skips the query entirely in that case.

The embedded guest chart test builds its security manager as a mock specced
against the real class, so has_guest_access_to_chart returned a truthy mock and
the denial assertion no longer held. It is closed by default alongside the other
paths the helper already closes, and the chart-direct grant now has a test of
its own rather than only being exercised implicitly.
The embedded endpoints reference EmbeddedChartResponseSchema by $ref, but it
was never added to openapi_spec_component_schemas, so the generated spec
pointed at a component that did not exist and OpenAPI validation failed. The
dashboard API registers its equivalent the same way. The config schema needs no
entry, since it is inlined rather than referenced.
Master gained migrations while this branch was open, so down_revision pointed
at a revision that is no longer the tip and the chain had two heads.
@amaannawab923
amaannawab923 marked this pull request as ready for review September 3, 2026 08:18
@amaannawab923 amaannawab923 changed the title feat(embedded): embed a single chart as an independent entity feat(embedded): embed a single chart as an independent entity [SIP-145] Sep 3, 2026
Comment on lines +2007 to +2012
class EmbeddedChartResponseSchema(Schema):
uuid = fields.String()
allowed_domains = fields.List(fields.String())
chart_id = fields.String()
changed_on = fields.DateTime()
changed_by = fields.Nested(UserSchema)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: EmbeddedChart stores the identifier as slice_id, not chart_id, so dumping this schema omits the chart identifier from embedded-chart API responses. [api mismatch]

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset/charts/schemas.py
**Line:** 2007:2012
**Comment:**
	*Api Mismatch: `EmbeddedChart` stores the identifier as `slice_id`, not `chart_id`, so dumping this schema omits the chart identifier from embedded-chart API responses.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@bito-code-review

Copy link
Copy Markdown
Contributor

The issue is correct. The EmbeddedChartResponseSchema in superset/charts/schemas.py defines chart_id as a field, but the EmbeddedChart model uses slice_id to store the identifier. To resolve this, you should update the schema to use slice_id instead of chart_id to match the model.

class EmbeddedChartResponseSchema(Schema):
    uuid = fields.String()
    allowed_domains = fields.List(fields.String())
    slice_id = fields.String()
    changed_on = fields.DateTime()
    changed_by = fields.Nested(UserSchema)

I have reviewed the other comments in this PR. Would you like me to fetch all of them, validate their correctness, and implement fixes for the rest as well?

superset/charts/schemas.py

class EmbeddedChartResponseSchema(Schema):
    uuid = fields.String()
    allowed_domains = fields.List(fields.String())
    slice_id = fields.String()
    changed_on = fields.DateTime()
    changed_by = fields.Nested(UserSchema)

Comment thread superset/charts/api.py
body = self.embedded_config_schema.load(request.json)
embedded = EmbeddedChartDAO.upsert(chart, body["allowed_domains"])
db.session.commit() # pylint: disable=consider-using-transaction
result = self.embedded_response_schema.dump(embedded)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The response schema declares chart_id, but EmbeddedChart exposes slice_id; dumping this object omits the chart identifier from every embedded-configuration response. [api mismatch]

Assessment: 🟠 Major · 🔁 Occurrence: Often

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset/charts/api.py
**Line:** 2027:2027
**Comment:**
	*Api Mismatch: The response schema declares `chart_id`, but `EmbeddedChart` exposes `slice_id`; dumping this object omits the chart identifier from every embedded-configuration response.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread superset/daos/chart.py
Comment on lines +182 to +184
embedded: EmbeddedChart = (
chart.embedded[0] if chart.embedded else EmbeddedChart()
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Concurrent requests can both observe an empty chart.embedded collection and create separate rows because slice_id is not unique, making the selected embed UUID and domains nondeterministic. [race condition]

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset/daos/chart.py
**Line:** 182:184
**Comment:**
	*Race Condition: Concurrent requests can both observe an empty `chart.embedded` collection and create separate rows because `slice_id` is not unique, making the selected embed UUID and domains nondeterministic.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

const [showDeactivateConfirm, setShowDeactivateConfirm] = useState(false);

const endpoint = `/api/v1/dashboard/${dashboardId}/embedded`;
const endpoint = `/api/v1/${resourceType}/${dashboardId}/embedded`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Changing resourceType without changing dashboardId does not rerun the configuration fetch, so the modal shows and updates the previous resource's embedding settings. [stale reference]

Assessment: 🟠 Major · 🔁 Occurrence: Rarely

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/dashboard/components/EmbeddedModal/index.tsx
**Line:** 77:77
**Comment:**
	*Stale Reference: Changing `resourceType` without changing `dashboardId` does not rerun the configuration fetch, so the modal shows and updates the previous resource's embedding settings.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

viz_type: slice.form_data.viz_type,
datasource: slice.form_data.datasource,
description: slice.description,
description_markeddown: slice.description_markeddown,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The chart stack reads description_markdown, but this payload stores description_markeddown, so expanded chart descriptions are always missing in embedded charts. [api mismatch]

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/embedded/embeddedChart/hydrateEmbedded.ts
**Line:** 110:110
**Comment:**
	*Api Mismatch: The chart stack reads `description_markdown`, but this payload stores `description_markeddown`, so expanded chart descriptions are always missing in embedded charts.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@bito-code-review

bito-code-review Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #3cd749

Actionable Suggestions - 0
Additional Suggestions - 8
  • superset/models/embedded_chart.py - 1
    • Unused revocation column · Line 43-46
      `guest_token_revoked_before` is added here but never consumed: `_is_guest_token_revoked_by_embedded` in `security/manager.py` skips non-DASHBOARD resources, `EmbeddedChartDAO.upsert` only sets `allow_domain_list`, and there is no chart revoke endpoint. The documented revocation semantics therefore never apply to charts. Wire up the CHART path or remove the column.
  • superset-frontend/src/embedded/index.tsx - 1
    • Lazy-load embedded chart · Line 50-50
      `EmbeddedChart` is statically imported at module scope, pulling the full dashboard `Chart` component tree (31 imports) into the initial embedded bundle. The dashboard path is code-split via `React.lazy` (`LazyDashboardPage`), so every embedded dashboard now pays this cost even when `resource_type` is `dashboard`. Lazy-load it the same way to keep the chart stack out of the initial bundle.
  • superset/security/manager.py - 1
    • Misleading not-found error · Line 5202-5206
      When a CHART resource id doesn't resolve, this raises `EmbeddedDashboardNotFoundError`, whose message reports an 'EmbeddedDashboard' not found. For a chart resource this is misleading to API consumers debugging a 400. Consider a chart-specific or generic not-found error here.
  • superset-frontend/src/types/bootstrapTypes.ts - 1
    • Inconsistent optional type contract · Line 189-189
      The backend (`superset/embedded/view.py`) always emits both fields, setting `dashboard_id` to `null` for chart embeds and `chart_id` to `null` for dashboards. Declaring `dashboard_id: string` as required while `chart_id?: string` is optional is inconsistent and misleads callers into assuming `dashboard_id` is always present. Consider `dashboard_id?: string`.
  • superset/migrations/versions/2026-09-01_10-00_a1c7e4b62f18_add_embedded_charts_table.py - 1
    • Stale migration docstring · Line 20-20
      The docstring says "Revises: 39097d124752" but `down_revision` (line 32) is `8f31c5d726ab`. That migration itself revises `39097d124752`, so the real chain is `39097d124752 -> 8f31c5d726ab -> a1c7e4b62f18`. Align the docstring with the actual revision to avoid misleading migration history.
  • superset/embedded/view.py - 1
    • Misleading log field · Line 111-115
      `dashboard_version="v2"` is now logged unconditionally, including for chart embeds where `resource_type == "chart"`. This dashboard-specific field is semantically misleading in event logs for chart resources. Consider emitting it only for dashboards, or adding a chart-specific version field alongside `resource_type`.
  • superset-frontend/src/embedded/embeddedChart/hydrateEmbedded.test.ts - 1
    • Overstated test coverage · Line 79-79
      The describe title claims 'every HYDRATE_DASHBOARD handler survives', but `cases` only covers `dashboardLayout`, `nativeFilters`, `dashboardState`, and `sliceEntities`. `dashboardInfo` (and `dashboardFilters`, `undoableDashboardLayout`) also handle `HYDRATE_DASHBOARD` and are part of the embedded path, yet aren't exercised here. A future change to `dashboardInfo`'s handler could break the embedded path without this test catching it, despite the title.
  • superset-frontend/src/embedded/embeddedChart/index.tsx - 1
    • Misleading magic value · Line 149-149
      The comment claims "nothing reads this as a lookup," but `props.dashboardId` is still consumed at `Chart.tsx` lines 698/703/765/826. It is benign today only because `chartAction.ts` guards with `if (dashboardId)` (line 693), which skips the falsy `0`. Consider omitting the prop or correcting the comment to avoid future confusion.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset/charts/schemas.py - 1
  • superset/charts/api.py - 1
Review Details
  • Files reviewed - 21 · Commit Range: d9f3ed3..a658e8b
    • superset-frontend/src/dashboard/components/EmbeddedModal/index.tsx
    • superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx
    • superset-frontend/src/embedded/embeddedChart/hydrateEmbedded.test.ts
    • superset-frontend/src/embedded/embeddedChart/hydrateEmbedded.ts
    • superset-frontend/src/embedded/embeddedChart/index.tsx
    • superset-frontend/src/embedded/embeddedChart/useExploreData.ts
    • superset-frontend/src/embedded/index.tsx
    • superset-frontend/src/hooks/useIsMobile.ts
    • superset-frontend/src/types/bootstrapTypes.ts
    • superset/charts/api.py
    • superset/charts/schemas.py
    • superset/commands/deletion_retention/purge_policy.py
    • superset/daos/chart.py
    • superset/embedded/view.py
    • superset/migrations/versions/2026-09-01_10-00_a1c7e4b62f18_add_embedded_charts_table.py
    • superset/models/embedded_chart.py
    • superset/models/slice.py
    • superset/security/guest_token.py
    • superset/security/manager.py
    • tests/integration_tests/charts/api_tests.py
    • tests/unit_tests/security/test_embedded_guest_chart_access.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@github-actions github-actions Bot added the requires:rebase Requires rebasing on top of current master label Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Related to the REST API requires:rebase Requires rebasing on top of current master review:draft risk:db-migration PRs that require a DB migration size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants