Skip to content

Commit

Permalink
Added Alert for ControlPanel and ChartContainer (apache#1626)
Browse files Browse the repository at this point in the history
* Added Alert for ControlPanel and ChartContainer

Done:
 - Add alert for Control Panel when fetch_datasource_metadata failes
 - Add alert for Chart Container when update_explore query fails

* Changed color to warning-yellow

* Solve linter issue

* Fixed indent and delete error_redirect
  • Loading branch information
vera-liu authored Nov 18, 2016
1 parent 0acf26b commit a8480f5
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 22 deletions.
36 changes: 23 additions & 13 deletions superset/assets/javascripts/explorev2/actions/exploreActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export function fetchSucceeded() {
}

export const FETCH_FAILED = 'FETCH_FAILED';
export function fetchFailed() {
return { type: FETCH_FAILED };
export function fetchFailed(error) {
return { type: FETCH_FAILED, error };
}

export function fetchFieldOptions(datasourceId, datasourceType) {
Expand All @@ -35,18 +35,19 @@ export function fetchFieldOptions(datasourceId, datasourceType) {
if (datasourceId) {
const params = [`datasource_id=${datasourceId}`, `datasource_type=${datasourceType}`];
const url = '/superset/fetch_datasource_metadata?' + params.join('&');

$.get(url, (data, status) => {
if (status === 'success') {
// populate options for select type fields
$.ajax({
type: 'GET',
url,
success: (data) => {
dispatch(setFieldOptions(data.field_options));
dispatch(fetchSucceeded());
} else if (status === 'error') {
dispatch(fetchFailed());
}
},
error(error) {
dispatch(fetchFailed(error.responseJSON.error));
},
});
} else {
// in what case don't we have a datasource id?
dispatch(fetchFailed('Please select a datasource'));
}
};
}
Expand Down Expand Up @@ -119,8 +120,8 @@ export function chartUpdateStarted() {
}

export const CHART_UPDATE_FAILED = 'CHART_UPDATE_FAILED ';
export function chartUpdateFailed() {
return { type: CHART_UPDATE_FAILED };
export function chartUpdateFailed(error) {
return { type: CHART_UPDATE_FAILED, error };
}

export function updateExplore(datasource_type, datasource_id, form_data) {
Expand All @@ -139,9 +140,18 @@ export function updateExplore(datasource_type, datasource_id, form_data) {
dispatch(updateChart(JSON.parse(data)));
},
error(error) {
dispatch(chartUpdateFailed(error));
dispatch(chartUpdateFailed(error.responseJSON.error));
},
});
};
}

export const REMOVE_CONTROL_PANEL_ALERT = 'REMOVE_CONTROL_PANEL_ALERT';
export function removeControlPanelAlert() {
return { type: REMOVE_CONTROL_PANEL_ALERT };
}

export const REMOVE_CHART_ALERT = 'REMOVE_CHART_ALERT';
export function removeChartAlert() {
return { type: REMOVE_CHART_ALERT };
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import $ from 'jquery';
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { Panel } from 'react-bootstrap';
import { Panel, Alert } from 'react-bootstrap';
import visMap from '../../../visualizations/main';
import { d3format } from '../../modules/utils';
import ExploreActionButtons from '../../explore/components/ExploreActionButtons';
Expand All @@ -24,6 +24,7 @@ const propTypes = {
data: PropTypes.any,
isChartLoading: PropTypes.bool,
isStarred: PropTypes.bool.isRequired,
alert: PropTypes.string,
};

class ChartContainer extends React.Component {
Expand Down Expand Up @@ -139,6 +140,9 @@ class ChartContainer extends React.Component {
};
}

removeAlert() {
this.props.actions.removeChartAlert();
}

renderVis() {
visMap[this.props.viz_type](this.state.mockSlice).render();
Expand Down Expand Up @@ -183,6 +187,16 @@ class ChartContainer extends React.Component {
</div>
}
>
{this.props.alert &&
<Alert bsStyle="warning">
{this.props.alert}
<i
className="fa fa-close pull-right"
onClick={this.removeAlert.bind(this)}
style={{ cursor: 'pointer' }}
/>
</Alert>
}
{!this.props.isChartLoading &&
<div
id={this.props.containerId}
Expand Down Expand Up @@ -213,6 +227,7 @@ function mapStateToProps(state) {
data: state.viz.data,
isChartLoading: state.isChartLoading,
isStarred: state.isStarred,
alert: state.chartAlert,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import { connect } from 'react-redux';
import { Panel } from 'react-bootstrap';
import { Panel, Alert } from 'react-bootstrap';
import { visTypes, commonControlPanelSections } from '../stores/store';
import ControlPanelSection from './ControlPanelSection';
import FieldSetRow from './FieldSetRow';
Expand All @@ -15,6 +15,7 @@ const propTypes = {
isDatasourceMetaLoading: PropTypes.bool.isRequired,
form_data: PropTypes.object.isRequired,
y_axis_zero: PropTypes.any,
alert: PropTypes.string,
};

class ControlPanelsContainer extends React.Component {
Expand Down Expand Up @@ -53,10 +54,23 @@ class ControlPanelsContainer extends React.Component {
const viz = visTypes[this.props.form_data.viz_type];
return viz.fieldOverrides;
}
removeAlert() {
this.props.actions.removeControlPanelAlert();
}

render() {
return (
<Panel>
{this.props.alert &&
<Alert bsStyle="warning">
{this.props.alert}
<i
className="fa fa-close pull-right"
onClick={this.removeAlert.bind(this)}
style={{ cursor: 'pointer' }}
/>
</Alert>
}
{!this.props.isDatasourceMetaLoading &&
<div className="scrollbar-container">
<div className="scrollbar-content">
Expand Down Expand Up @@ -91,6 +105,7 @@ ControlPanelsContainer.propTypes = propTypes;

function mapStateToProps(state) {
return {
alert: state.controlPanelAlert,
isDatasourceMetaLoading: state.isDatasourceMetaLoading,
fields: state.fields,
datasource_type: state.datasource_type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class ExploreViewContainer extends React.Component {

const params = $.param(data, true);
this.updateUrl(params);
// remove alerts when query
this.props.actions.removeControlPanelAlert();
this.props.actions.removeChartAlert();
}

getHeight() {
Expand Down Expand Up @@ -85,6 +88,7 @@ class ExploreViewContainer extends React.Component {
<ChartContainer
actions={this.props.actions}
height={this.state.height}
actions={this.props.actions}
/>
</div>
</div>
Expand Down
15 changes: 12 additions & 3 deletions superset/assets/javascripts/explorev2/reducers/exploreReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ export const exploreReducer = function (state, action) {

[actions.FETCH_FAILED]() {
// todo(alanna) handle failure/error state
return Object.assign({}, state, { isDatasourceMetaLoading: false });
return Object.assign({}, state,
{
isDatasourceMetaLoading: false,
controlPanelAlert: action.error,
});
},
[actions.REMOVE_CONTROL_PANEL_ALERT]() {
return Object.assign({}, state, { controlPanelAlert: null });
},

[actions.SET_FIELD_OPTIONS]() {
const newState = Object.assign({}, state);
const optionsByFieldName = action.options;
Expand Down Expand Up @@ -88,7 +94,10 @@ export const exploreReducer = function (state, action) {
return Object.assign({}, state, { isChartLoading: true });
},
[actions.CHART_UPDATE_FAILED]() {
return Object.assign({}, state, { isChartLoading: false });
return Object.assign({}, state, { isChartLoading: false, chartAlert: action.error });
},
[actions.REMOVE_CHART_ALERT]() {
return Object.assign({}, state, { chartAlert: null });
},
};
if (action.type in actionHandlers) {
Expand Down
12 changes: 8 additions & 4 deletions superset/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1294,16 +1294,20 @@ def slice(self, slice_id):
def update_explore(self, datasource_type, datasource_id):
"""Send back new viz on POST request for updating update explore view"""
form_data = json.loads(request.form.get('data'))
error_redirect = '/slicemodelview/list/'
try:
viz_obj = self.get_viz(
datasource_type=datasource_type,
datasource_id=datasource_id,
args=form_data)
except Exception as e:
flash('{}'.format(e), "alert")
return redirect(error_redirect)
return viz_obj.get_json()
logging.exception(e)
return json_error_response('{}'.format(e))
try:
viz_json = viz_obj.get_json()
except Exception as e:
logging.exception(e)
return json_error_response(utils.error_msg_from_exception(e))
return viz_json

@has_access_api
@expose("/explore_json/<datasource_type>/<datasource_id>/")
Expand Down

0 comments on commit a8480f5

Please sign in to comment.