From c842c9e2d8d2b579e514fb291def3f3b0a5860e3 Mon Sep 17 00:00:00 2001
From: Lyndsi Kay Williams <55605634+lyndsiWilliams@users.noreply.github.com>
Date: Fri, 10 Jun 2022 11:55:52 -0500
Subject: [PATCH] feat(explore): Dataset Panel Options when Source = Query II
(#20299)
* Created/tested query dataset dropdown
* Add isValidDatasourceType to @superset-ui/core and hide query dropdown
* Removed isValidDatasourceType check
* Remove the rest of isValidDatasourceType check
---
.../components/DatasourcePanel/index.tsx | 8 +-
.../DatasourceControl.test.tsx | 51 ++++++++++-
.../controls/DatasourceControl/index.jsx | 88 +++++++++++++++----
3 files changed, 122 insertions(+), 25 deletions(-)
diff --git a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
index e8ea3068141..b0042e138f4 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
@@ -307,12 +307,6 @@ export default function DataSourcePanel({
return true;
};
- const isValidDatasourceType =
- datasource.type === DatasourceType.Dataset ||
- datasource.type === DatasourceType.SlTable ||
- datasource.type === DatasourceType.SavedQuery ||
- datasource.type === DatasourceType.Query;
-
const mainBody = useMemo(
() => (
<>
@@ -327,7 +321,7 @@ export default function DataSourcePanel({
placeholder={t('Search Metrics & Columns')}
/>
- {isValidDatasourceType && showInfoboxCheck() && (
+ {datasource.type === DatasourceType.Query && showInfoboxCheck() && (
{
expect(postFormSpy).toBeCalledTimes(1);
});
+
+test('Should open a different menu when datasource=query', () => {
+ const props = createProps();
+ const queryProps = {
+ ...props,
+ datasource: {
+ ...props.datasource,
+ type: DatasourceType.Query,
+ },
+ };
+ render();
+
+ expect(screen.queryByText('Query preview')).not.toBeInTheDocument();
+ expect(screen.queryByText('View in SQL Lab')).not.toBeInTheDocument();
+ expect(screen.queryByText('Save as dataset')).not.toBeInTheDocument();
+
+ userEvent.click(screen.getByTestId('datasource-menu-trigger'));
+
+ expect(screen.getByText('Query preview')).toBeInTheDocument();
+ expect(screen.getByText('View in SQL Lab')).toBeInTheDocument();
+ expect(screen.getByText('Save as dataset')).toBeInTheDocument();
+});
+
+test('Click on Save as dataset', () => {
+ const props = createProps();
+ const queryProps = {
+ ...props,
+ datasource: {
+ ...props.datasource,
+ type: DatasourceType.Query,
+ },
+ };
+
+ render(, { useRedux: true });
+ userEvent.click(screen.getByTestId('datasource-menu-trigger'));
+ userEvent.click(screen.getByText('Save as dataset'));
+
+ // Renders a save dataset modal
+ const saveRadioBtn = screen.getByRole('radio', {
+ name: /save as new undefined/i,
+ });
+ const overwriteRadioBtn = screen.getByRole('radio', {
+ name: /overwrite existing select or type dataset name/i,
+ });
+ expect(saveRadioBtn).toBeVisible();
+ expect(overwriteRadioBtn).toBeVisible();
+ expect(screen.getByRole('button', { name: /save/i })).toBeVisible();
+ expect(screen.getByRole('button', { name: /close/i })).toBeVisible();
+});
diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx b/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx
index f3d4f8aabe0..15d07fd6dd9 100644
--- a/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx
+++ b/superset-frontend/src/explore/components/controls/DatasourceControl/index.jsx
@@ -19,7 +19,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
-import { t, styled, withTheme } from '@superset-ui/core';
+import { t, styled, withTheme, DatasourceType } from '@superset-ui/core';
import { getUrlParam } from 'src/utils/urlUtils';
import { AntdDropdown } from 'src/components';
@@ -30,6 +30,7 @@ import {
ChangeDatasourceModal,
DatasourceModal,
} from 'src/components/Datasource';
+import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
import { postForm } from 'src/explore/exploreUtils';
import Button from 'src/components/Button';
import ErrorAlert from 'src/components/ErrorMessage/ErrorAlert';
@@ -112,6 +113,8 @@ const Styles = styled.div`
const CHANGE_DATASET = 'change_dataset';
const VIEW_IN_SQL_LAB = 'view_in_sql_lab';
const EDIT_DATASET = 'edit_dataset';
+const QUERY_PREVIEW = 'query_preview';
+const SAVE_AS_DATASET = 'save_as_dataset';
class DatasourceControl extends React.PureComponent {
constructor(props) {
@@ -126,6 +129,7 @@ class DatasourceControl extends React.PureComponent {
this.toggleEditDatasourceModal = this.toggleEditDatasourceModal.bind(this);
this.toggleShowDatasource = this.toggleShowDatasource.bind(this);
this.handleMenuItemClick = this.handleMenuItemClick.bind(this);
+ this.toggleSaveDatasetModal = this.toggleSaveDatasetModal.bind(this);
}
onDatasourceSave(datasource) {
@@ -166,25 +170,51 @@ class DatasourceControl extends React.PureComponent {
}));
}
+ toggleSaveDatasetModal() {
+ this.setState(({ showSaveDatasetModal }) => ({
+ showSaveDatasetModal: !showSaveDatasetModal,
+ }));
+ }
+
handleMenuItemClick({ key }) {
- if (key === CHANGE_DATASET) {
- this.toggleChangeDatasourceModal();
- }
- if (key === EDIT_DATASET) {
- this.toggleEditDatasourceModal();
- }
- if (key === VIEW_IN_SQL_LAB) {
- const { datasource } = this.props;
- const payload = {
- datasourceKey: `${datasource.id}__${datasource.type}`,
- sql: datasource.sql,
- };
- postForm('/superset/sqllab/', payload);
+ switch (key) {
+ case CHANGE_DATASET:
+ this.toggleChangeDatasourceModal();
+ break;
+
+ case EDIT_DATASET:
+ this.toggleEditDatasourceModal();
+ break;
+
+ case VIEW_IN_SQL_LAB:
+ {
+ const { datasource } = this.props;
+ const payload = {
+ datasourceKey: `${datasource.id}__${datasource.type}`,
+ sql: datasource.sql,
+ };
+ postForm('/superset/sqllab/', payload);
+ }
+ break;
+
+ case QUERY_PREVIEW:
+ break;
+
+ case SAVE_AS_DATASET:
+ this.toggleSaveDatasetModal();
+ break;
+
+ default:
+ break;
}
}
render() {
- const { showChangeDatasourceModal, showEditDatasourceModal } = this.state;
+ const {
+ showChangeDatasourceModal,
+ showEditDatasourceModal,
+ showSaveDatasetModal,
+ } = this.state;
const { datasource, onChange, theme } = this.props;
const isMissingDatasource = datasource.id == null;
let isMissingParams = false;
@@ -205,7 +235,7 @@ class DatasourceControl extends React.PureComponent {
const editText = t('Edit dataset');
- const datasourceMenu = (
+ const defaultDatasourceMenu = (