mirror of https://github.com/apache/superset.git
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:
parent
699602d1c5
commit
9f7486f402
|
@ -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';
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue