From 4281ad5486f976107b3fb3637519defe63133b9b Mon Sep 17 00:00:00 2001 From: Erik Ritter Date: Thu, 2 Jul 2020 10:12:31 -0700 Subject: [PATCH] chore: type ResultSet.tsx (#10226) --- .../spec/javascripts/sqllab/fixtures.js | 4 +- .../src/SqlLab/actions/sqlLab.js | 2 +- .../{ResultSet.jsx => ResultSet.tsx} | 108 +++++++++--------- .../src/SqlLab/components/SqlEditor.jsx | 2 +- .../src/SqlLab/reducers/sqlLab.js | 8 +- superset-frontend/src/SqlLab/types.ts | 57 +++++++++ 6 files changed, 117 insertions(+), 64 deletions(-) rename superset-frontend/src/SqlLab/components/{ResultSet.jsx => ResultSet.tsx} (84%) create mode 100644 superset-frontend/src/SqlLab/types.ts diff --git a/superset-frontend/spec/javascripts/sqllab/fixtures.js b/superset-frontend/spec/javascripts/sqllab/fixtures.js index a88f93834507a..45bbb2ee9e123 100644 --- a/superset-frontend/spec/javascripts/sqllab/fixtures.js +++ b/superset-frontend/spec/javascripts/sqllab/fixtures.js @@ -387,7 +387,7 @@ export const stoppedQuery = { startDttm: 1497400851936, state: 'stopped', tab: 'Untitled Query 2', - tempTableName: '', + tempTable: '', }; export const runningQuery = { dbId: 1, @@ -428,7 +428,7 @@ export const query = { sql: 'SELECT * FROM something', sqlEditorId: defaultQueryEditor.id, tab: 'unimportant', - tempTableName: null, + tempTable: null, runAsync: false, ctas: false, cached: false, diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.js b/superset-frontend/src/SqlLab/actions/sqlLab.js index 8f9f509fab683..e38a4fe56d52a 100644 --- a/superset-frontend/src/SqlLab/actions/sqlLab.js +++ b/superset-frontend/src/SqlLab/actions/sqlLab.js @@ -350,7 +350,7 @@ export function runQuery(query) { sql: query.sql, sql_editor_id: query.sqlEditorId, tab: query.tab, - tmp_table_name: query.tempTableName, + tmp_table_name: query.tempTable, select_as_cta: query.ctas, ctas_method: query.ctas_method, templateParams: query.templateParams, diff --git a/superset-frontend/src/SqlLab/components/ResultSet.jsx b/superset-frontend/src/SqlLab/components/ResultSet.tsx similarity index 84% rename from superset-frontend/src/SqlLab/components/ResultSet.jsx rename to superset-frontend/src/SqlLab/components/ResultSet.tsx index 5dd34691bf2a1..75273b3e17218 100644 --- a/superset-frontend/src/SqlLab/components/ResultSet.jsx +++ b/superset-frontend/src/SqlLab/components/ResultSet.tsx @@ -16,8 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { CSSProperties } from 'react'; import { Alert, Button, ButtonGroup, ProgressBar } from 'react-bootstrap'; import shortid from 'shortid'; import { t } from '@superset-ui/translation'; @@ -31,40 +30,50 @@ import QueryStateLabel from './QueryStateLabel'; import CopyToClipboard from '../../components/CopyToClipboard'; import { prepareCopyToClipboardTabularData } from '../../utils/common'; import { CtasEnum } from '../actions/sqlLab'; - -const propTypes = { - actions: PropTypes.object, - csv: PropTypes.bool, - query: PropTypes.object, - search: PropTypes.bool, - showSql: PropTypes.bool, - visualize: PropTypes.bool, - cache: PropTypes.bool, - height: PropTypes.number.isRequired, - database: PropTypes.object, - displayLimit: PropTypes.number.isRequired, -}; -const defaultProps = { - search: true, - visualize: true, - showSql: false, - csv: true, - actions: {}, - cache: false, - database: {}, -}; +import { Query } from '../types'; const SEARCH_HEIGHT = 46; -const LOADING_STYLES = { position: 'relative', minHeight: 100 }; +const LOADING_STYLES: CSSProperties = { position: 'relative', minHeight: 100 }; + +interface ResultSetProps { + actions: Record; + cache?: boolean; + csv?: boolean; + database?: Record; + displayLimit: number; + height: number; + query: Query; + search?: boolean; + showSql?: boolean; + visualize?: boolean; +} -export default class ResultSet extends React.PureComponent { - constructor(props) { +interface ResultSetState { + searchText: string; + showExploreResultsButton: boolean; + data: Record[]; +} + +export default class ResultSet extends React.PureComponent< + ResultSetProps, + ResultSetState +> { + static defaultProps = { + cache: false, + csv: true, + database: {}, + search: true, + showSql: false, + visualize: true, + }; + + constructor(props: ResultSetProps) { super(props); this.state = { searchText: '', showExploreResultsButton: false, - data: null, + data: [], }; this.changeSearch = this.changeSearch.bind(this); @@ -79,7 +88,7 @@ export default class ResultSet extends React.PureComponent { // only do this the first time the component is rendered/mounted this.reRunQueryIfSessionTimeoutErrorOnMount(); } - UNSAFE_componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps: ResultSetProps) { // when new results comes in, save them locally and clear in store if ( this.props.cache && @@ -88,8 +97,7 @@ export default class ResultSet extends React.PureComponent { nextProps.query.results.data && nextProps.query.results.data.length > 0 ) { - this.setState( - { data: nextProps.query.results.data }, + this.setState({ data: nextProps.query.results.data }, () => this.clearQueryResults(nextProps.query), ); } @@ -100,16 +108,16 @@ export default class ResultSet extends React.PureComponent { this.fetchResults(nextProps.query); } } - clearQueryResults(query) { + clearQueryResults(query: Query) { this.props.actions.clearQueryResults(query); } - popSelectStar(tmpSchema, tmpTable) { + popSelectStar(tempSchema: string | null, tempTable: string) { const qe = { id: shortid.generate(), - title: tmpTable, + title: tempTable, autorun: false, dbId: this.props.query.dbId, - sql: `SELECT * FROM ${tmpSchema}.${tmpTable}`, + sql: `SELECT * FROM ${tempSchema ? `${tempSchema}.` : ''}${tempTable}`, }; this.props.actions.addQueryEditor(qe); } @@ -118,13 +126,13 @@ export default class ResultSet extends React.PureComponent { showExploreResultsButton: !this.state.showExploreResultsButton, }); } - changeSearch(event) { + changeSearch(event: React.ChangeEvent) { this.setState({ searchText: event.target.value }); } - fetchResults(query) { + fetchResults(query: Query) { this.props.actions.fetchQueryResults(query, this.props.displayLimit); } - reFetchQueryResults(query) { + reFetchQueryResults(query: Query) { this.props.actions.reFetchQueryResults(query); } reRunQueryIfSessionTimeoutErrorOnMount() { @@ -218,14 +226,7 @@ export default class ResultSet extends React.PureComponent { ); } else if (query.state === 'success' && query.ctas) { - // Async queries - let tmpSchema = query.tempSchema; - let tmpTable = query.tempTableName; - // Sync queries, query.results.query contains the source of truth for them. - if (query.results && query.results.query) { - tmpTable = query.results.query.tempTable; - tmpSchema = query.results.query.tempSchema; - } + const { tempSchema, tempTable } = query; let object = 'Table'; if (query.ctas_method === CtasEnum.VIEW) { object = 'View'; @@ -235,20 +236,21 @@ export default class ResultSet extends React.PureComponent { {t(object)} [ - {tmpSchema}.{tmpTable} + {tempSchema ? `${tempSchema}.` : ''} + {tempTable} ] {t('was created')}   { - window.open(query.trackingUrl); - }} + onClick={() => query.trackingUrl && window.open(query.trackingUrl)} > {t('Track Job')} @@ -358,5 +358,3 @@ export default class ResultSet extends React.PureComponent { ); } } -ResultSet.propTypes = propTypes; -ResultSet.defaultProps = defaultProps; diff --git a/superset-frontend/src/SqlLab/components/SqlEditor.jsx b/superset-frontend/src/SqlLab/components/SqlEditor.jsx index 54f729cacccee..5f78f41106dd9 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor.jsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor.jsx @@ -293,7 +293,7 @@ class SqlEditor extends React.PureComponent { sqlEditorId: qe.id, tab: qe.title, schema: qe.schema, - tempTableName: ctas ? this.state.ctas : '', + tempTable: ctas ? this.state.ctas : '', templateParams: qe.templateParams, queryLimit: qe.queryLimit || this.props.defaultQueryLimit, runAsync: this.props.database diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.js b/superset-frontend/src/SqlLab/reducers/sqlLab.js index 3dbd45fe079f3..6257ce8c9e873 100644 --- a/superset-frontend/src/SqlLab/reducers/sqlLab.js +++ b/superset-frontend/src/SqlLab/reducers/sqlLab.js @@ -324,16 +324,14 @@ export default function sqlLabReducer(state = {}, action) { }); }, [actions.QUERY_SUCCESS]() { - let rows; - if (action.results.data) { - rows = action.results.data.length; - } const alts = { endDttm: now(), progress: 100, results: action.results, - rows, + rows: action?.results?.data?.length, state: 'success', + tempSchema: action?.results?.query?.tempSchema, + tempTable: action?.results?.query?.tempTable, errorMessage: null, cached: false, }; diff --git a/superset-frontend/src/SqlLab/types.ts b/superset-frontend/src/SqlLab/types.ts new file mode 100644 index 0000000000000..3b1c4e125ec1e --- /dev/null +++ b/superset-frontend/src/SqlLab/types.ts @@ -0,0 +1,57 @@ +/** + * 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 { CtasEnum } from './actions/sqlLab'; + +export type Column = { + name: string; +}; + +export type Query = { + cached: boolean; + ctas: boolean; + ctas_method?: keyof typeof CtasEnum; + dbId: number; + errorMessage: string | null; + extra: { + progress: string | null; + }; + id: string; + isDataPreview: boolean; + link?: string; + progress: number; + results: { + columns: Column[]; + data: Record[]; + expanded_columns: Column[]; + }; + resultsKey: string | null; + sql: string; + sqlEditorId: string; + state: + | 'stopped' + | 'failed' + | 'pending' + | 'running' + | 'scheduled' + | 'success' + | 'timed_out'; + tempSchema: string | null; + tempTable: string; + trackingUrl: string | null; +};