From 498e9b1f18057a16f4d8726c97db2da4af37cdf0 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Tue, 1 Dec 2020 12:57:44 +0200 Subject: [PATCH 01/17] refactor: add queriesData fields for multiple queries --- superset-frontend/src/chart/Chart.jsx | 19 ++++--- superset-frontend/src/chart/ChartRenderer.jsx | 14 +++-- superset-frontend/src/chart/chartAction.js | 53 +++++++++++-------- superset-frontend/src/chart/chartReducer.js | 10 +++- .../src/dashboard/components/SliceHeader.jsx | 10 +++- .../components/SliceHeaderControls.jsx | 28 +++++++--- .../components/gridComponents/Chart.jsx | 11 ++-- .../src/dashboard/util/propShapes.jsx | 1 + .../explore/components/DisplayQueryButton.jsx | 2 +- .../explore/components/ExploreChartPanel.jsx | 1 + 10 files changed, 97 insertions(+), 52 deletions(-) diff --git a/superset-frontend/src/chart/Chart.jsx b/superset-frontend/src/chart/Chart.jsx index 2636751fd6e1e..a4ce2858383b7 100644 --- a/superset-frontend/src/chart/Chart.jsx +++ b/superset-frontend/src/chart/Chart.jsx @@ -57,6 +57,7 @@ const propTypes = { chartStatus: PropTypes.string, chartStackTrace: PropTypes.string, queryResponse: PropTypes.object, + queriesResponse: PropTypes.arrayOf(PropTypes.object), triggerQuery: PropTypes.bool, refreshOverlayVisible: PropTypes.bool, errorMessage: PropTypes.node, @@ -148,14 +149,8 @@ class Chart extends React.PureComponent { }); } - renderErrorMessage() { - const { - chartAlert, - chartStackTrace, - dashboardId, - owners, - queryResponse, - } = this.props; + renderErrorMessage(queryResponse) { + const { chartAlert, chartStackTrace, dashboardId, owners } = this.props; const error = queryResponse?.errors?.[0]; if (error) { @@ -185,14 +180,18 @@ class Chart extends React.PureComponent { errorMessage, onQuery, refreshOverlayVisible, + queryResponse, + queriesResponse, } = this.props; const isLoading = chartStatus === 'loading'; - const isFaded = refreshOverlayVisible && !errorMessage; this.renderContainerStartTime = Logger.getTimestamp(); if (chartStatus === 'failed') { - return this.renderErrorMessage(); + if (queriesResponse) { + return queriesResponse.map(item => this.renderErrorMessage(item)); + } + return this.renderErrorMessage(queryResponse); } if (errorMessage) { return ( diff --git a/superset-frontend/src/chart/ChartRenderer.jsx b/superset-frontend/src/chart/ChartRenderer.jsx index dce5e754d00d0..c986f001006a6 100644 --- a/superset-frontend/src/chart/ChartRenderer.jsx +++ b/superset-frontend/src/chart/ChartRenderer.jsx @@ -38,6 +38,7 @@ const propTypes = { chartAlert: PropTypes.string, chartStatus: PropTypes.string, queryResponse: PropTypes.object, + queriesResponse: PropTypes.arrayOf(PropTypes.object), triggerQuery: PropTypes.bool, refreshOverlayVisible: PropTypes.bool, // dashboard callbacks @@ -85,7 +86,8 @@ class ChartRenderer extends React.Component { if (resultsReady) { this.hasQueryResponseChange = - nextProps.queryResponse !== this.props.queryResponse; + nextProps.queryResponse !== this.props.queryResponse || + nextProps.queriesResponse !== this.props.queriesResponse; return ( this.hasQueryResponseChange || nextProps.annotationData !== this.props.annotationData || @@ -180,6 +182,7 @@ class ChartRenderer extends React.Component { initialValues, formData, queryResponse, + queriesResponse, } = this.props; // It's bad practice to use unprefixed `vizType` as classnames for chart @@ -197,10 +200,10 @@ class ChartRenderer extends React.Component { ? `-${ // eslint-disable-next-line camelcase typeof __webpack_require__ !== 'undefined' && - // eslint-disable-next-line camelcase, no-undef - typeof __webpack_require__.h === 'function' && - // eslint-disable-next-line no-undef - __webpack_require__.h() + // eslint-disable-next-line camelcase, no-undef + typeof __webpack_require__.h === 'function' && + // eslint-disable-next-line no-undef + __webpack_require__.h() }` : ''; @@ -219,6 +222,7 @@ class ChartRenderer extends React.Component { formData={formData} hooks={this.hooks} queryData={queryResponse} + queriesData={queriesResponse} onRenderSuccess={this.handleRenderSuccess} onRenderFailure={this.handleRenderFailure} /> diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js index 16dd3f4167570..dcc322f7cf3a7 100644 --- a/superset-frontend/src/chart/chartAction.js +++ b/superset-frontend/src/chart/chartAction.js @@ -132,7 +132,9 @@ const legacyChartDataRequest = async ( // Make the legacy endpoint return a payload that corresponds to the // V1 chart data endpoint response signature. return { - result: [json], + response: { + result: [json], + }, }; }); }; @@ -176,7 +178,7 @@ const v1ChartDataRequest = async ( body: JSON.stringify(payload), }; return SupersetClient.post(querySettings).then(({ json }) => { - return json; + return { response: json, hasMultiQueries: payload.queries.length > 1 }; }); }; @@ -226,7 +228,7 @@ export function runAnnotationQuery( key, isDashboardRequest = false, ) { - return function (dispatch, getState) { + return function(dispatch, getState) { const sliceKey = key || Object.keys(getState().charts)[0]; // make a copy of formData, not modifying original formData const fd = { @@ -355,31 +357,36 @@ export function exploreJSON( dispatch(chartUpdateStarted(controller, formData, key)); const chartDataRequestCaught = chartDataRequest - .then(response => { + .then(({ response, hasMultiQueries }) => { // new API returns an object with an array of restults // problem: response holds a list of results, when before we were just getting one result. // How to make the entire app compatible with multiple results? // For now just use the first result. - const result = response.result[0]; + let result = response.result[0]; + if (hasMultiQueries) { + result = response.result; + } - dispatch( - logEvent(LOG_ACTIONS_LOAD_CHART, { - slice_id: key, - applied_filters: result.applied_filters, - is_cached: result.is_cached, - force_refresh: force, - row_count: result.rowcount, - datasource: formData.datasource, - start_offset: logStart, - ts: new Date().getTime(), - duration: Logger.getTimestamp() - logStart, - has_extra_filters: - formData.extra_filters && formData.extra_filters.length > 0, - viz_type: formData.viz_type, - data_age: result.is_cached - ? moment(new Date()).diff(moment.utc(result.cached_dttm)) - : null, - }), + response.result.forEach(resultItem => + dispatch( + logEvent(LOG_ACTIONS_LOAD_CHART, { + slice_id: key, + applied_filters: resultItem.applied_filters, + is_cached: resultItem.is_cached, + force_refresh: force, + row_count: resultItem.rowcount, + datasource: formData.datasource, + start_offset: logStart, + ts: new Date().getTime(), + duration: Logger.getTimestamp() - logStart, + has_extra_filters: + formData.extra_filters && formData.extra_filters.length > 0, + viz_type: formData.viz_type, + data_age: resultItem.is_cached + ? moment(new Date()).diff(moment.utc(resultItem.cached_dttm)) + : null, + }), + ), ); return dispatch(chartUpdateSucceeded(result, key)); }) diff --git a/superset-frontend/src/chart/chartReducer.js b/superset-frontend/src/chart/chartReducer.js index b3e72124f9829..4af423b0c78fd 100644 --- a/superset-frontend/src/chart/chartReducer.js +++ b/superset-frontend/src/chart/chartReducer.js @@ -31,6 +31,7 @@ export const chart = { latestQueryFormData: {}, queryController: null, queryResponse: null, + queriesResponse: null, triggerQuery: true, lastRendered: 0, }; @@ -44,12 +45,19 @@ export default function chartReducer(charts = {}, action) { }; }, [actions.CHART_UPDATE_SUCCEEDED](state) { + const otherProps = {}; + if (Array.isArray(action.queryResponse)) { + otherProps.queryResponse = action.queryResponse[0]; + otherProps.queriesResponse = action.queryResponse; + } else { + otherProps.queryResponse = action.queryResponse; + } return { ...state, chartStatus: 'success', - queryResponse: action.queryResponse, chartAlert: null, chartUpdateEndTime: now(), + ...otherProps, }; }, [actions.CHART_UPDATE_STARTED](state) { diff --git a/superset-frontend/src/dashboard/components/SliceHeader.jsx b/superset-frontend/src/dashboard/components/SliceHeader.jsx index 1f62d839b2d29..3389b5333ab69 100644 --- a/superset-frontend/src/dashboard/components/SliceHeader.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeader.jsx @@ -29,8 +29,14 @@ const propTypes = { innerRef: PropTypes.func, slice: PropTypes.object.isRequired, isExpanded: PropTypes.bool, - isCached: PropTypes.bool, - cachedDttm: PropTypes.string, + isCached: PropTypes.oneOfType([ + PropTypes.bool, + PropTypes.arrayOf(PropTypes.bool), + ]), + cachedDttm: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.arrayOf(PropTypes.string), + ]), updatedDttm: PropTypes.number, updateSliceName: PropTypes.func, toggleExpandSlice: PropTypes.func, diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index 673f2baf6e956..202741862da1d 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -31,9 +31,15 @@ const propTypes = { componentId: PropTypes.string.isRequired, dashboardId: PropTypes.number.isRequired, addDangerToast: PropTypes.func.isRequired, - isCached: PropTypes.bool, + isCached: PropTypes.oneOfType([ + PropTypes.bool, + PropTypes.arrayOf(PropTypes.bool), + ]), + cachedDttm: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.arrayOf(PropTypes.string), + ]), isExpanded: PropTypes.bool, - cachedDttm: PropTypes.string, updatedDttm: PropTypes.number, supersetCanExplore: PropTypes.bool, supersetCanCSV: PropTypes.bool, @@ -171,11 +177,21 @@ class SliceHeaderControls extends React.PureComponent { addDangerToast, isFullSize, } = this.props; - const cachedWhen = moment.utc(cachedDttm).fromNow(); + const cachedDttmMulti = Array.isArray(cachedDttm) + ? cachedDttm + : [cachedDttm]; + const isCachedMulti = Array.isArray(isCached) ? isCached : [isCached]; + const cachedWhen = cachedDttmMulti.map(itemCachedDttm => + moment.utc(itemCachedDttm).fromNow(), + ); const updatedWhen = updatedDttm ? moment.utc(updatedDttm).fromNow() : ''; - const refreshTooltip = isCached - ? t('Cached %s', cachedWhen) - : (updatedWhen && t('Fetched %s', updatedWhen)) || ''; + const refreshTooltip = isCachedMulti + .map(itemCached => + (itemCached + ? t('Cached %s', cachedWhen) + : (updatedWhen && t('Fetched %s', updatedWhen)) || ''), + ) + .join(', '); const resizeLabel = isFullSize ? t('Minimize') : t('Maximize'); const menu = ( diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx index e42c259288b40..0af535ced120e 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx @@ -257,9 +257,13 @@ export default class Chart extends React.Component { return ; } - const { queryResponse, chartUpdateEndTime } = chart; - const isCached = queryResponse && queryResponse.is_cached; - const cachedDttm = queryResponse && queryResponse.cached_dttm; + const { queryResponse, chartUpdateEndTime, queriesResponse } = chart; + const isCached = queriesResponse + ? queriesResponse.map(({ is_cached }) => is_cached) + : queryResponse?.is_cached; + const cachedDttm = queriesResponse + ? queriesResponse.map(({ cached_dttm }) => cached_dttm) + : queryResponse?.cached_dttm; const isOverflowable = OVERFLOWABLE_VIZ_TYPES.has(slice.viz_type); const initialValues = isFilterBox(id) ? getFilterValuesByFilterId({ @@ -267,7 +271,6 @@ export default class Chart extends React.Component { filterId: id, }) : {}; - return (
{ resultFormat: 'json', resultType, }) - .then(response => { + .then(({ response }) => { // Currently displaying of only first query is supported const result = response.result[0]; setLanguage(result.language); diff --git a/superset-frontend/src/explore/components/ExploreChartPanel.jsx b/superset-frontend/src/explore/components/ExploreChartPanel.jsx index 674135e43fbfc..334c01ff5a881 100644 --- a/superset-frontend/src/explore/components/ExploreChartPanel.jsx +++ b/superset-frontend/src/explore/components/ExploreChartPanel.jsx @@ -86,6 +86,7 @@ class ExploreChartPanel extends React.PureComponent { onQuery={this.props.onQuery} owners={this.props?.slice?.owners} queryResponse={chart.queryResponse} + queriesResponse={chart.queriesResponse} refreshOverlayVisible={this.props.refreshOverlayVisible} setControlValue={this.props.actions.setControlValue} timeout={this.props.timeout} From a4b2a75621dd114c197f2e76c88948cf3e80e587 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Tue, 1 Dec 2020 20:21:45 +0200 Subject: [PATCH 02/17] feat: support multi queries request --- superset-frontend/src/chart/Chart.jsx | 7 +--- superset-frontend/src/chart/chartAction.js | 20 +++++------ superset-frontend/src/chart/chartReducer.js | 10 ++---- .../src/dashboard/components/SliceHeader.jsx | 14 +++----- .../components/SliceHeaderControls.jsx | 34 +++++++------------ .../components/gridComponents/Chart.jsx | 14 ++++---- .../explore/components/DisplayQueryButton.jsx | 2 +- 7 files changed, 35 insertions(+), 66 deletions(-) diff --git a/superset-frontend/src/chart/Chart.jsx b/superset-frontend/src/chart/Chart.jsx index a4ce2858383b7..221ec015055c3 100644 --- a/superset-frontend/src/chart/Chart.jsx +++ b/superset-frontend/src/chart/Chart.jsx @@ -56,7 +56,6 @@ const propTypes = { chartAlert: PropTypes.string, chartStatus: PropTypes.string, chartStackTrace: PropTypes.string, - queryResponse: PropTypes.object, queriesResponse: PropTypes.arrayOf(PropTypes.object), triggerQuery: PropTypes.bool, refreshOverlayVisible: PropTypes.bool, @@ -180,7 +179,6 @@ class Chart extends React.PureComponent { errorMessage, onQuery, refreshOverlayVisible, - queryResponse, queriesResponse, } = this.props; @@ -188,10 +186,7 @@ class Chart extends React.PureComponent { const isFaded = refreshOverlayVisible && !errorMessage; this.renderContainerStartTime = Logger.getTimestamp(); if (chartStatus === 'failed') { - if (queriesResponse) { - return queriesResponse.map(item => this.renderErrorMessage(item)); - } - return this.renderErrorMessage(queryResponse); + return queriesResponse.map(item => this.renderErrorMessage(item)); } if (errorMessage) { return ( diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js index dcc322f7cf3a7..785f195d3ee04 100644 --- a/superset-frontend/src/chart/chartAction.js +++ b/superset-frontend/src/chart/chartAction.js @@ -52,8 +52,8 @@ export function chartUpdateStarted(queryController, latestQueryFormData, key) { } export const CHART_UPDATE_SUCCEEDED = 'CHART_UPDATE_SUCCEEDED'; -export function chartUpdateSucceeded(queryResponse, key) { - return { type: CHART_UPDATE_SUCCEEDED, queryResponse, key }; +export function chartUpdateSucceeded(queryResponse, queriesResponse, key) { + return { type: CHART_UPDATE_SUCCEEDED, queryResponse, queriesResponse, key }; } export const CHART_UPDATE_STOPPED = 'CHART_UPDATE_STOPPED'; @@ -132,9 +132,7 @@ const legacyChartDataRequest = async ( // Make the legacy endpoint return a payload that corresponds to the // V1 chart data endpoint response signature. return { - response: { result: [json], - }, }; }); }; @@ -178,7 +176,7 @@ const v1ChartDataRequest = async ( body: JSON.stringify(payload), }; return SupersetClient.post(querySettings).then(({ json }) => { - return { response: json, hasMultiQueries: payload.queries.length > 1 }; + return json; }); }; @@ -357,17 +355,15 @@ export function exploreJSON( dispatch(chartUpdateStarted(controller, formData, key)); const chartDataRequestCaught = chartDataRequest - .then(({ response, hasMultiQueries }) => { + .then(response => { // new API returns an object with an array of restults // problem: response holds a list of results, when before we were just getting one result. // How to make the entire app compatible with multiple results? // For now just use the first result. - let result = response.result[0]; - if (hasMultiQueries) { - result = response.result; - } + const queryResponse = response.result[0]; // deprecated + const queriesResponse = response.result; - response.result.forEach(resultItem => + queriesResponse.forEach(resultItem => dispatch( logEvent(LOG_ACTIONS_LOAD_CHART, { slice_id: key, @@ -388,7 +384,7 @@ export function exploreJSON( }), ), ); - return dispatch(chartUpdateSucceeded(result, key)); + return dispatch(chartUpdateSucceeded(queryResponse, queriesResponse, key)); }) .catch(response => { const appendErrorLog = (errorDetails, isCached) => { diff --git a/superset-frontend/src/chart/chartReducer.js b/superset-frontend/src/chart/chartReducer.js index 4af423b0c78fd..4d3b78d901312 100644 --- a/superset-frontend/src/chart/chartReducer.js +++ b/superset-frontend/src/chart/chartReducer.js @@ -45,19 +45,13 @@ export default function chartReducer(charts = {}, action) { }; }, [actions.CHART_UPDATE_SUCCEEDED](state) { - const otherProps = {}; - if (Array.isArray(action.queryResponse)) { - otherProps.queryResponse = action.queryResponse[0]; - otherProps.queriesResponse = action.queryResponse; - } else { - otherProps.queryResponse = action.queryResponse; - } return { ...state, chartStatus: 'success', chartAlert: null, + queryResponse: action.queryResponse, + queriesResponse: action.queriesResponse, chartUpdateEndTime: now(), - ...otherProps, }; }, [actions.CHART_UPDATE_STARTED](state) { diff --git a/superset-frontend/src/dashboard/components/SliceHeader.jsx b/superset-frontend/src/dashboard/components/SliceHeader.jsx index 3389b5333ab69..605ba8ed104f2 100644 --- a/superset-frontend/src/dashboard/components/SliceHeader.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeader.jsx @@ -29,14 +29,8 @@ const propTypes = { innerRef: PropTypes.func, slice: PropTypes.object.isRequired, isExpanded: PropTypes.bool, - isCached: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.arrayOf(PropTypes.bool), - ]), - cachedDttm: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string), - ]), + isCached: PropTypes.arrayOf(PropTypes.bool), + cachedDttm: PropTypes.arrayOf(PropTypes.string), updatedDttm: PropTypes.number, updateSliceName: PropTypes.func, toggleExpandSlice: PropTypes.func, @@ -70,8 +64,8 @@ const defaultProps = { annotationError: {}, cachedDttm: null, updatedDttm: null, - isCached: false, - isExpanded: false, + isCached: [], + isExpanded: [], sliceName: '', supersetCanExplore: false, supersetCanCSV: false, diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index 202741862da1d..993f913c9395f 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -31,14 +31,8 @@ const propTypes = { componentId: PropTypes.string.isRequired, dashboardId: PropTypes.number.isRequired, addDangerToast: PropTypes.func.isRequired, - isCached: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.arrayOf(PropTypes.bool), - ]), - cachedDttm: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string), - ]), + isCached: PropTypes.arrayOf(PropTypes.bool), + cachedDttm: PropTypes.arrayOf(PropTypes.string), isExpanded: PropTypes.bool, updatedDttm: PropTypes.number, supersetCanExplore: PropTypes.bool, @@ -55,9 +49,9 @@ const defaultProps = { toggleExpandSlice: () => ({}), exploreChart: () => ({}), exportCSV: () => ({}), - cachedDttm: null, + cachedDttm: [], updatedDttm: null, - isCached: false, + isCached: [], isExpanded: false, supersetCanExplore: false, supersetCanCSV: false, @@ -177,21 +171,17 @@ class SliceHeaderControls extends React.PureComponent { addDangerToast, isFullSize, } = this.props; - const cachedDttmMulti = Array.isArray(cachedDttm) - ? cachedDttm - : [cachedDttm]; - const isCachedMulti = Array.isArray(isCached) ? isCached : [isCached]; - const cachedWhen = cachedDttmMulti.map(itemCachedDttm => + const cachedWhen = cachedDttm.map(itemCachedDttm => moment.utc(itemCachedDttm).fromNow(), ); const updatedWhen = updatedDttm ? moment.utc(updatedDttm).fromNow() : ''; - const refreshTooltip = isCachedMulti - .map(itemCached => - (itemCached - ? t('Cached %s', cachedWhen) - : (updatedWhen && t('Fetched %s', updatedWhen)) || ''), - ) - .join(', '); + let refreshTooltip = isCached.map(itemCached => + (itemCached + ? t('Cached %s', cachedWhen) + : (updatedWhen && t('Fetched %s', updatedWhen)) || ''), + ); + // If all queries have same cache time we can unit them to one + refreshTooltip = [...new Set(refreshTooltip)].join(', '); const resizeLabel = isFullSize ? t('Minimize') : t('Maximize'); const menu = ( diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx index 0af535ced120e..2d1dc523ec7c0 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx @@ -257,13 +257,12 @@ export default class Chart extends React.Component { return ; } - const { queryResponse, chartUpdateEndTime, queriesResponse } = chart; - const isCached = queriesResponse - ? queriesResponse.map(({ is_cached }) => is_cached) - : queryResponse?.is_cached; - const cachedDttm = queriesResponse - ? queriesResponse.map(({ cached_dttm }) => cached_dttm) - : queryResponse?.cached_dttm; + const { chartUpdateEndTime, queriesResponse } = chart; + // eslint-disable-next-line camelcase + const isCached = queriesResponse?.map(({ is_cached }) => is_cached) || []; + const cachedDttm = + // eslint-disable-next-line camelcase + queriesResponse?.map(({ cached_dttm }) => cached_dttm) || []; const isOverflowable = OVERFLOWABLE_VIZ_TYPES.has(slice.viz_type); const initialValues = isFilterBox(id) ? getFilterValuesByFilterId({ @@ -336,6 +335,7 @@ export default class Chart extends React.Component { dashboardId={dashboardId} initialValues={initialValues} formData={formData} + queriesResponse={chart.queriesResponse} queryResponse={chart.queryResponse} timeout={timeout} triggerQuery={chart.triggerQuery} diff --git a/superset-frontend/src/explore/components/DisplayQueryButton.jsx b/superset-frontend/src/explore/components/DisplayQueryButton.jsx index b61eceb7ae0f9..ab19c5fb4974c 100644 --- a/superset-frontend/src/explore/components/DisplayQueryButton.jsx +++ b/superset-frontend/src/explore/components/DisplayQueryButton.jsx @@ -120,7 +120,7 @@ export const DisplayQueryButton = props => { resultFormat: 'json', resultType, }) - .then(({ response }) => { + .then(response => { // Currently displaying of only first query is supported const result = response.result[0]; setLanguage(result.language); From efd98fb7652928e8c97935334f0aebb447ebe194 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Wed, 2 Dec 2020 08:13:12 +0200 Subject: [PATCH 03/17] lint: fix lint --- .../src/dashboard/components/SliceHeaderControls.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index 993f913c9395f..4318baad4351d 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -176,9 +176,9 @@ class SliceHeaderControls extends React.PureComponent { ); const updatedWhen = updatedDttm ? moment.utc(updatedDttm).fromNow() : ''; let refreshTooltip = isCached.map(itemCached => - (itemCached + itemCached ? t('Cached %s', cachedWhen) - : (updatedWhen && t('Fetched %s', updatedWhen)) || ''), + : (updatedWhen && t('Fetched %s', updatedWhen)) || '', ); // If all queries have same cache time we can unit them to one refreshTooltip = [...new Set(refreshTooltip)].join(', '); From 618fbaf02393df4d0967cef902ba50a2c80a9098 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Wed, 2 Dec 2020 09:03:15 +0200 Subject: [PATCH 04/17] lint: fix lint --- superset-frontend/src/chart/ChartRenderer.jsx | 8 ++++---- superset-frontend/src/chart/chartAction.js | 6 ++++-- .../src/dashboard/components/SliceHeaderControls.jsx | 9 +++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/superset-frontend/src/chart/ChartRenderer.jsx b/superset-frontend/src/chart/ChartRenderer.jsx index c986f001006a6..d41cf80b736f0 100644 --- a/superset-frontend/src/chart/ChartRenderer.jsx +++ b/superset-frontend/src/chart/ChartRenderer.jsx @@ -200,10 +200,10 @@ class ChartRenderer extends React.Component { ? `-${ // eslint-disable-next-line camelcase typeof __webpack_require__ !== 'undefined' && - // eslint-disable-next-line camelcase, no-undef - typeof __webpack_require__.h === 'function' && - // eslint-disable-next-line no-undef - __webpack_require__.h() + // eslint-disable-next-line camelcase, no-undef + typeof __webpack_require__.h === 'function' && + // eslint-disable-next-line no-undef + __webpack_require__.h() }` : ''; diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js index 785f195d3ee04..b2dafe1eb02ce 100644 --- a/superset-frontend/src/chart/chartAction.js +++ b/superset-frontend/src/chart/chartAction.js @@ -132,7 +132,7 @@ const legacyChartDataRequest = async ( // Make the legacy endpoint return a payload that corresponds to the // V1 chart data endpoint response signature. return { - result: [json], + result: [json], }; }); }; @@ -384,7 +384,9 @@ export function exploreJSON( }), ), ); - return dispatch(chartUpdateSucceeded(queryResponse, queriesResponse, key)); + return dispatch( + chartUpdateSucceeded(queryResponse, queriesResponse, key), + ); }) .catch(response => { const appendErrorLog = (errorDetails, isCached) => { diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index 4318baad4351d..61d68e99a3571 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -175,11 +175,12 @@ class SliceHeaderControls extends React.PureComponent { moment.utc(itemCachedDttm).fromNow(), ); const updatedWhen = updatedDttm ? moment.utc(updatedDttm).fromNow() : ''; - let refreshTooltip = isCached.map(itemCached => - itemCached + const getCachedTitle = itemCached => { + return itemCached ? t('Cached %s', cachedWhen) - : (updatedWhen && t('Fetched %s', updatedWhen)) || '', - ); + : updatedWhen && t('Fetched %s', updatedWhen); + }; + let refreshTooltip = isCached.map(getCachedTitle) || ''; // If all queries have same cache time we can unit them to one refreshTooltip = [...new Set(refreshTooltip)].join(', '); const resizeLabel = isFullSize ? t('Minimize') : t('Maximize'); From 62677169db508c95a09a28f8808bbd9e66f9852f Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Wed, 2 Dec 2020 09:05:57 +0200 Subject: [PATCH 05/17] lint: fix lint --- superset-frontend/src/chart/chartAction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js index b2dafe1eb02ce..abb30420e8a3a 100644 --- a/superset-frontend/src/chart/chartAction.js +++ b/superset-frontend/src/chart/chartAction.js @@ -226,7 +226,7 @@ export function runAnnotationQuery( key, isDashboardRequest = false, ) { - return function(dispatch, getState) { + return function (dispatch, getState) { const sliceKey = key || Object.keys(getState().charts)[0]; // make a copy of formData, not modifying original formData const fd = { From af13a2346858c7f44fa7649b28bf41d76deab79e Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Wed, 2 Dec 2020 15:53:36 +0200 Subject: [PATCH 06/17] fix: fix CR notes --- .../src/dashboard/components/SliceHeaderControls.jsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index 61d68e99a3571..f79b38ea187c7 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -82,9 +82,14 @@ const VerticalDotsContainer = styled.div` `; const RefreshTooltip = styled.div` - height: ${({ theme }) => theme.gridUnit * 4}px; + height: auto; margin: ${({ theme }) => theme.gridUnit}px 0; color: ${({ theme }) => theme.colors.grayscale.base}; + line-height: ${({ theme }) => theme.typography.sizes.m * 1.5}; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; `; const SCREENSHOT_NODE_SELECTOR = '.dashboard-component-chart-holder'; @@ -182,7 +187,9 @@ class SliceHeaderControls extends React.PureComponent { }; let refreshTooltip = isCached.map(getCachedTitle) || ''; // If all queries have same cache time we can unit them to one - refreshTooltip = [...new Set(refreshTooltip)].join(', '); + refreshTooltip = [...new Set(refreshTooltip)].map(item => ( +
{item}
+ )); const resizeLabel = isFullSize ? t('Minimize') : t('Maximize'); const menu = ( From 4e4238c1eb9a9e444c42b92502dc7224047f01c0 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Wed, 2 Dec 2020 15:57:22 +0200 Subject: [PATCH 07/17] fix: fix CR notes --- .../src/dashboard/components/SliceHeaderControls.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index f79b38ea187c7..544f009aaca6b 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -85,7 +85,7 @@ const RefreshTooltip = styled.div` height: auto; margin: ${({ theme }) => theme.gridUnit}px 0; color: ${({ theme }) => theme.colors.grayscale.base}; - line-height: ${({ theme }) => theme.typography.sizes.m * 1.5}; + line-height: ${({ theme }) => theme.typography.sizes.m * 1.5}px; display: flex; flex-direction: column; align-items: flex-start; From b6f4fe19d1e6298e82e02aa994f534f268deb8d8 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Wed, 2 Dec 2020 16:05:56 +0200 Subject: [PATCH 08/17] fix: fix CR notes --- .../src/dashboard/components/SliceHeaderControls.jsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index 544f009aaca6b..9ceebf15759fd 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -185,10 +185,15 @@ class SliceHeaderControls extends React.PureComponent { ? t('Cached %s', cachedWhen) : updatedWhen && t('Fetched %s', updatedWhen); }; - let refreshTooltip = isCached.map(getCachedTitle) || ''; + const refreshTooltipData = isCached.map(getCachedTitle) || ''; // If all queries have same cache time we can unit them to one - refreshTooltip = [...new Set(refreshTooltip)].map(item => ( -
{item}
+ let refreshTooltip = [...new Set(refreshTooltipData)]; + refreshTooltip = refreshTooltip.map((item, index) => ( +
+ {refreshTooltip.length > 1 + ? `${t('Query')} ${index + 1}: ${item}` + : item} +
)); const resizeLabel = isFullSize ? t('Minimize') : t('Maximize'); From df1f3cb08010a68d73242d64b3a15d974961ceec Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Thu, 3 Dec 2020 09:06:02 +0200 Subject: [PATCH 09/17] fix: fix error case for multi queries --- superset-frontend/src/chart/Chart.jsx | 2 +- superset-frontend/src/chart/chartAction.js | 10 ++++++---- superset-frontend/src/chart/chartReducer.js | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/superset-frontend/src/chart/Chart.jsx b/superset-frontend/src/chart/Chart.jsx index 221ec015055c3..83527a8b5ee7b 100644 --- a/superset-frontend/src/chart/Chart.jsx +++ b/superset-frontend/src/chart/Chart.jsx @@ -179,7 +179,7 @@ class Chart extends React.PureComponent { errorMessage, onQuery, refreshOverlayVisible, - queriesResponse, + queriesResponse = [], } = this.props; const isLoading = chartStatus === 'loading'; diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js index abb30420e8a3a..37ef037b69ff5 100644 --- a/superset-frontend/src/chart/chartAction.js +++ b/superset-frontend/src/chart/chartAction.js @@ -62,8 +62,8 @@ export function chartUpdateStopped(key) { } export const CHART_UPDATE_FAILED = 'CHART_UPDATE_FAILED'; -export function chartUpdateFailed(queryResponse, key) { - return { type: CHART_UPDATE_FAILED, queryResponse, key }; +export function chartUpdateFailed(queryResponse, queriesResponse, key) { + return { type: CHART_UPDATE_FAILED, queryResponse, queriesResponse, key }; } export const CHART_RENDERING_FAILED = 'CHART_RENDERING_FAILED'; @@ -226,7 +226,7 @@ export function runAnnotationQuery( key, isDashboardRequest = false, ) { - return function (dispatch, getState) { + return function(dispatch, getState) { const sliceKey = key || Object.keys(getState().charts)[0]; // make a copy of formData, not modifying original formData const fd = { @@ -413,7 +413,9 @@ export function exploreJSON( } else { appendErrorLog(parsedResponse.error, parsedResponse.is_cached); } - return dispatch(chartUpdateFailed(parsedResponse, key)); + return dispatch( + chartUpdateFailed(parsedResponse, [parsedResponse], key), + ); }); }); diff --git a/superset-frontend/src/chart/chartReducer.js b/superset-frontend/src/chart/chartReducer.js index 4d3b78d901312..ad729004edbbb 100644 --- a/superset-frontend/src/chart/chartReducer.js +++ b/superset-frontend/src/chart/chartReducer.js @@ -96,6 +96,7 @@ export default function chartReducer(charts = {}, action) { : t('Network error.'), chartUpdateEndTime: now(), queryResponse: action.queryResponse, + queriesResponse: action.queriesResponse, chartStackTrace: action.queryResponse ? action.queryResponse.stacktrace : null, From 2c8fc5d384ec3331791e3c4c4f046982c1df1ff1 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Thu, 3 Dec 2020 09:58:04 +0200 Subject: [PATCH 10/17] feat: change queryResponse to queriesResponse --- superset-frontend/src/chart/ChartRenderer.jsx | 9 +++----- superset-frontend/src/chart/chartAction.js | 23 ++++++------------- superset-frontend/src/chart/chartReducer.js | 11 ++++----- .../components/FiltersBadge/selectors.ts | 4 ++-- .../components/gridComponents/Chart.jsx | 1 - .../src/dashboard/util/propShapes.jsx | 1 - .../explore/components/DisplayQueryButton.jsx | 1 - .../components/ExploreActionButtons.jsx | 6 ++--- .../explore/components/ExploreChartHeader.jsx | 4 +++- .../explore/components/ExploreChartPanel.jsx | 1 - .../src/explore/reducers/getInitialState.js | 2 +- superset-frontend/webpack.config.js | 14 ++++++++--- 12 files changed, 34 insertions(+), 43 deletions(-) diff --git a/superset-frontend/src/chart/ChartRenderer.jsx b/superset-frontend/src/chart/ChartRenderer.jsx index d41cf80b736f0..81699ca182657 100644 --- a/superset-frontend/src/chart/ChartRenderer.jsx +++ b/superset-frontend/src/chart/ChartRenderer.jsx @@ -37,7 +37,6 @@ const propTypes = { // state chartAlert: PropTypes.string, chartStatus: PropTypes.string, - queryResponse: PropTypes.object, queriesResponse: PropTypes.arrayOf(PropTypes.object), triggerQuery: PropTypes.bool, refreshOverlayVisible: PropTypes.bool, @@ -79,14 +78,13 @@ class ChartRenderer extends React.Component { shouldComponentUpdate(nextProps) { const resultsReady = - nextProps.queryResponse && + nextProps.queriesResponse && ['success', 'rendered'].indexOf(nextProps.chartStatus) > -1 && - !nextProps.queryResponse.error && + !nextProps.queriesResponse?.[0]?.error && !nextProps.refreshOverlayVisible; if (resultsReady) { this.hasQueryResponseChange = - nextProps.queryResponse !== this.props.queryResponse || nextProps.queriesResponse !== this.props.queriesResponse; return ( this.hasQueryResponseChange || @@ -181,7 +179,6 @@ class ChartRenderer extends React.Component { datasource, initialValues, formData, - queryResponse, queriesResponse, } = this.props; @@ -221,7 +218,7 @@ class ChartRenderer extends React.Component { initialValues={initialValues} formData={formData} hooks={this.hooks} - queryData={queryResponse} + queryData={queriesResponse?.[0]} // deprecated queriesData={queriesResponse} onRenderSuccess={this.handleRenderSuccess} onRenderFailure={this.handleRenderFailure} diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js index 37ef037b69ff5..07c9af60aad8d 100644 --- a/superset-frontend/src/chart/chartAction.js +++ b/superset-frontend/src/chart/chartAction.js @@ -52,8 +52,8 @@ export function chartUpdateStarted(queryController, latestQueryFormData, key) { } export const CHART_UPDATE_SUCCEEDED = 'CHART_UPDATE_SUCCEEDED'; -export function chartUpdateSucceeded(queryResponse, queriesResponse, key) { - return { type: CHART_UPDATE_SUCCEEDED, queryResponse, queriesResponse, key }; +export function chartUpdateSucceeded(queriesResponse, key) { + return { type: CHART_UPDATE_SUCCEEDED, queriesResponse, key }; } export const CHART_UPDATE_STOPPED = 'CHART_UPDATE_STOPPED'; @@ -62,8 +62,8 @@ export function chartUpdateStopped(key) { } export const CHART_UPDATE_FAILED = 'CHART_UPDATE_FAILED'; -export function chartUpdateFailed(queryResponse, queriesResponse, key) { - return { type: CHART_UPDATE_FAILED, queryResponse, queriesResponse, key }; +export function chartUpdateFailed(queriesResponse, key) { + return { type: CHART_UPDATE_FAILED, queriesResponse, key }; } export const CHART_RENDERING_FAILED = 'CHART_RENDERING_FAILED'; @@ -226,7 +226,7 @@ export function runAnnotationQuery( key, isDashboardRequest = false, ) { - return function(dispatch, getState) { + return function (dispatch, getState) { const sliceKey = key || Object.keys(getState().charts)[0]; // make a copy of formData, not modifying original formData const fd = { @@ -356,11 +356,6 @@ export function exploreJSON( const chartDataRequestCaught = chartDataRequest .then(response => { - // new API returns an object with an array of restults - // problem: response holds a list of results, when before we were just getting one result. - // How to make the entire app compatible with multiple results? - // For now just use the first result. - const queryResponse = response.result[0]; // deprecated const queriesResponse = response.result; queriesResponse.forEach(resultItem => @@ -384,9 +379,7 @@ export function exploreJSON( }), ), ); - return dispatch( - chartUpdateSucceeded(queryResponse, queriesResponse, key), - ); + return dispatch(chartUpdateSucceeded(queriesResponse, key)); }) .catch(response => { const appendErrorLog = (errorDetails, isCached) => { @@ -413,9 +406,7 @@ export function exploreJSON( } else { appendErrorLog(parsedResponse.error, parsedResponse.is_cached); } - return dispatch( - chartUpdateFailed(parsedResponse, [parsedResponse], key), - ); + return dispatch(chartUpdateFailed([parsedResponse], key)); }); }); diff --git a/superset-frontend/src/chart/chartReducer.js b/superset-frontend/src/chart/chartReducer.js index ad729004edbbb..ae78555d3cf24 100644 --- a/superset-frontend/src/chart/chartReducer.js +++ b/superset-frontend/src/chart/chartReducer.js @@ -30,7 +30,6 @@ export const chart = { chartUpdateStartTime: 0, latestQueryFormData: {}, queryController: null, - queryResponse: null, queriesResponse: null, triggerQuery: true, lastRendered: 0, @@ -49,7 +48,6 @@ export default function chartReducer(charts = {}, action) { ...state, chartStatus: 'success', chartAlert: null, - queryResponse: action.queryResponse, queriesResponse: action.queriesResponse, chartUpdateEndTime: now(), }; @@ -91,14 +89,13 @@ export default function chartReducer(charts = {}, action) { return { ...state, chartStatus: 'failed', - chartAlert: action.queryResponse - ? action.queryResponse.error + chartAlert: action.queriesResponse + ? action.queriesResponse?.[0]?.error : t('Network error.'), chartUpdateEndTime: now(), - queryResponse: action.queryResponse, queriesResponse: action.queriesResponse, - chartStackTrace: action.queryResponse - ? action.queryResponse.stacktrace + chartStackTrace: action.queriesResponse + ? action.queriesResponse?.[0]?.stacktrace : null, }; }, diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts b/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts index 9cdd43a22c9e6..6aaa0d97a9570 100644 --- a/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts +++ b/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts @@ -132,12 +132,12 @@ export const selectIndicatorsForChart = ( // for now we only need to know which columns are compatible/incompatible, // so grab the columns from the applied/rejected filters const appliedColumns: Set = new Set( - (chart?.queryResponse?.applied_filters || []).map( + (chart?.queriesResponse?.[0]?.applied_filters || []).map( (filter: any) => filter.column, ), ); const rejectedColumns: Set = new Set( - (chart?.queryResponse?.rejected_filters || []).map( + (chart?.queriesResponse?.[0]?.rejected_filters || []).map( (filter: any) => filter.column, ), ); diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx index 2d1dc523ec7c0..3eede7e1e0b98 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx @@ -336,7 +336,6 @@ export default class Chart extends React.Component { initialValues={initialValues} formData={formData} queriesResponse={chart.queriesResponse} - queryResponse={chart.queryResponse} timeout={timeout} triggerQuery={chart.triggerQuery} vizType={slice.viz_type} diff --git a/superset-frontend/src/dashboard/util/propShapes.jsx b/superset-frontend/src/dashboard/util/propShapes.jsx index 8fbc099142e93..78bcf3f0639b3 100644 --- a/superset-frontend/src/dashboard/util/propShapes.jsx +++ b/superset-frontend/src/dashboard/util/propShapes.jsx @@ -50,7 +50,6 @@ export const chartPropShape = PropTypes.shape({ chartUpdateStartTime: PropTypes.number, latestQueryFormData: PropTypes.object, queryController: PropTypes.shape({ abort: PropTypes.func }), - queryResponse: PropTypes.object, queriesResponse: PropTypes.arrayOf(PropTypes.object), triggerQuery: PropTypes.bool, lastRendered: PropTypes.number, diff --git a/superset-frontend/src/explore/components/DisplayQueryButton.jsx b/superset-frontend/src/explore/components/DisplayQueryButton.jsx index ab19c5fb4974c..ac6b55cd4aa10 100644 --- a/superset-frontend/src/explore/components/DisplayQueryButton.jsx +++ b/superset-frontend/src/explore/components/DisplayQueryButton.jsx @@ -53,7 +53,6 @@ SyntaxHighlighter.registerLanguage('json', jsonSyntax); const propTypes = { onOpenInEditor: PropTypes.func, - queryResponse: PropTypes.object, chartStatus: PropTypes.string, chartHeight: PropTypes.string.isRequired, latestQueryFormData: PropTypes.object.isRequired, diff --git a/superset-frontend/src/explore/components/ExploreActionButtons.jsx b/superset-frontend/src/explore/components/ExploreActionButtons.jsx index f738723d9d12f..64fe618b10592 100644 --- a/superset-frontend/src/explore/components/ExploreActionButtons.jsx +++ b/superset-frontend/src/explore/components/ExploreActionButtons.jsx @@ -33,7 +33,7 @@ const propTypes = { chartStatus: PropTypes.string, chartHeight: PropTypes.string.isRequired, latestQueryFormData: PropTypes.object, - queryResponse: PropTypes.object, + queriesResponse: PropTypes.arrayOf(PropTypes.object), slice: PropTypes.object, }; @@ -43,7 +43,7 @@ export default function ExploreActionButtons({ chartHeight, chartStatus, latestQueryFormData, - queryResponse, + queriesResponse, slice, }) { const exportToCSVClasses = cx('btn btn-default btn-sm', { @@ -106,7 +106,7 @@ export default function ExploreActionButtons({ )} { const srcPath = `./node_modules/${pkg}/src`; - if (/superset-ui/.test(pkg) && fs.existsSync(srcPath)) { + if ( + (/superset-ui/.test(pkg) || /superset-maf-ui/.test(pkg)) && + fs.existsSync(srcPath) + ) { console.log( `[Superset Plugin] Use symlink source for ${pkg} @ ${version}`, ); From 47a1293123c799299bac6c72413b03cfe562a33d Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Thu, 3 Dec 2020 09:58:58 +0200 Subject: [PATCH 11/17] fix: revert webpack --- superset-frontend/webpack.config.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/superset-frontend/webpack.config.js b/superset-frontend/webpack.config.js index 2b6fb07e7bb6d..cd843fbf122c6 100644 --- a/superset-frontend/webpack.config.js +++ b/superset-frontend/webpack.config.js @@ -326,22 +326,17 @@ const config = { { test: /\.jsx?$/, // include source code for plugins, but exclude node_modules and test files within them - exclude: [ - /superset-ui.*\/node_modules\//, - /superset-maf-ui.*\/node_modules\//, - /\.test.jsx?$/, - ], + exclude: [/superset-ui.*\/node_modules\//, /\.test.jsx?$/], include: [ new RegExp(`${APP_DIR}/src`), /superset-ui.*\/src/, - /superset-maf-ui.*\/src/, new RegExp(`${APP_DIR}/.storybook`), ], use: [babelLoader], }, { test: /\.css$/, - include: [APP_DIR, /superset-ui.+\/src/, /superset-maf-ui.+\/src/], + include: [APP_DIR, /superset-ui.+\/src/], use: [ isDevMode ? 'style-loader' : MiniCssExtractPlugin.loader, { @@ -456,10 +451,7 @@ if (isDevMode) { let hasSymlink = false; Object.entries(packageConfig.dependencies).forEach(([pkg, version]) => { const srcPath = `./node_modules/${pkg}/src`; - if ( - (/superset-ui/.test(pkg) || /superset-maf-ui/.test(pkg)) && - fs.existsSync(srcPath) - ) { + if (/superset-ui/.test(pkg) && fs.existsSync(srcPath)) { console.log( `[Superset Plugin] Use symlink source for ${pkg} @ ${version}`, ); From 85a3aa52b4225a4d364a7da7d35c051ed1eccc63 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Thu, 3 Dec 2020 10:22:49 +0200 Subject: [PATCH 12/17] test: fix tests --- .../javascripts/chart/chartActions_spec.js | 2 +- .../components/FiltersBadge_spec.tsx | 36 +++++++++++-------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/superset-frontend/spec/javascripts/chart/chartActions_spec.js b/superset-frontend/spec/javascripts/chart/chartActions_spec.js index dc57e22b7a410..7bca9f7172150 100644 --- a/superset-frontend/spec/javascripts/chart/chartActions_spec.js +++ b/superset-frontend/spec/javascripts/chart/chartActions_spec.js @@ -189,7 +189,7 @@ describe('chart actions', () => { expect(dispatch.callCount).toBe(5); const updateFailedAction = dispatch.args[4][0]; expect(updateFailedAction.type).toBe(actions.CHART_UPDATE_FAILED); - expect(updateFailedAction.queryResponse.error).toBe('misc error'); + expect(updateFailedAction.queriesResponse[0].error).toBe('misc error'); setupDefaultFetchMock(); }); diff --git a/superset-frontend/spec/javascripts/dashboard/components/FiltersBadge_spec.tsx b/superset-frontend/spec/javascripts/dashboard/components/FiltersBadge_spec.tsx index ea89927944daa..4cf6abdfdfe76 100644 --- a/superset-frontend/spec/javascripts/dashboard/components/FiltersBadge_spec.tsx +++ b/superset-frontend/spec/javascripts/dashboard/components/FiltersBadge_spec.tsx @@ -50,11 +50,13 @@ describe('FiltersBadge', () => { store.dispatch({ type: CHART_UPDATE_SUCCEEDED, key: sliceId, - queryResponse: { - status: 'success', - applied_filters: [], - rejected_filters: [], - }, + queriesResponse: [ + { + status: 'success', + applied_filters: [], + rejected_filters: [], + }, + ], dashboardFilters, }); const wrapper = shallow(); @@ -69,11 +71,13 @@ describe('FiltersBadge', () => { store.dispatch({ type: CHART_UPDATE_SUCCEEDED, key: sliceId, - queryResponse: { - status: 'success', - applied_filters: [{ column: 'region' }], - rejected_filters: [], - }, + queriesResponse: [ + { + status: 'success', + applied_filters: [{ column: 'region' }], + rejected_filters: [], + }, + ], dashboardFilters, }); const wrapper = shallow(); @@ -90,11 +94,13 @@ describe('FiltersBadge', () => { store.dispatch({ type: CHART_UPDATE_SUCCEEDED, key: sliceId, - queryResponse: { - status: 'success', - applied_filters: [], - rejected_filters: [{ column: 'region', reason: 'not_in_datasource' }], - }, + queriesResponse: [ + { + status: 'success', + applied_filters: [], + rejected_filters: [{ column: 'region', reason: 'not_in_datasource' }], + }, + ], dashboardFilters, }); const wrapper = shallow(); From f01b9af7b5abe99fcd9a00cea0db149ca9a7d982 Mon Sep 17 00:00:00 2001 From: Amit Miran <47772523+amitmiran137@users.noreply.github.com> Date: Sun, 13 Dec 2020 19:58:21 +0200 Subject: [PATCH 13/17] chore: lint --- superset-frontend/src/chart/chartAction.js | 1 - 1 file changed, 1 deletion(-) diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js index a55216ada8521..1e0c3327b63bd 100644 --- a/superset-frontend/src/chart/chartAction.js +++ b/superset-frontend/src/chart/chartAction.js @@ -362,7 +362,6 @@ export function exploreJSON( const chartDataRequestCaught = chartDataRequest .then(response => { const queriesResponse = response.result; - if (isFeatureEnabled(FeatureFlag.GLOBAL_ASYNC_QUERIES)) { // deal with getChartDataRequest transforming the response data const result = 'result' in response ? response.result[0] : response; From 80460ea84d76dc71f082c8dd8d71303e88030135 Mon Sep 17 00:00:00 2001 From: amitmiran137 Date: Fri, 18 Dec 2020 07:48:50 +0200 Subject: [PATCH 14/17] chore: adjust asyncEvent to multiple results --- superset-frontend/src/middleware/asyncEvent.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/superset-frontend/src/middleware/asyncEvent.ts b/superset-frontend/src/middleware/asyncEvent.ts index 32d4010b7df47..9232e21d2feb8 100644 --- a/superset-frontend/src/middleware/asyncEvent.ts +++ b/superset-frontend/src/middleware/asyncEvent.ts @@ -100,7 +100,7 @@ const initAsyncEvents = (options: AsyncEventOptions) => { const { json } = await SupersetClient.get({ endpoint: asyncEvent.result_url, }); - data = 'result' in json ? json.result[0] : json; + data = 'result' in json ? json.result : json; } catch (response) { status = 'error'; data = await getClientErrorObject(response); @@ -151,8 +151,9 @@ const initAsyncEvents = (options: AsyncEventOptions) => { ); break; case JOB_STATUS.ERROR: + const errors = [parseErrorJson(asyncEvent)]; store.dispatch( - errorAction(componentId, parseErrorJson(asyncEvent)), + errorAction(componentId, errors), ); break; default: @@ -164,10 +165,11 @@ const initAsyncEvents = (options: AsyncEventOptions) => { const fetchResults = await Promise.all(fetchDataEvents); fetchResults.forEach(result => { + const data = Array.isArray(result.data) ? result.data : [result.data]; if (result.status === 'success') { - store.dispatch(successAction(result.componentId, result.data)); + store.dispatch(successAction(result.componentId, data)); } else { - store.dispatch(errorAction(result.componentId, result.data)); + store.dispatch(errorAction(result.componentId, data)); } }); } From 0d8b75855c3fdc84692c082102aa2b07f96a7f92 Mon Sep 17 00:00:00 2001 From: amitmiran137 Date: Fri, 18 Dec 2020 13:03:50 +0200 Subject: [PATCH 15/17] fix: lint --- superset-frontend/src/middleware/asyncEvent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/middleware/asyncEvent.ts b/superset-frontend/src/middleware/asyncEvent.ts index 9232e21d2feb8..88a587cd2865e 100644 --- a/superset-frontend/src/middleware/asyncEvent.ts +++ b/superset-frontend/src/middleware/asyncEvent.ts @@ -153,7 +153,7 @@ const initAsyncEvents = (options: AsyncEventOptions) => { case JOB_STATUS.ERROR: const errors = [parseErrorJson(asyncEvent)]; store.dispatch( - errorAction(componentId, errors), + errorAction(componentId, errors) ); break; default: From 197ba55f9828ccb644f46df3f58e1bc129c30b65 Mon Sep 17 00:00:00 2001 From: amitmiran137 Date: Fri, 18 Dec 2020 13:20:01 +0200 Subject: [PATCH 16/17] fix: eslint --- superset-frontend/src/middleware/asyncEvent.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/superset-frontend/src/middleware/asyncEvent.ts b/superset-frontend/src/middleware/asyncEvent.ts index 88a587cd2865e..2efec0c4f190f 100644 --- a/superset-frontend/src/middleware/asyncEvent.ts +++ b/superset-frontend/src/middleware/asyncEvent.ts @@ -152,9 +152,7 @@ const initAsyncEvents = (options: AsyncEventOptions) => { break; case JOB_STATUS.ERROR: const errors = [parseErrorJson(asyncEvent)]; - store.dispatch( - errorAction(componentId, errors) - ); + store.dispatch(errorAction(componentId, errors)); break; default: console.warn('received event with status', asyncEvent.status); @@ -165,7 +163,9 @@ const initAsyncEvents = (options: AsyncEventOptions) => { const fetchResults = await Promise.all(fetchDataEvents); fetchResults.forEach(result => { - const data = Array.isArray(result.data) ? result.data : [result.data]; + const data = Array.isArray(result.data) + ? result.data + : [result.data]; if (result.status === 'success') { store.dispatch(successAction(result.componentId, data)); } else { From d6ffbf2d6fddab9f618af477f67679cadceb8786 Mon Sep 17 00:00:00 2001 From: amitmiran137 Date: Fri, 18 Dec 2020 13:27:31 +0200 Subject: [PATCH 17/17] fix: another eslint rule --- superset-frontend/src/middleware/asyncEvent.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/superset-frontend/src/middleware/asyncEvent.ts b/superset-frontend/src/middleware/asyncEvent.ts index 2efec0c4f190f..b7a4912ad63d4 100644 --- a/superset-frontend/src/middleware/asyncEvent.ts +++ b/superset-frontend/src/middleware/asyncEvent.ts @@ -16,10 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import { Middleware, MiddlewareAPI, Dispatch } from 'redux'; +import { Dispatch, Middleware, MiddlewareAPI } from 'redux'; import { makeApi, SupersetClient } from '@superset-ui/core'; import { SupersetError } from 'src/components/ErrorMessage/types'; -import { isFeatureEnabled, FeatureFlag } from '../featureFlags'; +import { FeatureFlag, isFeatureEnabled } from '../featureFlags'; import { getClientErrorObject, parseErrorJson, @@ -151,8 +151,9 @@ const initAsyncEvents = (options: AsyncEventOptions) => { ); break; case JOB_STATUS.ERROR: - const errors = [parseErrorJson(asyncEvent)]; - store.dispatch(errorAction(componentId, errors)); + store.dispatch( + errorAction(componentId, [parseErrorJson(asyncEvent)]), + ); break; default: console.warn('received event with status', asyncEvent.status);