This is an automated email from the ASF dual-hosted git repository.
justinpark pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new db3fa8df77 fix(sqllab): Show warning message when deprecated db is
selected (#29607)
db3fa8df77 is described below
commit db3fa8df771a7d2b6e56ca2f37282ca9ea64aab6
Author: JUST.in DO IT <[email protected]>
AuthorDate: Wed Jul 17 10:37:58 2024 -0700
fix(sqllab): Show warning message when deprecated db is selected (#29607)
---
.../SqlLab/components/SqlEditor/SqlEditor.test.tsx | 12 +-
.../src/SqlLab/components/SqlEditor/index.tsx | 185 ++++++++++++---------
superset-frontend/src/SqlLab/fixtures.ts | 2 +-
3 files changed, 116 insertions(+), 83 deletions(-)
diff --git
a/superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
b/superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
index 9697d14a95..d24c7e9d8b 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
@@ -160,13 +160,23 @@ describe('SqlEditor', () => {
});
it('does not render SqlEditor if no db selected', async () => {
- const queryEditor = initialState.sqlLab.queryEditors[1];
+ const queryEditor = initialState.sqlLab.queryEditors[2];
const { findByText } = setup({ ...mockedProps, queryEditor }, store);
expect(
await findByText('Select a database to write a query'),
).toBeInTheDocument();
});
+ it('renders db unavailable message', async () => {
+ const queryEditor = initialState.sqlLab.queryEditors[1];
+ const { findByText } = setup({ ...mockedProps, queryEditor }, store);
+ expect(
+ await findByText(
+ 'The database that was used to generate this query could not be found',
+ ),
+ ).toBeInTheDocument();
+ });
+
it('render a SqlEditorLeftBar', async () => {
const { getByTestId } = setup(mockedProps, store);
await waitFor(() =>
diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
index dd22442def..c17ac9324b 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
@@ -99,6 +99,7 @@ import {
setItem,
} from 'src/utils/localStorageHelpers';
import { EmptyStateBig } from 'src/components/EmptyState';
+import Alert from 'src/components/Alert';
import getBootstrapData from 'src/utils/getBootstrapData';
import useLogAction from 'src/logger/useLogAction';
import {
@@ -258,31 +259,38 @@ const SqlEditor: FC<Props> = ({
const theme = useTheme();
const dispatch = useDispatch();
- const { database, latestQuery, hideLeftBar, currentQueryEditorId } =
- useSelector<
- SqlLabRootState,
- {
- database?: DatabaseObject;
- latestQuery?: QueryResponse;
- hideLeftBar?: boolean;
- currentQueryEditorId: QueryEditor['id'];
- }
- >(({ sqlLab: { unsavedQueryEditor, databases, queries, tabHistory } }) => {
- let { dbId, latestQueryId, hideLeftBar } = queryEditor;
- if (unsavedQueryEditor?.id === queryEditor.id) {
- dbId = unsavedQueryEditor.dbId || dbId;
- latestQueryId = unsavedQueryEditor.latestQueryId || latestQueryId;
- hideLeftBar = isBoolean(unsavedQueryEditor.hideLeftBar)
- ? unsavedQueryEditor.hideLeftBar
- : hideLeftBar;
- }
- return {
- database: databases[dbId || ''],
- latestQuery: queries[latestQueryId || ''],
- hideLeftBar,
- currentQueryEditorId: tabHistory.slice(-1)[0],
- };
- }, shallowEqual);
+ const {
+ database,
+ latestQuery,
+ hideLeftBar,
+ currentQueryEditorId,
+ hasSqlStatement,
+ } = useSelector<
+ SqlLabRootState,
+ {
+ database?: DatabaseObject;
+ latestQuery?: QueryResponse;
+ hideLeftBar?: boolean;
+ currentQueryEditorId: QueryEditor['id'];
+ hasSqlStatement: boolean;
+ }
+ >(({ sqlLab: { unsavedQueryEditor, databases, queries, tabHistory } }) => {
+ let { dbId, latestQueryId, hideLeftBar } = queryEditor;
+ if (unsavedQueryEditor?.id === queryEditor.id) {
+ dbId = unsavedQueryEditor.dbId || dbId;
+ latestQueryId = unsavedQueryEditor.latestQueryId || latestQueryId;
+ hideLeftBar = isBoolean(unsavedQueryEditor.hideLeftBar)
+ ? unsavedQueryEditor.hideLeftBar
+ : hideLeftBar;
+ }
+ return {
+ hasSqlStatement: Boolean(queryEditor.sql?.trim().length > 0),
+ database: databases[dbId || ''],
+ latestQuery: queries[latestQueryId || ''],
+ hideLeftBar,
+ currentQueryEditorId: tabHistory.slice(-1)[0],
+ };
+ }, shallowEqual);
const logAction = useLogAction({ queryEditorId: queryEditor.id });
const isActive = currentQueryEditorId === queryEditor.id;
@@ -728,7 +736,7 @@ const SqlEditor: FC<Props> = ({
dispatch(addSavedQueryToTabState(queryEditor, savedQuery));
};
- const renderEditorBottomBar = () => {
+ const renderEditorBottomBar = (hideActions: boolean) => {
const { allow_ctas: allowCTAS, allow_cvas: allowCVAS } = database || {};
const showMenu = allowCTAS || allowCVAS;
@@ -767,63 +775,78 @@ const SqlEditor: FC<Props> = ({
return (
<StyledToolbar className="sql-toolbar" id="js-sql-toolbar">
- <div className="leftItems">
- <span>
- <RunQueryActionButton
- allowAsync={database?.allow_run_async === true}
- queryEditorId={queryEditor.id}
- queryState={latestQuery?.state}
- runQuery={runQuery}
- stopQuery={stopQuery}
- overlayCreateAsMenu={showMenu ? runMenuBtn : null}
- />
- </span>
- {isFeatureEnabled(FeatureFlag.EstimateQueryCost) &&
- database?.allows_cost_estimate && (
+ {hideActions ? (
+ <Alert
+ type="warning"
+ message={t(
+ 'The database that was used to generate this query could not be
found',
+ )}
+ description={t(
+ 'Choose one of the available databases on the left panel.',
+ )}
+ closable={false}
+ />
+ ) : (
+ <>
+ <div className="leftItems">
<span>
- <EstimateQueryCostButton
- getEstimate={getQueryCostEstimate}
+ <RunQueryActionButton
+ allowAsync={database?.allow_run_async === true}
queryEditorId={queryEditor.id}
- tooltip={t('Estimate the cost before running a query')}
+ queryState={latestQuery?.state}
+ runQuery={runQuery}
+ stopQuery={stopQuery}
+ overlayCreateAsMenu={showMenu ? runMenuBtn : null}
/>
</span>
- )}
- <span>
- <QueryLimitSelect
- queryEditorId={queryEditor.id}
- maxRow={maxRow}
- defaultQueryLimit={defaultQueryLimit}
- />
- </span>
- {latestQuery && (
- <Timer
- startTime={latestQuery.startDttm}
- endTime={latestQuery.endDttm}
- status={STATE_TYPE_MAP[latestQuery.state]}
- isRunning={latestQuery.state === 'running'}
- />
- )}
- </div>
- <div className="rightItems">
- <span>
- <SaveQuery
- queryEditorId={queryEditor.id}
- columns={latestQuery?.results?.columns || []}
- onSave={onSaveQuery}
- onUpdate={(query, remoteId) =>
- dispatch(updateSavedQuery(query, remoteId))
- }
- saveQueryWarning={saveQueryWarning}
- database={database}
- />
- </span>
- <span>
- <ShareSqlLabQuery queryEditorId={queryEditor.id} />
- </span>
- <AntdDropdown overlay={renderDropdown()} trigger={['click']}>
- <Icons.MoreHoriz iconColor={theme.colors.grayscale.base} />
- </AntdDropdown>
- </div>
+ {isFeatureEnabled(FeatureFlag.EstimateQueryCost) &&
+ database?.allows_cost_estimate && (
+ <span>
+ <EstimateQueryCostButton
+ getEstimate={getQueryCostEstimate}
+ queryEditorId={queryEditor.id}
+ tooltip={t('Estimate the cost before running a query')}
+ />
+ </span>
+ )}
+ <span>
+ <QueryLimitSelect
+ queryEditorId={queryEditor.id}
+ maxRow={maxRow}
+ defaultQueryLimit={defaultQueryLimit}
+ />
+ </span>
+ {latestQuery && (
+ <Timer
+ startTime={latestQuery.startDttm}
+ endTime={latestQuery.endDttm}
+ status={STATE_TYPE_MAP[latestQuery.state]}
+ isRunning={latestQuery.state === 'running'}
+ />
+ )}
+ </div>
+ <div className="rightItems">
+ <span>
+ <SaveQuery
+ queryEditorId={queryEditor.id}
+ columns={latestQuery?.results?.columns || []}
+ onSave={onSaveQuery}
+ onUpdate={(query, remoteId) =>
+ dispatch(updateSavedQuery(query, remoteId))
+ }
+ saveQueryWarning={saveQueryWarning}
+ database={database}
+ />
+ </span>
+ <span>
+ <ShareSqlLabQuery queryEditorId={queryEditor.id} />
+ </span>
+ <AntdDropdown overlay={renderDropdown()} trigger={['click']}>
+ <Icons.MoreHoriz iconColor={theme.colors.grayscale.base} />
+ </AntdDropdown>
+ </div>
+ </>
+ )}
</StyledToolbar>
);
};
@@ -866,7 +889,7 @@ const SqlEditor: FC<Props> = ({
height={`${aceEditorHeight}px`}
hotkeys={hotkeys}
/>
- {renderEditorBottomBar()}
+ {renderEditorBottomBar(showEmptyState)}
</div>
<SouthPane
queryEditorId={queryEditor.id}
@@ -923,7 +946,7 @@ const SqlEditor: FC<Props> = ({
>
<Skeleton active />
</div>
- ) : showEmptyState ? (
+ ) : showEmptyState && !hasSqlStatement ? (
<EmptyStateBig
image="vector.svg"
title={t('Select a database to write a query')}
diff --git a/superset-frontend/src/SqlLab/fixtures.ts
b/superset-frontend/src/SqlLab/fixtures.ts
index 95d45ba760..2573916544 100644
--- a/superset-frontend/src/SqlLab/fixtures.ts
+++ b/superset-frontend/src/SqlLab/fixtures.ts
@@ -210,7 +210,7 @@ export const extraQueryEditor1 = {
export const extraQueryEditor2 = {
...defaultQueryEditor,
id: 'owkdi998',
- sql: 'SELECT *\nFROM\nWHERE\nGROUP BY',
+ sql: '',
name: 'Untitled Query 3',
};