From 9c8f494c9dfcc2bf32b5aca13d6fb943fb4e9857 Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Thu, 23 May 2019 09:15:04 -0700 Subject: [PATCH] A few improvements to scheduling queries (#7585) * Better message for scheduling queries * Only allow scheduling after success * Ask for query name and description * Use CSS instead of
--- superset/assets/src/SqlLab/actions/sqlLab.js | 11 +++ .../SqlLab/components/ScheduleQueryButton.jsx | 68 +++++++++++++++++-- .../src/SqlLab/components/SqlEditor.jsx | 12 +++- .../SqlLab/components/TabbedSqlEditors.jsx | 4 ++ superset/config.py | 3 +- 5 files changed, 88 insertions(+), 10 deletions(-) diff --git a/superset/assets/src/SqlLab/actions/sqlLab.js b/superset/assets/src/SqlLab/actions/sqlLab.js index 81c8e8d559..9c5a9d0482 100644 --- a/superset/assets/src/SqlLab/actions/sqlLab.js +++ b/superset/assets/src/SqlLab/actions/sqlLab.js @@ -107,6 +107,17 @@ export function saveQuery(query) { .catch(() => dispatch(addDangerToast(t('Your query could not be saved')))); } +export function scheduleQuery(query) { + return dispatch => + SupersetClient.post({ + endpoint: '/savedqueryviewapi/api/create', + postPayload: query, + stringify: false, + }) + .then(() => dispatch(addSuccessToast(t('Your query has been scheduled. To see details of your query, navigate to Saved Queries')))) + .catch(() => dispatch(addDangerToast(t('Your query could not be scheduled')))); +} + export function startQuery(query) { Object.assign(query, { id: query.id ? query.id : shortid.generate(), diff --git a/superset/assets/src/SqlLab/components/ScheduleQueryButton.jsx b/superset/assets/src/SqlLab/components/ScheduleQueryButton.jsx index 99ecaa5256..d8f82fba62 100644 --- a/superset/assets/src/SqlLab/components/ScheduleQueryButton.jsx +++ b/superset/assets/src/SqlLab/components/ScheduleQueryButton.jsx @@ -20,6 +20,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import Form from 'react-jsonschema-form'; import chrono from 'chrono-node'; +import { Col, FormControl, FormGroup, Row } from 'react-bootstrap'; import { t } from '@superset-ui/translation'; import Button from '../../components/Button'; @@ -76,11 +77,17 @@ const propTypes = { dbId: PropTypes.number.isRequired, animation: PropTypes.bool, onSchedule: PropTypes.func, + scheduleQueryWarning: PropTypes.string, + disabled: PropTypes.bool, + tooltip: PropTypes.string, }; const defaultProps = { defaultLabel: t('Undefined'), animation: true, onSchedule: () => {}, + scheduleQueryWarning: null, + disabled: false, + tooltip: null, }; class ScheduleQueryButton extends React.PureComponent { @@ -123,12 +130,53 @@ class ScheduleQueryButton extends React.PureComponent { } renderModalBody() { return ( -
+ + + + + + + + + + + + + + + + + + + {this.props.scheduleQueryWarning && ( + + + + {this.props.scheduleQueryWarning} + + + + )} + ); } render() { @@ -139,7 +187,13 @@ class ScheduleQueryButton extends React.PureComponent { modalTitle={t('Schedule Query')} modalBody={this.renderModalBody()} triggerNode={ - } diff --git a/superset/assets/src/SqlLab/components/SqlEditor.jsx b/superset/assets/src/SqlLab/components/SqlEditor.jsx index 0b25dcf20e..a4aabb73fd 100644 --- a/superset/assets/src/SqlLab/components/SqlEditor.jsx +++ b/superset/assets/src/SqlLab/components/SqlEditor.jsx @@ -67,13 +67,14 @@ const propTypes = { defaultQueryLimit: PropTypes.number.isRequired, maxRow: PropTypes.number.isRequired, saveQueryWarning: PropTypes.string, + scheduleQueryWarning: PropTypes.string, }; const defaultProps = { database: null, latestQuery: null, hideLeftBar: false, - saveQueryWarning: null, + scheduleQueryWarning: null, }; class SqlEditor extends React.PureComponent { @@ -334,6 +335,10 @@ class SqlEditor extends React.PureComponent { ); } + const successful = this.props.latestQuery && this.props.latestQuery.state === 'success'; + const scheduleToolTip = successful + ? t('Schedule the query periodically') + : t('You must run the query successfully first'); return (
@@ -355,9 +360,12 @@ class SqlEditor extends React.PureComponent { defaultLabel={qe.title} sql={qe.sql} className="m-r-5" - onSchedule={this.props.actions.saveQuery} + onSchedule={this.props.actions.scheduleQuery} schema={qe.schema} dbId={qe.dbId} + scheduleQueryWarning={this.props.scheduleQueryWarning} + tooltip={scheduleToolTip} + disabled={!successful} /> } diff --git a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx index a8516f1743..7c32021107 100644 --- a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx +++ b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx @@ -41,11 +41,13 @@ const propTypes = { tables: PropTypes.array.isRequired, offline: PropTypes.bool, saveQueryWarning: PropTypes.string, + scheduleQueryWarning: PropTypes.string, }; const defaultProps = { queryEditors: [], offline: false, saveQueryWarning: null, + scheduleQueryWarning: null, }; let queryCount = 1; @@ -250,6 +252,7 @@ class TabbedSqlEditors extends React.PureComponent { defaultQueryLimit={this.props.defaultQueryLimit} maxRow={this.props.maxRow} saveQueryWarning={this.props.saveQueryWarning} + scheduleQueryWarning={this.props.scheduleQueryWarning} /> )} @@ -294,6 +297,7 @@ function mapStateToProps({ sqlLab, common }) { defaultQueryLimit: common.conf.DEFAULT_SQLLAB_LIMIT, maxRow: common.conf.SQL_MAX_ROW, saveQueryWarning: common.conf.SQLLAB_SAVE_WARNING_MESSAGE, + scheduleQueryWarning: common.conf.SQLLAB_SCHEDULE_WARNING_MESSAGE, }; } function mapDispatchToProps(dispatch) { diff --git a/superset/config.py b/superset/config.py index 5f9bd8a3bf..fc287b7f2c 100644 --- a/superset/config.py +++ b/superset/config.py @@ -357,8 +357,9 @@ DEFAULT_SQLLAB_LIMIT = 1000 # Maximum number of tables/views displayed in the dropdown window in SQL Lab. MAX_TABLE_NAMES = 3000 -# Adds a warning message on sqllab save query modal. +# Adds a warning message on sqllab save query and schedule query modals. SQLLAB_SAVE_WARNING_MESSAGE = None +SQLLAB_SCHEDULE_WARNING_MESSAGE = None # If defined, shows this text in an alert-warning box in the navbar # one example use case may be "STAGING" to make it clear that this is