This is an automated email from the ASF dual-hosted git repository.
kgabryje pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new f0b6419 feat(native-filters): Set default scope by filters' and
charts' datasets (#15302)
f0b6419 is described below
commit f0b64190b51c36342eff567ed9d373b487163492
Author: Kamil Gabryjelski <[email protected]>
AuthorDate: Thu Jun 24 09:23:35 2021 +0200
feat(native-filters): Set default scope by filters' and charts' datasets
(#15302)
* feat(native-filters): Set default scope by filter's and charts datasets
* Fix undefined error
* Use JSON.stringify in dependency array
* Fix lint issue
* Lock scope after switching radio buttons
* Fix weird eslint issue
* Change prop names
* Implement useComponentDidUpdate
* Fix lint
* Refactor useComponentDidUpdate
* Remove screen.debug()
---
.../util/getFormDataWithExtraFilters_spec.ts | 1 +
.../hooks/useComponentDidUpdate/index.ts} | 12 +--
.../useComponentDidUpdate.test.ts} | 23 +++---
.../useComponentDidUpdate.ts} | 19 ++---
.../CrossFilterScopingForm.test.tsx | 6 +-
.../CrossFilterScopingForm/index.tsx | 6 +-
.../FiltersConfigForm/FilterScope/FilterScope.tsx | 85 ++++++++++++++++------
.../FiltersConfigForm/FilterScope/ScopingTree.tsx | 29 +++++++-
.../FiltersConfigForm/FilterScope/state.ts | 16 +++-
.../FiltersConfigForm/FilterScope/types.ts | 12 ++-
.../FiltersConfigForm/FilterScope/utils.ts | 39 ++++++++--
.../FiltersConfigForm/FiltersConfigForm.tsx | 51 ++++++++++---
superset-frontend/src/dashboard/types.ts | 17 ++++-
13 files changed, 232 insertions(+), 84 deletions(-)
diff --git
a/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts
b/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts
index 6561b60..ddcb3cf 100644
---
a/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts
+++
b/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts
@@ -48,6 +48,7 @@ describe('getFormDataWithExtraFilters', () => {
val: ['United States'],
},
],
+ datasource: '123',
},
};
const mockArgs: GetFormDataWithExtraFiltersArguments = {
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
b/superset-frontend/src/common/hooks/useComponentDidUpdate/index.ts
similarity index 84%
copy from
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
copy to superset-frontend/src/common/hooks/useComponentDidUpdate/index.ts
index cb804bf..fa01058 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
+++ b/superset-frontend/src/common/hooks/useComponentDidUpdate/index.ts
@@ -17,14 +17,4 @@
* under the License.
*/
-export enum Scoping {
- all,
- specific,
-}
-
-/** UI Ant tree type */
-export type TreeItem = {
- children: TreeItem[];
- key: string;
- title: string;
-};
+export * from './useComponentDidUpdate';
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
b/superset-frontend/src/common/hooks/useComponentDidUpdate/useComponentDidUpdate.test.ts
similarity index 62%
copy from
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
copy to
superset-frontend/src/common/hooks/useComponentDidUpdate/useComponentDidUpdate.test.ts
index cb804bf..a1615ec 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
+++
b/superset-frontend/src/common/hooks/useComponentDidUpdate/useComponentDidUpdate.test.ts
@@ -16,15 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
+import { renderHook } from '@testing-library/react-hooks';
+import { useComponentDidUpdate } from './useComponentDidUpdate';
-export enum Scoping {
- all,
- specific,
-}
-
-/** UI Ant tree type */
-export type TreeItem = {
- children: TreeItem[];
- key: string;
- title: string;
-};
+test('the effect should not be executed on the first render', () => {
+ const effect = jest.fn();
+ const hook = renderHook(props => useComponentDidUpdate(props.effect), {
+ initialProps: { effect },
+ });
+ expect(effect).toBeCalledTimes(0);
+ const changedEffect = jest.fn();
+ hook.rerender({ effect: changedEffect });
+ expect(changedEffect).toBeCalledTimes(1);
+});
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
b/superset-frontend/src/common/hooks/useComponentDidUpdate/useComponentDidUpdate.ts
similarity index 72%
copy from
superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
copy to
superset-frontend/src/common/hooks/useComponentDidUpdate/useComponentDidUpdate.ts
index cb804bf..aa84568 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
+++
b/superset-frontend/src/common/hooks/useComponentDidUpdate/useComponentDidUpdate.ts
@@ -17,14 +17,15 @@
* under the License.
*/
-export enum Scoping {
- all,
- specific,
-}
+import { EffectCallback, useEffect, useRef } from 'react';
-/** UI Ant tree type */
-export type TreeItem = {
- children: TreeItem[];
- key: string;
- title: string;
+export const useComponentDidUpdate = (effect: EffectCallback) => {
+ const isMountedRef = useRef(false);
+ useEffect(() => {
+ if (isMountedRef.current) {
+ effect();
+ } else {
+ isMountedRef.current = true;
+ }
+ }, [effect]);
};
diff --git
a/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm/CrossFilterScopingForm.test.tsx
b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm/CrossFilterScopingForm.test.tsx
index 581ac8e..39cb6f9 100644
---
a/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm/CrossFilterScopingForm.test.tsx
+++
b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm/CrossFilterScopingForm.test.tsx
@@ -43,9 +43,9 @@ test('Should send correct props', () => {
expect(FilterScope).toHaveBeenCalledWith(
expect.objectContaining({
chartId: 123,
- scope: 'Scope',
- formScope: 'scope',
- formScoping: 'scoping',
+ filterScope: 'Scope',
+ formFilterScope: 'scope',
+ formScopingType: 'scoping',
}),
{},
);
diff --git
a/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm/index.tsx
b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm/index.tsx
index c184f9e..d1364f3 100644
---
a/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm/index.tsx
+++
b/superset-frontend/src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingForm/index.tsx
@@ -45,11 +45,11 @@ const CrossFilterScopingForm:
FC<CrossFilterScopingFormProps> = ({
...values,
});
}}
- scope={scope}
+ filterScope={scope}
chartId={chartId}
- formScope={formScope}
+ formFilterScope={formScope}
forceUpdate={forceUpdate}
- formScoping={formScoping}
+ formScopingType={formScoping}
/>
);
};
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.tsx
index e8ffde2..5bec228 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope.tsx
@@ -17,23 +17,25 @@
* under the License.
*/
-import React, { FC } from 'react';
+import React, { FC, useCallback, useState } from 'react';
import { t, styled } from '@superset-ui/core';
import { Radio } from 'src/components/Radio';
import { Form, Typography } from 'src/common/components';
+import { useComponentDidUpdate } from
'src/common/hooks/useComponentDidUpdate/useComponentDidUpdate';
import { Scope } from '../../../types';
-import { Scoping } from './types';
+import { ScopingType } from './types';
import ScopingTree from './ScopingTree';
import { getDefaultScopeValue, isScopingAll } from './utils';
type FilterScopeProps = {
pathToFormValue?: string[];
updateFormValues: (values: any) => void;
- formScope?: Scope;
+ formFilterScope?: Scope;
forceUpdate: Function;
- scope?: Scope;
- formScoping?: Scoping;
+ filterScope?: Scope;
+ formScopingType?: ScopingType;
chartId?: number;
+ initiallyExcludedCharts?: number[];
};
const Wrapper = styled.div`
@@ -50,59 +52,98 @@ const CleanFormItem = styled(Form.Item)`
const FilterScope: FC<FilterScopeProps> = ({
pathToFormValue = [],
- formScoping,
- formScope,
+ formScopingType,
+ formFilterScope,
forceUpdate,
- scope,
+ filterScope,
updateFormValues,
chartId,
+ initiallyExcludedCharts,
}) => {
- const initialScope = scope || getDefaultScopeValue(chartId);
- const initialScoping = isScopingAll(initialScope, chartId)
- ? Scoping.all
- : Scoping.specific;
+ const [initialFilterScope] = useState(
+ filterScope || getDefaultScopeValue(chartId, initiallyExcludedCharts),
+ );
+ const [initialScopingType] = useState(
+ isScopingAll(initialFilterScope, chartId)
+ ? ScopingType.all
+ : ScopingType.specific,
+ );
+ const [hasScopeBeenModified, setHasScopeBeenModified] = useState(
+ !!filterScope,
+ );
+
+ const onUpdateFormValues = useCallback(
+ (formValues: any) => {
+ updateFormValues(formValues);
+ setHasScopeBeenModified(true);
+ },
+ [updateFormValues],
+ );
+
+ const updateScopes = useCallback(() => {
+ if (filterScope || hasScopeBeenModified) {
+ return;
+ }
+
+ const newScope = getDefaultScopeValue(chartId, initiallyExcludedCharts);
+ updateFormValues({
+ scope: newScope,
+ scoping: isScopingAll(newScope, chartId)
+ ? ScopingType.all
+ : ScopingType.specific,
+ });
+ }, [
+ chartId,
+ filterScope,
+ hasScopeBeenModified,
+ initiallyExcludedCharts,
+ updateFormValues,
+ ]);
+ useComponentDidUpdate(updateScopes);
return (
<Wrapper>
<CleanFormItem
name={[...pathToFormValue, 'scoping']}
- initialValue={initialScoping}
+ initialValue={initialScopingType}
>
<Radio.Group
onChange={({ target: { value } }) => {
- if (value === Scoping.all) {
+ if (value === ScopingType.all) {
const scope = getDefaultScopeValue(chartId);
updateFormValues({
scope,
});
}
+ setHasScopeBeenModified(true);
forceUpdate();
}}
>
- <Radio value={Scoping.all}>{t('Apply to all panels')}</Radio>
- <Radio value={Scoping.specific}>
+ <Radio value={ScopingType.all}>{t('Apply to all panels')}</Radio>
+ <Radio value={ScopingType.specific}>
{t('Apply to specific panels')}
</Radio>
</Radio.Group>
</CleanFormItem>
<Typography.Text type="secondary">
- {(formScoping ?? initialScoping) === Scoping.specific
+ {(formScopingType ?? initialScopingType) === ScopingType.specific
? t('Only selected panels will be affected by this filter')
: t('All panels with this column will be affected by this filter')}
</Typography.Text>
- {(formScoping ?? initialScoping) === Scoping.specific && (
+ {(formScopingType ?? initialScopingType) === ScopingType.specific && (
<ScopingTree
- updateFormValues={updateFormValues}
- initialScope={initialScope}
- formScope={formScope}
+ updateFormValues={onUpdateFormValues}
+ initialScope={initialFilterScope}
+ formScope={formFilterScope}
forceUpdate={forceUpdate}
chartId={chartId}
+ initiallyExcludedCharts={initiallyExcludedCharts}
/>
)}
<CleanFormItem
name={[...pathToFormValue, 'scope']}
hidden
- initialValue={initialScope}
+ initialValue={initialFilterScope}
/>
</Wrapper>
);
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/ScopingTree.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/ScopingTree.tsx
index d9dcf51..af140f8 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/ScopingTree.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/ScopingTree.tsx
@@ -20,6 +20,8 @@
import React, { FC, useMemo, useState } from 'react';
import { Tree } from 'src/common/components';
import { DASHBOARD_ROOT_ID } from 'src/dashboard/util/constants';
+import { Tooltip } from 'src/components/Tooltip';
+import Icons from 'src/components/Icons';
import { useFilterScopeTree } from './state';
import { findFilterScope, getTreeCheckedItems } from './utils';
import { Scope } from '../../../types';
@@ -30,6 +32,26 @@ type ScopingTreeProps = {
formScope?: Scope;
initialScope: Scope;
chartId?: number;
+ initiallyExcludedCharts?: number[];
+};
+
+const buildTreeLeafTitle = (
+ label: string,
+ hasTooltip: boolean,
+ tooltipTitle?: string,
+) => {
+ let title = <span>{label}</span>;
+ if (hasTooltip) {
+ title = (
+ <>
+ {title}
+ <Tooltip title={tooltipTitle}>
+ <Icons.Info iconSize="m" />
+ </Tooltip>
+ </>
+ );
+ }
+ return title;
};
const ScopingTree: FC<ScopingTreeProps> = ({
@@ -38,12 +60,17 @@ const ScopingTree: FC<ScopingTreeProps> = ({
forceUpdate,
updateFormValues,
chartId,
+ initiallyExcludedCharts = [],
}) => {
const [expandedKeys, setExpandedKeys] = useState<string[]>([
DASHBOARD_ROOT_ID,
]);
- const { treeData, layout } = useFilterScopeTree(chartId);
+ const { treeData, layout } = useFilterScopeTree(
+ chartId,
+ initiallyExcludedCharts,
+ buildTreeLeafTitle,
+ );
const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
const handleExpand = (expandedKeys: string[]) => {
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/state.ts
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/state.ts
index 8926c60..f9b94a3 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/state.ts
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/state.ts
@@ -25,12 +25,14 @@ import {
CHART_TYPE,
DASHBOARD_ROOT_TYPE,
} from 'src/dashboard/util/componentTypes';
-import { TreeItem } from './types';
+import { BuildTreeLeafTitle, TreeItem } from './types';
import { buildTree } from './utils';
// eslint-disable-next-line import/prefer-default-export
export function useFilterScopeTree(
currentChartId?: number,
+ initiallyExcludedCharts: number[] = [],
+ buildTreeLeafTitle: BuildTreeLeafTitle = label => label,
): {
treeData: [TreeItem];
layout: Layout;
@@ -61,8 +63,16 @@ export function useFilterScopeTree(
);
useMemo(() => {
- buildTree(layout[DASHBOARD_ROOT_ID], tree, layout, charts, validNodes);
- }, [charts, layout, tree]);
+ buildTree(
+ layout[DASHBOARD_ROOT_ID],
+ tree,
+ layout,
+ charts,
+ validNodes,
+ initiallyExcludedCharts,
+ buildTreeLeafTitle,
+ );
+ }, [layout, tree, charts, initiallyExcludedCharts, buildTreeLeafTitle]);
return { treeData: [tree], layout };
}
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
index cb804bf..8c9d2a5 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/types.ts
@@ -17,7 +17,9 @@
* under the License.
*/
-export enum Scoping {
+import { ReactNode } from 'react';
+
+export enum ScopingType {
all,
specific,
}
@@ -26,5 +28,11 @@ export enum Scoping {
export type TreeItem = {
children: TreeItem[];
key: string;
- title: string;
+ title: ReactNode;
};
+
+export type BuildTreeLeafTitle = (
+ label: string,
+ hasTooltip: boolean,
+ tooltipTitle?: string,
+) => ReactNode;
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils.ts
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils.ts
index 8cb48c1..bbb896e 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils.ts
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils.ts
@@ -23,7 +23,8 @@ import {
TAB_TYPE,
} from 'src/dashboard/util/componentTypes';
import { DASHBOARD_ROOT_ID } from 'src/dashboard/util/constants';
-import { TreeItem } from './types';
+import { t } from '@superset-ui/core';
+import { BuildTreeLeafTitle, TreeItem } from './types';
import { Scope } from '../../../types';
export const isShowTypeInTree = ({ type, meta }: LayoutItem, charts?: Charts)
=>
@@ -36,6 +37,8 @@ export const buildTree = (
layout: Layout,
charts: Charts,
validNodes: string[],
+ initiallyExcludedCharts: number[],
+ buildTreeLeafTitle: BuildTreeLeafTitle,
) => {
let itemToPass: TreeItem = treeItem;
if (
@@ -43,20 +46,35 @@ export const buildTree = (
node.type !== DASHBOARD_ROOT_TYPE &&
validNodes.includes(node.id)
) {
- const currentTreeItem = {
- key: node.id,
- title:
- node.meta.sliceNameOverride ||
+ const title = buildTreeLeafTitle(
+ node.meta.sliceNameOverride ||
node.meta.sliceName ||
node.meta.text ||
node.id.toString(),
+ initiallyExcludedCharts.includes(node.meta?.chartId),
+ t(
+ "This chart might be incompatible with the filter (datasets don't
match)",
+ ),
+ );
+
+ const currentTreeItem = {
+ key: node.id,
+ title,
children: [],
};
treeItem.children.push(currentTreeItem);
itemToPass = currentTreeItem;
}
node.children.forEach(child =>
- buildTree(layout[child], itemToPass, layout, charts, validNodes),
+ buildTree(
+ layout[child],
+ itemToPass,
+ layout,
+ charts,
+ validNodes,
+ initiallyExcludedCharts,
+ buildTreeLeafTitle,
+ ),
);
};
@@ -148,9 +166,14 @@ export const findFilterScope = (
};
};
-export const getDefaultScopeValue = (chartId?: number): Scope => ({
+export const getDefaultScopeValue = (
+ chartId?: number,
+ initiallyExcludedCharts: number[] = [],
+): Scope => ({
rootPath: [DASHBOARD_ROOT_ID],
- excluded: chartId ? [chartId] : [],
+ excluded: chartId
+ ? [chartId, ...initiallyExcludedCharts]
+ : initiallyExcludedCharts,
});
export const isScopingAll = (scope: Scope, chartId?: number) =>
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
index fb80888..f38d737 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
@@ -64,6 +64,12 @@ import Tabs from 'src/components/Tabs';
import Icons from 'src/components/Icons';
import { Tooltip } from 'src/components/Tooltip';
import BasicErrorAlert from 'src/components/ErrorMessage/BasicErrorAlert';
+import {
+ Chart,
+ ChartsState,
+ DatasourcesState,
+ RootState,
+} from 'src/dashboard/types';
import { ColumnSelect } from './ColumnSelect';
import { NativeFiltersForm } from '../types';
import {
@@ -324,9 +330,10 @@ const FiltersConfigForm = (
)
.map(([key]) => key);
- const loadedDatasets = useSelector<any, DatasourceMeta>(
+ const loadedDatasets = useSelector<RootState, DatasourcesState>(
({ datasources }) => datasources,
);
+ const charts = useSelector<RootState, ChartsState>(({ charts }) => charts);
const doLoadedDatasetsHaveTemporalColumns = useMemo(
() =>
@@ -349,9 +356,9 @@ const FiltersConfigForm = (
?.datasourceCount;
const hasColumn =
hasDataset && !FILTERS_WITHOUT_COLUMN.includes(formFilter?.filterType);
+ const nativeFilterItem = nativeFilterItems[formFilter?.filterType] ?? {};
// @ts-ignore
- const enableNoResults = !!nativeFilterItems[formFilter?.filterType]?.value
- ?.enableNoResults;
+ const enableNoResults = !!nativeFilterItem.value?.enableNoResults;
const datasetId = formFilter?.dataset?.value;
useEffect(() => {
@@ -517,6 +524,11 @@ const FiltersConfigForm = (
[],
);
+ const updateFormValues = useCallback(
+ (values: any) => setNativeFilterFieldValues(form, filterId, values),
+ [filterId, form],
+ );
+
const parentFilterOptions = parentFilters.map(filter => ({
value: filter.id,
label: filter.title,
@@ -598,6 +610,28 @@ const FiltersConfigForm = (
setActiveFilterPanelKey(activeFilterPanelKey);
}, [hasCheckedAdvancedControl]);
+ const initiallyExcludedCharts = useMemo(() => {
+ const excluded: number[] = [];
+ if (formFilter?.dataset?.value === undefined) {
+ return [];
+ }
+
+ Object.values(charts).forEach((chart: Chart) => {
+ const chartDatasetUid = chart.formData?.datasource;
+ if (chartDatasetUid === undefined) {
+ return;
+ }
+ if (loadedDatasets[chartDatasetUid]?.id !== formFilter?.dataset?.value) {
+ excluded.push(chart.id);
+ }
+ });
+ return excluded;
+ }, [
+ JSON.stringify(charts),
+ formFilter?.dataset?.value,
+ JSON.stringify(loadedDatasets),
+ ]);
+
if (removed) {
return <RemovedFilter onClick={() => restoreFilter(filterId)} />;
}
@@ -1053,14 +1087,13 @@ const FiltersConfigForm = (
forceRender
>
<FilterScope
- updateFormValues={(values: any) =>
- setNativeFilterFieldValues(form, filterId, values)
- }
+ updateFormValues={updateFormValues}
pathToFormValue={['filters', filterId]}
forceUpdate={forceUpdate}
- scope={filterToEdit?.scope}
- formScope={formFilter?.scope}
- formScoping={formFilter?.scoping}
+ filterScope={filterToEdit?.scope}
+ formFilterScope={formFilter?.scope}
+ formScopingType={formFilter?.scoping}
+ initiallyExcludedCharts={initiallyExcludedCharts}
/>
</TabPane>
</StyledTabs>
diff --git a/superset-frontend/src/dashboard/types.ts
b/superset-frontend/src/dashboard/types.ts
index 8659ba3..3fef394 100644
--- a/superset-frontend/src/dashboard/types.ts
+++ b/superset-frontend/src/dashboard/types.ts
@@ -16,7 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { ChartProps, ExtraFormData, JsonObject } from '@superset-ui/core';
+import {
+ ChartProps,
+ ExtraFormData,
+ GenericDataType,
+ JsonObject,
+} from '@superset-ui/core';
+import { DatasourceMeta } from '@superset-ui/chart-controls';
import { chart } from 'src/chart/chartReducer';
import componentTypes from 'src/dashboard/util/componentTypes';
import { DataMaskStateWithId } from '../dataMask/types';
@@ -38,6 +44,7 @@ export interface ChartQueryPayload extends
Partial<ChartReducerInitialState> {
export type Chart = ChartState & {
formData: {
viz_type: string;
+ datasource: string;
};
};
@@ -60,10 +67,16 @@ export type DashboardInfo = {
};
export type ChartsState = { [key: string]: Chart };
+export type DatasourcesState = {
+ [key: string]: DatasourceMeta & {
+ column_types: GenericDataType[];
+ table_name: string;
+ };
+};
/** Root state of redux */
export type RootState = {
- datasources: JsonObject;
+ datasources: DatasourcesState;
sliceEntities: JsonObject;
charts: ChartsState;
dashboardLayout: DashboardLayoutState;