diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.test.ts b/superset-frontend/src/SqlLab/actions/sqlLab.test.ts index 0de713eae3a..740d0a6e36e 100644 --- a/superset-frontend/src/SqlLab/actions/sqlLab.test.ts +++ b/superset-frontend/src/SqlLab/actions/sqlLab.test.ts @@ -33,6 +33,7 @@ import { } from 'src/SqlLab/fixtures'; 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 { ToastType } from '../../components/MessageToasts/types'; const isFeatureEnabledMock = isFeatureEnabled as unknown as jest.Mock; @@ -882,6 +883,44 @@ describe('async actions', () => { request(store.dispatch, store.getState, undefined); expect(store.getActions()).toEqual(expectedActions); }); + + test('creates a new query editor from the saved state in the empty tab', () => { + const unsavedEmptyTabState = { + id: EMPTY_STATE_QE_ID, + dbId: 2, + catalog: 'test_catalog', + schema: 'test_schema', + }; + const store = mockStore({ + ...initialState, + sqlLab: { + ...initialState.sqlLab, + tabHistory: [EMPTY_STATE_QE_ID], + unsavedQueryEditor: unsavedEmptyTabState, + }, + }); + const expectedActions = [ + { + type: actions.ADD_QUERY_EDITOR, + queryEditor: { + id: 'abcd', + immutableId: 'abcd', + sql: expect.stringContaining('SELECT ...'), + name: 'Untitled Query 4', + dbId: unsavedEmptyTabState.dbId, + catalog: unsavedEmptyTabState.catalog, + schema: unsavedEmptyTabState.schema, + inLocalStorage: true, + autorun: false, + queryLimit: initialState.common.conf.DEFAULT_SQLLAB_LIMIT, + loaded: true, + }, + }, + ]; + const request = actions.addNewQueryEditor(); + request(store.dispatch, store.getState, undefined); + expect(store.getActions()).toEqual(expectedActions); + }); }); }); diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.ts b/superset-frontend/src/SqlLab/actions/sqlLab.ts index 093d1a497eb..dc5441ecfd0 100644 --- a/superset-frontend/src/SqlLab/actions/sqlLab.ts +++ b/superset-frontend/src/SqlLab/actions/sqlLab.ts @@ -47,6 +47,7 @@ import { newQueryTabName } from '../utils/newQueryTabName'; import getInitialState from '../reducers/getInitialState'; import { rehydratePersistedState } from '../utils/reduxStateToLocalStorageHelper'; import { PREVIEW_QUERY_LIMIT } from '../constants'; +import { EMPTY_STATE_QE_ID } from '../hooks/useQueryEditor'; // Type definitions for SqlLab actions export interface Query { @@ -754,7 +755,7 @@ export function addNewQueryEditor(): SqlLabThunkAction { const defaultDbId = common.conf.SQLLAB_DEFAULT_DBID as number | undefined; const activeQueryEditor = queryEditors.find( (qe: QueryEditor) => qe.id === tabHistory[tabHistory.length - 1], - ); + ) ?? { id: EMPTY_STATE_QE_ID }; const dbIds = Object.values(databases).map( (database: { id: number }) => database.id, ); diff --git a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/SqlEditorLeftBar.test.tsx b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/SqlEditorLeftBar.test.tsx index 673171787ae..ea90b1cb3fa 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/SqlEditorLeftBar.test.tsx +++ b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/SqlEditorLeftBar.test.tsx @@ -32,6 +32,8 @@ import { defaultQueryEditor, extraQueryEditor2, } from 'src/SqlLab/fixtures'; +import { EMPTY_STATE_QE_ID } from 'src/SqlLab/hooks/useQueryEditor'; +import * as useDatabaseSelectorModule from '../SqlEditorTopBar/useDatabaseSelector'; import type { RootState } from 'src/views/store'; import type { Store } from 'redux'; @@ -235,3 +237,16 @@ test('ignore schema api when current schema is deprecated', async () => { ]), ); }); + +test('uses EMPTY_STATE_QE_ID when queryEditorId is empty', async () => { + const useDatabaseSelectorSpy = jest.spyOn( + useDatabaseSelectorModule, + 'default', + ); + + await renderAndWait({ queryEditorId: '' }, undefined, initialState); + + expect(useDatabaseSelectorSpy).toHaveBeenCalledWith(EMPTY_STATE_QE_ID); + + useDatabaseSelectorSpy.mockRestore(); +}); diff --git a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx index 9ff47fd6223..e4297629271 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx +++ b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx @@ -32,6 +32,7 @@ import { t } from '@apache-superset/core/translation'; import { styled, css } from '@apache-superset/core/theme'; import type { SchemaOption, CatalogOption } from 'src/hooks/apiResources'; import { DatabaseSelector, type DatabaseObject } from 'src/components'; +import { EMPTY_STATE_QE_ID } from 'src/SqlLab/hooks/useQueryEditor'; import useDatabaseSelector from '../SqlEditorTopBar/useDatabaseSelector'; import TableExploreTree from '../TableExploreTree'; @@ -63,7 +64,8 @@ const StyledDivider = styled.div` `; const SqlEditorLeftBar = ({ queryEditorId }: SqlEditorLeftBarProps) => { - const dbSelectorProps = useDatabaseSelector(queryEditorId); + const activeQEId = queryEditorId || EMPTY_STATE_QE_ID; + const dbSelectorProps = useDatabaseSelector(activeQEId); const { db, catalog, schema, onDbChange, onCatalogChange, onSchemaChange } = dbSelectorProps; @@ -198,7 +200,7 @@ const SqlEditorLeftBar = ({ queryEditorId }: SqlEditorLeftBarProps) => { /> - + {shouldShowReset && (