You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ly...@apache.org on 2022/07/22 17:07:24 UTC

[superset] 18/39: added frontend piece

This is an automated email from the ASF dual-hosted git repository.

lyndsi pushed a commit to branch lyndsi/sql-lab-new-explore-button-functionality-and-move-save-dataset-to-split-save-button
in repository https://gitbox.apache.org/repos/asf/superset.git

commit d7a44ecf58b63230dd211b7a65c6c1d45b6e8656
Author: AAfghahi <ar...@gmail.com>
AuthorDate: Tue Jun 28 18:00:32 2022 -0400

    added frontend piece
---
 .../superset-ui-core/src/query/api/v1/types.ts     |  1 +
 superset-frontend/src/components/Chart/Chart.jsx   | 62 +++++++++++++++-------
 .../src/components/Chart/ChartErrorMessage.tsx     |  1 -
 .../src/components/Chart/chartAction.js            |  1 +
 .../src/components/ErrorMessage/types.ts           |  9 ++++
 .../components/ErrorMessage/vizTypeErrorAlert.tsx  | 54 +++++++++++++++++++
 superset/errors.py                                 |  2 +-
 superset/views/core.py                             | 19 +++----
 8 files changed, 118 insertions(+), 31 deletions(-)

diff --git a/superset-frontend/packages/superset-ui-core/src/query/api/v1/types.ts b/superset-frontend/packages/superset-ui-core/src/query/api/v1/types.ts
index 09ef1bc7d6..46413d890f 100644
--- a/superset-frontend/packages/superset-ui-core/src/query/api/v1/types.ts
+++ b/superset-frontend/packages/superset-ui-core/src/query/api/v1/types.ts
@@ -61,6 +61,7 @@ export enum SupersetApiErrorType {
   VIZ_GET_DF_ERROR = 'VIZ_GET_DF_ERROR',
   UNKNOWN_DATASOURCE_TYPE_ERROR = 'UNKNOWN_DATASOURCE_TYPE_ERROR',
   FAILED_FETCHING_DATASOURCE_INFO_ERROR = 'FAILED_FETCHING_DATASOURCE_INFO_ERROR',
+  VIZ_TYPE_REQUIRES_DATASET_ERROR = 'VIZ_TYPE_REQUIRES_DATASET_ERROR',
 
   // Security access errors,
   TABLE_SECURITY_ACCESS_ERROR = 'TABLE_SECURITY_ACCESS_ERROR',
diff --git a/superset-frontend/src/components/Chart/Chart.jsx b/superset-frontend/src/components/Chart/Chart.jsx
index 7d02bf3452..48f59c0b5d 100644
--- a/superset-frontend/src/components/Chart/Chart.jsx
+++ b/superset-frontend/src/components/Chart/Chart.jsx
@@ -25,6 +25,7 @@ import { PLACEHOLDER_DATASOURCE } from 'src/dashboard/constants';
 import Loading from 'src/components/Loading';
 import { EmptyStateBig } from 'src/components/EmptyState';
 import ErrorBoundary from 'src/components/ErrorBoundary';
+import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal';
 import { Logger, LOG_ACTIONS_RENDER_CHART } from 'src/logger/LogUtils';
 import { URL_PARAMS } from 'src/constants';
 import { getUrlParam } from 'src/utils/urlUtils';
@@ -122,8 +123,10 @@ const MonospaceDiv = styled.div`
 class Chart extends React.PureComponent {
   constructor(props) {
     super(props);
+    this.state = { showSaveDatasetModal: false };
     this.handleRenderContainerFailure =
       this.handleRenderContainerFailure.bind(this);
+    this.toggleSaveDatasetModal = this.toggleSaveDatasetModal.bind(this);
   }
 
   componentDidMount() {
@@ -136,6 +139,12 @@ class Chart extends React.PureComponent {
     }
   }
 
+  toggleSaveDatasetModal = () => {
+    this.setState(({ showSaveDatasetModal }) => ({
+      showSaveDatasetModal: !showSaveDatasetModal,
+    }));
+  };
+
   componentDidUpdate() {
     // during migration, hold chart queries before user choose review or cancel
     if (
@@ -253,6 +262,7 @@ class Chart extends React.PureComponent {
       width,
     } = this.props;
 
+    const { showSaveDatasetModal } = this.state;
     const isLoading = chartStatus === 'loading';
     this.renderContainerStartTime = Logger.getTimestamp();
     if (chartStatus === 'failed') {
@@ -296,27 +306,39 @@ class Chart extends React.PureComponent {
     }
 
     return (
-      <ErrorBoundary
-        onError={this.handleRenderContainerFailure}
-        showMessage={false}
-      >
-        <Styles
-          data-ui-anchor="chart"
-          className="chart-container"
-          data-test="chart-container"
-          height={height}
-          width={width}
+      <>
+        <ErrorBoundary
+          onError={this.handleRenderContainerFailure}
+          showMessage={false}
         >
-          <div className="slice_container" data-test="slice-container">
-            <ChartRenderer
-              {...this.props}
-              source={this.props.dashboardId ? 'dashboard' : 'explore'}
-              data-test={this.props.vizType}
-            />
-          </div>
-          {isLoading && !isDeactivatedViz && <Loading />}
-        </Styles>
-      </ErrorBoundary>
+          <Styles
+            data-ui-anchor="chart"
+            className="chart-container"
+            data-test="chart-container"
+            height={height}
+            width={width}
+          >
+            <div className="slice_container" data-test="slice-container">
+              <ChartRenderer
+                {...this.props}
+                source={this.props.dashboardId ? 'dashboard' : 'explore'}
+                data-test={this.props.vizType}
+              />
+            </div>
+            {isLoading && !isDeactivatedViz && <Loading />}
+          </Styles>
+        </ErrorBoundary>
+        {showSaveDatasetModal && (
+          <SaveDatasetModal
+            key={Math.random()}
+            visible={showSaveDatasetModal}
+            onHide={this.toggleSaveDatasetModal}
+            buttonTextOnSave={t('Save')}
+            buttonTextOnOverwrite={t('Overwrite')}
+            datasource={this.props.datasource}
+          />
+        )}
+      </>
     );
   }
 }
diff --git a/superset-frontend/src/components/Chart/ChartErrorMessage.tsx b/superset-frontend/src/components/Chart/ChartErrorMessage.tsx
index 077ca2282a..162abd0d98 100644
--- a/superset-frontend/src/components/Chart/ChartErrorMessage.tsx
+++ b/superset-frontend/src/components/Chart/ChartErrorMessage.tsx
@@ -42,6 +42,5 @@ export const ChartErrorMessage: React.FC<Props> = ({
     ...error,
     extra: { ...error.extra, owners },
   };
-
   return <ErrorMessageWithStackTrace {...props} error={ownedError} />;
 };
diff --git a/superset-frontend/src/components/Chart/chartAction.js b/superset-frontend/src/components/Chart/chartAction.js
index 139d91cd1d..dfc42237e1 100644
--- a/superset-frontend/src/components/Chart/chartAction.js
+++ b/superset-frontend/src/components/Chart/chartAction.js
@@ -66,6 +66,7 @@ export function chartUpdateStopped(key) {
 
 export const CHART_UPDATE_FAILED = 'CHART_UPDATE_FAILED';
 export function chartUpdateFailed(queriesResponse, key) {
+  console.log(queriesResponse);
   return { type: CHART_UPDATE_FAILED, queriesResponse, key };
 }
 
diff --git a/superset-frontend/src/components/ErrorMessage/types.ts b/superset-frontend/src/components/ErrorMessage/types.ts
index 87ef4a1bc4..ad91b05c67 100644
--- a/superset-frontend/src/components/ErrorMessage/types.ts
+++ b/superset-frontend/src/components/ErrorMessage/types.ts
@@ -17,6 +17,8 @@
  * under the License.
  */
 
+import vizTypeErrorAlert from './vizTypeErrorAlert';
+
 // Keep in sync with superset/views/errors.py
 export const ErrorTypeEnum = {
   // Frontend errors
@@ -48,6 +50,7 @@ export const ErrorTypeEnum = {
   UNKNOWN_DATASOURCE_TYPE_ERROR: 'UNKNOWN_DATASOURCE_TYPE_ERROR',
   FAILED_FETCHING_DATASOURCE_INFO_ERROR:
     'FAILED_FETCHING_DATASOURCE_INFO_ERROR',
+  VIZ_TYPE_REQUIRES_DATASET_ERROR: 'VIZ_TYPE_REQUIRES_DATASET_ERROR',
 
   // Security access errors
   TABLE_SECURITY_ACCESS_ERROR: 'TABLE_SECURITY_ACCESS_ERROR',
@@ -105,3 +108,9 @@ export type ErrorMessageComponentProps<ExtraType = Record<string, any> | null> =
 
 export type ErrorMessageComponent =
   React.ComponentType<ErrorMessageComponentProps>;
+
+// created in case a component needs a specific error. This maps to
+// the specific error component.
+export const CUSTOM_ERROR_ALERT_MAP = {
+  VIZ_TYPE_REQUIRES_DATASET_ERROR: vizTypeErrorAlert,
+};
diff --git a/superset-frontend/src/components/ErrorMessage/vizTypeErrorAlert.tsx b/superset-frontend/src/components/ErrorMessage/vizTypeErrorAlert.tsx
new file mode 100644
index 0000000000..e55addba00
--- /dev/null
+++ b/superset-frontend/src/components/ErrorMessage/vizTypeErrorAlert.tsx
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import Alert from 'src/components/Alert';
+import { t } from '@superset-ui/core';
+
+interface vizTypeErrorAlertProps {
+  onClickFunction: () => void;
+}
+
+export default function vizTypeErrorAlert({
+  onClickFunction,
+}: vizTypeErrorAlertProps) {
+  return (
+    <Alert
+      closable
+      type="error"
+      message="Chart type requires a dataset"
+      description={
+        <>
+          {t(
+            'This chart type is not supported when using an unsaved query as a chart source. ',
+          )}
+          <span
+            role="button"
+            tabIndex={0}
+            onClick={() => onClickFunction()}
+            className="add-dataset-alert-description"
+            css={{ textDecoration: 'underline' }}
+          >
+            {t('Create a dataset')}
+          </span>
+          {t(' to visualize your data.')}
+        </>
+      }
+    />
+  );
+}
diff --git a/superset/errors.py b/superset/errors.py
index 5d59efb1f7..dfa7a63528 100644
--- a/superset/errors.py
+++ b/superset/errors.py
@@ -183,7 +183,7 @@ ERROR_TYPES_TO_ISSUE_CODES_MAPPING = {
     SupersetErrorType.ASYNC_WORKERS_ERROR: [1035],
     SupersetErrorType.DATABASE_NOT_FOUND_ERROR: [1011, 1036],
     SupersetErrorType.CONNECTION_DATABASE_TIMEOUT: [1001, 1009],
-    SupersetErrorType.CHART_TYPE_REQUIRES_DATASET_ERROR: [1038],
+    SupersetErrorType.VIZ_TYPE_REQUIRES_DATASET_ERROR: [1038],
 }
 
 
diff --git a/superset/views/core.py b/superset/views/core.py
index fce24a2f3e..8067b4e4a5 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -635,7 +635,6 @@ class Superset(BaseSupersetView):  # pylint: disable=too-many-public-methods
                 status=403,
             )
 
-        print("I am in explore json")
         form_data = get_form_data()[0]
         try:
             datasource_id, datasource_type = get_datasource_info(
@@ -644,14 +643,16 @@ class Superset(BaseSupersetView):  # pylint: disable=too-many-public-methods
             force = request.args.get("force") == "true"
 
             if datasource_type == "query":
-                raise SupersetErrorException(
-                    SupersetError(
-                        message=__(
-                            "This chart type is not supported when using an unsaved query as a chart source. Create a dataset to visualize your data."
-                        ),
-                        error_type=SupersetErrorType.DML_NOT_ALLOWED_ERROR,
-                        level=ErrorLevel.ERROR,
-                    )
+                return json_errors_response(
+                    errors=[
+                        SupersetError(
+                            message=__(
+                                "This chart type is not supported when using an unsaved query as a chart source. Create a dataset to visualize your data."
+                            ),
+                            error_type=SupersetErrorType.VIZ_TYPE_REQUIRES_DATASET_ERROR,
+                            level=ErrorLevel.ERROR,
+                        )
+                    ]
                 )
             # TODO: support CSV, SQL query and other non-JSON types
             if (