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}&nbsp;
+        <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;

Reply via email to