mirror of
https://github.com/apache/superset.git
synced 2026-04-25 02:55:07 +00:00
feat: add empty states to sqlab editor and select (#19598)
* feat: add empty states to sqlab editor and select * add suggestions and test * update type * lint fix and add suggestions * fix typo * run lint * remove unused code * fix test * remove redux for propagation and other suggestions * add t * lint * fix text and remove code * ts and fix t in p * fix spelling * remove unused prop * add fn to prop change state * remove unused code * remove unused types * update code and test * fix lint * fix ts * update ts * add type export and fix test * Update superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * Update superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * Update superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * Update superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * remove handlerror and unused code Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
154f1ea8c9
commit
06ec88eb99
@@ -38,6 +38,7 @@ import {
|
||||
queryEditorSetSelectedText,
|
||||
queryEditorSetSchemaOptions,
|
||||
} from 'src/SqlLab/actions/sqlLab';
|
||||
import { EmptyStateBig } from 'src/components/EmptyState';
|
||||
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
|
||||
import { initialState, queries, table } from 'src/SqlLab/fixtures';
|
||||
|
||||
@@ -57,7 +58,19 @@ describe('SqlEditor', () => {
|
||||
queryEditorSetSchemaOptions,
|
||||
addDangerToast: jest.fn(),
|
||||
},
|
||||
database: {},
|
||||
database: {
|
||||
allow_ctas: false,
|
||||
allow_cvas: false,
|
||||
allow_dml: false,
|
||||
allow_file_upload: false,
|
||||
allow_multi_schema_metadata_fetch: false,
|
||||
allow_run_async: false,
|
||||
backend: 'postgresql',
|
||||
database_name: 'examples',
|
||||
expose_in_sqllab: true,
|
||||
force_ctas_schema: null,
|
||||
id: 1,
|
||||
},
|
||||
queryEditorId: initialState.sqlLab.queryEditors[0].id,
|
||||
latestQuery: queries[0],
|
||||
tables: [table],
|
||||
@@ -80,6 +93,12 @@ describe('SqlEditor', () => {
|
||||
},
|
||||
);
|
||||
|
||||
it('does not render SqlEditor if no db selected', () => {
|
||||
const database = {};
|
||||
const updatedProps = { ...mockedProps, database };
|
||||
const wrapper = buildWrapper(updatedProps);
|
||||
expect(wrapper.find(EmptyStateBig)).toExist();
|
||||
});
|
||||
it('render a SqlEditorLeftBar', async () => {
|
||||
const wrapper = buildWrapper();
|
||||
await waitForComponentToPaint(wrapper);
|
||||
|
||||
@@ -66,6 +66,8 @@ import {
|
||||
setItem,
|
||||
} from 'src/utils/localStorageHelpers';
|
||||
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
|
||||
import { EmptyStateBig } from 'src/components/EmptyState';
|
||||
import { isEmpty } from 'lodash';
|
||||
import TemplateParamsEditor from '../TemplateParamsEditor';
|
||||
import ConnectedSouthPane from '../SouthPane/state';
|
||||
import SaveQuery from '../SaveQuery';
|
||||
@@ -180,6 +182,7 @@ class SqlEditor extends React.PureComponent {
|
||||
),
|
||||
showCreateAsModal: false,
|
||||
createAs: '',
|
||||
showEmptyState: false,
|
||||
};
|
||||
this.sqlEditorRef = React.createRef();
|
||||
this.northPaneRef = React.createRef();
|
||||
@@ -189,6 +192,7 @@ class SqlEditor extends React.PureComponent {
|
||||
this.onResizeEnd = this.onResizeEnd.bind(this);
|
||||
this.canValidateQuery = this.canValidateQuery.bind(this);
|
||||
this.runQuery = this.runQuery.bind(this);
|
||||
this.setEmptyState = this.setEmptyState.bind(this);
|
||||
this.stopQuery = this.stopQuery.bind(this);
|
||||
this.saveQuery = this.saveQuery.bind(this);
|
||||
this.onSqlChanged = this.onSqlChanged.bind(this);
|
||||
@@ -228,7 +232,11 @@ class SqlEditor extends React.PureComponent {
|
||||
// We need to measure the height of the sql editor post render to figure the height of
|
||||
// the south pane so it gets rendered properly
|
||||
// eslint-disable-next-line react/no-did-mount-set-state
|
||||
const db = this.props.database;
|
||||
this.setState({ height: this.getSqlEditorHeight() });
|
||||
if (!db || isEmpty(db)) {
|
||||
this.setEmptyState(true);
|
||||
}
|
||||
|
||||
window.addEventListener('resize', this.handleWindowResize);
|
||||
window.addEventListener('beforeunload', this.onBeforeUnload);
|
||||
@@ -369,6 +377,10 @@ class SqlEditor extends React.PureComponent {
|
||||
return base;
|
||||
}
|
||||
|
||||
setEmptyState(bool) {
|
||||
this.setState({ showEmptyState: bool });
|
||||
}
|
||||
|
||||
setQueryEditorSql(sql) {
|
||||
this.props.queryEditorSetSql(this.props.queryEditor, sql);
|
||||
}
|
||||
@@ -760,10 +772,21 @@ class SqlEditor extends React.PureComponent {
|
||||
queryEditor={this.props.queryEditor}
|
||||
tables={this.props.tables}
|
||||
actions={this.props.actions}
|
||||
setEmptyState={this.setEmptyState}
|
||||
/>
|
||||
</div>
|
||||
</CSSTransition>
|
||||
{this.queryPane()}
|
||||
{this.state.showEmptyState ? (
|
||||
<EmptyStateBig
|
||||
image="vector.svg"
|
||||
title={t('Select a database to write a query')}
|
||||
description={t(
|
||||
'Choose one of the available databases from the panel on the left.',
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
this.queryPane()
|
||||
)}
|
||||
<StyledModal
|
||||
visible={this.state.showCreateAsModal}
|
||||
title={t(createViewModalTitle)}
|
||||
|
||||
@@ -16,7 +16,15 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import React, { useEffect, useRef, useCallback, useMemo } from 'react';
|
||||
import React, {
|
||||
useEffect,
|
||||
useRef,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useState,
|
||||
Dispatch,
|
||||
SetStateAction,
|
||||
} from 'react';
|
||||
import Button from 'src/components/Button';
|
||||
import { t, styled, css, SupersetTheme } from '@superset-ui/core';
|
||||
import Collapse from 'src/components/Collapse';
|
||||
@@ -25,6 +33,7 @@ import { TableSelectorMultiple } from 'src/components/TableSelector';
|
||||
import { IconTooltip } from 'src/components/IconTooltip';
|
||||
import { QueryEditor } from 'src/SqlLab/types';
|
||||
import { DatabaseObject } from 'src/components/DatabaseSelector';
|
||||
import { EmptyStateSmall } from 'src/components/EmptyState';
|
||||
import TableElement, { Table, TableElementProps } from '../TableElement';
|
||||
|
||||
interface ExtendedTable extends Table {
|
||||
@@ -54,6 +63,8 @@ interface SqlEditorLeftBarProps {
|
||||
tables?: ExtendedTable[];
|
||||
actions: actionsTypes & TableElementProps['actions'];
|
||||
database: DatabaseObject;
|
||||
setEmptyState: Dispatch<SetStateAction<boolean>>;
|
||||
showDisabled: boolean;
|
||||
}
|
||||
|
||||
const StyledScrollbarContainer = styled.div`
|
||||
@@ -88,15 +99,23 @@ export default function SqlEditorLeftBar({
|
||||
queryEditor,
|
||||
tables = [],
|
||||
height = 500,
|
||||
setEmptyState,
|
||||
}: SqlEditorLeftBarProps) {
|
||||
// Ref needed to avoid infinite rerenders on handlers
|
||||
// that require and modify the queryEditor
|
||||
const queryEditorRef = useRef<QueryEditor>(queryEditor);
|
||||
const [emptyResultsWithSearch, setEmptyResultsWithSearch] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
queryEditorRef.current = queryEditor;
|
||||
}, [queryEditor]);
|
||||
|
||||
const onEmptyResults = (searchText?: string) => {
|
||||
setEmptyResultsWithSearch(!!searchText);
|
||||
};
|
||||
|
||||
const onDbChange = ({ id: dbId }: { id: number }) => {
|
||||
setEmptyState(false);
|
||||
actions.queryEditorSetDb(queryEditor, dbId);
|
||||
actions.queryEditorSetFunctionNames(queryEditor, dbId);
|
||||
};
|
||||
@@ -164,6 +183,22 @@ export default function SqlEditorLeftBar({
|
||||
const shouldShowReset = window.location.search === '?reset=1';
|
||||
const tableMetaDataHeight = height - 130; // 130 is the height of the selects above
|
||||
|
||||
const emptyStateComponent = (
|
||||
<EmptyStateSmall
|
||||
image="empty.svg"
|
||||
title={
|
||||
emptyResultsWithSearch
|
||||
? t('No databases match your search')
|
||||
: t('There are no databases available')
|
||||
}
|
||||
description={
|
||||
<p>
|
||||
{t('Manage your databases')}{' '}
|
||||
<a href="/databaseview/list">{t('here')}</a>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
);
|
||||
const handleSchemaChange = useCallback(
|
||||
(schema: string) => {
|
||||
if (queryEditorRef.current) {
|
||||
@@ -185,6 +220,8 @@ export default function SqlEditorLeftBar({
|
||||
return (
|
||||
<div className="SqlEditorLeftBar">
|
||||
<TableSelectorMultiple
|
||||
onEmptyResults={onEmptyResults}
|
||||
emptyState={emptyStateComponent}
|
||||
database={database}
|
||||
getDbList={actions.setDatabases}
|
||||
handleError={actions.addDangerToast}
|
||||
|
||||
Reference in New Issue
Block a user