fix(dashboard): redirect using sanitized slug from save response - #42853
fix(dashboard): redirect using sanitized slug from save response#42853sadpandajoe wants to merge 1 commit into
Conversation
When a dashboard's URL slug in Edit Properties starts with a reserved URL character (e.g. `?` or `/`), saving succeeded but the post-save redirect navigated to a malformed/blank URL on first render; a later reload worked because it used the stored, sanitized slug. The post-save redirect in `saveDashboardRequest`'s `onUpdateSuccess` handler built the target from the raw locally-submitted slug. The backend sanitizes reserved characters out of the slug (`BaseDashboardSchema.post_load` strips `[^\w\-]`), so the persisted slug returned in the PUT response can differ from what was submitted. Build the redirect from the response slug, falling back to the dashboard id when the response has no slug. Adds regression tests covering the sanitized-slug redirect and the empty-slug id fallback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
✅ Deploy Preview for superset-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
Fixes a dashboard post-save redirect bug where the frontend previously built the redirect URL from the raw, locally-submitted slug (which can include reserved URL characters), instead of the backend-sanitized slug returned by the update API response. This ensures the first render after saving lands on the correct dashboard URL.
Changes:
- Update
saveDashboardRequest’s update-success redirect to useupdatedDashboard.slugfrom the PUT response (fallback toid). - Add frontend Jest regressions covering “sanitized slug differs from submitted slug” and “no usable slug in response” redirect behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| superset-frontend/src/dashboard/actions/dashboardState.ts | Redirect after dashboard property save uses sanitized slug from PUT response instead of raw submitted slug. |
| superset-frontend/src/dashboard/actions/dashboardState.test.ts | Adds regression tests validating redirect uses response slug and falls back to id when slug is not usable. |
| putStub = jest.spyOn(SupersetClient, 'put').mockResolvedValue({ | ||
| json: { | ||
| result: { ...mockDashboardData, id: updatedId, slug: null }, | ||
| last_modified_time: 0, | ||
| }, |
|
The test case This change will ensure the test exercises the logic where superset-frontend/src/dashboard/actions/dashboardState.test.ts |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #42853 +/- ##
==========================================
- Coverage 65.73% 65.73% -0.01%
==========================================
Files 2843 2843
Lines 162659 162660 +1
Branches 37239 37239
==========================================
Hits 106921 106921
- Misses 53645 53646 +1
Partials 2093 2093
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Code Review Agent Run #c358f3Actionable Suggestions - 0Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
SUMMARY
Fixes a dashboard post-save redirect bug (Shortcut sc-107323): when the URL Slug in Edit dashboard properties starts with a reserved URL character (
?or/), saving succeeds but the post-save redirect lands on a malformed/blank URL on the first render. A manual page reload afterwards works, because the reload uses the stored, backend-sanitized slug.Root cause. In
superset-frontend/src/dashboard/actions/dashboardState.ts, theonUpdateSuccesshandler insaveDashboardRequestbuilt the redirect from the raw, locally-submitted slug:The backend sanitizes reserved characters out of the slug before persisting it —
BaseDashboardSchema.post_loadinsuperset/dashboards/schemas.pyrunsre.sub(r"[^\w\-]+", "", ...)— so the persisted slug returned in thePUT /api/v1/dashboard/{id}response can differ from what was submitted. Building the redirect from the raw value produces e.g./dashboard/?test/, which the router resolves to a slug-less/dashboard/and renders blank on first paint.Fix. Build the redirect from the slug in the update response (
updatedDashboard.slug), falling back toidwhen the response carries no slug:The Copy / Save as path (
onCopySuccess) already redirects on the responseidonly and is unaffected. The change is one decision point plus regression tests.BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Captured in a real dev environment at a fixed 1280×800 viewport. Scenario (identical for both): log in → open the USA Births Names dashboard → Edit dashboard → ⋯ → Edit properties → set URL Slug to
?test→ Apply → Save → observe the address bar on first render (no manual reload). Alocation.hrefbanner is injected into each still because Playwright screenshots don't include browser chrome.Before (master) — post-save URL is
/dashboard/with the slug lost; the dashboard renders blank:After (this PR) — post-save URL is the sanitized
/dashboard/test/; the dashboard renders correctly:Full screen recordings (VP8 WebM): before-master.webm · after-fix.webm. Capture script: capture.mjs.
TESTING INSTRUCTIONS
Manual:
?test, and Save.masterthe first render is blank (URL missing the dashboard); with this change the redirect goes to/dashboard/test/(the sanitized slug) and the dashboard renders. A slug of only reserved characters (e.g.?) sanitizes to empty and correctly falls back to/dashboard/<id>/.Automated (
superset-frontend):Two regression tests were added: (a) submitted slug
?test+ PUT-response slugtest⇒ redirect/dashboard/test/; (b) PUT-response slug empty/null ⇒ redirect falls back to/dashboard/<id>/. Both fail onmasterand pass with this change.ADDITIONAL INFORMATION