diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/TabbedSqlEditors.test.jsx b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/TabbedSqlEditors.test.jsx index 7acef14cf06c..552afe37f8fe 100644 --- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/TabbedSqlEditors.test.jsx +++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/TabbedSqlEditors.test.jsx @@ -79,6 +79,7 @@ describe('TabbedSqlEditors', () => { defaultQueryLimit: 1000, maxRow: 100000, }; + const getWrapper = () => shallow() .dive() @@ -227,4 +228,10 @@ describe('TabbedSqlEditors', () => { wrapper.setProps({ offline: true }); expect(wrapper.find(EditableTabs).props().hideAdd).toBe(true); }); + it('should have an empty state when query editors is empty', () => { + wrapper = getWrapper(); + wrapper.setProps({ queryEditors: [] }); + const firstTab = wrapper.find(EditableTabs.TabPane).first(); + expect(firstTab.props()['data-key']).toBe(0); + }); }); diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx index cf2867eb8962..4e486c1c69f4 100644 --- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx +++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx @@ -30,6 +30,7 @@ import { areArraysShallowEqual } from 'src/reduxUtils'; import { Tooltip } from 'src/components/Tooltip'; import { detectOS } from 'src/utils/common'; import * as Actions from 'src/SqlLab/actions/sqlLab'; +import { EmptyStateBig } from 'src/components/EmptyState'; import SqlEditor from '../SqlEditor'; import TabStatusIcon from '../TabStatusIcon'; @@ -64,6 +65,10 @@ const TabTitleWrapper = styled.div` align-items: center; `; +const StyledTab = styled.span` + line-height: 24px; +`; + const TabTitle = styled.span` margin-right: ${({ theme }) => theme.gridUnit * 2}px; text-transform: none; @@ -314,6 +319,7 @@ class TabbedSqlEditors extends React.PureComponent { } render() { + const noQueryEditors = this.props.queryEditors?.length === 0; const editors = this.props.queryEditors.map(qe => { let latestQuery; if (qe.latestQueryId) { @@ -401,6 +407,37 @@ class TabbedSqlEditors extends React.PureComponent { ); }); + const emptyTab = ( + + {t('Add a new tab')} + + + + + ); + + const emptyTabState = ( + + + + ); + return ( noQueryEditors && this.newQueryEditor()} onEdit={this.handleEdit} + type={noQueryEditors ? 'card' : 'editable-card'} addIcon={ {editors} + {noQueryEditors && emptyTabState} ); } diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.js b/superset-frontend/src/SqlLab/reducers/sqlLab.js index 68de3ebd66d8..d5abf3b540b7 100644 --- a/superset-frontend/src/SqlLab/reducers/sqlLab.js +++ b/superset-frontend/src/SqlLab/reducers/sqlLab.js @@ -358,7 +358,7 @@ export default function sqlLabReducer(state = {}, action) { [actions.SET_ACTIVE_QUERY_EDITOR]() { const qeIds = state.queryEditors.map(qe => qe.id); if ( - qeIds.indexOf(action.queryEditor.id) > -1 && + qeIds.indexOf(action.queryEditor?.id) > -1 && state.tabHistory[state.tabHistory.length - 1] !== action.queryEditor.id ) { const tabHistory = state.tabHistory.slice(); diff --git a/superset-frontend/src/assets/images/empty_sql_chart.svg b/superset-frontend/src/assets/images/empty_sql_chart.svg new file mode 100644 index 000000000000..6ab969575c9d --- /dev/null +++ b/superset-frontend/src/assets/images/empty_sql_chart.svg @@ -0,0 +1,22 @@ + + + + +