You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by gr...@apache.org on 2020/03/09 02:51:31 UTC
[incubator-superset] branch master updated: [log] Add dashboard_id
param to explore_json request (#9243)
This is an automated email from the ASF dual-hosted git repository.
graceguo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new 8bc30da [log] Add dashboard_id param to explore_json request (#9243)
8bc30da is described below
commit 8bc30da6211df67ee8bec21e160ce587817ba85b
Author: Grace Guo <gr...@airbnb.com>
AuthorDate: Sun Mar 8 19:51:08 2020 -0700
[log] Add dashboard_id param to explore_json request (#9243)
* [log] Add dashboard_id param to explore_json request
* fix cypress test
---
.../cypress/integration/dashboard/edit_mode.js | 3 +-
.../cypress/integration/dashboard/filter.js | 6 ++--
.../cypress/integration/dashboard/load.js | 8 ++++--
.../cypress/integration/dashboard/save.js | 4 +--
.../cypress/integration/dashboard/tabs.js | 10 ++++---
.../cypress/integration/dashboard/url_params.js | 4 ++-
superset-frontend/src/chart/Chart.jsx | 5 ++++
superset-frontend/src/chart/chartAction.js | 32 ++++++++++++++++++----
.../src/dashboard/actions/dashboardState.js | 16 +++++++++--
.../src/dashboard/components/Header.jsx | 15 ++++++++--
.../src/dashboard/components/SliceHeader.jsx | 3 ++
.../dashboard/components/SliceHeaderControls.jsx | 6 +++-
.../dashboard/components/gridComponents/Chart.jsx | 10 ++++++-
.../components/gridComponents/ChartHolder.jsx | 3 ++
.../dashboard/containers/DashboardComponent.jsx | 4 ++-
15 files changed, 101 insertions(+), 28 deletions(-)
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.js b/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.js
index c279cc5..913609c 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/edit_mode.js
@@ -28,11 +28,12 @@ export default () =>
cy.get('#app').then(data => {
const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
const dashboard = bootstrapData.dashboard_data;
+ const dashboardId = dashboard.id;
const boxplotChartId = dashboard.slices.find(
slice => slice.form_data.viz_type === 'box_plot',
).slice_id;
const formData = `{"slice_id":${boxplotChartId}}`;
- const boxplotRequest = `/superset/explore_json/?form_data=${formData}`;
+ const boxplotRequest = `/superset/explore_json/?form_data=${formData}&dashboard_id=${dashboardId}`;
cy.route('POST', boxplotRequest).as('boxplotRequest');
});
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/filter.js b/superset-frontend/cypress-base/cypress/integration/dashboard/filter.js
index 6da7de2..c219796 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/filter.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/filter.js
@@ -22,6 +22,7 @@ export default () =>
describe('dashboard filter', () => {
let sliceIds = [];
let filterId;
+ let dashboardId;
beforeEach(() => {
cy.server();
@@ -32,6 +33,7 @@ export default () =>
cy.get('#app').then(data => {
const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
const dashboard = bootstrapData.dashboard_data;
+ dashboardId = dashboard.id;
sliceIds = dashboard.slices.map(slice => slice.slice_id);
filterId = dashboard.slices.find(
slice => slice.form_data.viz_type === 'filter_box',
@@ -43,7 +45,7 @@ export default () =>
const aliases = [];
const formData = `{"slice_id":${filterId}}`;
- const filterRoute = `/superset/explore_json/?form_data=${formData}`;
+ const filterRoute = `/superset/explore_json/?form_data=${formData}&dashboard_id=${dashboardId}`;
cy.route('POST', filterRoute).as('fetchFilter');
cy.wait('@fetchFilter');
sliceIds
@@ -54,7 +56,7 @@ export default () =>
cy.route(
'POST',
- `/superset/explore_json/?form_data={"slice_id":${id}}`,
+ `/superset/explore_json/?form_data={"slice_id":${id}}&dashboard_id=${dashboardId}`,
).as(alias);
});
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/load.js b/superset-frontend/cypress-base/cypress/integration/dashboard/load.js
index 6050cbf..5cb64fe 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/load.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/load.js
@@ -31,14 +31,16 @@ export default () =>
cy.get('#app').then(data => {
const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
+ const dashboardId = bootstrapData.dashboard_data.id;
const slices = bootstrapData.dashboard_data.slices;
// then define routes and create alias for each requests
slices.forEach(slice => {
const alias = `getJson_${slice.slice_id}`;
const formData = `{"slice_id":${slice.slice_id}}`;
- cy.route('POST', `/superset/explore_json/?form_data=${formData}`).as(
- alias,
- );
+ cy.route(
+ 'POST',
+ `/superset/explore_json/?form_data=${formData}&dashboard_id=${dashboardId}`,
+ ).as(alias);
aliases.push(`@${alias}`);
});
});
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/save.js b/superset-frontend/cypress-base/cypress/integration/dashboard/save.js
index 263fd8a..03dec46 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/save.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/save.js
@@ -60,11 +60,9 @@ export default () =>
});
it('should save/overwrite dashboard', () => {
- cy.wait('@copyRequest');
-
// should have box_plot chart
const formData = `{"slice_id":${boxplotChartId}}`;
- const boxplotRequest = `/superset/explore_json/?form_data=${formData}`;
+ const boxplotRequest = `/superset/explore_json/?form_data=${formData}&dashboard_id=${dashboardId}`;
cy.route('POST', boxplotRequest).as('boxplotRequest');
cy.wait('@boxplotRequest');
cy.get('.grid-container .box_plot').should('be.exist');
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.js b/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.js
index 4a86d3c..51dfa54 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/tabs.js
@@ -24,6 +24,7 @@ export default () =>
let treemapId;
let linechartId;
let boxplotId;
+ let dashboardId;
// cypress can not handle window.scrollTo
// https://github.com/cypress-io/cypress/issues/2761
@@ -43,6 +44,7 @@ export default () =>
cy.get('#app').then(data => {
const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
const dashboard = bootstrapData.dashboard_data;
+ dashboardId = dashboard.id;
filterId = dashboard.slices.find(
slice => slice.form_data.viz_type === 'filter_box',
).slice_id;
@@ -61,7 +63,7 @@ export default () =>
};
const filterRequest = `/superset/explore_json/?form_data=${JSON.stringify(
filterFormdata,
- )}`;
+ )}&dashboard_id=${dashboardId}`;
cy.route('POST', filterRequest).as('filterRequest');
const treemapFormdata = {
@@ -69,7 +71,7 @@ export default () =>
};
const treemapRequest = `/superset/explore_json/?form_data=${JSON.stringify(
treemapFormdata,
- )}`;
+ )}&dashboard_id=${dashboardId}`;
cy.route('POST', treemapRequest).as('treemapRequest');
const linechartFormdata = {
@@ -77,7 +79,7 @@ export default () =>
};
const linechartRequest = `/superset/explore_json/?form_data=${JSON.stringify(
linechartFormdata,
- )}`;
+ )}&dashboard_id=${dashboardId}`;
cy.route('POST', linechartRequest).as('linechartRequest');
const boxplotFormdata = {
@@ -85,7 +87,7 @@ export default () =>
};
const boxplotRequest = `/superset/explore_json/?form_data=${JSON.stringify(
boxplotFormdata,
- )}`;
+ )}&dashboard_id=${dashboardId}`;
cy.route('POST', boxplotRequest).as('boxplotRequest');
});
});
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.js b/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.js
index d7f983e..54b74a6 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.js
@@ -22,6 +22,7 @@ export default () =>
describe('dashboard url params', () => {
const urlParams = { param1: '123', param2: 'abc' };
let sliceIds = [];
+ let dashboardId;
beforeEach(() => {
cy.server();
@@ -32,6 +33,7 @@ export default () =>
cy.get('#app').then(data => {
const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
const dashboard = bootstrapData.dashboard_data;
+ dashboardId = dashboard.id;
sliceIds = dashboard.slices.map(slice => slice.slice_id);
});
});
@@ -43,7 +45,7 @@ export default () =>
aliases.push(`@${alias}`);
cy.route(
'POST',
- `/superset/explore_json/?form_data={"slice_id":${id}}`,
+ `/superset/explore_json/?form_data={"slice_id":${id}}&dashboard_id=${dashboardId}`,
).as(alias);
});
diff --git a/superset-frontend/src/chart/Chart.jsx b/superset-frontend/src/chart/Chart.jsx
index 7a4679c..227b7af 100644
--- a/superset-frontend/src/chart/Chart.jsx
+++ b/superset-frontend/src/chart/Chart.jsx
@@ -34,6 +34,8 @@ const propTypes = {
actions: PropTypes.object,
chartId: PropTypes.number.isRequired,
datasource: PropTypes.object.isRequired,
+ // current chart is included by dashboard
+ dashboardId: PropTypes.number,
// original selected values for FilterBox viz
// so that FilterBox can pre-populate selected values
// only affect UI control
@@ -71,6 +73,7 @@ const defaultProps = {
initialValues: BLANK,
setControlValue() {},
triggerRender: false,
+ dashboardId: null,
};
class Chart extends React.PureComponent {
@@ -101,6 +104,7 @@ class Chart extends React.PureComponent {
false,
this.props.timeout,
this.props.chartId,
+ this.props.dashboardId,
);
} else {
// Create chart with POST request
@@ -109,6 +113,7 @@ class Chart extends React.PureComponent {
false,
this.props.timeout,
this.props.chartId,
+ this.props.dashboardId,
);
}
}
diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js
index 657d0be..c7a125f 100644
--- a/superset-frontend/src/chart/chartAction.js
+++ b/superset-frontend/src/chart/chartAction.js
@@ -207,6 +207,7 @@ export function exploreJSON(
timeout = 60,
key,
method,
+ dashboardId,
) {
return dispatch => {
const { url, payload } = getExploreUrlAndPayload({
@@ -215,6 +216,7 @@ export function exploreJSON(
force,
allowDomainSharding,
method,
+ requestParams: dashboardId ? { dashboard_id: dashboardId } : {},
});
const logStart = Logger.getTimestamp();
const controller = new AbortController();
@@ -308,7 +310,13 @@ export function exploreJSON(
}
export const GET_SAVED_CHART = 'GET_SAVED_CHART';
-export function getSavedChart(formData, force = false, timeout = 60, key) {
+export function getSavedChart(
+ formData,
+ force = false,
+ timeout = 60,
+ key,
+ dashboardId,
+) {
/*
* Perform a GET request to `/explore_json`.
*
@@ -319,18 +327,24 @@ export function getSavedChart(formData, force = false, timeout = 60, key) {
* GET /explore_json?{"chart_id":1,"extra_filters":"..."}
*
*/
- return exploreJSON(formData, force, timeout, key, 'GET');
+ return exploreJSON(formData, force, timeout, key, 'GET', dashboardId);
}
export const POST_CHART_FORM_DATA = 'POST_CHART_FORM_DATA';
-export function postChartFormData(formData, force = false, timeout = 60, key) {
+export function postChartFormData(
+ formData,
+ force = false,
+ timeout = 60,
+ key,
+ dashboardId,
+) {
/*
* Perform a POST request to `/explore_json`.
*
* This will post the form data to the endpoint, returning a new chart.
*
*/
- return exploreJSON(formData, force, timeout, key, 'POST');
+ return exploreJSON(formData, force, timeout, key, 'POST', dashboardId);
}
export function redirectSQLLab(formData) {
@@ -359,7 +373,7 @@ export function redirectSQLLab(formData) {
};
}
-export function refreshChart(chartKey, force) {
+export function refreshChart(chartKey, force, dashboardId) {
return (dispatch, getState) => {
const chart = (getState().charts || {})[chartKey];
const timeout = getState().dashboardInfo.common.conf
@@ -372,7 +386,13 @@ export function refreshChart(chartKey, force) {
return;
}
dispatch(
- postChartFormData(chart.latestQueryFormData, force, timeout, chart.id),
+ postChartFormData(
+ chart.latestQueryFormData,
+ force,
+ timeout,
+ chart.id,
+ dashboardId,
+ ),
);
};
}
diff --git a/superset-frontend/src/dashboard/actions/dashboardState.js b/superset-frontend/src/dashboard/actions/dashboardState.js
index 20bb35d..33737f8 100644
--- a/superset-frontend/src/dashboard/actions/dashboardState.js
+++ b/superset-frontend/src/dashboard/actions/dashboardState.js
@@ -218,10 +218,17 @@ export function saveDashboardRequest(data, id, saveType) {
};
}
-export function fetchCharts(chartList = [], force = false, interval = 0) {
+export function fetchCharts(
+ chartList = [],
+ force = false,
+ interval = 0,
+ dashboardId,
+) {
return (dispatch, getState) => {
if (!interval) {
- chartList.forEach(chartKey => dispatch(refreshChart(chartKey, force)));
+ chartList.forEach(chartKey =>
+ dispatch(refreshChart(chartKey, force, dashboardId)),
+ );
return;
}
@@ -237,7 +244,10 @@ export function fetchCharts(chartList = [], force = false, interval = 0) {
? refreshTime / (chartList.length - 1)
: 0;
chartList.forEach((chartKey, i) => {
- setTimeout(() => dispatch(refreshChart(chartKey, force)), delay * i);
+ setTimeout(
+ () => dispatch(refreshChart(chartKey, force, dashboardId)),
+ delay * i,
+ );
});
};
}
diff --git a/superset-frontend/src/dashboard/components/Header.jsx b/superset-frontend/src/dashboard/components/Header.jsx
index 4c8d014..c889d06 100644
--- a/superset-frontend/src/dashboard/components/Header.jsx
+++ b/superset-frontend/src/dashboard/components/Header.jsx
@@ -194,7 +194,13 @@ class Header extends React.PureComponent {
interval: 0,
chartCount: chartList.length,
});
- return this.props.fetchCharts(chartList, true);
+
+ return this.props.fetchCharts(
+ chartList,
+ true,
+ 0,
+ this.props.dashboardInfo.id,
+ );
}
return false;
}
@@ -212,7 +218,12 @@ class Header extends React.PureComponent {
interval,
chartCount: affectedCharts.length,
});
- return fetchCharts(affectedCharts, true, interval * 0.2);
+ return fetchCharts(
+ affectedCharts,
+ true,
+ interval * 0.2,
+ dashboardInfo.id,
+ );
};
this.refreshTimer = setPeriodicRunner({
diff --git a/superset-frontend/src/dashboard/components/SliceHeader.jsx b/superset-frontend/src/dashboard/components/SliceHeader.jsx
index 3d36a51..a1fb9f3 100644
--- a/superset-frontend/src/dashboard/components/SliceHeader.jsx
+++ b/superset-frontend/src/dashboard/components/SliceHeader.jsx
@@ -44,6 +44,7 @@ const propTypes = {
supersetCanCSV: PropTypes.bool,
sliceCanEdit: PropTypes.bool,
componentId: PropTypes.string.isRequired,
+ dashboardId: PropTypes.number.isRequired,
filters: PropTypes.object.isRequired,
addDangerToast: PropTypes.func.isRequired,
};
@@ -94,6 +95,7 @@ class SliceHeader extends React.PureComponent {
annotationQuery,
annotationError,
componentId,
+ dashboardId,
addDangerToast,
} = this.props;
@@ -145,6 +147,7 @@ class SliceHeader extends React.PureComponent {
supersetCanCSV={supersetCanCSV}
sliceCanEdit={sliceCanEdit}
componentId={componentId}
+ dashboardId={dashboardId}
addDangerToast={addDangerToast}
/>
)}
diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx
index 779609d..6bd5061 100644
--- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx
+++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx
@@ -28,6 +28,7 @@ import { getActiveFilters } from '../util/activeDashboardFilters';
const propTypes = {
slice: PropTypes.object.isRequired,
componentId: PropTypes.string.isRequired,
+ dashboardId: PropTypes.number.isRequired,
addDangerToast: PropTypes.func.isRequired,
isCached: PropTypes.bool,
isExpanded: PropTypes.bool,
@@ -91,7 +92,10 @@ class SliceHeaderControls extends React.PureComponent {
refreshChart() {
if (this.props.updatedDttm) {
- this.props.forceRefresh(this.props.slice.slice_id);
+ this.props.forceRefresh(
+ this.props.slice.slice_id,
+ this.props.dashboardId,
+ );
}
}
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
index 02932ca..b399528 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
@@ -36,6 +36,7 @@ import getFilterValuesByFilterId from '../../util/getFilterValuesByFilterId';
const propTypes = {
id: PropTypes.number.isRequired,
componentId: PropTypes.string.isRequired,
+ dashboardId: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
updateSliceName: PropTypes.func.isRequired,
@@ -205,13 +206,18 @@ class Chart extends React.Component {
slice_id: this.props.slice.slice_id,
is_cached: this.props.isCached,
});
- return this.props.refreshChart(this.props.chart.id, true);
+ return this.props.refreshChart(
+ this.props.chart.id,
+ true,
+ this.props.dashboardId,
+ );
}
render() {
const {
id,
componentId,
+ dashboardId,
chart,
slice,
datasource,
@@ -269,6 +275,7 @@ class Chart extends React.Component {
supersetCanCSV={supersetCanCSV}
sliceCanEdit={sliceCanEdit}
componentId={componentId}
+ dashboardId={dashboardId}
filters={filters}
addDangerToast={addDangerToast}
/>
@@ -306,6 +313,7 @@ class Chart extends React.Component {
chartId={id}
chartStatus={chart.chartStatus}
datasource={datasource}
+ dashboardId={dashboardId}
initialValues={initialValues}
formData={formData}
queryResponse={chart.queryResponse}
diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
index a3cf5c1..85d5fdf 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
@@ -42,6 +42,7 @@ const CHART_MARGIN = 32;
const propTypes = {
id: PropTypes.string.isRequired,
parentId: PropTypes.string.isRequired,
+ dashboardId: PropTypes.number.isRequired,
component: componentShape.isRequired,
parentComponent: componentShape.isRequired,
index: PropTypes.number.isRequired,
@@ -175,6 +176,7 @@ class ChartHolder extends React.Component {
handleComponentDrop,
editMode,
isComponentVisible,
+ dashboardId,
} = this.props;
// inherit the size of parent columns
@@ -228,6 +230,7 @@ class ChartHolder extends React.Component {
<Chart
componentId={component.id}
id={component.meta.chartId}
+ dashboardId={dashboardId}
width={Math.floor(
widthMultiple * columnWidth +
(widthMultiple - 1) * GRID_GUTTER_SIZE -
diff --git a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
index d1e2b8d..dd2c188 100644
--- a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
+++ b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
@@ -46,6 +46,7 @@ const propTypes = {
logEvent: PropTypes.func.isRequired,
directPathToChild: PropTypes.arrayOf(PropTypes.string),
directPathLastUpdated: PropTypes.number,
+ dashboardId: PropTypes.number.isRequired,
};
const defaultProps = {
@@ -55,7 +56,7 @@ const defaultProps = {
};
function mapStateToProps(
- { dashboardLayout: undoableLayout, dashboardState },
+ { dashboardLayout: undoableLayout, dashboardState, dashboardInfo },
ownProps,
) {
const dashboardLayout = undoableLayout.present;
@@ -68,6 +69,7 @@ function mapStateToProps(
filters: getActiveFilters(),
directPathToChild: dashboardState.directPathToChild,
directPathLastUpdated: dashboardState.directPathLastUpdated,
+ dashboardId: dashboardInfo.id,
filterFieldOnFocus:
dashboardState.focusedFilterField.length === 0
? {}