mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
Added Alert for ControlPanel and ChartContainer (#1626)
* 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
This commit is contained in:
parent
0acf26b37c
commit
a8480f5492
@ -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) {
|
||||
@ -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'));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -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) {
|
||||
@ -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 };
|
||||
}
|
||||
|
@ -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';
|
||||
@ -24,6 +24,7 @@ const propTypes = {
|
||||
data: PropTypes.any,
|
||||
isChartLoading: PropTypes.bool,
|
||||
isStarred: PropTypes.bool.isRequired,
|
||||
alert: PropTypes.string,
|
||||
};
|
||||
|
||||
class ChartContainer extends React.Component {
|
||||
@ -139,6 +140,9 @@ class ChartContainer extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
removeAlert() {
|
||||
this.props.actions.removeChartAlert();
|
||||
}
|
||||
|
||||
renderVis() {
|
||||
visMap[this.props.viz_type](this.state.mockSlice).render();
|
||||
@ -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}
|
||||
@ -213,6 +227,7 @@ function mapStateToProps(state) {
|
||||
data: state.viz.data,
|
||||
isChartLoading: state.isChartLoading,
|
||||
isStarred: state.isStarred,
|
||||
alert: state.chartAlert,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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';
|
||||
@ -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 {
|
||||
@ -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">
|
||||
@ -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,
|
||||
|
@ -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() {
|
||||
@ -85,6 +88,7 @@ class ExploreViewContainer extends React.Component {
|
||||
<ChartContainer
|
||||
actions={this.props.actions}
|
||||
height={this.state.height}
|
||||
actions={this.props.actions}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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;
|
||||
@ -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) {
|
||||
|
@ -1294,16 +1294,20 @@ class Superset(BaseSupersetView):
|
||||
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>/")
|
||||
|
Loading…
Reference in New Issue
Block a user