[explore] force control validation before runQuery (#2544)

* [explore] force control validation before runQuery

* Addressing comments
This commit is contained in:
Maxime Beauchemin 2017-04-10 21:45:44 -07:00 committed by GitHub
parent 493ba18362
commit 75a358c616
7 changed files with 14 additions and 8 deletions

View File

@ -58,6 +58,7 @@ class ChartContainer extends React.PureComponent {
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if ( if (
this.props.queryResponse &&
( (
prevProps.queryResponse !== this.props.queryResponse || prevProps.queryResponse !== this.props.queryResponse ||
prevProps.height !== this.props.height || prevProps.height !== this.props.height ||

View File

@ -48,8 +48,12 @@ export default class Control extends React.PureComponent {
super(props); super(props);
this.validate = this.validate.bind(this); this.validate = this.validate.bind(this);
this.onChange = this.onChange.bind(this); this.onChange = this.onChange.bind(this);
this.validateAndSetValue(props.value, []);
} }
onChange(value, errors) { onChange(value, errors) {
this.validateAndSetValue(value, errors);
}
validateAndSetValue(value, errors) {
let validationErrors = this.validate(value); let validationErrors = this.validate(value);
if (errors && errors.length > 0) { if (errors && errors.length > 0) {
validationErrors = validationErrors.concat(errors); validationErrors = validationErrors.concat(errors);

View File

@ -47,7 +47,7 @@ class ExploreViewContainer extends React.Component {
} }
componentDidUpdate() { componentDidUpdate() {
if (this.props.triggerQuery) { if (this.props.triggerQuery && !this.hasErrors()) {
this.runQuery(); this.runQuery();
} }
} }
@ -95,6 +95,10 @@ class ExploreViewContainer extends React.Component {
toggleModal() { toggleModal() {
this.setState({ showModal: !this.state.showModal }); this.setState({ showModal: !this.state.showModal });
} }
hasErrors() {
const ctrls = this.props.controls;
return Object.keys(ctrls).some(k => ctrls[k].validationErrors.length > 0);
}
renderErrorMessage() { renderErrorMessage() {
// Returns an error message as a node if any errors are in the store // Returns an error message as a node if any errors are in the store
const errors = []; const errors = [];

View File

@ -9,7 +9,7 @@ const propTypes = {
onSave: PropTypes.func, onSave: PropTypes.func,
onStop: PropTypes.func, onStop: PropTypes.func,
loading: PropTypes.bool, loading: PropTypes.bool,
errorMessage: PropTypes.string, errorMessage: PropTypes.node,
}; };
const defaultProps = { const defaultProps = {
@ -37,6 +37,7 @@ export default function QueryAndSaveBtns(
className="query" className="query"
onClick={onQuery} onClick={onQuery}
bsStyle={qryButtonStyle} bsStyle={qryButtonStyle}
disabled={!!errorMessage}
> >
<i className="fa fa-bolt" /> Query <i className="fa fa-bolt" /> Query
</Button> </Button>

View File

@ -29,7 +29,7 @@ import { exploreReducer } from './reducers/exploreReducer';
// Initial state // Initial state
const bootstrappedState = Object.assign( const bootstrappedState = Object.assign(
bootstrapData, { bootstrapData, {
chartStatus: 'loading', chartStatus: null,
chartUpdateEndTime: null, chartUpdateEndTime: null,
chartUpdateStartTime: now(), chartUpdateStartTime: now(),
dashboards: [], dashboards: [],

View File

@ -255,10 +255,6 @@ const visTypes = {
}, },
], ],
controlOverrides: { controlOverrides: {
metrics: {
default: null,
validators: null,
},
time_grain_sqla: { time_grain_sqla: {
default: null, default: null,
}, },

View File

@ -112,7 +112,7 @@ class BaseViz(object):
"""Building a query object""" """Building a query object"""
form_data = self.form_data form_data = self.form_data
groupby = form_data.get("groupby") or [] groupby = form_data.get("groupby") or []
metrics = form_data.get("metrics") or ['count'] metrics = form_data.get("metrics") or []
# extra_filters are temporary/contextual filters that are external # extra_filters are temporary/contextual filters that are external
# to the slice definition. We use those for dynamic interactive # to the slice definition. We use those for dynamic interactive