ayushanand13 opened a new pull request, #41252:
URL: https://github.com/apache/superset/pull/41252
### SUMMARY
Creating a dashboard via **+ Dashboard** lands the user directly in edit
mode at `/superset/dashboard/<id>/?edit=true`. In that flow the **Undo**
control was enabled before any user action, and clicking it threw:
```
TypeError: Cannot read properties of undefined (reading 'type')
```
…reverting the layout to an empty state and leaving the UI broken until
reload.
**Root cause.** `HYDRATE_DASHBOARD` is a tracked layout action, and
`redux-undo`'s `CLEAR_HISTORY` resets its internal `_latestUnfiltered` pointer
to the *current* `present` (non-null). When the undo history is cleared while
the layout is still the pre-hydration `{}` (as happens during dashboard
navigation), the next hydration captures that empty layout as an undoable
baseline. **Undo** then reverts `dashboardLayout.present` to `{}`, and
rendering code that reads `component.type` dereferences `undefined`.
This builds on #40569, which cleared history *after* hydrate from the page
component. That mitigates the common path but is order-dependent and
bypassable; this PR closes the gap at the reducer level so it holds for the **+
Dashboard** flow and for SPA navigation between dashboards.
**Fix** — harden the `undoableDashboardLayout` reducer:
1. **Reset undo history on every `HYDRATE_DASHBOARD`.** Hydration
establishes the baseline for the dashboard being opened — it is not a user edit
and must never be undoable. Doing this in the reducer (rather than relying on a
follow-up `clearDashboardHistory()` dispatch) guarantees the **Undo** control
starts disabled and that no layout from a previously edited dashboard lingers
after navigation.
2. **Guard undo/redo against invalid layouts.** A valid dashboard layout
always contains the root component (`ROOT_ID`). Undo/redo is never allowed to
replace a valid layout with a rootless one; if it would, the corrupt history is
dropped and the last valid layout is kept — so clicking **Undo** can never
crash the dashboard.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
_See the screen recording in #41246._
- **Before:** on a brand-new dashboard (`?edit=true`), **Undo** is enabled
with no user action and clicking it throws `TypeError: Cannot read properties
of undefined (reading 'type')`.
- **After:** **Undo** is disabled until a real layout change is made, and
undo/redo can never revert to an empty/invalid layout.
### TESTING INSTRUCTIONS
**Automated** (new reducer unit tests):
```bash
cd superset-frontend
npm run test -- src/dashboard/reducers/undoableDashboardLayout.test.ts
```
The tests cover:
- the undo history is empty/disabled right after hydration;
- a stale/empty baseline left by a premature `clearHistory` does **not**
survive hydration;
- re-hydrating a different dashboard drops the previous one from the undo
stack (SPA navigation);
- undo never reverts the layout to an invalid state and drops corrupt
history;
- a genuine layout edit is still undone correctly.
**Manual:**
1. Log in as a user who can create dashboards.
2. Go to **Dashboards** → **+ Dashboard** (opens
`/superset/dashboard/<id>/?edit=true`).
3. Without making any change, confirm the **Undo** button is **disabled**.
4. Add a chart / drag a component, then click **Undo** — it reverts that
change with no error.
5. Navigate to another dashboard in edit mode and confirm **Undo** does not
act on the previous dashboard's layout.
### ADDITIONAL INFORMATION
- [x] Has associated issue: Fixes #41246
- [ ] Required feature flags:
- [x] Changes UI
- [ ] Includes DB Migration (follow approval process in
[SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] 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
--
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]