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 <[email protected]> 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 (
