AAfghahi commented on a change in pull request #18821:
URL: https://github.com/apache/superset/pull/18821#discussion_r812179933
##########
File path: superset-frontend/src/SqlLab/components/ResultSet/index.tsx
##########
@@ -171,106 +158,135 @@ const updateDataset = async (
return data.json.result;
};
-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: [],
- showSaveDatasetModal: false,
- newSaveDatasetName: this.getDefaultDatasetName(),
- saveDatasetRadioBtnState: DatasetRadioState.SAVE_NEW,
- shouldOverwriteDataSet: false,
- datasetToOverwrite: {},
- saveModalAutocompleteValue: '',
- userDatasetOptions: [],
- alertIsOpen: false,
- };
- this.changeSearch = this.changeSearch.bind(this);
- this.fetchResults = this.fetchResults.bind(this);
- this.popSelectStar = this.popSelectStar.bind(this);
- this.reFetchQueryResults = this.reFetchQueryResults.bind(this);
- this.toggleExploreResultsButton =
- this.toggleExploreResultsButton.bind(this);
- this.handleSaveInDataset = this.handleSaveInDataset.bind(this);
- this.handleHideSaveModal = this.handleHideSaveModal.bind(this);
- this.handleDatasetNameChange = this.handleDatasetNameChange.bind(this);
- this.handleSaveDatasetRadioBtnState =
- this.handleSaveDatasetRadioBtnState.bind(this);
- this.handleOverwriteCancel = this.handleOverwriteCancel.bind(this);
- this.handleOverwriteDataset = this.handleOverwriteDataset.bind(this);
- this.handleOverwriteDatasetOption =
- this.handleOverwriteDatasetOption.bind(this);
- this.handleSaveDatasetModalSearch = debounce(
- this.handleSaveDatasetModalSearch.bind(this),
- 1000,
- );
- this.handleFilterAutocompleteOption =
- this.handleFilterAutocompleteOption.bind(this);
- this.handleOnChangeAutoComplete =
- this.handleOnChangeAutoComplete.bind(this);
- this.handleExploreBtnClick = this.handleExploreBtnClick.bind(this);
- }
-
- async componentDidMount() {
- // only do this the first time the component is rendered/mounted
- this.reRunQueryIfSessionTimeoutErrorOnMount();
- const userDatasetsOwned = await this.getUserDatasets();
- this.setState({ userDatasetOptions: userDatasetsOwned });
- }
-
- UNSAFE_componentWillReceiveProps(nextProps: ResultSetProps) {
- // when new results comes in, save them locally and clear in store
+const ResultSet = ({
+ actions,
+ cache,
+ csv,
+ database,
+ displayLimit,
+ height,
+ query,
+ search,
Review comment:
it seems like this has a default value, which you should put in. Same
with database, csv, showSql, and visualize.
##########
File path: superset-frontend/src/SqlLab/components/ResultSet/index.tsx
##########
@@ -664,180 +599,177 @@ export default class ResultSet extends
React.PureComponent<
)}
</ReturnedRows>
);
- }
+ };
- render() {
- const { query } = this.props;
- let sql;
- let exploreDBId = query.dbId;
- if (this.props.database && this.props.database.explore_database_id) {
- exploreDBId = this.props.database.explore_database_id;
- }
+ let highlightedSql;
+ let exploreDBId = query.dbId;
+ if (database && database.explore_database_id) {
+ exploreDBId = database.explore_database_id;
+ }
- if (this.props.showSql) {
- sql = <HighlightedSql sql={query.sql} />;
- }
+ if (showSql) {
+ highlightedSql = <HighlightedSql sql={query.sql} />;
+ }
- if (query.state === 'stopped') {
- return <Alert type="warning" message={t('Query was stopped')} />;
+ if (query.state === 'stopped') {
+ return <Alert type="warning" message={t('Query was stopped')} />;
+ }
+ if (query.state === 'failed') {
+ return (
+ <ResultSetErrorMessage>
+ <ErrorMessageWithStackTrace
+ title={t('Database error')}
+ error={query?.errors?.[0]}
+ subtitle={<MonospaceDiv>{query.errorMessage}</MonospaceDiv>}
+ copyText={query.errorMessage || undefined}
+ link={query.link}
+ source="sqllab"
+ />
+ </ResultSetErrorMessage>
+ );
+ }
+ if (query.state === 'success' && query.ctas) {
+ const { tempSchema, tempTable } = query;
+ let object = 'Table';
+ if (query.ctas_method === CtasEnum.VIEW) {
+ object = 'View';
}
- if (query.state === 'failed') {
- return (
- <ResultSetErrorMessage>
- <ErrorMessageWithStackTrace
- title={t('Database error')}
- error={query?.errors?.[0]}
- subtitle={<MonospaceDiv>{query.errorMessage}</MonospaceDiv>}
- copyText={query.errorMessage || undefined}
- link={query.link}
- source="sqllab"
- />
- </ResultSetErrorMessage>
- );
+ return (
+ <div>
+ <Alert
+ type="info"
+ message={
+ <>
+ {t(object)} [
+ <strong>
+ {tempSchema ? `${tempSchema}.` : ''}
+ {tempTable}
+ </strong>
+ ] {t('was created')}
+ <ButtonGroup>
+ <Button
+ buttonSize="small"
+ className="m-r-5"
+ onClick={() => popSelectStar(tempSchema, tempTable)}
+ >
+ {t('Query in a new tab')}
+ </Button>
+ <ExploreCtasResultsButton
+ // @ts-ignore Redux types are difficult to work with,
ignoring for now
+ table={tempTable}
+ schema={tempSchema}
+ dbId={exploreDBId}
+ database={database}
+ actions={actions}
+ />
+ </ButtonGroup>
+ </>
+ }
+ />
+ </div>
+ );
+ }
+ if (query.state === 'success' && query.results) {
+ const { results } = query;
+ const tableHeight = alertIsOpen ? height - 70 : height;
+ let tempData;
+ if (cache && query.cached) {
+ tempData = data;
+ } else if (results && results.data) {
+ tempData = results.data;
}
- if (query.state === 'success' && query.ctas) {
- const { tempSchema, tempTable } = query;
- let object = 'Table';
- if (query.ctas_method === CtasEnum.VIEW) {
- object = 'View';
- }
+ if (tempData && tempData.length > 0) {
+ const expandedColumns = results.expanded_columns
+ ? results.expanded_columns.map(col => col.name)
+ : [];
return (
- <div>
- <Alert
- type="info"
- message={
- <>
- {t(object)} [
- <strong>
- {tempSchema ? `${tempSchema}.` : ''}
- {tempTable}
- </strong>
- ] {t('was created')}
- <ButtonGroup>
- <Button
- buttonSize="small"
- className="m-r-5"
- onClick={() => this.popSelectStar(tempSchema, tempTable)}
- >
- {t('Query in a new tab')}
- </Button>
- <ExploreCtasResultsButton
- // @ts-ignore Redux types are difficult to work with,
ignoring for now
- table={tempTable}
- schema={tempSchema}
- dbId={exploreDBId}
- database={this.props.database}
- actions={this.props.actions}
- />
- </ButtonGroup>
- </>
- }
+ <>
+ {renderControls()}
+ {renderRowsReturned()}
+ {highlightedSql}
+ <FilterableTable
+ data={tempData}
+ orderedColumnKeys={results.columns.map(col => col.name)}
+ height={tableHeight}
+ filterText={searchText}
+ expandedColumns={expandedColumns}
/>
- </div>
+ </>
);
}
- if (query.state === 'success' && query.results) {
- const { results } = query;
- const height = this.state.alertIsOpen
- ? this.props.height - 70
- : this.props.height;
- let data;
- if (this.props.cache && query.cached) {
- ({ data } = this.state);
- } else if (results && results.data) {
- ({ data } = results);
- }
- if (data && data.length > 0) {
- const expandedColumns = results.expanded_columns
- ? results.expanded_columns.map(col => col.name)
- : [];
- return (
- <>
- {this.renderControls()}
- {this.renderRowsReturned()}
- {sql}
- <FilterableTable
- data={data}
- orderedColumnKeys={results.columns.map(col => col.name)}
- height={height}
- filterText={this.state.searchText}
- expandedColumns={expandedColumns}
- />
- </>
- );
- }
- if (data && data.length === 0) {
- return (
- <Alert type="warning" message={t('The query returned no data')} />
- );
- }
- }
- if (query.cached || (query.state === 'success' && !query.results)) {
- if (query.isDataPreview) {
- return (
- <Button
- buttonSize="small"
- buttonStyle="primary"
- onClick={() =>
- this.reFetchQueryResults({
- ...query,
- isDataPreview: true,
- })
- }
- >
- {t('Fetch data preview')}
- </Button>
- );
- }
- if (query.resultsKey) {
- return (
- <Button
- buttonSize="small"
- buttonStyle="primary"
- onClick={() => this.fetchResults(query)}
- >
- {t('Refetch results')}
- </Button>
- );
- }
+ if (tempData && tempData.length === 0) {
+ return <Alert type="warning" message={t('The query returned no data')}
/>;
}
- let trackingUrl;
- let progressBar;
- if (query.progress > 0) {
- progressBar = (
- <ProgressBar
- percent={parseInt(query.progress.toFixed(0), 10)}
- striped
- />
+ }
+ if (query.cached || (query.state === 'success' && !query.results)) {
+ if (query.isDataPreview) {
+ return (
+ <Button
+ buttonSize="small"
+ buttonStyle="primary"
+ onClick={() =>
+ reFetchQueryResults({
+ ...query,
+ isDataPreview: true,
+ })
+ }
+ >
+ {t('Fetch data preview')}
+ </Button>
);
}
- if (query.trackingUrl) {
- trackingUrl = (
+ if (query.resultsKey) {
+ return (
<Button
buttonSize="small"
- onClick={() => query.trackingUrl && window.open(query.trackingUrl)}
+ buttonStyle="primary"
+ onClick={() => fetchResults(query)}
>
- {t('Track job')}
+ {t('Refetch results')}
</Button>
);
}
- const progressMsg =
- query && query.extra && query.extra.progress
- ? query.extra.progress
- : null;
-
- return (
- <div style={LOADING_STYLES}>
- <div>{!progressBar && <Loading position="normal" />}</div>
- {/* show loading bar whenever progress bar is completed but needs time
to render */}
- <div>{query.progress === 100 && <Loading position="normal" />}</div>
- <QueryStateLabel query={query} />
- <div>
- {progressMsg && <Alert type="success" message={progressMsg} />}
- </div>
- <div>{query.progress !== 100 && progressBar}</div>
- <div>{trackingUrl}</div>
- </div>
+ }
+ let trackingUrl;
+ let progressBar;
+ if (query.progress > 0) {
+ progressBar = (
+ <ProgressBar percent={parseInt(query.progress.toFixed(0), 10)} striped />
);
}
-}
+ if (query.trackingUrl) {
+ trackingUrl = (
+ <Button
+ buttonSize="small"
+ onClick={() => query.trackingUrl && window.open(query.trackingUrl)}
+ >
+ {t('Track job')}
+ </Button>
+ );
+ }
+ const progressMsg =
+ query && query.extra && query.extra.progress ? query.extra.progress : null;
+
+ return (
+ <div style={LOADING_STYLES}>
+ <div>{!progressBar && <Loading position="normal" />}</div>
+ {/* show loading bar whenever progress bar is completed but needs time
to render */}
+ <div>{query.progress === 100 && <Loading position="normal" />}</div>
+ <QueryStateLabel query={query} />
+ <div>{progressMsg && <Alert type="success" message={progressMsg}
/>}</div>
+ <div>{query.progress !== 100 && progressBar}</div>
+ <div>{trackingUrl}</div>
+ </div>
+ );
+};
+
+ResultSet.defaultProps = {
Review comment:
I think you can move this in favor of stating defaults in the functional
component itself.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]