From a0c1fbf7140080c1ef318685cdc579fc59b6008d Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Tue, 10 May 2022 17:07:46 +0800 Subject: [PATCH 01/27] wip --- .../superset-ui-chart-controls/src/types.ts | 2 + .../src/utils/index.ts | 1 + .../src/utils/normalizedFormData.ts | 110 ++++++++++++++++++ .../test/utils/normalizedFormData.test.tsx | 38 ++++++ .../BigNumber/BigNumberTotal/controlPanel.ts | 9 ++ .../src/Timeseries/Regular/controlPanel.tsx | 8 ++ .../src/explore/reducers/exploreReducer.js | 38 ++++-- 7 files changed, 194 insertions(+), 12 deletions(-) create mode 100644 superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts create mode 100644 superset-frontend/packages/superset-ui-chart-controls/test/utils/normalizedFormData.test.tsx diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 53e3a198bd7ce..af952478c8ad7 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -28,6 +28,7 @@ import type { } from '@superset-ui/core'; import { sharedControls } from './shared-controls'; import sharedControlComponents from './shared-controls/components'; +import { StandardizedFormData } from './utils'; export type { Metric } from '@superset-ui/core'; export type { ControlFormItemSpec } from './components/ControlForm'; @@ -345,6 +346,7 @@ export interface ControlPanelConfig { controlOverrides?: ControlOverrides; sectionOverrides?: SectionOverrides; onInit?: (state: ControlStateMapping) => void; + denormalizeFormData?: (formData: StandardizedFormData) => QueryFormData; } export type ControlOverrides = { diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts b/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts index bfb5b5e824e64..99ab98cde648f 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts @@ -22,3 +22,4 @@ export * from './expandControlConfig'; export * from './getColorFormatters'; export { default as mainMetric } from './mainMetric'; export { default as columnChoices } from './columnChoices'; +export * from './normalizedFormData'; diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts b/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts new file mode 100644 index 0000000000000..c0d1f6920abaf --- /dev/null +++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts @@ -0,0 +1,110 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { + AdhocColumn, + AdhocFilter, + AdhocMetric, + ensureIsArray, + JsonObject, + PhysicalColumn, + QueryFormData, +} from '@superset-ui/core'; + +const sharedControls = { + metrics: ['metric', 'metrics', 'metric_2'], + columns: ['groupby', 'columns'], + filters: ['adhoc_filters'], +}; +const reversedMap = new Map(); +Object.entries(sharedControls).forEach(([key, names]) => { + names.forEach(name => { + reversedMap.set(name, key); + }); +}); + +function isStandardizedFormData(formData: JsonObject): boolean { + return 'sharedFormData' in formData && 'memorizedFormData' in formData; +} + +export interface SharedFormData { + metrics: AdhocMetric[]; + columns: (AdhocColumn | PhysicalColumn)[]; + filters: AdhocFilter[]; +} + +export class StandardizedFormData { + private sfd; + + constructor( + sharedFormData: SharedFormData, + memorizedFormData: Map, + ) { + this.sfd = { + sharedFormData, + memorizedFormData, + }; + } + + getLatestFormData(vizType: string) { + if (this.sfd.memorizedFormData.has(vizType)) { + return this.sfd.memorizedFormData.get(vizType); + } + + return this.sfd.memorizedFormData.size === 0 + ? {} + : this.sfd.memorizedFormData[this.sfd.memorizedFormData.keys()[0]]; + } + + get sharedFormData() { + return this.sfd.sharedFormData; + } + + get memorizedFormData() { + return Array.from(this.sfd.memorizedFormData.entries()); + } +} + +export function getStandadizedFormData( + formData: QueryFormData, +): StandardizedFormData { + const sharedFormData = { + metrics: [], + columns: [], + filters: [], + }; + + Object.entries(formData).forEach(([key, value]) => { + if (reversedMap.has(key)) { + sharedFormData[reversedMap.get(key)].push(...ensureIsArray(value)); + } + }); + + const memorizedFormData = + isStandardizedFormData(formData) && + Array.isArray(formData.memorizedFormData) + ? new Map(formData.memorizedFormData) + : new Map(); + const vizType = formData.viz_type; + if (memorizedFormData.has(vizType)) { + memorizedFormData.delete(vizType); + } + memorizedFormData.set(vizType, formData); + + return new StandardizedFormData(sharedFormData, memorizedFormData); +} diff --git a/superset-frontend/packages/superset-ui-chart-controls/test/utils/normalizedFormData.test.tsx b/superset-frontend/packages/superset-ui-chart-controls/test/utils/normalizedFormData.test.tsx new file mode 100644 index 0000000000000..2e9cd8aced1c3 --- /dev/null +++ b/superset-frontend/packages/superset-ui-chart-controls/test/utils/normalizedFormData.test.tsx @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { SqlaFormData } from '@superset-ui/core'; +import { getStandadizedFormData } from '../../src'; + +const formData: SqlaFormData = { + metrics: [ + 'count(*)', + { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, + ], + metric: 'max(sales)', + datasource: 'foo', + viz_type: 'table', +}; + +test('should standardize metrics', () => { + expect(getStandadizedFormData(formData).sharedFormData.metrics).toEqual([ + 'count(*)', + { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, + 'max(sales)', + ]); +}); diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts index 8511c3ca5645e..cbbf70fd0909d 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts @@ -96,4 +96,13 @@ export default { label: t('Number format'), }, }, + + denormalizeFormData: sfd => { + const formData = sfd.getLatestFormData('big_number_total'); + return { + ...formData, + metric: sfd.sharedFormData.metrics[0], + adhoc_filters: sfd.sharedFormData.filters, + }; + }, } as ControlPanelConfig; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx index f234df0c82b4a..df36552a17aa3 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx @@ -240,6 +240,14 @@ const config: ControlPanelConfig = { default: rowLimit, }, }, + denormalizeFormData: sfd => { + const formData = sfd.getLatestFormData('echarts_timeseries_line'); + return { + ...formData, + metrics: sfd.sharedFormData.metrics, + adhoc_filters: sfd.sharedFormData.filters, + }; + }, }; export default config; diff --git a/superset-frontend/src/explore/reducers/exploreReducer.js b/superset-frontend/src/explore/reducers/exploreReducer.js index 4dfcc9a1781bc..19328718da5f6 100644 --- a/superset-frontend/src/explore/reducers/exploreReducer.js +++ b/superset-frontend/src/explore/reducers/exploreReducer.js @@ -17,7 +17,7 @@ * under the License. */ /* eslint camelcase: 0 */ -import { ensureIsArray } from '@superset-ui/core'; +import { ensureIsArray, getChartControlPanelRegistry } from '@superset-ui/core'; import { DYNAMIC_PLUGIN_CONTROLS_READY } from 'src/components/Chart/chartAction'; import { DEFAULT_TIME_RANGE } from 'src/explore/constants'; import { getControlsState } from 'src/explore/store'; @@ -29,6 +29,7 @@ import { } from 'src/explore/controlUtils'; import * as actions from 'src/explore/actions/exploreActions'; import { LocalStorageKeys, setItem } from 'src/utils/localStorageHelpers'; +import { getStandadizedFormData } from '@superset-ui/chart-controls'; export default function exploreReducer(state = {}, action) { const actionHandlers = { @@ -205,18 +206,31 @@ export default function exploreReducer(state = {}, action) { }); const hasErrors = errors && errors.length > 0; - const currentControlsState = + const isVizSwitch = action.controlName === 'viz_type' && - action.value !== state.controls.viz_type.value - ? // rebuild the full control state if switching viz type - getControlsState( - state, - getFormDataFromControls({ - ...state.controls, - viz_type: control, - }), - ) - : state.controls; + action.value !== state.controls.viz_type.value; + let currentControlsState = state.controls; + if (isVizSwitch) { + const targetControlPanel = + getChartControlPanelRegistry().get(action.value) || {}; + + if (targetControlPanel.denormalizeFormData) { + const fd = targetControlPanel.denormalizeFormData( + getStandadizedFormData(state.form_data), + ); + fd.viz_type = action.value; + currentControlsState = getControlsState(state, fd); + new_form_data = fd; + } else { + currentControlsState = getControlsState( + state, + getFormDataFromControls({ + ...state.controls, + viz_type: control, + }), + ); + } + } return { ...state, From 238cf1a9897258b2d270007e0a334d736562246d Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Tue, 10 May 2022 21:22:19 +0800 Subject: [PATCH 02/27] wip --- .../src/utils/normalizedFormData.ts | 8 +++----- .../src/explore/reducers/exploreReducer.js | 12 ++++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts b/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts index c0d1f6920abaf..8605f2a4b9ae0 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts @@ -66,9 +66,7 @@ export class StandardizedFormData { return this.sfd.memorizedFormData.get(vizType); } - return this.sfd.memorizedFormData.size === 0 - ? {} - : this.sfd.memorizedFormData[this.sfd.memorizedFormData.keys()[0]]; + return this.memorizedFormData.slice(-1)[0][1]; } get sharedFormData() { @@ -81,14 +79,14 @@ export class StandardizedFormData { } export function getStandadizedFormData( - formData: QueryFormData, + sourceFormData: QueryFormData, ): StandardizedFormData { const sharedFormData = { metrics: [], columns: [], filters: [], }; - + const formData = { ...sourceFormData }; Object.entries(formData).forEach(([key, value]) => { if (reversedMap.has(key)) { sharedFormData[reversedMap.get(key)].push(...ensureIsArray(value)); diff --git a/superset-frontend/src/explore/reducers/exploreReducer.js b/superset-frontend/src/explore/reducers/exploreReducer.js index 19328718da5f6..876695d9d66d8 100644 --- a/superset-frontend/src/explore/reducers/exploreReducer.js +++ b/superset-frontend/src/explore/reducers/exploreReducer.js @@ -131,11 +131,10 @@ export default function exploreReducer(state = {}, action) { }; }, [actions.SET_FIELD_VALUE]() { - const new_form_data = state.form_data; + const { controlName, value, validationErrors } = action; + let new_form_data = { ...state.form_data, [controlName]: value }; const old_metrics_data = state.form_data.metrics; const new_column_config = state.form_data.column_config; - const { controlName, value, validationErrors } = action; - new_form_data[controlName] = value; const vizType = new_form_data.viz_type; @@ -215,12 +214,13 @@ export default function exploreReducer(state = {}, action) { getChartControlPanelRegistry().get(action.value) || {}; if (targetControlPanel.denormalizeFormData) { - const fd = targetControlPanel.denormalizeFormData( - getStandadizedFormData(state.form_data), - ); + const sfd = getStandadizedFormData(state.form_data); + console.log('sfd????', sfd); + const fd = targetControlPanel.denormalizeFormData(sfd); fd.viz_type = action.value; currentControlsState = getControlsState(state, fd); new_form_data = fd; + console.log('??????', new_form_data); } else { currentControlsState = getControlsState( state, From d930a87a34f0a536f9bf6d567656ede29336f97c Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Tue, 10 May 2022 21:23:02 +0800 Subject: [PATCH 03/27] wip --- superset-frontend/src/explore/reducers/exploreReducer.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/superset-frontend/src/explore/reducers/exploreReducer.js b/superset-frontend/src/explore/reducers/exploreReducer.js index 876695d9d66d8..567af52b09021 100644 --- a/superset-frontend/src/explore/reducers/exploreReducer.js +++ b/superset-frontend/src/explore/reducers/exploreReducer.js @@ -215,12 +215,10 @@ export default function exploreReducer(state = {}, action) { if (targetControlPanel.denormalizeFormData) { const sfd = getStandadizedFormData(state.form_data); - console.log('sfd????', sfd); const fd = targetControlPanel.denormalizeFormData(sfd); fd.viz_type = action.value; currentControlsState = getControlsState(state, fd); new_form_data = fd; - console.log('??????', new_form_data); } else { currentControlsState = getControlsState( state, From b3c8702269c7b15ebe00bf30f6aa716af9a5bce3 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Tue, 10 May 2022 22:16:47 +0800 Subject: [PATCH 04/27] encapsulated --- .../src/utils/index.ts | 2 +- ...zedFormData.ts => standardizedFormData.ts} | 99 +++++++++---------- ... => standardizedFormDataFormData.test.tsx} | 5 +- .../src/explore/reducers/exploreReducer.js | 4 +- 4 files changed, 55 insertions(+), 55 deletions(-) rename superset-frontend/packages/superset-ui-chart-controls/src/utils/{normalizedFormData.ts => standardizedFormData.ts} (52%) rename superset-frontend/packages/superset-ui-chart-controls/test/utils/{normalizedFormData.test.tsx => standardizedFormDataFormData.test.tsx} (89%) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts b/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts index 99ab98cde648f..833808207c35f 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts @@ -22,4 +22,4 @@ export * from './expandControlConfig'; export * from './getColorFormatters'; export { default as mainMetric } from './mainMetric'; export { default as columnChoices } from './columnChoices'; -export * from './normalizedFormData'; +export * from './standardizedFormData'; diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts b/superset-frontend/packages/superset-ui-chart-controls/src/utils/standardizedFormData.ts similarity index 52% rename from superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts rename to superset-frontend/packages/superset-ui-chart-controls/src/utils/standardizedFormData.ts index 8605f2a4b9ae0..3dbd7c8ecbaf9 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/normalizedFormData.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/standardizedFormData.ts @@ -26,41 +26,69 @@ import { QueryFormData, } from '@superset-ui/core'; -const sharedControls = { - metrics: ['metric', 'metrics', 'metric_2'], - columns: ['groupby', 'columns'], - filters: ['adhoc_filters'], -}; -const reversedMap = new Map(); -Object.entries(sharedControls).forEach(([key, names]) => { - names.forEach(name => { - reversedMap.set(name, key); - }); -}); - function isStandardizedFormData(formData: JsonObject): boolean { return 'sharedFormData' in formData && 'memorizedFormData' in formData; } -export interface SharedFormData { - metrics: AdhocMetric[]; - columns: (AdhocColumn | PhysicalColumn)[]; - filters: AdhocFilter[]; +interface iStandardizedFormData { + sharedFormData: { + metrics: AdhocMetric[]; + columns: (AdhocColumn | PhysicalColumn)[]; + filters: AdhocFilter[]; + }; + memorizedFormData: Map; } export class StandardizedFormData { - private sfd; + private sfd: iStandardizedFormData; + + constructor(sourceFormData: QueryFormData) { + const sharedFormData = { + metrics: [], + columns: [], + filters: [], + }; + // shallow copy + const formData = { ...sourceFormData }; + const reversedMap = StandardizedFormData.getReversedMap(); - constructor( - sharedFormData: SharedFormData, - memorizedFormData: Map, - ) { + Object.entries(formData).forEach(([key, value]) => { + if (reversedMap.has(key)) { + sharedFormData[reversedMap.get(key)].push(...ensureIsArray(value)); + } + }); + + const memorizedFormData = + isStandardizedFormData(formData) && + Array.isArray(formData.memorizedFormData) + ? new Map(formData.memorizedFormData) + : new Map(); + const vizType = formData.viz_type; + if (memorizedFormData.has(vizType)) { + memorizedFormData.delete(vizType); + } + memorizedFormData.set(vizType, formData); this.sfd = { sharedFormData, memorizedFormData, }; } + static getReversedMap() { + const sharedControls = { + metrics: ['metric', 'metrics', 'metric_2'], + columns: ['groupby', 'columns'], + filters: ['adhoc_filters'], + }; + const reversedMap = new Map(); + Object.entries(sharedControls).forEach(([key, names]) => { + names.forEach(name => { + reversedMap.set(name, key); + }); + }); + return reversedMap; + } + getLatestFormData(vizType: string) { if (this.sfd.memorizedFormData.has(vizType)) { return this.sfd.memorizedFormData.get(vizType); @@ -77,32 +105,3 @@ export class StandardizedFormData { return Array.from(this.sfd.memorizedFormData.entries()); } } - -export function getStandadizedFormData( - sourceFormData: QueryFormData, -): StandardizedFormData { - const sharedFormData = { - metrics: [], - columns: [], - filters: [], - }; - const formData = { ...sourceFormData }; - Object.entries(formData).forEach(([key, value]) => { - if (reversedMap.has(key)) { - sharedFormData[reversedMap.get(key)].push(...ensureIsArray(value)); - } - }); - - const memorizedFormData = - isStandardizedFormData(formData) && - Array.isArray(formData.memorizedFormData) - ? new Map(formData.memorizedFormData) - : new Map(); - const vizType = formData.viz_type; - if (memorizedFormData.has(vizType)) { - memorizedFormData.delete(vizType); - } - memorizedFormData.set(vizType, formData); - - return new StandardizedFormData(sharedFormData, memorizedFormData); -} diff --git a/superset-frontend/packages/superset-ui-chart-controls/test/utils/normalizedFormData.test.tsx b/superset-frontend/packages/superset-ui-chart-controls/test/utils/standardizedFormDataFormData.test.tsx similarity index 89% rename from superset-frontend/packages/superset-ui-chart-controls/test/utils/normalizedFormData.test.tsx rename to superset-frontend/packages/superset-ui-chart-controls/test/utils/standardizedFormDataFormData.test.tsx index 2e9cd8aced1c3..1ffed668da9c9 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/test/utils/normalizedFormData.test.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/test/utils/standardizedFormDataFormData.test.tsx @@ -17,7 +17,7 @@ * under the License. */ import { SqlaFormData } from '@superset-ui/core'; -import { getStandadizedFormData } from '../../src'; +import { StandardizedFormData } from '../../src'; const formData: SqlaFormData = { metrics: [ @@ -30,7 +30,8 @@ const formData: SqlaFormData = { }; test('should standardize metrics', () => { - expect(getStandadizedFormData(formData).sharedFormData.metrics).toEqual([ + const sfd = new StandardizedFormData(formData); + expect(sfd.sharedFormData.metrics).toEqual([ 'count(*)', { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, 'max(sales)', diff --git a/superset-frontend/src/explore/reducers/exploreReducer.js b/superset-frontend/src/explore/reducers/exploreReducer.js index 567af52b09021..8d60f7e2710a0 100644 --- a/superset-frontend/src/explore/reducers/exploreReducer.js +++ b/superset-frontend/src/explore/reducers/exploreReducer.js @@ -29,7 +29,7 @@ import { } from 'src/explore/controlUtils'; import * as actions from 'src/explore/actions/exploreActions'; import { LocalStorageKeys, setItem } from 'src/utils/localStorageHelpers'; -import { getStandadizedFormData } from '@superset-ui/chart-controls'; +import { StandardizedFormData } from '@superset-ui/chart-controls'; export default function exploreReducer(state = {}, action) { const actionHandlers = { @@ -214,7 +214,7 @@ export default function exploreReducer(state = {}, action) { getChartControlPanelRegistry().get(action.value) || {}; if (targetControlPanel.denormalizeFormData) { - const sfd = getStandadizedFormData(state.form_data); + const sfd = new StandardizedFormData(state.form_data); const fd = targetControlPanel.denormalizeFormData(sfd); fd.viz_type = action.value; currentControlsState = getControlsState(state, fd); From eddd64cfe9a8443ce68fa0c730ac219cea959ae7 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Wed, 11 May 2022 15:07:45 +0800 Subject: [PATCH 05/27] wip --- .../superset-ui-chart-controls/src/types.ts | 14 +++- .../src/utils/index.ts | 1 - .../BigNumber/BigNumberTotal/controlPanel.ts | 13 +-- .../src/Timeseries/Regular/controlPanel.tsx | 12 +-- .../src/explore/controlUtils/index.ts | 1 + .../standardizedFormData.test.tsx} | 11 ++- .../controlUtils}/standardizedFormData.ts | 79 ++++++++++++------- .../src/explore/reducers/exploreReducer.js | 33 +++----- 8 files changed, 93 insertions(+), 71 deletions(-) rename superset-frontend/{packages/superset-ui-chart-controls/test/utils/standardizedFormDataFormData.test.tsx => src/explore/controlUtils/standardizedFormData.test.tsx} (78%) rename superset-frontend/{packages/superset-ui-chart-controls/src/utils => src/explore/controlUtils}/standardizedFormData.ts (58%) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index af952478c8ad7..2fb85f6d29705 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -26,9 +26,9 @@ import type { Metric, QueryFormData, } from '@superset-ui/core'; +import { AdhocMetric, PhysicalColumn } from '@superset-ui/core'; import { sharedControls } from './shared-controls'; import sharedControlComponents from './shared-controls/components'; -import { StandardizedFormData } from './utils'; export type { Metric } from '@superset-ui/core'; export type { ControlFormItemSpec } from './components/ControlForm'; @@ -341,12 +341,22 @@ export interface ControlPanelSectionConfig { controlSetRows: ControlSetRow[]; } +export interface iStandardizedFormData { + sharedFormData: { + metrics: AdhocMetric[]; + columns: (AdhocColumn | PhysicalColumn)[]; + }; + memorizedFormData: Map; +} + export interface ControlPanelConfig { controlPanelSections: (ControlPanelSectionConfig | null)[]; controlOverrides?: ControlOverrides; sectionOverrides?: SectionOverrides; onInit?: (state: ControlStateMapping) => void; - denormalizeFormData?: (formData: StandardizedFormData) => QueryFormData; + denormalizeFormData?: ( + formData: QueryFormData & { standardized_form_data: iStandardizedFormData }, + ) => QueryFormData; } export type ControlOverrides = { diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts b/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts index 833808207c35f..bfb5b5e824e64 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts @@ -22,4 +22,3 @@ export * from './expandControlConfig'; export * from './getColorFormatters'; export { default as mainMetric } from './mainMetric'; export { default as columnChoices } from './columnChoices'; -export * from './standardizedFormData'; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts index cbbf70fd0909d..73a1311ee74cd 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts @@ -96,13 +96,8 @@ export default { label: t('Number format'), }, }, - - denormalizeFormData: sfd => { - const formData = sfd.getLatestFormData('big_number_total'); - return { - ...formData, - metric: sfd.sharedFormData.metrics[0], - adhoc_filters: sfd.sharedFormData.filters, - }; - }, + denormalizeFormData: formData => ({ + ...formData, + metric: formData.standardized_form_data.sharedFormData.metrics[0], + }), } as ControlPanelConfig; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx index df36552a17aa3..73e7106ee9fb4 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx @@ -240,14 +240,10 @@ const config: ControlPanelConfig = { default: rowLimit, }, }, - denormalizeFormData: sfd => { - const formData = sfd.getLatestFormData('echarts_timeseries_line'); - return { - ...formData, - metrics: sfd.sharedFormData.metrics, - adhoc_filters: sfd.sharedFormData.filters, - }; - }, + denormalizeFormData: formData => ({ + ...formData, + metrics: formData.standardized_form_data.sharedFormData.metrics, + }), }; export default config; diff --git a/superset-frontend/src/explore/controlUtils/index.ts b/superset-frontend/src/explore/controlUtils/index.ts index d9cb1132f4f5c..b39233422b80a 100644 --- a/superset-frontend/src/explore/controlUtils/index.ts +++ b/superset-frontend/src/explore/controlUtils/index.ts @@ -21,3 +21,4 @@ export * from './getControlConfig'; export * from './getControlState'; export * from './getFormDataFromControls'; export * from './getControlValuesCompatibleWithDatasource'; +export * from './standardizedFormData'; diff --git a/superset-frontend/packages/superset-ui-chart-controls/test/utils/standardizedFormDataFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx similarity index 78% rename from superset-frontend/packages/superset-ui-chart-controls/test/utils/standardizedFormDataFormData.test.tsx rename to superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index 1ffed668da9c9..5796dcdcfdecf 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/test/utils/standardizedFormDataFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { SqlaFormData } from '@superset-ui/core'; -import { StandardizedFormData } from '../../src'; +import { getChartControlPanelRegistry, SqlaFormData } from '@superset-ui/core'; +import { StandardizedFormData } from './standardizedFormData'; const formData: SqlaFormData = { metrics: [ @@ -30,7 +30,14 @@ const formData: SqlaFormData = { }; test('should standardize metrics', () => { + getChartControlPanelRegistry().registerValue('big_number_total', { + controlPanelSections: [], + denormalizeFormData: () => { + console.log('xxx'); + }, + }); const sfd = new StandardizedFormData(formData); + // sfd.transform('big_number_total'); expect(sfd.sharedFormData.metrics).toEqual([ 'count(*)', { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts similarity index 58% rename from superset-frontend/packages/superset-ui-chart-controls/src/utils/standardizedFormData.ts rename to superset-frontend/src/explore/controlUtils/standardizedFormData.ts index 3dbd7c8ecbaf9..d73e32781acd4 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -17,27 +17,13 @@ * under the License. */ import { - AdhocColumn, - AdhocFilter, - AdhocMetric, ensureIsArray, - JsonObject, - PhysicalColumn, + getChartControlPanelRegistry, QueryFormData, } from '@superset-ui/core'; - -function isStandardizedFormData(formData: JsonObject): boolean { - return 'sharedFormData' in formData && 'memorizedFormData' in formData; -} - -interface iStandardizedFormData { - sharedFormData: { - metrics: AdhocMetric[]; - columns: (AdhocColumn | PhysicalColumn)[]; - filters: AdhocFilter[]; - }; - memorizedFormData: Map; -} +import { iStandardizedFormData } from '@superset-ui/chart-controls'; +import { getControlsState } from 'src/explore/store'; +import { getFormDataFromControls } from './getFormDataFromControls'; export class StandardizedFormData { private sfd: iStandardizedFormData; @@ -46,9 +32,7 @@ export class StandardizedFormData { const sharedFormData = { metrics: [], columns: [], - filters: [], }; - // shallow copy const formData = { ...sourceFormData }; const reversedMap = StandardizedFormData.getReversedMap(); @@ -58,11 +42,11 @@ export class StandardizedFormData { } }); - const memorizedFormData = - isStandardizedFormData(formData) && - Array.isArray(formData.memorizedFormData) - ? new Map(formData.memorizedFormData) - : new Map(); + const memorizedFormData = Array.isArray( + formData?.standardized_form_data?.memorizedFormData, + ) + ? new Map(formData.standardized_form_data.memorizedFormData) + : new Map(); const vizType = formData.viz_type; if (memorizedFormData.has(vizType)) { memorizedFormData.delete(vizType); @@ -78,7 +62,6 @@ export class StandardizedFormData { const sharedControls = { metrics: ['metric', 'metrics', 'metric_2'], columns: ['groupby', 'columns'], - filters: ['adhoc_filters'], }; const reversedMap = new Map(); Object.entries(sharedControls).forEach(([key, names]) => { @@ -89,9 +72,9 @@ export class StandardizedFormData { return reversedMap; } - getLatestFormData(vizType: string) { + getLatestFormData(vizType: string): QueryFormData { if (this.sfd.memorizedFormData.has(vizType)) { - return this.sfd.memorizedFormData.get(vizType); + return this.sfd.memorizedFormData.get(vizType) as QueryFormData; } return this.memorizedFormData.slice(-1)[0][1]; @@ -104,4 +87,44 @@ export class StandardizedFormData { get memorizedFormData() { return Array.from(this.sfd.memorizedFormData.entries()); } + + dumpSFD() { + return { + sharedFormData: this.sharedFormData, + memorizedFormData: this.memorizedFormData, + }; + } + + transform( + sourceVizType: string, + targetVizType: string, + exploreState: Record, + ): { + formData: QueryFormData; + controlsState: any; + } { + const sourceFormData = this.getLatestFormData(sourceVizType); + const targetControlsState = getControlsState(exploreState, { + ...sourceFormData, + viz_type: targetVizType, + }); + const targetFormData = { + ...getFormDataFromControls(targetControlsState), + standardized_form_data: this.dumpSFD(), + }; + + const controlPanel = getChartControlPanelRegistry().get(targetVizType); + if (controlPanel?.denormalizeFormData) { + const transformed = controlPanel.denormalizeFormData(targetFormData); + return { + formData: transformed, + controlsState: getControlsState(exploreState, transformed), + }; + } + + return { + formData: targetFormData, + controlsState: targetControlsState, + }; + } } diff --git a/superset-frontend/src/explore/reducers/exploreReducer.js b/superset-frontend/src/explore/reducers/exploreReducer.js index 8d60f7e2710a0..6229ffc536a06 100644 --- a/superset-frontend/src/explore/reducers/exploreReducer.js +++ b/superset-frontend/src/explore/reducers/exploreReducer.js @@ -17,19 +17,18 @@ * under the License. */ /* eslint camelcase: 0 */ -import { ensureIsArray, getChartControlPanelRegistry } from '@superset-ui/core'; +import { ensureIsArray } from '@superset-ui/core'; import { DYNAMIC_PLUGIN_CONTROLS_READY } from 'src/components/Chart/chartAction'; import { DEFAULT_TIME_RANGE } from 'src/explore/constants'; import { getControlsState } from 'src/explore/store'; import { getControlConfig, - getFormDataFromControls, getControlStateFromControlConfig, getControlValuesCompatibleWithDatasource, + StandardizedFormData, } from 'src/explore/controlUtils'; import * as actions from 'src/explore/actions/exploreActions'; import { LocalStorageKeys, setItem } from 'src/utils/localStorageHelpers'; -import { StandardizedFormData } from '@superset-ui/chart-controls'; export default function exploreReducer(state = {}, action) { const actionHandlers = { @@ -210,24 +209,16 @@ export default function exploreReducer(state = {}, action) { action.value !== state.controls.viz_type.value; let currentControlsState = state.controls; if (isVizSwitch) { - const targetControlPanel = - getChartControlPanelRegistry().get(action.value) || {}; - - if (targetControlPanel.denormalizeFormData) { - const sfd = new StandardizedFormData(state.form_data); - const fd = targetControlPanel.denormalizeFormData(sfd); - fd.viz_type = action.value; - currentControlsState = getControlsState(state, fd); - new_form_data = fd; - } else { - currentControlsState = getControlsState( - state, - getFormDataFromControls({ - ...state.controls, - viz_type: control, - }), - ); - } + // get StandardizedFormData from source form_data + const sfd = new StandardizedFormData(state.form_data); + const transformed = sfd.transform( + state.controls.viz_type.value, + action.value, + state, + ); + console.log(transformed); + new_form_data = transformed.formData; + currentControlsState = transformed.controlsState; } return { From d078abd88a8ecc598ecc6b871a162cbd32e98092 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Wed, 11 May 2022 15:26:10 +0800 Subject: [PATCH 06/27] fix transform --- .../src/explore/controlUtils/standardizedFormData.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index d73e32781acd4..7dc5d8e9a8a53 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -73,6 +73,8 @@ export class StandardizedFormData { } getLatestFormData(vizType: string): QueryFormData { + console.log('memorized formdata', this.sfd.memorizedFormData); + console.log('vizType', vizType); if (this.sfd.memorizedFormData.has(vizType)) { return this.sfd.memorizedFormData.get(vizType) as QueryFormData; } @@ -103,9 +105,9 @@ export class StandardizedFormData { formData: QueryFormData; controlsState: any; } { - const sourceFormData = this.getLatestFormData(sourceVizType); + const latestFormData = this.getLatestFormData(targetVizType); const targetControlsState = getControlsState(exploreState, { - ...sourceFormData, + ...latestFormData, viz_type: targetVizType, }); const targetFormData = { From e6c3f04f260003e024afc1e79b4de46043a8b9de Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Wed, 11 May 2022 15:26:52 +0800 Subject: [PATCH 07/27] remove console --- .../src/explore/controlUtils/standardizedFormData.ts | 2 -- superset-frontend/src/explore/reducers/exploreReducer.js | 1 - 2 files changed, 3 deletions(-) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index 7dc5d8e9a8a53..c58dcb05c93ff 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -73,8 +73,6 @@ export class StandardizedFormData { } getLatestFormData(vizType: string): QueryFormData { - console.log('memorized formdata', this.sfd.memorizedFormData); - console.log('vizType', vizType); if (this.sfd.memorizedFormData.has(vizType)) { return this.sfd.memorizedFormData.get(vizType) as QueryFormData; } diff --git a/superset-frontend/src/explore/reducers/exploreReducer.js b/superset-frontend/src/explore/reducers/exploreReducer.js index 6229ffc536a06..39412ace8d71d 100644 --- a/superset-frontend/src/explore/reducers/exploreReducer.js +++ b/superset-frontend/src/explore/reducers/exploreReducer.js @@ -216,7 +216,6 @@ export default function exploreReducer(state = {}, action) { action.value, state, ); - console.log(transformed); new_form_data = transformed.formData; currentControlsState = transformed.controlsState; } From 93f300389eaf23d09f8c06abc04f89545d28ba86 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Wed, 11 May 2022 21:18:01 +0800 Subject: [PATCH 08/27] fix type --- .../superset-ui-chart-controls/src/types.ts | 10 ++++++---- .../controlUtils/standardizedFormData.ts | 17 +++++++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 2fb85f6d29705..5b1018e1baf8a 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -341,11 +341,13 @@ export interface ControlPanelSectionConfig { controlSetRows: ControlSetRow[]; } +export interface SharedFormData { + metrics: AdhocMetric[]; + columns: (AdhocColumn | PhysicalColumn)[]; +} + export interface iStandardizedFormData { - sharedFormData: { - metrics: AdhocMetric[]; - columns: (AdhocColumn | PhysicalColumn)[]; - }; + sharedFormData: SharedFormData; memorizedFormData: Map; } diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index c58dcb05c93ff..03a8d459154fe 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -21,10 +21,19 @@ import { getChartControlPanelRegistry, QueryFormData, } from '@superset-ui/core'; -import { iStandardizedFormData } from '@superset-ui/chart-controls'; +import { + ControlStateMapping, + SharedFormData, + iStandardizedFormData, +} from '@superset-ui/chart-controls'; import { getControlsState } from 'src/explore/store'; import { getFormDataFromControls } from './getFormDataFromControls'; +const sharedControls: Record = { + metrics: ['metric', 'metrics', 'metric_2'], + columns: ['groupby', 'columns'], +}; + export class StandardizedFormData { private sfd: iStandardizedFormData; @@ -59,10 +68,6 @@ export class StandardizedFormData { } static getReversedMap() { - const sharedControls = { - metrics: ['metric', 'metrics', 'metric_2'], - columns: ['groupby', 'columns'], - }; const reversedMap = new Map(); Object.entries(sharedControls).forEach(([key, names]) => { names.forEach(name => { @@ -101,7 +106,7 @@ export class StandardizedFormData { exploreState: Record, ): { formData: QueryFormData; - controlsState: any; + controlsState: ControlStateMapping; } { const latestFormData = this.getLatestFormData(targetVizType); const targetControlsState = getControlsState(exploreState, { From b2f4230c2c90cce3944dc95938e6621aedcfd2fe Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 00:44:12 +0800 Subject: [PATCH 09/27] add public controls --- .../superset-ui-chart-controls/src/types.ts | 1 + .../controlUtils/standardizedFormData.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 5b1018e1baf8a..14c121fc515b7 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -344,6 +344,7 @@ export interface ControlPanelSectionConfig { export interface SharedFormData { metrics: AdhocMetric[]; columns: (AdhocColumn | PhysicalColumn)[]; + xaxis: (AdhocColumn | PhysicalColumn)[]; } export interface iStandardizedFormData { diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index 03a8d459154fe..f8703e3f3e585 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -32,7 +32,19 @@ import { getFormDataFromControls } from './getFormDataFromControls'; const sharedControls: Record = { metrics: ['metric', 'metrics', 'metric_2'], columns: ['groupby', 'columns'], + xaxis: ['x_axis'], }; +const publicControls = [ + 'granularity', + 'granularity_sqla', + 'time_grain_sqla', + 'time_range', + 'adhoc_filters', + 'limit', + 'timeseries_limit_metric', + 'order_desc', + 'row_limit', +]; export class StandardizedFormData { private sfd: iStandardizedFormData; @@ -109,8 +121,15 @@ export class StandardizedFormData { controlsState: ControlStateMapping; } { const latestFormData = this.getLatestFormData(targetVizType); + const publicFormData = {}; + publicControls.forEach(key => { + if (key in exploreState.form_data) { + publicFormData[key] = exploreState.form_data[key]; + } + }); const targetControlsState = getControlsState(exploreState, { ...latestFormData, + ...publicFormData, viz_type: targetVizType, }); const targetFormData = { From 8681a9b428dc4e0af5bb1d186b82dec96688c146 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 00:47:46 +0800 Subject: [PATCH 10/27] add axis --- .../src/explore/controlUtils/standardizedFormData.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index f8703e3f3e585..6940085a7c89f 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -53,6 +53,7 @@ export class StandardizedFormData { const sharedFormData = { metrics: [], columns: [], + xaxis: [], }; const formData = { ...sourceFormData }; const reversedMap = StandardizedFormData.getReversedMap(); From 6e1fed7c59da128340dc5960385de1f579300793 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 01:10:28 +0800 Subject: [PATCH 11/27] add comments --- .../src/explore/controlUtils/standardizedFormData.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index 6940085a7c89f..b68a4858e2e42 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -50,6 +50,9 @@ export class StandardizedFormData { private sfd: iStandardizedFormData; constructor(sourceFormData: QueryFormData) { + /* + * Support form_data for smooth switching between different viz + * */ const sharedFormData = { metrics: [], columns: [], @@ -121,6 +124,15 @@ export class StandardizedFormData { formData: QueryFormData; controlsState: ControlStateMapping; } { + /* + * Transfrom form_data between different viz. Return new form_data and controlsState. + * 1. get memorized form_data by viz type or get previous form_data + * 2. collect public control values + * 3. generate initial targetControlsState + * 4. attach `standardized_form_data` to the initial form_data + * 5. call denormalizeFormData to transform initial form_data if the plugin was defined + * 6. use final form_data to generate controlsState + * */ const latestFormData = this.getLatestFormData(targetVizType); const publicFormData = {}; publicControls.forEach(key => { From 86a9f8a3adf2c7a58a8aac2388f494ec473f4b78 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 01:13:21 +0800 Subject: [PATCH 12/27] ut --- .../explore/controlUtils/standardizedFormData.test.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index 5796dcdcfdecf..08c1b7cc45e46 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { getChartControlPanelRegistry, SqlaFormData } from '@superset-ui/core'; +import { SqlaFormData } from '@superset-ui/core'; import { StandardizedFormData } from './standardizedFormData'; const formData: SqlaFormData = { @@ -30,14 +30,7 @@ const formData: SqlaFormData = { }; test('should standardize metrics', () => { - getChartControlPanelRegistry().registerValue('big_number_total', { - controlPanelSections: [], - denormalizeFormData: () => { - console.log('xxx'); - }, - }); const sfd = new StandardizedFormData(formData); - // sfd.transform('big_number_total'); expect(sfd.sharedFormData.metrics).toEqual([ 'count(*)', { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, From 596366ceeae0a2f58a03280e82b3b5b2d2a5e714 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 01:19:46 +0800 Subject: [PATCH 13/27] pie chart and bignumber --- .../src/BigNumber/BigNumberWithTrendline/controlPanel.tsx | 4 ++++ .../plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx index 3ba00f55ea212..395ea3d6d6096 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx @@ -270,6 +270,10 @@ const config: ControlPanelConfig = { label: t('Number format'), }, }, + denormalizeFormData: formData => ({ + ...formData, + metric: formData.standardized_form_data.sharedFormData.metrics[0], + }), }; export default config; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx index 9056446f9f412..25cc64e7b7cd5 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx @@ -253,6 +253,11 @@ const config: ControlPanelConfig = { default: 100, }, }, + denormalizeFormData: formData => ({ + ...formData, + metric: formData.standardized_form_data.sharedFormData.metrics[0], + columns: formData.standardized_form_data.sharedFormData.columns, + }), }; export default config; From 54d3083fd107c77696f3f1628cf71d1fb3811375 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 02:04:17 +0800 Subject: [PATCH 14/27] fix pie --- .../plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx index 25cc64e7b7cd5..55ff3d0e6ec01 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx @@ -256,7 +256,7 @@ const config: ControlPanelConfig = { denormalizeFormData: formData => ({ ...formData, metric: formData.standardized_form_data.sharedFormData.metrics[0], - columns: formData.standardized_form_data.sharedFormData.columns, + groupby: formData.standardized_form_data.sharedFormData.columns, }), }; From 3b04ff40193f30212769ab28c4c3eb40e0a11918 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 18:25:04 +0800 Subject: [PATCH 15/27] table and ut --- .../plugin-chart-table/src/controlPanel.tsx | 8 + .../standardizedFormData.test.tsx | 173 +++++++++++++++++- .../controlUtils/standardizedFormData.ts | 15 +- .../src/explore/reducers/exploreReducer.js | 6 +- 4 files changed, 188 insertions(+), 14 deletions(-) diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx index bb855bd7ccc56..f1a360be5f33a 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx @@ -531,6 +531,14 @@ const config: ControlPanelConfig = { ], }, ], + denormalizeFormData: formData => ({ + ...formData, + metrics: formData.standardized_form_data.sharedFormData.metrics, + groupby: [ + ...formData.standardized_form_data.sharedFormData.columns, + ...formData.standardized_form_data.sharedFormData.xaxis, + ], + }), }; export default config; diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index 08c1b7cc45e46..d0d30df2cba34 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -16,24 +16,187 @@ * specific language governing permissions and limitations * under the License. */ -import { SqlaFormData } from '@superset-ui/core'; +import { getChartControlPanelRegistry, SqlaFormData } from '@superset-ui/core'; +import TableChartPlugin from '@superset-ui/plugin-chart-table'; +import { BigNumberTotalChartPlugin } from '@superset-ui/plugin-chart-echarts'; import { StandardizedFormData } from './standardizedFormData'; -const formData: SqlaFormData = { +const transformationMockFD: SqlaFormData = { metrics: [ 'count(*)', { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, ], metric: 'max(sales)', + metric_2: 'min(sales)', + groupby: ['foo'], + columns: ['bar'], + x_axis: 'dttm', datasource: 'foo', viz_type: 'table', }; -test('should standardize metrics', () => { - const sfd = new StandardizedFormData(formData); - expect(sfd.sharedFormData.metrics).toEqual([ +const tableVizFormData = { + datasource: '30__table', + viz_type: 'table', + time_grain_sqla: 'P1D', + time_range: 'No filter', + query_mode: 'aggregate', + groupby: ['name'], + metrics: ['count'], + all_columns: [], + percent_metrics: [], + adhoc_filters: [], + order_by_cols: [], + row_limit: 10000, + server_page_length: 10, + order_desc: true, + table_timestamp_format: 'smart_date', + show_cell_bars: true, + color_pn: true, + applied_time_extras: {}, + url_params: { + form_data_key: + 'p3No_sqDW7k-kMTzlBPAPd9vwp1IXTf6stbyzjlrPPa0ninvdYUUiMC6F1iKit3Y', + dataset_id: '30', + }, +}; +const tableVizStore = { + form_data: tableVizFormData, + controls: { + datasource: { + value: '30__table', + }, + viz_type: { + value: 'table', + }, + slice_id: {}, + cache_timeout: {}, + url_params: { + value: { + form_data_key: + 'p3No_sqDW7k-kMTzlBPAPd9vwp1IXTf6stbyzjlrPPa0ninvdYUUiMC6F1iKit3Y', + dataset_id: '30', + }, + }, + granularity_sqla: {}, + time_grain_sqla: { + value: 'P1D', + }, + time_range: { + value: 'No filter', + }, + query_mode: { + value: 'aggregate', + }, + groupby: { + value: ['name'], + }, + metrics: { + value: ['count'], + }, + all_columns: { + value: [], + }, + percent_metrics: { + value: [], + }, + adhoc_filters: { + value: [], + }, + timeseries_limit_metric: {}, + order_by_cols: { + value: [], + }, + server_pagination: {}, + row_limit: { + value: 10000, + }, + server_page_length: { + value: 10, + }, + include_time: {}, + order_desc: { + value: true, + }, + show_totals: {}, + emit_filter: {}, + table_timestamp_format: { + value: 'smart_date', + }, + page_length: {}, + include_search: {}, + show_cell_bars: { + value: true, + }, + align_pn: {}, + color_pn: { + value: true, + }, + column_config: {}, + conditional_formatting: {}, + }, + datasource: { + type: 'table', + columns: [], + }, +}; + +beforeAll(() => { + getChartControlPanelRegistry().registerValue( + 'big_number_total', + new BigNumberTotalChartPlugin().controlPanel, + ); + getChartControlPanelRegistry().registerValue( + 'table', + new TableChartPlugin().controlPanel, + ); +}); + +test('should collect control values and create SFD', () => { + const sfd = new StandardizedFormData(transformationMockFD); + expect(sfd.dumpSFD().sharedFormData.metrics).toEqual([ 'count(*)', { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, 'max(sales)', + 'min(sales)', ]); + expect(sfd.dumpSFD().sharedFormData.columns).toEqual(['foo', 'bar']); + expect(sfd.dumpSFD().sharedFormData.xaxis).toEqual(['dttm']); + expect(sfd.dumpSFD().memorizedFormData).toEqual([ + ['table', transformationMockFD], + ]); +}); + +test('should transform form_data between table and bigNumberTotal', () => { + // table -> bigNumberTotal + const sfd = new StandardizedFormData(tableVizFormData); + const { formData: bntFormData, controlsState: btnControlsState } = + sfd.transform('big_number_total', tableVizStore); + expect(Object.keys(bntFormData).sort()).toEqual( + [...Object.keys(btnControlsState), 'standardized_form_data'].sort(), + ); + expect(bntFormData.viz_type).toBe('big_number_total'); + expect(bntFormData.metric).toBe('count'); + + // change control values + bntFormData.metric = 'sum(sales)'; + bntFormData.time_range = '2021 : 2022'; + btnControlsState.metric.value = 'sum(sales)'; + btnControlsState.time_range.value = '2021 : 2022'; + + // bigNumberTotal -> table + const sfd2 = new StandardizedFormData(bntFormData); + const { formData: tblFormData, controlsState: tblControlsState } = + sfd2.transform('table', { + ...tableVizStore, + form_data: bntFormData, + controls: btnControlsState, + }); + expect(Object.keys(tblFormData).sort()).toEqual( + [...Object.keys(tblControlsState), 'standardized_form_data'].sort(), + ); + expect(tblFormData.viz_type).toBe('table'); + expect(tblFormData.metrics).toEqual(['sum(sales)']); + expect(tblFormData.groupby).toEqual([]); + expect(tblFormData.time_range).toBe('2021 : 2022'); }); diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index b68a4858e2e42..caa04ba0c7e3d 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -93,7 +93,7 @@ export class StandardizedFormData { return reversedMap; } - getLatestFormData(vizType: string): QueryFormData { + private getLatestFormData(vizType: string): QueryFormData { if (this.sfd.memorizedFormData.has(vizType)) { return this.sfd.memorizedFormData.get(vizType) as QueryFormData; } @@ -101,11 +101,11 @@ export class StandardizedFormData { return this.memorizedFormData.slice(-1)[0][1]; } - get sharedFormData() { + private get sharedFormData() { return this.sfd.sharedFormData; } - get memorizedFormData() { + private get memorizedFormData() { return Array.from(this.sfd.memorizedFormData.entries()); } @@ -117,7 +117,6 @@ export class StandardizedFormData { } transform( - sourceVizType: string, targetVizType: string, exploreState: Record, ): { @@ -133,6 +132,14 @@ export class StandardizedFormData { * 5. call denormalizeFormData to transform initial form_data if the plugin was defined * 6. use final form_data to generate controlsState * */ + // const foo = {}; + // Object.entries(exploreState.controls).forEach(([key, value]) => foo[key] = {'value': value.value}) + // console.log( + // { + // form_data: exploreState.form_data, + // controls: foo, + // }); + const latestFormData = this.getLatestFormData(targetVizType); const publicFormData = {}; publicControls.forEach(key => { diff --git a/superset-frontend/src/explore/reducers/exploreReducer.js b/superset-frontend/src/explore/reducers/exploreReducer.js index 39412ace8d71d..05dff64be0f77 100644 --- a/superset-frontend/src/explore/reducers/exploreReducer.js +++ b/superset-frontend/src/explore/reducers/exploreReducer.js @@ -211,11 +211,7 @@ export default function exploreReducer(state = {}, action) { if (isVizSwitch) { // get StandardizedFormData from source form_data const sfd = new StandardizedFormData(state.form_data); - const transformed = sfd.transform( - state.controls.viz_type.value, - action.value, - state, - ); + const transformed = sfd.transform(action.value, state); new_form_data = transformed.formData; currentControlsState = transformed.controlsState; } From 7b8dc2f026cac7ff7d3c2955cf914b9c7374fc00 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 18:26:03 +0800 Subject: [PATCH 16/27] remove scaffold --- .../src/explore/controlUtils/standardizedFormData.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index caa04ba0c7e3d..35aea8b9c5962 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -132,14 +132,6 @@ export class StandardizedFormData { * 5. call denormalizeFormData to transform initial form_data if the plugin was defined * 6. use final form_data to generate controlsState * */ - // const foo = {}; - // Object.entries(exploreState.controls).forEach(([key, value]) => foo[key] = {'value': value.value}) - // console.log( - // { - // form_data: exploreState.form_data, - // controls: foo, - // }); - const latestFormData = this.getLatestFormData(targetVizType); const publicFormData = {}; publicControls.forEach(key => { From 3e10d0942d3bb5a23ed5ae04e5fecfc013783027 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 20:38:07 +0800 Subject: [PATCH 17/27] add pivottable --- .../packages/superset-ui-chart-controls/src/types.ts | 1 - .../src/plugin/controlPanel.tsx | 12 ++++++++++++ .../plugins/plugin-chart-table/src/controlPanel.tsx | 5 +---- .../controlUtils/standardizedFormData.test.tsx | 1 - .../src/explore/controlUtils/standardizedFormData.ts | 5 +++-- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 14c121fc515b7..5b1018e1baf8a 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -344,7 +344,6 @@ export interface ControlPanelSectionConfig { export interface SharedFormData { metrics: AdhocMetric[]; columns: (AdhocColumn | PhysicalColumn)[]; - xaxis: (AdhocColumn | PhysicalColumn)[]; } export interface iStandardizedFormData { diff --git a/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx index 99efb8bbcce9f..183e1cd3daf26 100644 --- a/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx @@ -18,6 +18,7 @@ */ import React from 'react'; import { + ensureIsArray, QueryFormMetric, smartDateFormatter, t, @@ -367,6 +368,17 @@ const config: ControlPanelConfig = { ], }, ], + denormalizeFormData: formData => { + const groupbyColumns = + formData.standardized_form_data.sharedFormData.columns.filter( + col => !ensureIsArray(formData.groupbyRows).includes(col), + ); + return { + ...formData, + metrics: formData.standardized_form_data.sharedFormData.metrics, + groupbyColumns, + }; + }, }; export default config; diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx index f1a360be5f33a..ac5c487a1c5db 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx @@ -534,10 +534,7 @@ const config: ControlPanelConfig = { denormalizeFormData: formData => ({ ...formData, metrics: formData.standardized_form_data.sharedFormData.metrics, - groupby: [ - ...formData.standardized_form_data.sharedFormData.columns, - ...formData.standardized_form_data.sharedFormData.xaxis, - ], + groupby: formData.standardized_form_data.sharedFormData.columns, }), }; diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index d0d30df2cba34..75db07cc53933 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -161,7 +161,6 @@ test('should collect control values and create SFD', () => { 'min(sales)', ]); expect(sfd.dumpSFD().sharedFormData.columns).toEqual(['foo', 'bar']); - expect(sfd.dumpSFD().sharedFormData.xaxis).toEqual(['dttm']); expect(sfd.dumpSFD().memorizedFormData).toEqual([ ['table', transformationMockFD], ]); diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index 35aea8b9c5962..6cb84019850bd 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -31,8 +31,7 @@ import { getFormDataFromControls } from './getFormDataFromControls'; const sharedControls: Record = { metrics: ['metric', 'metrics', 'metric_2'], - columns: ['groupby', 'columns'], - xaxis: ['x_axis'], + columns: ['groupby', 'columns', 'groupbyColumns', 'groupbyRows'], }; const publicControls = [ 'granularity', @@ -42,8 +41,10 @@ const publicControls = [ 'adhoc_filters', 'limit', 'timeseries_limit_metric', + 'series_limit_metric', 'order_desc', 'row_limit', + 'x_axis', ]; export class StandardizedFormData { From 6fdb5b1bbb3858ca271cb4e316efc63de184dfee Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 20:59:56 +0800 Subject: [PATCH 18/27] add comments --- .../controlUtils/standardizedFormData.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index 6cb84019850bd..9be42a06808e4 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -34,17 +34,34 @@ const sharedControls: Record = { columns: ['groupby', 'columns', 'groupbyColumns', 'groupbyRows'], }; const publicControls = [ + // time section 'granularity', 'granularity_sqla', 'time_grain_sqla', 'time_range', + // filters 'adhoc_filters', + // subquery limit(series limit) 'limit', + // order by clause 'timeseries_limit_metric', 'series_limit_metric', + // desc or asc in order by clause 'order_desc', + // outer query limit 'row_limit', + // x asxs column 'x_axis', + // advanced analytics - rolling window + 'rolling_type', + 'rolling_periods', + 'min_periods', + // advanced analytics - time comparison + 'time_compare', + 'comparison_type', + // advanced analytics - resample + 'resample_rule', + 'resample_method', ]; export class StandardizedFormData { From 4dd96e03d9b6ea95cb1662005e8199d5de56d49f Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Thu, 12 May 2022 21:02:01 +0800 Subject: [PATCH 19/27] minor fix --- .../src/explore/controlUtils/standardizedFormData.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index 9be42a06808e4..e8d195f6657e1 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -74,7 +74,6 @@ export class StandardizedFormData { const sharedFormData = { metrics: [], columns: [], - xaxis: [], }; const formData = { ...sourceFormData }; const reversedMap = StandardizedFormData.getReversedMap(); From 8e3bc74e88d162b7c16167c43c3a621b2fcf2836 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Fri, 13 May 2022 14:13:03 +0800 Subject: [PATCH 20/27] more ut --- .../standardizedFormData.test.tsx | 404 ++++++++++-------- .../controlUtils/standardizedFormData.ts | 5 +- 2 files changed, 238 insertions(+), 171 deletions(-) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index 75db07cc53933..cdf77b79fcd1f 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -19,183 +19,251 @@ import { getChartControlPanelRegistry, SqlaFormData } from '@superset-ui/core'; import TableChartPlugin from '@superset-ui/plugin-chart-table'; import { BigNumberTotalChartPlugin } from '@superset-ui/plugin-chart-echarts'; -import { StandardizedFormData } from './standardizedFormData'; +import { sections } from '@superset-ui/chart-controls'; +import { + StandardizedFormData, + sharedControls, + publicControls, +} from './standardizedFormData'; +import { xAxisControl } from '../../../plugins/plugin-chart-echarts/src/controls'; -const transformationMockFD: SqlaFormData = { - metrics: [ - 'count(*)', - { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, - ], - metric: 'max(sales)', - metric_2: 'min(sales)', - groupby: ['foo'], - columns: ['bar'], - x_axis: 'dttm', - datasource: 'foo', - viz_type: 'table', -}; - -const tableVizFormData = { - datasource: '30__table', - viz_type: 'table', - time_grain_sqla: 'P1D', - time_range: 'No filter', - query_mode: 'aggregate', - groupby: ['name'], - metrics: ['count'], - all_columns: [], - percent_metrics: [], - adhoc_filters: [], - order_by_cols: [], - row_limit: 10000, - server_page_length: 10, - order_desc: true, - table_timestamp_format: 'smart_date', - show_cell_bars: true, - color_pn: true, - applied_time_extras: {}, - url_params: { - form_data_key: - 'p3No_sqDW7k-kMTzlBPAPd9vwp1IXTf6stbyzjlrPPa0ninvdYUUiMC6F1iKit3Y', - dataset_id: '30', - }, -}; -const tableVizStore = { - form_data: tableVizFormData, - controls: { +describe('should collect control values and create SFD', () => { + const sharedControlsFormData = {}; + Object.entries(sharedControls).forEach(([, names]) => { + names.forEach(name => { + sharedControlsFormData[name] = name; + }); + }); + const publicControlsFormData = Object.fromEntries( + publicControls.map((name, idx) => [[name], idx]), + ); + const sourceMockFormData: SqlaFormData = { + ...sharedControlsFormData, + ...publicControlsFormData, + removedKey: 'removedKey', + removedKey2: ['foo', 'bar'], + datasource: '100__table', + viz_type: 'source_viz', + }; + const sourceMockStore = { + form_data: sourceMockFormData, + controls: Object.fromEntries( + Object.entries(sourceMockFormData).map(([key, value]) => [ + key, + { value }, + ]), + ), datasource: { - value: '30__table', - }, - viz_type: { - value: 'table', + type: 'table', + columns: [], }, - slice_id: {}, - cache_timeout: {}, + }; + beforeAll(() => { + getChartControlPanelRegistry().registerValue('source_viz', { + controlPanelSections: [ + sections.advancedAnalyticsControls, + { + label: 'transform controls', + controlSetRows: publicControls.map(control => [control]), + }, + { + label: 'axis column', + controlSetRows: [xAxisControl], + }, + ], + }); + getChartControlPanelRegistry().registerValue('target_viz', { + controlPanelSections: [ + sections.advancedAnalyticsControls, + { + label: 'transform controls', + controlSetRows: publicControls.map(control => [control]), + }, + { + label: 'axis column', + controlSetRows: [[xAxisControl]], + }, + ], + denormalizeFormData: (formData: SqlaFormData) => ({ + ...formData, + columns: formData.standardized_form_data.sharedFormData.columns, + metrics: formData.standardized_form_data.sharedFormData.metrics, + }), + }); + }); + + test('collect sharedControls', () => { + const sfd = new StandardizedFormData(sourceMockFormData); + + expect(sfd.dumpSFD().sharedFormData.metrics).toEqual( + sharedControls.metrics.map(controlName => controlName), + ); + expect(sfd.dumpSFD().sharedFormData.columns).toEqual( + sharedControls.columns.map(controlName => controlName), + ); + }); + + test('should transform all publicControls', () => { + const sfd = new StandardizedFormData(sourceMockFormData); + const { formData } = sfd.transform('target_viz', sourceMockStore); + Object.entries(publicControlsFormData).forEach(([key]) => { + expect(formData).toHaveProperty(key); + }); + Object.entries(sharedControls).forEach(([key, value]) => { + expect(formData[key]).toEqual(value); + }); + }); +}); + +describe('should transform form_data between table and bigNumberTotal', () => { + const tableVizFormData = { + datasource: '30__table', + viz_type: 'table', + time_grain_sqla: 'P1D', + time_range: 'No filter', + query_mode: 'aggregate', + groupby: ['name'], + metrics: ['count'], + all_columns: [], + percent_metrics: [], + adhoc_filters: [], + order_by_cols: [], + row_limit: 10000, + server_page_length: 10, + order_desc: true, + table_timestamp_format: 'smart_date', + show_cell_bars: true, + color_pn: true, + applied_time_extras: {}, url_params: { - value: { - form_data_key: - 'p3No_sqDW7k-kMTzlBPAPd9vwp1IXTf6stbyzjlrPPa0ninvdYUUiMC6F1iKit3Y', - dataset_id: '30', - }, - }, - granularity_sqla: {}, - time_grain_sqla: { - value: 'P1D', - }, - time_range: { - value: 'No filter', - }, - query_mode: { - value: 'aggregate', - }, - groupby: { - value: ['name'], - }, - metrics: { - value: ['count'], - }, - all_columns: { - value: [], - }, - percent_metrics: { - value: [], - }, - adhoc_filters: { - value: [], - }, - timeseries_limit_metric: {}, - order_by_cols: { - value: [], - }, - server_pagination: {}, - row_limit: { - value: 10000, - }, - server_page_length: { - value: 10, - }, - include_time: {}, - order_desc: { - value: true, - }, - show_totals: {}, - emit_filter: {}, - table_timestamp_format: { - value: 'smart_date', + form_data_key: + 'p3No_sqDW7k-kMTzlBPAPd9vwp1IXTf6stbyzjlrPPa0ninvdYUUiMC6F1iKit3Y', + dataset_id: '30', }, - page_length: {}, - include_search: {}, - show_cell_bars: { - value: true, + }; + const tableVizStore = { + form_data: tableVizFormData, + controls: { + datasource: { + value: '30__table', + }, + viz_type: { + value: 'table', + }, + slice_id: {}, + cache_timeout: {}, + url_params: { + value: { + form_data_key: + 'p3No_sqDW7k-kMTzlBPAPd9vwp1IXTf6stbyzjlrPPa0ninvdYUUiMC6F1iKit3Y', + dataset_id: '30', + }, + }, + granularity_sqla: {}, + time_grain_sqla: { + value: 'P1D', + }, + time_range: { + value: 'No filter', + }, + query_mode: { + value: 'aggregate', + }, + groupby: { + value: ['name'], + }, + metrics: { + value: ['count'], + }, + all_columns: { + value: [], + }, + percent_metrics: { + value: [], + }, + adhoc_filters: { + value: [], + }, + timeseries_limit_metric: {}, + order_by_cols: { + value: [], + }, + server_pagination: {}, + row_limit: { + value: 10000, + }, + server_page_length: { + value: 10, + }, + include_time: {}, + order_desc: { + value: true, + }, + show_totals: {}, + emit_filter: {}, + table_timestamp_format: { + value: 'smart_date', + }, + page_length: {}, + include_search: {}, + show_cell_bars: { + value: true, + }, + align_pn: {}, + color_pn: { + value: true, + }, + column_config: {}, + conditional_formatting: {}, }, - align_pn: {}, - color_pn: { - value: true, + datasource: { + type: 'table', + columns: [], }, - column_config: {}, - conditional_formatting: {}, - }, - datasource: { - type: 'table', - columns: [], - }, -}; + }; -beforeAll(() => { - getChartControlPanelRegistry().registerValue( - 'big_number_total', - new BigNumberTotalChartPlugin().controlPanel, - ); - getChartControlPanelRegistry().registerValue( - 'table', - new TableChartPlugin().controlPanel, - ); -}); - -test('should collect control values and create SFD', () => { - const sfd = new StandardizedFormData(transformationMockFD); - expect(sfd.dumpSFD().sharedFormData.metrics).toEqual([ - 'count(*)', - { label: 'sum(val)', expressionType: 'SQL', sqlExpression: 'sum(val)' }, - 'max(sales)', - 'min(sales)', - ]); - expect(sfd.dumpSFD().sharedFormData.columns).toEqual(['foo', 'bar']); - expect(sfd.dumpSFD().memorizedFormData).toEqual([ - ['table', transformationMockFD], - ]); -}); + beforeAll(() => { + getChartControlPanelRegistry().registerValue( + 'big_number_total', + new BigNumberTotalChartPlugin().controlPanel, + ); + getChartControlPanelRegistry().registerValue( + 'table', + new TableChartPlugin().controlPanel, + ); + }); -test('should transform form_data between table and bigNumberTotal', () => { - // table -> bigNumberTotal - const sfd = new StandardizedFormData(tableVizFormData); - const { formData: bntFormData, controlsState: btnControlsState } = - sfd.transform('big_number_total', tableVizStore); - expect(Object.keys(bntFormData).sort()).toEqual( - [...Object.keys(btnControlsState), 'standardized_form_data'].sort(), - ); - expect(bntFormData.viz_type).toBe('big_number_total'); - expect(bntFormData.metric).toBe('count'); + test('transform', () => { + // table -> bigNumberTotal + const sfd = new StandardizedFormData(tableVizFormData); + const { formData: bntFormData, controlsState: btnControlsState } = + sfd.transform('big_number_total', tableVizStore); + expect(Object.keys(bntFormData).sort()).toEqual( + [...Object.keys(btnControlsState), 'standardized_form_data'].sort(), + ); + expect(bntFormData.viz_type).toBe('big_number_total'); + expect(bntFormData.metric).toBe('count'); - // change control values - bntFormData.metric = 'sum(sales)'; - bntFormData.time_range = '2021 : 2022'; - btnControlsState.metric.value = 'sum(sales)'; - btnControlsState.time_range.value = '2021 : 2022'; + // change control values + bntFormData.metric = 'sum(sales)'; + bntFormData.time_range = '2021 : 2022'; + btnControlsState.metric.value = 'sum(sales)'; + btnControlsState.time_range.value = '2021 : 2022'; - // bigNumberTotal -> table - const sfd2 = new StandardizedFormData(bntFormData); - const { formData: tblFormData, controlsState: tblControlsState } = - sfd2.transform('table', { - ...tableVizStore, - form_data: bntFormData, - controls: btnControlsState, - }); - expect(Object.keys(tblFormData).sort()).toEqual( - [...Object.keys(tblControlsState), 'standardized_form_data'].sort(), - ); - expect(tblFormData.viz_type).toBe('table'); - expect(tblFormData.metrics).toEqual(['sum(sales)']); - expect(tblFormData.groupby).toEqual([]); - expect(tblFormData.time_range).toBe('2021 : 2022'); + // bigNumberTotal -> table + const sfd2 = new StandardizedFormData(bntFormData); + const { formData: tblFormData, controlsState: tblControlsState } = + sfd2.transform('table', { + ...tableVizStore, + form_data: bntFormData, + controls: btnControlsState, + }); + expect(Object.keys(tblFormData).sort()).toEqual( + [...Object.keys(tblControlsState), 'standardized_form_data'].sort(), + ); + expect(tblFormData.viz_type).toBe('table'); + expect(tblFormData.metrics).toEqual(['sum(sales)']); + expect(tblFormData.groupby).toEqual([]); + expect(tblFormData.time_range).toBe('2021 : 2022'); + }); }); diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index e8d195f6657e1..d5d74a55be4f3 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -29,13 +29,12 @@ import { import { getControlsState } from 'src/explore/store'; import { getFormDataFromControls } from './getFormDataFromControls'; -const sharedControls: Record = { +export const sharedControls: Record = { metrics: ['metric', 'metrics', 'metric_2'], columns: ['groupby', 'columns', 'groupbyColumns', 'groupbyRows'], }; -const publicControls = [ +export const publicControls = [ // time section - 'granularity', 'granularity_sqla', 'time_grain_sqla', 'time_range', From 34bcaa60685abfe93252f058b22fbbdccda873ea Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Fri, 13 May 2022 14:20:16 +0800 Subject: [PATCH 21/27] remove unused var --- .../src/explore/controlUtils/standardizedFormData.test.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index cdf77b79fcd1f..937ee716305e6 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -40,8 +40,6 @@ describe('should collect control values and create SFD', () => { const sourceMockFormData: SqlaFormData = { ...sharedControlsFormData, ...publicControlsFormData, - removedKey: 'removedKey', - removedKey2: ['foo', 'bar'], datasource: '100__table', viz_type: 'source_viz', }; From 5867b5f990e69cada0dcda10f5cb71a951452b31 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Fri, 13 May 2022 21:20:09 +0800 Subject: [PATCH 22/27] address comments --- .../packages/superset-ui-chart-controls/src/types.ts | 6 ++++-- .../src/explore/controlUtils/standardizedFormData.ts | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 5b1018e1baf8a..4556ddb171610 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -346,7 +346,7 @@ export interface SharedFormData { columns: (AdhocColumn | PhysicalColumn)[]; } -export interface iStandardizedFormData { +export interface StandardizedFormDataInterface { sharedFormData: SharedFormData; memorizedFormData: Map; } @@ -357,7 +357,9 @@ export interface ControlPanelConfig { sectionOverrides?: SectionOverrides; onInit?: (state: ControlStateMapping) => void; denormalizeFormData?: ( - formData: QueryFormData & { standardized_form_data: iStandardizedFormData }, + formData: QueryFormData & { + standardized_form_data: StandardizedFormDataInterface; + }, ) => QueryFormData; } diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index d5d74a55be4f3..293fb19fcf4d0 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -24,7 +24,7 @@ import { import { ControlStateMapping, SharedFormData, - iStandardizedFormData, + StandardizedFormDataInterface, } from '@superset-ui/chart-controls'; import { getControlsState } from 'src/explore/store'; import { getFormDataFromControls } from './getFormDataFromControls'; @@ -64,7 +64,7 @@ export const publicControls = [ ]; export class StandardizedFormData { - private sfd: iStandardizedFormData; + private sfd: StandardizedFormDataInterface; constructor(sourceFormData: QueryFormData) { /* @@ -74,7 +74,7 @@ export class StandardizedFormData { metrics: [], columns: [], }; - const formData = { ...sourceFormData }; + const formData = Object.freeze(sourceFormData); const reversedMap = StandardizedFormData.getReversedMap(); Object.entries(formData).forEach(([key, value]) => { From 00d5cd564f995ddb398c95681f7d242b6abc83ee Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Mon, 16 May 2022 20:55:46 +0800 Subject: [PATCH 23/27] minor typos --- .../packages/superset-ui-chart-controls/src/types.ts | 7 ++++--- .../explore/controlUtils/standardizedFormData.test.tsx | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 4556ddb171610..fd6036eb48b1c 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -25,8 +25,9 @@ import type { JsonValue, Metric, QueryFormData, + QueryFormMetric, + QueryFormColumn, } from '@superset-ui/core'; -import { AdhocMetric, PhysicalColumn } from '@superset-ui/core'; import { sharedControls } from './shared-controls'; import sharedControlComponents from './shared-controls/components'; @@ -342,8 +343,8 @@ export interface ControlPanelSectionConfig { } export interface SharedFormData { - metrics: AdhocMetric[]; - columns: (AdhocColumn | PhysicalColumn)[]; + metrics: QueryFormMetric[]; + columns: QueryFormColumn[]; } export interface StandardizedFormDataInterface { diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index 937ee716305e6..0236a76eed72f 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -234,10 +234,10 @@ describe('should transform form_data between table and bigNumberTotal', () => { test('transform', () => { // table -> bigNumberTotal const sfd = new StandardizedFormData(tableVizFormData); - const { formData: bntFormData, controlsState: btnControlsState } = + const { formData: bntFormData, controlsState: bntControlsState } = sfd.transform('big_number_total', tableVizStore); expect(Object.keys(bntFormData).sort()).toEqual( - [...Object.keys(btnControlsState), 'standardized_form_data'].sort(), + [...Object.keys(bntControlsState), 'standardized_form_data'].sort(), ); expect(bntFormData.viz_type).toBe('big_number_total'); expect(bntFormData.metric).toBe('count'); @@ -245,8 +245,8 @@ describe('should transform form_data between table and bigNumberTotal', () => { // change control values bntFormData.metric = 'sum(sales)'; bntFormData.time_range = '2021 : 2022'; - btnControlsState.metric.value = 'sum(sales)'; - btnControlsState.time_range.value = '2021 : 2022'; + bntControlsState.metric.value = 'sum(sales)'; + bntControlsState.time_range.value = '2021 : 2022'; // bigNumberTotal -> table const sfd2 = new StandardizedFormData(bntFormData); @@ -254,7 +254,7 @@ describe('should transform form_data between table and bigNumberTotal', () => { sfd2.transform('table', { ...tableVizStore, form_data: bntFormData, - controls: btnControlsState, + controls: bntControlsState, }); expect(Object.keys(tblFormData).sort()).toEqual( [...Object.keys(tblControlsState), 'standardized_form_data'].sort(), From 6d26cb4ecfab87607ac232ac5c9a9b7f94f33b67 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Mon, 16 May 2022 21:13:41 +0800 Subject: [PATCH 24/27] rename standardized_form_data=>standardizedFormData --- .../packages/superset-ui-chart-controls/src/types.ts | 2 +- .../src/BigNumber/BigNumberTotal/controlPanel.ts | 2 +- .../src/BigNumber/BigNumberWithTrendline/controlPanel.tsx | 2 +- .../plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx | 4 ++-- .../src/Timeseries/Regular/controlPanel.tsx | 2 +- .../plugin-chart-pivot-table/src/plugin/controlPanel.tsx | 4 ++-- .../plugins/plugin-chart-table/src/controlPanel.tsx | 4 ++-- .../explore/controlUtils/standardizedFormData.test.tsx | 8 ++++---- .../src/explore/controlUtils/standardizedFormData.ts | 8 ++++---- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index fd6036eb48b1c..41b670a412443 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -359,7 +359,7 @@ export interface ControlPanelConfig { onInit?: (state: ControlStateMapping) => void; denormalizeFormData?: ( formData: QueryFormData & { - standardized_form_data: StandardizedFormDataInterface; + standardizedFormData: StandardizedFormDataInterface; }, ) => QueryFormData; } diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts index 73a1311ee74cd..60d55f98a5d42 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts @@ -98,6 +98,6 @@ export default { }, denormalizeFormData: formData => ({ ...formData, - metric: formData.standardized_form_data.sharedFormData.metrics[0], + metric: formData.standardizedFormData.sharedFormData.metrics[0], }), } as ControlPanelConfig; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx index 395ea3d6d6096..4a37f1484bfc2 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx @@ -272,7 +272,7 @@ const config: ControlPanelConfig = { }, denormalizeFormData: formData => ({ ...formData, - metric: formData.standardized_form_data.sharedFormData.metrics[0], + metric: formData.standardizedFormData.sharedFormData.metrics[0], }), }; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx index 55ff3d0e6ec01..7cf8a8b66a9c8 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx @@ -255,8 +255,8 @@ const config: ControlPanelConfig = { }, denormalizeFormData: formData => ({ ...formData, - metric: formData.standardized_form_data.sharedFormData.metrics[0], - groupby: formData.standardized_form_data.sharedFormData.columns, + metric: formData.standardizedFormData.sharedFormData.metrics[0], + groupby: formData.standardizedFormData.sharedFormData.columns, }), }; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx index 73e7106ee9fb4..d9b5d99d30552 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx @@ -242,7 +242,7 @@ const config: ControlPanelConfig = { }, denormalizeFormData: formData => ({ ...formData, - metrics: formData.standardized_form_data.sharedFormData.metrics, + metrics: formData.standardizedFormData.sharedFormData.metrics, }), }; diff --git a/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx index 183e1cd3daf26..95b234fef0fca 100644 --- a/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx @@ -370,12 +370,12 @@ const config: ControlPanelConfig = { ], denormalizeFormData: formData => { const groupbyColumns = - formData.standardized_form_data.sharedFormData.columns.filter( + formData.standardizedFormData.sharedFormData.columns.filter( col => !ensureIsArray(formData.groupbyRows).includes(col), ); return { ...formData, - metrics: formData.standardized_form_data.sharedFormData.metrics, + metrics: formData.standardizedFormData.sharedFormData.metrics, groupbyColumns, }; }, diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx index ac5c487a1c5db..f3b983b43729b 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx @@ -533,8 +533,8 @@ const config: ControlPanelConfig = { ], denormalizeFormData: formData => ({ ...formData, - metrics: formData.standardized_form_data.sharedFormData.metrics, - groupby: formData.standardized_form_data.sharedFormData.columns, + metrics: formData.standardizedFormData.sharedFormData.metrics, + groupby: formData.standardizedFormData.sharedFormData.columns, }), }; diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index 0236a76eed72f..aad49f579e578 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -84,8 +84,8 @@ describe('should collect control values and create SFD', () => { ], denormalizeFormData: (formData: SqlaFormData) => ({ ...formData, - columns: formData.standardized_form_data.sharedFormData.columns, - metrics: formData.standardized_form_data.sharedFormData.metrics, + columns: formData.standardizedFormData.sharedFormData.columns, + metrics: formData.standardizedFormData.sharedFormData.metrics, }), }); }); @@ -237,7 +237,7 @@ describe('should transform form_data between table and bigNumberTotal', () => { const { formData: bntFormData, controlsState: bntControlsState } = sfd.transform('big_number_total', tableVizStore); expect(Object.keys(bntFormData).sort()).toEqual( - [...Object.keys(bntControlsState), 'standardized_form_data'].sort(), + [...Object.keys(bntControlsState), 'standardizedFormData'].sort(), ); expect(bntFormData.viz_type).toBe('big_number_total'); expect(bntFormData.metric).toBe('count'); @@ -257,7 +257,7 @@ describe('should transform form_data between table and bigNumberTotal', () => { controls: bntControlsState, }); expect(Object.keys(tblFormData).sort()).toEqual( - [...Object.keys(tblControlsState), 'standardized_form_data'].sort(), + [...Object.keys(tblControlsState), 'standardizedFormData'].sort(), ); expect(tblFormData.viz_type).toBe('table'); expect(tblFormData.metrics).toEqual(['sum(sales)']); diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index 293fb19fcf4d0..c29ab3d573b8c 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -84,9 +84,9 @@ export class StandardizedFormData { }); const memorizedFormData = Array.isArray( - formData?.standardized_form_data?.memorizedFormData, + formData?.standardizedorm_data?.memorizedFormData, ) - ? new Map(formData.standardized_form_data.memorizedFormData) + ? new Map(formData.standardizedFormData.memorizedFormData) : new Map(); const vizType = formData.viz_type; if (memorizedFormData.has(vizType)) { @@ -144,7 +144,7 @@ export class StandardizedFormData { * 1. get memorized form_data by viz type or get previous form_data * 2. collect public control values * 3. generate initial targetControlsState - * 4. attach `standardized_form_data` to the initial form_data + * 4. attach `standardizedFormData` to the initial form_data * 5. call denormalizeFormData to transform initial form_data if the plugin was defined * 6. use final form_data to generate controlsState * */ @@ -162,7 +162,7 @@ export class StandardizedFormData { }); const targetFormData = { ...getFormDataFromControls(targetControlsState), - standardized_form_data: this.dumpSFD(), + standardizedFormData: this.dumpSFD(), }; const controlPanel = getChartControlPanelRegistry().get(targetVizType); From 76066526b5e2afd05cb6775b7f1cafb2e0cc3fe0 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Mon, 16 May 2022 22:25:46 +0800 Subject: [PATCH 25/27] sharedFormData => standardizedState --- .../superset-ui-chart-controls/src/types.ts | 4 ++-- .../src/BigNumber/BigNumberTotal/controlPanel.ts | 2 +- .../BigNumberWithTrendline/controlPanel.tsx | 2 +- .../src/Pie/controlPanel.tsx | 4 ++-- .../src/Timeseries/Regular/controlPanel.tsx | 2 +- .../src/plugin/controlPanel.tsx | 4 ++-- .../plugin-chart-table/src/controlPanel.tsx | 4 ++-- .../controlUtils/standardizedFormData.test.tsx | 8 ++++---- .../explore/controlUtils/standardizedFormData.ts | 16 ++++++++-------- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 41b670a412443..7d138fc8443a4 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -342,13 +342,13 @@ export interface ControlPanelSectionConfig { controlSetRows: ControlSetRow[]; } -export interface SharedFormData { +export interface standardizedState { metrics: QueryFormMetric[]; columns: QueryFormColumn[]; } export interface StandardizedFormDataInterface { - sharedFormData: SharedFormData; + standardizedState: standardizedState; memorizedFormData: Map; } diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts index 60d55f98a5d42..c715c8f232b0a 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts @@ -98,6 +98,6 @@ export default { }, denormalizeFormData: formData => ({ ...formData, - metric: formData.standardizedFormData.sharedFormData.metrics[0], + metric: formData.standardizedFormData.standardizedState.metrics[0], }), } as ControlPanelConfig; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx index 4a37f1484bfc2..c61ec6d0462bb 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx @@ -272,7 +272,7 @@ const config: ControlPanelConfig = { }, denormalizeFormData: formData => ({ ...formData, - metric: formData.standardizedFormData.sharedFormData.metrics[0], + metric: formData.standardizedFormData.standardizedState.metrics[0], }), }; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx index 7cf8a8b66a9c8..6e3a1ba593a2a 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Pie/controlPanel.tsx @@ -255,8 +255,8 @@ const config: ControlPanelConfig = { }, denormalizeFormData: formData => ({ ...formData, - metric: formData.standardizedFormData.sharedFormData.metrics[0], - groupby: formData.standardizedFormData.sharedFormData.columns, + metric: formData.standardizedFormData.standardizedState.metrics[0], + groupby: formData.standardizedFormData.standardizedState.columns, }), }; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx index d9b5d99d30552..eaf3cb2615fd3 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/Regular/controlPanel.tsx @@ -242,7 +242,7 @@ const config: ControlPanelConfig = { }, denormalizeFormData: formData => ({ ...formData, - metrics: formData.standardizedFormData.sharedFormData.metrics, + metrics: formData.standardizedFormData.standardizedState.metrics, }), }; diff --git a/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx index 95b234fef0fca..acbdb04bc75bf 100644 --- a/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-pivot-table/src/plugin/controlPanel.tsx @@ -370,12 +370,12 @@ const config: ControlPanelConfig = { ], denormalizeFormData: formData => { const groupbyColumns = - formData.standardizedFormData.sharedFormData.columns.filter( + formData.standardizedFormData.standardizedState.columns.filter( col => !ensureIsArray(formData.groupbyRows).includes(col), ); return { ...formData, - metrics: formData.standardizedFormData.sharedFormData.metrics, + metrics: formData.standardizedFormData.standardizedState.metrics, groupbyColumns, }; }, diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx index f3b983b43729b..4f5530f6b9025 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx @@ -533,8 +533,8 @@ const config: ControlPanelConfig = { ], denormalizeFormData: formData => ({ ...formData, - metrics: formData.standardizedFormData.sharedFormData.metrics, - groupby: formData.standardizedFormData.sharedFormData.columns, + metrics: formData.standardizedFormData.standardizedState.metrics, + groupby: formData.standardizedFormData.standardizedState.columns, }), }; diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index aad49f579e578..bc701a6d7dec2 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -84,8 +84,8 @@ describe('should collect control values and create SFD', () => { ], denormalizeFormData: (formData: SqlaFormData) => ({ ...formData, - columns: formData.standardizedFormData.sharedFormData.columns, - metrics: formData.standardizedFormData.sharedFormData.metrics, + columns: formData.standardizedFormData.standardizedState.columns, + metrics: formData.standardizedFormData.standardizedState.metrics, }), }); }); @@ -93,10 +93,10 @@ describe('should collect control values and create SFD', () => { test('collect sharedControls', () => { const sfd = new StandardizedFormData(sourceMockFormData); - expect(sfd.dumpSFD().sharedFormData.metrics).toEqual( + expect(sfd.dumpSFD().standardizedState.metrics).toEqual( sharedControls.metrics.map(controlName => controlName), ); - expect(sfd.dumpSFD().sharedFormData.columns).toEqual( + expect(sfd.dumpSFD().standardizedState.columns).toEqual( sharedControls.columns.map(controlName => controlName), ); }); diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index c29ab3d573b8c..ed6d4326746dd 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -23,13 +23,13 @@ import { } from '@superset-ui/core'; import { ControlStateMapping, - SharedFormData, + standardizedState, StandardizedFormDataInterface, } from '@superset-ui/chart-controls'; import { getControlsState } from 'src/explore/store'; import { getFormDataFromControls } from './getFormDataFromControls'; -export const sharedControls: Record = { +export const sharedControls: Record = { metrics: ['metric', 'metrics', 'metric_2'], columns: ['groupby', 'columns', 'groupbyColumns', 'groupbyRows'], }; @@ -70,7 +70,7 @@ export class StandardizedFormData { /* * Support form_data for smooth switching between different viz * */ - const sharedFormData = { + const standardizedState = { metrics: [], columns: [], }; @@ -79,7 +79,7 @@ export class StandardizedFormData { Object.entries(formData).forEach(([key, value]) => { if (reversedMap.has(key)) { - sharedFormData[reversedMap.get(key)].push(...ensureIsArray(value)); + standardizedState[reversedMap.get(key)].push(...ensureIsArray(value)); } }); @@ -94,7 +94,7 @@ export class StandardizedFormData { } memorizedFormData.set(vizType, formData); this.sfd = { - sharedFormData, + standardizedState, memorizedFormData, }; } @@ -117,8 +117,8 @@ export class StandardizedFormData { return this.memorizedFormData.slice(-1)[0][1]; } - private get sharedFormData() { - return this.sfd.sharedFormData; + private get standardizedState() { + return this.sfd.standardizedState; } private get memorizedFormData() { @@ -127,7 +127,7 @@ export class StandardizedFormData { dumpSFD() { return { - sharedFormData: this.sharedFormData, + standardizedState: this.standardizedState, memorizedFormData: this.memorizedFormData, }; } From b0fd499b437f71314f23585718dfaef95b1a93a8 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Tue, 17 May 2022 09:30:50 +0800 Subject: [PATCH 26/27] fix typo and add UT for memorizedFormData --- .../superset-ui-chart-controls/src/types.ts | 4 +-- .../standardizedFormData.test.tsx | 31 ++++++++++++++++--- .../controlUtils/standardizedFormData.ts | 6 ++-- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 7d138fc8443a4..7926ffd759e8c 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -342,13 +342,13 @@ export interface ControlPanelSectionConfig { controlSetRows: ControlSetRow[]; } -export interface standardizedState { +export interface StandardizedState { metrics: QueryFormMetric[]; columns: QueryFormColumn[]; } export interface StandardizedFormDataInterface { - standardizedState: standardizedState; + standardizedState: StandardizedState; memorizedFormData: Map; } diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index bc701a6d7dec2..bc3d1ccd1b4b9 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { getChartControlPanelRegistry, SqlaFormData } from '@superset-ui/core'; +import { getChartControlPanelRegistry, QueryFormData } from '@superset-ui/core'; import TableChartPlugin from '@superset-ui/plugin-chart-table'; import { BigNumberTotalChartPlugin } from '@superset-ui/plugin-chart-echarts'; import { sections } from '@superset-ui/chart-controls'; @@ -37,7 +37,7 @@ describe('should collect control values and create SFD', () => { const publicControlsFormData = Object.fromEntries( publicControls.map((name, idx) => [[name], idx]), ); - const sourceMockFormData: SqlaFormData = { + const sourceMockFormData: QueryFormData = { ...sharedControlsFormData, ...publicControlsFormData, datasource: '100__table', @@ -66,7 +66,7 @@ describe('should collect control values and create SFD', () => { }, { label: 'axis column', - controlSetRows: [xAxisControl], + controlSetRows: [[xAxisControl]], }, ], }); @@ -82,7 +82,7 @@ describe('should collect control values and create SFD', () => { controlSetRows: [[xAxisControl]], }, ], - denormalizeFormData: (formData: SqlaFormData) => ({ + denormalizeFormData: (formData: QueryFormData) => ({ ...formData, columns: formData.standardizedFormData.standardizedState.columns, metrics: formData.standardizedFormData.standardizedState.metrics, @@ -111,6 +111,29 @@ describe('should collect control values and create SFD', () => { expect(formData[key]).toEqual(value); }); }); + + test('should inherit standardizedFormData', () => { + // from source_viz to target_viz + const sfd = new StandardizedFormData(sourceMockFormData); + const { formData, controlsState } = sfd.transform( + 'target_viz', + sourceMockStore, + ); + + // from target_viz to source_viz + const sfd2 = new StandardizedFormData(formData); + const { formData: fd2 } = sfd2.transform('source_viz', { + ...sourceMockStore, + form_data: formData, + controls: controlsState, + }); + + expect( + fd2.standardizedFormData.memorizedFormData.map( + (fd: [string, QueryFormData]) => fd[0], + ), + ).toEqual(['source_viz', 'target_viz']); + }); }); describe('should transform form_data between table and bigNumberTotal', () => { diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts index ed6d4326746dd..c42ef95085f1f 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.ts +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.ts @@ -23,13 +23,13 @@ import { } from '@superset-ui/core'; import { ControlStateMapping, - standardizedState, + StandardizedState, StandardizedFormDataInterface, } from '@superset-ui/chart-controls'; import { getControlsState } from 'src/explore/store'; import { getFormDataFromControls } from './getFormDataFromControls'; -export const sharedControls: Record = { +export const sharedControls: Record = { metrics: ['metric', 'metrics', 'metric_2'], columns: ['groupby', 'columns', 'groupbyColumns', 'groupbyRows'], }; @@ -84,7 +84,7 @@ export class StandardizedFormData { }); const memorizedFormData = Array.isArray( - formData?.standardizedorm_data?.memorizedFormData, + formData?.standardizedFormData?.memorizedFormData, ) ? new Map(formData.standardizedFormData.memorizedFormData) : new Map(); From a05c924807666335660a4aa35769d9652157da8d Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Tue, 17 May 2022 10:58:31 +0800 Subject: [PATCH 27/27] UT --- .../standardizedFormData.test.tsx | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx index bc3d1ccd1b4b9..e048c044983a8 100644 --- a/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx +++ b/superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx @@ -112,27 +112,44 @@ describe('should collect control values and create SFD', () => { }); }); - test('should inherit standardizedFormData', () => { + test('should inherit standardizedFormData and memorizedFormData is LIFO', () => { // from source_viz to target_viz const sfd = new StandardizedFormData(sourceMockFormData); const { formData, controlsState } = sfd.transform( 'target_viz', sourceMockStore, ); + expect( + formData.standardizedFormData.memorizedFormData.map( + (fd: [string, QueryFormData]) => fd[0], + ), + ).toEqual(['source_viz']); // from target_viz to source_viz const sfd2 = new StandardizedFormData(formData); - const { formData: fd2 } = sfd2.transform('source_viz', { + const { formData: fd2, controlsState: cs2 } = sfd2.transform('source_viz', { ...sourceMockStore, form_data: formData, controls: controlsState, }); - expect( fd2.standardizedFormData.memorizedFormData.map( (fd: [string, QueryFormData]) => fd[0], ), ).toEqual(['source_viz', 'target_viz']); + + // from source_viz to target_viz + const sfd3 = new StandardizedFormData(fd2); + const { formData: fd3 } = sfd3.transform('target_viz', { + ...sourceMockStore, + form_data: fd2, + controls: cs2, + }); + expect( + fd3.standardizedFormData.memorizedFormData.map( + (fd: [string, QueryFormData]) => fd[0], + ), + ).toEqual(['target_viz', 'source_viz']); }); });