diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.test.ts b/superset-frontend/src/SqlLab/actions/sqlLab.test.ts index ace267844692..234b5ec587d7 100644 --- a/superset-frontend/src/SqlLab/actions/sqlLab.test.ts +++ b/superset-frontend/src/SqlLab/actions/sqlLab.test.ts @@ -34,6 +34,7 @@ import { import { SupersetClient, isFeatureEnabled } from '@superset-ui/core'; import { ADD_TOAST } from 'src/components/MessageToasts/actions'; import { EMPTY_STATE_QE_ID } from 'src/SqlLab/hooks/useQueryEditor'; +import { api } from 'src/hooks/apiResources/queryApi'; import { ToastType } from '../../components/MessageToasts/types'; const isFeatureEnabledMock = isFeatureEnabled as unknown as jest.Mock; @@ -1107,6 +1108,44 @@ describe('async actions', () => { }); }); + // eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks + describe('removeQuery', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + test('removes the deleted query from the editor queries cache', async () => { + const queryToRemove = { + ...query, + id: 'queryToRemove', + sqlEditorId: 'editor1', + }; + const updateCache = jest.spyOn(api.util, 'updateQueryData'); + + await actions.removeQuery(queryToRemove)( + jest.fn(), + () => typedInitialState, + undefined, + ); + + expect(updateCache).toHaveBeenCalledWith( + 'editorQueries', + { editorId: queryToRemove.sqlEditorId }, + expect.any(Function), + ); + const recipe = updateCache.mock.calls[0][2] as (draft: { + count: number; + result: { id: string }[]; + }) => void; + const draft = { + count: 2, + result: [{ id: 'queryToRemove' }, { id: 'keep' }], + }; + recipe(draft); + expect(draft).toEqual({ count: 1, result: [{ id: 'keep' }] }); + }); + }); + // eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks describe('queryEditorSetDb', () => { test('updates the tab state in the backend', () => { diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.ts b/superset-frontend/src/SqlLab/actions/sqlLab.ts index 7058471a55b1..6b763d1ff10d 100644 --- a/superset-frontend/src/SqlLab/actions/sqlLab.ts +++ b/superset-frontend/src/SqlLab/actions/sqlLab.ts @@ -48,6 +48,8 @@ import getInitialState from '../reducers/getInitialState'; import { rehydratePersistedState } from '../utils/reduxStateToLocalStorageHelper'; import { PREVIEW_QUERY_LIMIT } from '../constants'; import { EMPTY_STATE_QE_ID } from '../hooks/useQueryEditor'; +import { queryHistoryApi } from '../../hooks/apiResources/queries'; +import type { AppDispatch as RootDispatch } from '../../views/store'; // Type definitions for SqlLab actions export interface Query { @@ -985,7 +987,7 @@ export function removeAllOtherQueryEditors( } export function removeQuery(query: Query): SqlLabThunkAction> { - return function (dispatch: AppDispatch) { + return function (dispatch: RootDispatch) { const queryEditorId = query.sqlEditorId ?? query.id; const sync = isFeatureEnabled(FeatureFlag.SqllabBackendPersistence) ? SupersetClient.delete({ @@ -996,7 +998,22 @@ export function removeQuery(query: Query): SqlLabThunkAction> { : Promise.resolve(); return sync - .then(() => dispatch({ type: REMOVE_QUERY, query })) + .then(() => { + dispatch({ type: REMOVE_QUERY, query }); + dispatch( + queryHistoryApi.util.updateQueryData( + 'editorQueries', + { editorId: queryEditorId }, + draft => { + const index = draft.result.findIndex(({ id }) => id === query.id); + if (index !== -1) { + draft.result.splice(index, 1); + draft.count = Math.max(0, draft.count - 1); + } + }, + ), + ); + }) .catch(() => dispatch( addDangerToast( diff --git a/superset-frontend/src/hooks/apiResources/queries.ts b/superset-frontend/src/hooks/apiResources/queries.ts index 2fc9a4391560..282edfeca65c 100644 --- a/superset-frontend/src/hooks/apiResources/queries.ts +++ b/superset-frontend/src/hooks/apiResources/queries.ts @@ -107,7 +107,7 @@ export const mapQueryResponse = ( user: query.user, }); -const queryHistoryApi = api.injectEndpoints({ +export const queryHistoryApi = api.injectEndpoints({ endpoints: builder => ({ editorQueries: builder.query({ providesTags: ['EditorQueries'],