From 587b2be7711ddd34dda8c987b9be6f7d75764239 Mon Sep 17 00:00:00 2001 From: justin-park Date: Wed, 19 Oct 2022 11:35:38 -0700 Subject: [PATCH] fix(sqllab): wiped out unsaved changes by delayed actions --- .../src/SqlLab/reducers/sqlLab.js | 49 ++++++++++++------- .../src/SqlLab/reducers/sqlLab.test.js | 26 ++++++++-- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.js b/superset-frontend/src/SqlLab/reducers/sqlLab.js index 1414235965b61..ed103a2afe1bc 100644 --- a/superset-frontend/src/SqlLab/reducers/sqlLab.js +++ b/superset-frontend/src/SqlLab/reducers/sqlLab.js @@ -32,9 +32,22 @@ import { } from '../../reduxUtils'; function alterUnsavedQueryEditorState(state, updatedState, id) { + if (state.tabHistory[state.tabHistory.length - 1] !== id) { + const { queryEditors } = alterInArr( + state, + 'queryEditors', + { id }, + updatedState, + ); + return { + queryEditors, + }; + } return { - ...(state.unsavedQueryEditor.id === id && state.unsavedQueryEditor), - ...(id ? { id, ...updatedState } : state.unsavedQueryEditor), + unsavedQueryEditor: { + ...(state.unsavedQueryEditor.id === id && state.unsavedQueryEditor), + ...(id ? { id, ...updatedState } : state.unsavedQueryEditor), + }, }; } @@ -227,7 +240,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.START_QUERY_VALIDATION]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { validationResult: { @@ -259,7 +272,7 @@ export default function sqlLabReducer(state = {}, action) { // Otherwise, persist the results on the queryEditor state return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { validationResult: { @@ -367,7 +380,7 @@ export default function sqlLabReducer(state = {}, action) { return { ...newState, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { latestQueryId: action.query.id, @@ -538,7 +551,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SETDB]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { dbId: action.dbId, @@ -550,7 +563,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_FUNCTION_NAMES]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { functionNames: action.functionNames, @@ -562,7 +575,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_SCHEMA]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { schema: action.schema, @@ -574,7 +587,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_SCHEMA_OPTIONS]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { schemaOptions: action.options, @@ -586,7 +599,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_TABLE_OPTIONS]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { tableOptions: action.options, @@ -598,7 +611,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_TITLE]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { name: action.name, @@ -610,7 +623,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_SQL]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { sql: action.sql, @@ -622,7 +635,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_QUERY_LIMIT]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { queryLimit: action.queryLimit, @@ -634,7 +647,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_TEMPLATE_PARAMS]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { templateParams: action.templateParams, @@ -646,7 +659,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_SELECTED_TEXT]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { selectedText: action.sql, @@ -658,7 +671,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_SET_AUTORUN]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { autorun: action.autorun, @@ -670,7 +683,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_PERSIST_HEIGHT]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { northPercent: action.northPercent, @@ -683,7 +696,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.QUERY_EDITOR_TOGGLE_LEFT_BAR]() { return { ...state, - unsavedQueryEditor: alterUnsavedQueryEditorState( + ...alterUnsavedQueryEditorState( state, { hideLeftBar: action.hideLeftBar, diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.test.js b/superset-frontend/src/SqlLab/reducers/sqlLab.test.js index 088d01031a598..dd4c0be4b4ce7 100644 --- a/superset-frontend/src/SqlLab/reducers/sqlLab.test.js +++ b/superset-frontend/src/SqlLab/reducers/sqlLab.test.js @@ -191,13 +191,33 @@ describe('sqlLabReducer', () => { const selectedText = 'TEST'; const action = { type: actions.QUERY_EDITOR_SET_SELECTED_TEXT, - queryEditor: newState.queryEditors[0], + queryEditor: qe, sql: selectedText, }; - expect(newState.queryEditors[0].selectedText).toBeFalsy(); + expect(qe.selectedText).toBeFalsy(); newState = sqlLabReducer(newState, action); expect(newState.unsavedQueryEditor.selectedText).toBe(selectedText); - expect(newState.unsavedQueryEditor.id).toBe(newState.queryEditors[0].id); + expect(newState.unsavedQueryEditor.id).toBe(qe.id); + }); + it('should not wiped out unsaved changes while delayed async call intercepted', () => { + const expectedSql = 'Updated SQL WORKING IN PROGRESS--'; + const action = { + type: actions.QUERY_EDITOR_SET_SQL, + queryEditor: qe, + sql: expectedSql, + }; + newState = sqlLabReducer(newState, action); + expect(newState.unsavedQueryEditor.sql).toBe(expectedSql); + const interceptedAction = { + type: actions.QUERY_EDITOR_SET_FUNCTION_NAMES, + queryEditor: newState.queryEditors[0], + functionNames: ['func1', 'func2'], + }; + newState = sqlLabReducer(newState, interceptedAction); + expect(newState.unsavedQueryEditor.sql).toBe(expectedSql); + expect(newState.queryEditors[0].functionNames).toBe( + interceptedAction.functionNames, + ); }); }); describe('Tables', () => {