diff --git a/superset/assets/javascripts/components/InfoTooltipWithTrigger.jsx b/superset/assets/javascripts/components/InfoTooltipWithTrigger.jsx index 709a216da40..3a097a8b5b2 100644 --- a/superset/assets/javascripts/components/InfoTooltipWithTrigger.jsx +++ b/superset/assets/javascripts/components/InfoTooltipWithTrigger.jsx @@ -10,6 +10,7 @@ const propTypes = { className: PropTypes.string, onClick: PropTypes.func, placement: PropTypes.string, + bsStyle: PropTypes.string, }; const defaultProps = { icon: 'info-circle', @@ -18,14 +19,15 @@ const defaultProps = { }; export default function InfoTooltipWithTrigger({ - label, tooltip, icon, className, onClick, placement }) { + label, tooltip, icon, className, onClick, placement, bsStyle }) { + const iconClass = `fa fa-${icon} ${className} ${bsStyle ? 'text-' + bsStyle : ''}`; return ( {tooltip}} > diff --git a/superset/assets/javascripts/explore/components/ControlPanelSection.jsx b/superset/assets/javascripts/explore/components/ControlPanelSection.jsx index c3fa9ddb799..7992fa6f8f2 100644 --- a/superset/assets/javascripts/explore/components/ControlPanelSection.jsx +++ b/superset/assets/javascripts/explore/components/ControlPanelSection.jsx @@ -8,12 +8,14 @@ const propTypes = { description: PropTypes.string, children: PropTypes.node.isRequired, startExpanded: PropTypes.bool, + hasErrors: PropTypes.bool, }; const defaultProps = { label: null, description: null, startExpanded: false, + hasErrors: false, }; export default class ControlPanelSection extends React.Component { @@ -25,10 +27,9 @@ export default class ControlPanelSection extends React.Component { this.setState({ expanded: !this.state.expanded }); } renderHeader() { - const { label, description } = this.props; - let header; - if (label) { - header = ( + const { label, description, hasErrors } = this.props; + return ( + label &&
{label} {' '} {description && } -
- ); - } - return header; + {hasErrors && + + } + ); } render() { diff --git a/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx b/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx index d9e9d6c3145..dfa958c5088 100644 --- a/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx +++ b/superset/assets/javascripts/explore/components/ControlPanelsContainer.jsx @@ -50,6 +50,7 @@ class ControlPanelsContainer extends React.Component { this.props.actions.removeControlPanelAlert(); } render() { + const ctrls = this.props.controls; return (
@@ -63,33 +64,39 @@ class ControlPanelsContainer extends React.Component { /> } - {this.sectionsToRender().map(section => ( - - {section.controlSetRows.map((controlSets, i) => ( - ( - controlName && - this.props.controls[controlName] && - - ))} - /> - ))} - - ))} + {this.sectionsToRender().map((section) => { + const hasErrors = section.controlSetRows.some(rows => rows.some((s) => { + const errors = ctrls[s].validationErrors; + return errors && (errors.length > 0); + })); + return ( + + {section.controlSetRows.map((controlSets, i) => ( + ( + controlName && + ctrls[controlName] && + + ))} + /> + ))} + ); + })}
);