You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ms...@apache.org on 2025/12/05 15:33:33 UTC
(superset) branch master updated: feat(state): remove chart state when navigation away from the dashboard (#36421)
This is an automated email from the ASF dual-hosted git repository.
msyavuz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 8c603a6f8b feat(state): remove chart state when navigation away from the dashboard (#36421)
8c603a6f8b is described below
commit 8c603a6f8bd2c66e9c681da44633b2cb844fca79
Author: Alexandru Soare <37...@users.noreply.github.com>
AuthorDate: Fri Dec 5 17:33:26 2025 +0200
feat(state): remove chart state when navigation away from the dashboard (#36421)
---
.../src/dashboard/actions/dashboardState.js | 5 ++
.../src/dashboard/components/Dashboard.jsx | 1 +
.../src/dashboard/components/Dashboard.test.jsx | 2 +
.../src/dashboard/containers/Dashboard.ts | 2 +
.../src/dashboard/reducers/dashboardState.js | 7 ++
.../src/dashboard/reducers/dashboardState.test.js | 78 ++++++++++++++++++++++
6 files changed, 95 insertions(+)
diff --git a/superset-frontend/src/dashboard/actions/dashboardState.js b/superset-frontend/src/dashboard/actions/dashboardState.js
index 45f9c2af46..18b567e20f 100644
--- a/superset-frontend/src/dashboard/actions/dashboardState.js
+++ b/superset-frontend/src/dashboard/actions/dashboardState.js
@@ -769,6 +769,11 @@ export function restoreChartStates(chartStates) {
return { type: RESTORE_CHART_STATES, chartStates };
}
+export const CLEAR_ALL_CHART_STATES = 'CLEAR_ALL_CHART_STATES';
+export function clearAllChartStates() {
+ return { type: CLEAR_ALL_CHART_STATES };
+}
+
// Undo history ---------------------------------------------------------------
export const SET_MAX_UNDO_HISTORY_EXCEEDED = 'SET_MAX_UNDO_HISTORY_EXCEEDED';
export function setMaxUndoHistoryExceeded(maxUndoHistoryExceeded = true) {
diff --git a/superset-frontend/src/dashboard/components/Dashboard.jsx b/superset-frontend/src/dashboard/components/Dashboard.jsx
index 7d909b5154..4b47b34081 100644
--- a/superset-frontend/src/dashboard/components/Dashboard.jsx
+++ b/superset-frontend/src/dashboard/components/Dashboard.jsx
@@ -188,6 +188,7 @@ class Dashboard extends PureComponent {
componentWillUnmount() {
window.removeEventListener('visibilitychange', this.onVisibilityChange);
this.props.actions.clearDataMaskState();
+ this.props.actions.clearAllChartStates();
}
onVisibilityChange() {
diff --git a/superset-frontend/src/dashboard/components/Dashboard.test.jsx b/superset-frontend/src/dashboard/components/Dashboard.test.jsx
index 008b9fdd47..dd00834ba2 100644
--- a/superset-frontend/src/dashboard/components/Dashboard.test.jsx
+++ b/superset-frontend/src/dashboard/components/Dashboard.test.jsx
@@ -46,6 +46,7 @@ describe('Dashboard', () => {
const mockTriggerQuery = jest.fn();
const mockLogEvent = jest.fn();
const mockClearDataMask = jest.fn();
+ const mockClearAllChartStates = jest.fn();
const props = {
actions: {
@@ -54,6 +55,7 @@ describe('Dashboard', () => {
triggerQuery: mockTriggerQuery,
logEvent: mockLogEvent,
clearDataMaskState: mockClearDataMask,
+ clearAllChartStates: mockClearAllChartStates,
},
dashboardState,
dashboardInfo,
diff --git a/superset-frontend/src/dashboard/containers/Dashboard.ts b/superset-frontend/src/dashboard/containers/Dashboard.ts
index a59767c004..f649a471a1 100644
--- a/superset-frontend/src/dashboard/containers/Dashboard.ts
+++ b/superset-frontend/src/dashboard/containers/Dashboard.ts
@@ -23,6 +23,7 @@ import Dashboard from 'src/dashboard/components/Dashboard';
import {
addSliceToDashboard,
removeSliceFromDashboard,
+ clearAllChartStates,
} from 'src/dashboard/actions/dashboardState';
import { setDatasources } from 'src/dashboard/actions/datasources';
@@ -61,6 +62,7 @@ function mapDispatchToProps(dispatch: Dispatch) {
{
setDatasources,
clearDataMaskState,
+ clearAllChartStates,
addSliceToDashboard,
removeSliceFromDashboard,
triggerQuery,
diff --git a/superset-frontend/src/dashboard/reducers/dashboardState.js b/superset-frontend/src/dashboard/reducers/dashboardState.js
index e24f875022..70b5b6ab19 100644
--- a/superset-frontend/src/dashboard/reducers/dashboardState.js
+++ b/superset-frontend/src/dashboard/reducers/dashboardState.js
@@ -53,6 +53,7 @@ import {
UPDATE_CHART_STATE,
REMOVE_CHART_STATE,
RESTORE_CHART_STATES,
+ CLEAR_ALL_CHART_STATES,
} from '../actions/dashboardState';
import { HYDRATE_DASHBOARD } from '../actions/hydrate';
@@ -326,6 +327,12 @@ export default function dashboardStateReducer(state = {}, action) {
chartStates: chartStates || {},
};
},
+ [CLEAR_ALL_CHART_STATES]() {
+ return {
+ ...state,
+ chartStates: {},
+ };
+ },
};
if (action.type in actionHandlers) {
diff --git a/superset-frontend/src/dashboard/reducers/dashboardState.test.js b/superset-frontend/src/dashboard/reducers/dashboardState.test.js
index 56e647c3be..83fe01c8b6 100644
--- a/superset-frontend/src/dashboard/reducers/dashboardState.test.js
+++ b/superset-frontend/src/dashboard/reducers/dashboardState.test.js
@@ -29,6 +29,10 @@ import {
TOGGLE_FAVE_STAR,
TOGGLE_NATIVE_FILTERS_BAR,
UNSET_FOCUSED_FILTER_FIELD,
+ UPDATE_CHART_STATE,
+ REMOVE_CHART_STATE,
+ RESTORE_CHART_STATES,
+ CLEAR_ALL_CHART_STATES,
} from 'src/dashboard/actions/dashboardState';
import dashboardStateReducer from 'src/dashboard/reducers/dashboardState';
@@ -215,4 +219,78 @@ describe('dashboardState reducer', () => {
),
).toEqual({ nativeFiltersBarOpen: false });
});
+
+ test('should update chart state', () => {
+ const chartState = { columnState: [], filterModel: {} };
+ const result = dashboardStateReducer(
+ { chartStates: {} },
+ {
+ type: UPDATE_CHART_STATE,
+ chartId: 123,
+ vizType: 'ag-grid-table',
+ chartState,
+ lastModified: 1234567890,
+ },
+ );
+ expect(result.chartStates[123]).toEqual({
+ chartId: 123,
+ vizType: 'ag-grid-table',
+ state: chartState,
+ lastModified: 1234567890,
+ });
+ });
+
+ test('should remove chart state', () => {
+ const initState = {
+ chartStates: {
+ 123: { chartId: 123, vizType: 'ag-grid-table', state: {} },
+ 456: { chartId: 456, vizType: 'ag-grid-table', state: {} },
+ },
+ };
+ const result = dashboardStateReducer(initState, {
+ type: REMOVE_CHART_STATE,
+ chartId: 123,
+ });
+ expect(result.chartStates[123]).toBeUndefined();
+ expect(result.chartStates[456]).toBeDefined();
+ });
+
+ test('should restore chart states', () => {
+ const chartStates = {
+ 123: { chartId: 123, vizType: 'ag-grid-table', state: {} },
+ };
+ const result = dashboardStateReducer(
+ { chartStates: {} },
+ { type: RESTORE_CHART_STATES, chartStates },
+ );
+ expect(result.chartStates).toEqual(chartStates);
+ });
+
+ test('should restore chart states to empty when given null', () => {
+ const initState = {
+ chartStates: {
+ 123: { chartId: 123, vizType: 'ag-grid-table', state: {} },
+ },
+ };
+ const result = dashboardStateReducer(initState, {
+ type: RESTORE_CHART_STATES,
+ chartStates: null,
+ });
+ expect(result.chartStates).toEqual({});
+ });
+
+ test('should clear all chart states', () => {
+ const initState = {
+ chartStates: {
+ 123: { chartId: 123, vizType: 'ag-grid-table', state: {} },
+ 456: { chartId: 456, vizType: 'ag-grid-table', state: {} },
+ },
+ otherState: 'preserved',
+ };
+ const result = dashboardStateReducer(initState, {
+ type: CLEAR_ALL_CHART_STATES,
+ });
+ expect(result.chartStates).toEqual({});
+ expect(result.otherState).toEqual('preserved');
+ });
});