remove extra call to get_viz in explorev2 (#1812)

* Not working errors

* Remove update_explore endpoint, only update explore endpoints in reducer on query

* Change scroll to auto and make container reponse to height:

* Remove update_explore endpoint

* Remove can_update_explore perm
This commit is contained in:
vera-liu 2016-12-12 10:58:07 -08:00 committed by GitHub
parent 699602d1c5
commit 9f7486f402
8 changed files with 84 additions and 116 deletions

View File

@ -98,41 +98,24 @@ export function setFieldValue(datasource_type, key, value, label) {
return { type: SET_FIELD_VALUE, datasource_type, key, value, label };
}
export const UPDATE_CHART = 'UPDATE_CHART';
export function updateChart(viz) {
return { type: UPDATE_CHART, viz };
}
export const CHART_UPDATE_STARTED = 'CHART_UPDATE_STARTED';
export function chartUpdateStarted() {
return { type: CHART_UPDATE_STARTED };
}
export const CHART_UPDATE_FAILED = 'CHART_UPDATE_FAILED ';
export const CHART_UPDATE_SUCCEEDED = 'CHART_UPDATE_SUCCEEDED';
export function chartUpdateSucceeded(query) {
return { type: CHART_UPDATE_SUCCEEDED, query };
}
export const CHART_UPDATE_FAILED = 'CHART_UPDATE_FAILED';
export function chartUpdateFailed(error) {
return { type: CHART_UPDATE_FAILED, error };
}
export function updateExplore(datasource_type, datasource_id, form_data) {
return function (dispatch) {
dispatch(chartUpdateStarted());
const updateUrl =
`/superset/update_explore/${datasource_type}/${datasource_id}/`;
$.ajax({
type: 'POST',
url: updateUrl,
data: {
data: JSON.stringify(form_data),
},
success: (data) => {
dispatch(updateChart(JSON.parse(data)));
},
error(error) {
dispatch(chartUpdateFailed(error.responseJSON.error));
},
});
};
export const UPDATE_EXPLORE_ENDPOINTS = 'UPDATE_EXPLORE_ENDPOINTS';
export function updateExploreEndpoints(jsonUrl, csvUrl, standaloneUrl) {
return { type: UPDATE_EXPLORE_ENDPOINTS, jsonUrl, csvUrl, standaloneUrl };
}
export const REMOVE_CONTROL_PANEL_ALERT = 'REMOVE_CONTROL_PANEL_ALERT';

View File

@ -26,13 +26,13 @@ const propTypes = {
json_endpoint: PropTypes.string.isRequired,
csv_endpoint: PropTypes.string.isRequired,
standalone_endpoint: PropTypes.string.isRequired,
query: PropTypes.string.isRequired,
query: PropTypes.string,
column_formats: PropTypes.object,
data: PropTypes.any,
chartStatus: PropTypes.bool,
chartStatus: PropTypes.string,
isStarred: PropTypes.bool.isRequired,
chartUpdateStartTime: PropTypes.string.isRequired,
chartUpdateEndTime: PropTypes.string.isRequired,
chartUpdateStartTime: PropTypes.number.isRequired,
chartUpdateEndTime: PropTypes.number,
alert: PropTypes.string,
table_name: PropTypes.string,
};
@ -55,7 +55,15 @@ class ChartContainer extends React.Component {
}
componentWillReceiveProps(nextProps) {
this.setState({ mockSlice: this.getMockedSliceObject(nextProps) });
if (nextProps.chartStatus !== this.props.chartStatus
|| nextProps.height !== this.props.height) {
this.setState({ mockSlice: this.getMockedSliceObject(nextProps) });
}
}
shouldComponentUpdate(nextProps) {
return (nextProps.chartStatus !== this.props.chartStatus
|| nextProps.height !== this.props.height);
}
componentDidUpdate() {
@ -114,8 +122,10 @@ class ChartContainer extends React.Component {
{}
),
done: () => {
done: (payload) => {
// finished rendering callback
// Todo: end timer and chartLoading set to success
props.actions.chartUpdateSucceeded(payload.query);
},
clearError: () => {
@ -166,16 +176,19 @@ class ChartContainer extends React.Component {
</Alert>
);
}
if (this.props.chartStatus === 'loading') {
return (<img alt="loading" width="25" src="/static/assets/images/loading.gif" />);
}
const loading = this.props.chartStatus === 'loading';
return (
<div
id={this.props.containerId}
ref={(ref) => { this.chartContainerRef = ref; }}
className={this.props.viz_type}
style={{ overflowX: 'scroll' }}
/>
<div>
{loading &&
<img alt="loading" width="25" src="/static/assets/images/loading.gif" />
}
<div
id={this.props.containerId}
ref={(ref) => { this.chartContainerRef = ref; }}
className={this.props.viz_type}
style={{ overflowX: 'auto' }}
/>
</div>
);
}
@ -219,7 +232,7 @@ class ChartContainer extends React.Component {
endTime={this.props.chartUpdateEndTime}
isRunning={this.props.chartStatus === 'loading'}
state={CHART_STATUS_MAP[this.props.chartStatus]}
style={{ 'font-size': '10px', 'margin-right': '5px' }}
style={{ fontSize: '10px', marginRight: '5px' }}
/>
<ExploreActionButtons
slice={this.state.mockSlice}

View File

@ -8,9 +8,7 @@ import ControlPanelsContainer from './ControlPanelsContainer';
import SaveModal from './SaveModal';
import QueryAndSaveBtns from '../../explore/components/QueryAndSaveBtns';
import { autoQueryFields } from '../stores/fields';
import { getParamObject } from '../exploreUtils';
const $ = require('jquery');
import { getExploreUrl } from '../exploreUtils';
const propTypes = {
form_data: React.PropTypes.object.isRequired,
@ -48,11 +46,12 @@ class ExploreViewContainer extends React.Component {
}
onQuery(form_data) {
const data = getParamObject(form_data, this.props.datasource_type);
this.queryFormData(data);
const params = $.param(data, true);
this.updateUrl(params);
this.props.actions.chartUpdateStarted();
history.pushState(
{},
document.title,
getExploreUrl(form_data, this.props.datasource_type)
);
// remove alerts when query
this.props.actions.removeControlPanelAlert();
this.props.actions.removeChartAlert();
@ -63,17 +62,6 @@ class ExploreViewContainer extends React.Component {
return `${window.innerHeight - navHeight}px`;
}
updateUrl(params) {
const baseUrl =
`/superset/explore/${this.props.datasource_type}/${this.props.form_data.datasource}/`;
const newEndpoint = `${baseUrl}?${params}`;
history.pushState({}, document.title, newEndpoint);
}
queryFormData(data) {
this.props.actions.updateExplore(
this.props.datasource_type, this.props.form_data.datasource, data);
}
handleResize() {
this.setState({ height: this.getHeight() });
}
@ -119,7 +107,6 @@ class ExploreViewContainer extends React.Component {
<ChartContainer
actions={this.props.actions}
height={this.state.height}
actions={this.props.actions}
/>
</div>
</div>

View File

@ -1,4 +1,5 @@
/* eslint camelcase: 0 */
const $ = require('jquery');
function formatFilters(filters) {
// outputs an object of url params of filters
// prefix can be 'flt' or 'having'
@ -22,7 +23,7 @@ export function getParamObject(form_data, datasource_type, saveNewSlice) {
};
Object.keys(form_data).forEach((field) => {
// filter out null fields
if (form_data[field] !== null && field !== 'datasource'
if (form_data[field] !== null && field !== 'datasource' && field !== 'filters'
&& !(saveNewSlice && field === 'slice_name')) {
data[field] = form_data[field];
}
@ -31,3 +32,21 @@ export function getParamObject(form_data, datasource_type, saveNewSlice) {
Object.assign(data, filterParams);
return data;
}
export function getExploreUrl(form_data, datasource_type, endpoint = 'base') {
const data = getParamObject(form_data, datasource_type);
const params = `${datasource_type}/` +
`${form_data.datasource}/?${$.param(data, true)}`;
switch (endpoint) {
case 'base':
return `/superset/explore/${params}`;
case 'json':
return `/superset/explore_json/${params}`;
case 'csv':
return `/superset/explore/${params}&csv=true`;
case 'standalone':
return `/superset/explore/${params}&standalone=true`;
default:
return `/superset/explore/${params}`;
}
}

View File

@ -1,7 +1,9 @@
/* eslint camelcase: 0 */
import { defaultFormData } from '../stores/store';
import * as actions from '../actions/exploreActions';
import { addToArr, removeFromArr, alterInArr } from '../../../utils/reducerUtils';
import { now } from '../../modules/dates';
import { getExploreUrl } from '../exploreUtils';
export const exploreReducer = function (state, action) {
const actionHandlers = {
@ -105,29 +107,35 @@ export const exploreReducer = function (state, action) {
{ viz: Object.assign({}, state.viz, { form_data: newFormData }) }
);
},
[actions.UPDATE_CHART]() {
[actions.CHART_UPDATE_SUCCEEDED]() {
const vizUpdates = {
column_formats: action.viz.column_formats,
json_endpoint: action.viz.json_endpoint,
csv_endpoint: action.viz.csv_endpoint,
standalone_endpoint: action.viz.standalone_endpoint,
query: action.viz.query,
data: action.viz.data,
query: action.query,
};
const chartUpdateEndTime = now();
return Object.assign(
{},
state,
{
viz: Object.assign({}, state.viz, vizUpdates),
chartStatus: 'success',
chartUpdateEndTime,
viz: Object.assign({}, state.viz, vizUpdates),
});
},
[actions.CHART_UPDATE_STARTED]() {
const chartUpdateStartTime = now();
const form_data = Object.assign({}, state.viz.form_data);
const datasource_type = state.datasource_type;
const vizUpdates = {
json_endpoint: getExploreUrl(form_data, datasource_type, 'json'),
csv_endpoint: getExploreUrl(form_data, datasource_type, 'csv'),
standalone_endpoint:
getExploreUrl(form_data, datasource_type, 'standalone'),
};
return Object.assign({}, state,
{ chartStatus: 'loading', chartUpdateEndTime: null, chartUpdateStartTime });
{
chartStatus: 'loading',
chartUpdateEndTime: null,
chartUpdateStartTime,
viz: Object.assign({}, state.viz, vizUpdates),
});
},
[actions.CHART_UPDATE_FAILED]() {
const chartUpdateEndTime = now();

View File

@ -1364,28 +1364,6 @@ class Superset(BaseSupersetView):
viz_obj = self.get_viz(slice_id)
return redirect(viz_obj.get_url(**request.args))
@log_this
@has_access_api
@expose(
"/update_explore/<datasource_type>/<datasource_id>/", methods=['POST'])
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'))
try:
viz_obj = self.get_viz(
datasource_type=datasource_type,
datasource_id=datasource_id,
args=form_data)
except Exception as e:
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>/")
def explore_json(self, datasource_type, datasource_id):

View File

@ -265,7 +265,6 @@ class SupersetTestCase(unittest.TestCase):
self.assertIn(('can_fave_slices', 'Superset'), gamma_perm_set)
self.assertIn(('can_save_dash', 'Superset'), gamma_perm_set)
self.assertIn(('can_slice', 'Superset'), gamma_perm_set)
self.assertIn(('can_update_explore', 'Superset'), gamma_perm_set)

View File

@ -95,25 +95,6 @@ class CoreTests(SupersetTestCase):
assert_admin_view_menus_in('Alpha', self.assertNotIn)
assert_admin_view_menus_in('Gamma', self.assertNotIn)
def test_update_explore(self):
self.login(username='admin')
tbl_id = self.table_ids.get('energy_usage')
data = json.dumps({
'viz_type': 'sankey',
'groupby': ['source', 'target'],
'metrics': ['sum__value'],
'row_limit': 5000,
'flt_col_0': 'source',
'datasource_name': 'energy_usage',
'datasource_id': tbl_id,
'datasource_type': 'table',
'previous_viz_type': 'sankey'
})
response = self.client.post('/superset/update_explore/table/{}/'.format(tbl_id),
data=dict(data=data))
assert response.status_code == 200
self.logout()
def test_save_slice(self):
self.login(username='admin')
slice_name = "Energy Sankey"