You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2021/05/03 11:59:16 UTC

[superset] branch master updated: perf(native-filters): avoid unnecessary reloading of charts (#14408)

This is an automated email from the ASF dual-hosted git repository.

villebro 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 bbb1f2d  perf(native-filters): avoid unnecessary reloading of charts (#14408)
bbb1f2d is described below

commit bbb1f2d75705957a6239bd6084feadbdacc9d410
Author: simcha90 <56...@users.noreply.github.com>
AuthorDate: Mon May 3 14:56:41 2021 +0300

    perf(native-filters): avoid unnecessary reloading of charts (#14408)
    
    * fix:fix get permission function
    
    * refactor: filter default value
    
    * refactor: update default value loading
    
    * refactor: apply defaultValues
    
    * lint: fix lint
    
    * lint: fix lint
    
    * test: fix test
    
    * refactor: use extraFormData for reload charts
    
    * test: fix tests
    
    * test: fix tests
    
    * test: fix tests
---
 .../spec/fixtures/mockNativeFilters.ts             | 20 ++++--
 .../dashboard/components/Dashboard_spec.jsx        |  2 +-
 .../dashboard/fixtures/mockNativeFilters.ts        |  7 +-
 .../util/getFormDataWithExtraFilters_spec.ts       |  1 -
 .../spec/javascripts/filters/utils_spec.ts         | 12 +---
 superset-frontend/src/chart/Chart.jsx              |  7 --
 superset-frontend/src/chart/ChartContainer.jsx     |  7 +-
 .../src/dashboard/actions/nativeFilters.ts         | 17 +----
 .../src/dashboard/components/Dashboard.jsx         | 32 +++++++--
 .../CascadeFilters/CascadePopover/index.tsx        |  3 +-
 .../FilterBar/CascadeFilters/types.ts              |  5 +-
 .../nativeFilters/FilterBar/FilterBar.test.tsx     | 25 +++----
 .../FilterBar/FilterControls/state.ts              |  4 +-
 .../FilterBar/FilterControls/types.ts              |  4 +-
 .../FilterBar/FilterSets/EditSection.tsx           |  4 +-
 .../nativeFilters/FilterBar/FilterSets/index.tsx   | 26 ++++---
 .../components/nativeFilters/FilterBar/index.tsx   | 61 ++++++++---------
 .../components/nativeFilters/FilterBar/state.ts    | 70 ++++++-------------
 .../components/nativeFilters/FilterBar/utils.ts    |  7 ++
 .../FiltersConfigForm/ControlItems.tsx             |  2 +-
 .../FiltersConfigForm/FiltersConfigForm.tsx        | 20 +++---
 .../nativeFilters/FiltersConfigModal/types.ts      |  3 +-
 .../nativeFilters/FiltersConfigModal/utils.ts      |  3 +-
 .../dashboard/components/nativeFilters/types.ts    |  3 +-
 .../dashboard/components/nativeFilters/utils.ts    |  4 +-
 .../src/dashboard/containers/Dashboard.ts          |  7 +-
 .../src/dashboard/reducers/nativeFilters.ts        | 12 +---
 superset-frontend/src/dashboard/reducers/types.ts  |  1 -
 superset-frontend/src/dashboard/types.ts           |  4 +-
 .../dashboard/util/activeAllDashboardFilters.ts    | 12 ++--
 superset-frontend/src/dataMask/actions.ts          |  9 ++-
 superset-frontend/src/dataMask/reducer.ts          | 80 +++++++++++++++++-----
 superset-frontend/src/dataMask/types.ts            |  2 +-
 superset-frontend/src/filters/utils.ts             | 27 ++++----
 34 files changed, 260 insertions(+), 243 deletions(-)

diff --git a/superset-frontend/spec/fixtures/mockNativeFilters.ts b/superset-frontend/spec/fixtures/mockNativeFilters.ts
index 12abae7..afc4959 100644
--- a/superset-frontend/spec/fixtures/mockNativeFilters.ts
+++ b/superset-frontend/spec/fixtures/mockNativeFilters.ts
@@ -21,7 +21,6 @@ import { NativeFiltersState } from 'src/dashboard/reducers/types';
 import { DataMaskStateWithId } from '../../src/dataMask/types';
 
 export const nativeFilters: NativeFiltersState = {
-  isInitialized: true,
   filterSets: {},
   filters: {
     'NATIVE_FILTER-e7Q8zKixx': {
@@ -36,7 +35,11 @@ export const nativeFilters: NativeFiltersState = {
           },
         },
       ],
-      defaultValue: null,
+      defaultDataMask: {
+        filterState: {
+          value: null,
+        },
+      },
       cascadeParentIds: [],
       scope: {
         rootPath: ['ROOT_ID'],
@@ -61,7 +64,11 @@ export const nativeFilters: NativeFiltersState = {
           },
         },
       ],
-      defaultValue: null,
+      defaultDataMask: {
+        filterState: {
+          value: null,
+        },
+      },
       cascadeParentIds: [],
       scope: {
         rootPath: ['ROOT_ID'],
@@ -115,14 +122,17 @@ export const extraFormData: ExtraFormData = {
 export const NATIVE_FILTER_ID = 'NATIVE_FILTER-p4LImrSgA';
 
 export const singleNativeFiltersState = {
-  isInitialized: true,
   filters: {
     [NATIVE_FILTER_ID]: {
       id: [NATIVE_FILTER_ID],
       name: 'eth',
       type: 'text',
       targets: [{ datasetId: 13, column: { name: 'ethnic_minority' } }],
-      defaultValue: null,
+      defaultDataMask: {
+        filterState: {
+          value: null,
+        },
+      },
       cascadeParentIds: [],
       scope: { rootPath: ['ROOT_ID'], excluded: [227, 229] },
       inverseSelection: false,
diff --git a/superset-frontend/spec/javascripts/dashboard/components/Dashboard_spec.jsx b/superset-frontend/spec/javascripts/dashboard/components/Dashboard_spec.jsx
index 61730c5..a881d0c 100644
--- a/superset-frontend/spec/javascripts/dashboard/components/Dashboard_spec.jsx
+++ b/superset-frontend/spec/javascripts/dashboard/components/Dashboard_spec.jsx
@@ -167,7 +167,7 @@ describe('Dashboard', () => {
         ...OVERRIDE_FILTERS,
         [NATIVE_FILTER_ID]: {
           scope: [230],
-          values: [extraFormData],
+          values: extraFormData,
         },
       });
     });
diff --git a/superset-frontend/spec/javascripts/dashboard/fixtures/mockNativeFilters.ts b/superset-frontend/spec/javascripts/dashboard/fixtures/mockNativeFilters.ts
index da7377d..8a106a2 100644
--- a/superset-frontend/spec/javascripts/dashboard/fixtures/mockNativeFilters.ts
+++ b/superset-frontend/spec/javascripts/dashboard/fixtures/mockNativeFilters.ts
@@ -30,7 +30,6 @@ export const mockDataMaskInfo: DataMaskStateWithId = {
 };
 
 export const nativeFiltersInfo: NativeFiltersState = {
-  isInitialized: true,
   filterSets: {
     'set-id': {
       id: 'DefaultsID',
@@ -54,7 +53,11 @@ export const nativeFiltersInfo: NativeFiltersState = {
           },
         },
       ],
-      defaultValue: null,
+      defaultDataMask: {
+        filterState: {
+          value: null,
+        },
+      },
       scope: {
         rootPath: [],
         excluded: [],
diff --git a/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts b/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts
index c183a2e..38c29e0 100644
--- a/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts
+++ b/superset-frontend/spec/javascripts/dashboard/util/getFormDataWithExtraFilters_spec.ts
@@ -52,7 +52,6 @@ describe('getFormDataWithExtraFilters', () => {
     },
     sliceId: chartId,
     nativeFilters: {
-      isInitialized: true,
       filterSets: {},
       filters: {
         [filterId]: ({
diff --git a/superset-frontend/spec/javascripts/filters/utils_spec.ts b/superset-frontend/spec/javascripts/filters/utils_spec.ts
index d997e64..9d225f4 100644
--- a/superset-frontend/spec/javascripts/filters/utils_spec.ts
+++ b/superset-frontend/spec/javascripts/filters/utils_spec.ts
@@ -129,21 +129,15 @@ describe('Filter utils', () => {
       );
     });
     it('getSelectExtraFormData - col: "testCol", value: [], emptyFilter: false, inverseSelection: false', () => {
-      expect(getSelectExtraFormData('testCol', [], false, false)).toEqual({
-        filters: [],
-      });
+      expect(getSelectExtraFormData('testCol', [], false, false)).toEqual({});
     });
     it('getSelectExtraFormData - col: "testCol", value: undefined, emptyFilter: false, inverseSelection: false', () => {
       expect(
         getSelectExtraFormData('testCol', undefined, false, false),
-      ).toEqual({
-        filters: [],
-      });
+      ).toEqual({});
     });
     it('getSelectExtraFormData - col: "testCol", value: null, emptyFilter: false, inverseSelection: false', () => {
-      expect(getSelectExtraFormData('testCol', null, false, false)).toEqual({
-        filters: [],
-      });
+      expect(getSelectExtraFormData('testCol', null, false, false)).toEqual({});
     });
   });
 
diff --git a/superset-frontend/src/chart/Chart.jsx b/superset-frontend/src/chart/Chart.jsx
index 8e32731..0ca590a 100644
--- a/superset-frontend/src/chart/Chart.jsx
+++ b/superset-frontend/src/chart/Chart.jsx
@@ -121,13 +121,6 @@ class Chart extends React.PureComponent {
   }
 
   runQuery() {
-    if (
-      this.props.dashboardId && // we on dashboard screen
-      isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) &&
-      !this.props.isFiltersInitialized
-    ) {
-      return;
-    }
     if (this.props.chartId > 0 && isFeatureEnabled(FeatureFlag.CLIENT_CACHE)) {
       // Load saved chart with a GET request
       this.props.actions.getSavedChart(
diff --git a/superset-frontend/src/chart/ChartContainer.jsx b/superset-frontend/src/chart/ChartContainer.jsx
index 7c88667..9925986 100644
--- a/superset-frontend/src/chart/ChartContainer.jsx
+++ b/superset-frontend/src/chart/ChartContainer.jsx
@@ -37,9 +37,4 @@ function mapDispatchToProps(dispatch) {
   };
 }
 
-export default connect(
-  ({ nativeFilters }) => ({
-    isFiltersInitialized: nativeFilters?.isInitialized,
-  }),
-  mapDispatchToProps,
-)(Chart);
+export default connect(null, mapDispatchToProps)(Chart);
diff --git a/superset-frontend/src/dashboard/actions/nativeFilters.ts b/superset-frontend/src/dashboard/actions/nativeFilters.ts
index e7c8266..660f422 100644
--- a/superset-frontend/src/dashboard/actions/nativeFilters.ts
+++ b/superset-frontend/src/dashboard/actions/nativeFilters.ts
@@ -22,8 +22,8 @@ import { Dispatch } from 'redux';
 import { FilterConfiguration } from 'src/dashboard/components/nativeFilters/types';
 import { DataMaskType, DataMaskStateWithId } from 'src/dataMask/types';
 import {
-  SET_DATA_MASK_FOR_FILTER_CONFIG_COMPLETE,
   SET_DATA_MASK_FOR_FILTER_CONFIG_FAIL,
+  setDataMaskForFilterConfigComplete,
 } from 'src/dataMask/actions';
 import { HYDRATE_DASHBOARD } from './hydrate';
 import { dashboardInfoChanged } from './dashboardInfo';
@@ -65,14 +65,6 @@ export interface SetFilterSetsConfigFail {
   type: typeof SET_FILTER_SETS_CONFIG_FAIL;
   filterSetsConfig: FilterSet[];
 }
-export const SET_FILTERS_INITIALIZED = 'SET_FILTERS_INITIALIZED';
-export interface SetFiltersInitialized {
-  type: typeof SET_FILTERS_INITIALIZED;
-}
-
-export const setFiltersInitialized = (): SetFiltersInitialized => ({
-  type: SET_FILTERS_INITIALIZED,
-});
 
 export const setFilterConfiguration = (
   filterConfig: FilterConfiguration,
@@ -108,11 +100,7 @@ export const setFilterConfiguration = (
       type: SET_FILTER_CONFIG_COMPLETE,
       filterConfig,
     });
-    dispatch({
-      type: SET_DATA_MASK_FOR_FILTER_CONFIG_COMPLETE,
-      unitName: DataMaskType.NativeFilters,
-      filterConfig,
-    });
+    dispatch(setDataMaskForFilterConfigComplete(filterConfig));
   } catch (err) {
     dispatch({ type: SET_FILTER_CONFIG_FAIL, filterConfig });
     dispatch({ type: SET_DATA_MASK_FOR_FILTER_CONFIG_FAIL, filterConfig });
@@ -200,6 +188,5 @@ export type AnyFilterAction =
   | SetFilterSetsConfigBegin
   | SetFilterSetsConfigComplete
   | SetFilterSetsConfigFail
-  | SetFiltersInitialized
   | SaveFilterSets
   | SetBooststapData;
diff --git a/superset-frontend/src/dashboard/components/Dashboard.jsx b/superset-frontend/src/dashboard/components/Dashboard.jsx
index b504a8d..4a5c883 100644
--- a/superset-frontend/src/dashboard/components/Dashboard.jsx
+++ b/superset-frontend/src/dashboard/components/Dashboard.jsx
@@ -18,7 +18,7 @@
  */
 import React from 'react';
 import PropTypes from 'prop-types';
-import { t } from '@superset-ui/core';
+import { isFeatureEnabled, t, FeatureFlag } from '@superset-ui/core';
 
 import { PluginContext } from 'src/components/DynamicPlugins';
 import Loading from 'src/components/Loading';
@@ -56,6 +56,7 @@ const propTypes = {
   charts: PropTypes.objectOf(chartPropShape).isRequired,
   slices: PropTypes.objectOf(slicePropShape).isRequired,
   activeFilters: PropTypes.object.isRequired,
+  chartConfiguration: PropTypes.object.isRequired,
   datasources: PropTypes.object.isRequired,
   ownDataCharts: PropTypes.object.isRequired,
   layout: PropTypes.object.isRequired,
@@ -120,6 +121,11 @@ class Dashboard extends React.PureComponent {
       };
     }
     window.addEventListener('visibilitychange', this.onVisibilityChange);
+    this.applyCharts();
+  }
+
+  componentDidUpdate() {
+    this.applyCharts();
   }
 
   UNSAFE_componentWillReceiveProps(nextProps) {
@@ -147,15 +153,28 @@ class Dashboard extends React.PureComponent {
     }
   }
 
-  componentDidUpdate() {
+  applyCharts() {
     const { hasUnsavedChanges, editMode } = this.props.dashboardState;
 
     const { appliedFilters, appliedOwnDataCharts } = this;
-    const { activeFilters, ownDataCharts } = this.props;
+    const { activeFilters, ownDataCharts, chartConfiguration } = this.props;
+    if (
+      isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS) &&
+      !chartConfiguration
+    ) {
+      // For a first loading we need to wait for cross filters charts data loaded to get all active filters
+      // for correct comparing  of filters to avoid unnecessary requests
+      return;
+    }
+
     if (
       !editMode &&
-      (!areObjectsEqual(appliedOwnDataCharts, ownDataCharts) ||
-        !areObjectsEqual(appliedFilters, activeFilters))
+      (!areObjectsEqual(appliedOwnDataCharts, ownDataCharts, {
+        ignoreUndefined: true,
+      }) ||
+        !areObjectsEqual(appliedFilters, activeFilters, {
+          ignoreUndefined: true,
+        }))
     ) {
       this.applyFilters();
     }
@@ -223,6 +242,9 @@ class Dashboard extends React.PureComponent {
           !areObjectsEqual(
             appliedFilters[filterKey].values,
             activeFilters[filterKey].values,
+            {
+              ignoreUndefined: true,
+            },
           )
         ) {
           affectedChartIds.push(...activeFilters[filterKey].scope);
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadePopover/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadePopover/index.tsx
index 60396ca..f256108 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadePopover/index.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadePopover/index.tsx
@@ -28,6 +28,7 @@ import FilterControl from 'src/dashboard/components/nativeFilters/FilterBar/Filt
 import CascadeFilterControl from 'src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/CascadeFilterControl';
 import { CascadeFilter } from 'src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/types';
 import { Filter } from 'src/dashboard/components/nativeFilters/types';
+import { RootState } from 'src/dashboard/types';
 
 interface CascadePopoverProps {
   filter: CascadeFilter;
@@ -82,7 +83,7 @@ const CascadePopover: React.FC<CascadePopoverProps> = ({
   directPathToChild,
 }) => {
   const [currentPathToChild, setCurrentPathToChild] = useState<string[]>();
-  const dataMask = useSelector<any, DataMaskWithId>(
+  const dataMask = useSelector<RootState, DataMaskWithId>(
     state => state.dataMask[filter.id] ?? getInitialDataMask(filter.id),
   );
 
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/types.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/types.ts
index 4354046..c5a9d13 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/types.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CascadeFilters/types.ts
@@ -17,8 +17,9 @@
  * under the License.
  */
 
+import { DataMask } from '@superset-ui/core';
 import { Filter } from '../../types';
 
-export interface CascadeFilter extends Filter {
+export type CascadeFilter = Filter & { dataMask?: DataMask } & {
   cascadeChildren: CascadeFilter[];
-}
+};
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx
index d6420df..5f2342c 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx
@@ -84,7 +84,6 @@ const addFilterFlow = () => {
 const addFilterSetFlow = async () => {
   // add filter set
   userEvent.click(screen.getByText('Filter Sets (0)'));
-  expect(screen.getByTestId(getTestId('new-filter-set-button'))).toBeDisabled();
 
   // check description
   expect(screen.getByText('Filters (1)')).toBeInTheDocument();
@@ -92,7 +91,6 @@ const addFilterSetFlow = async () => {
   expect(screen.getAllByText('Last week').length).toBe(2);
 
   // apply filters
-  userEvent.click(screen.getByTestId(getTestId('apply-button')));
   expect(screen.getByTestId(getTestId('new-filter-set-button'))).toBeEnabled();
 
   // create filter set
@@ -139,7 +137,7 @@ describe('FilterBar', () => {
               "name":"${FILTER_NAME}",
               "filterType":"filter_time",
               "targets":[{"datasetId":11,"column":{"name":"color"}}],
-              "defaultValue":null,
+              "defaultDataMask":{"filterState":{"value":null}},
               "controlValues":{},
               "cascadeParentIds":[],
               "scope":{"rootPath":["ROOT_ID"],"excluded":[]},
@@ -154,7 +152,7 @@ describe('FilterBar', () => {
                   "name":"${FILTER_NAME}",
                   "filterType":"filter_time",
                   "targets":[{}],
-                  "defaultValue":"Last week",
+                  "defaultDataMask":{"filterState":{"value":"Last week"},"extraFormData":{"time_range":"Last week"}},
                   "controlValues":{},
                   "cascadeParentIds":[],
                   "scope":{"rootPath":["ROOT_ID"],"excluded":[]},
@@ -163,7 +161,7 @@ describe('FilterBar', () => {
               },
               "dataMask":{
                 "${filterId}":{
-                  "extraFormData":{"override_form_data":{"time_range":"Last week"}},
+                  "extraFormData":{"time_range":"Last week"},
                   "filterState":{"value":"Last week"},
                   "ownState":{},
                   "id":"${filterId}"
@@ -308,10 +306,6 @@ describe('FilterBar', () => {
     addFilterFlow();
 
     await screen.findByText('All Filters (1)');
-
-    // apply filter
-    expect(screen.getByTestId(getTestId('apply-button'))).toBeEnabled();
-    userEvent.click(screen.getByTestId(getTestId('apply-button')));
     expect(screen.getByTestId(getTestId('apply-button'))).toBeDisabled();
   });
 
@@ -319,6 +313,7 @@ describe('FilterBar', () => {
   it.skip('add and apply filter set', async () => {
     // @ts-ignore
     global.featureFlags = {
+      [FeatureFlag.DASHBOARD_NATIVE_FILTERS]: true,
       [FeatureFlag.DASHBOARD_NATIVE_FILTERS_SET]: true,
     };
     renderWrapper(openedBarProps, stateWithoutNativeFilters);
@@ -326,21 +321,23 @@ describe('FilterBar', () => {
     addFilterFlow();
 
     await screen.findByText('All Filters (1)');
-    expect(screen.getByTestId(getTestId('apply-button'))).toBeEnabled();
 
     await addFilterSetFlow();
 
     // change filter
-    userEvent.click(screen.getByText('All Filters (1)'));
     expect(screen.getByTestId(getTestId('apply-button'))).toBeDisabled();
 
     await changeFilterValue();
     await waitFor(() => expect(screen.getAllByText('Last day').length).toBe(2));
 
     // apply new filter value
-    expect(screen.getByTestId(getTestId('apply-button'))).toBeEnabled();
+    await waitFor(() =>
+      expect(screen.getByTestId(getTestId('apply-button'))).toBeEnabled(),
+    );
     userEvent.click(screen.getByTestId(getTestId('apply-button')));
-    expect(screen.getByTestId(getTestId('apply-button'))).toBeDisabled();
+    await waitFor(() =>
+      expect(screen.getByTestId(getTestId('apply-button'))).toBeDisabled(),
+    );
 
     // applying filter set
     userEvent.click(screen.getByText('Filter Sets (1)'));
@@ -357,7 +354,6 @@ describe('FilterBar', () => {
     expect(screen.getByTestId(getTestId('apply-button'))).toBeDisabled();
   });
 
-  // TODO: fix flakiness and re-enable
   it.skip('add and edit filter set', async () => {
     // @ts-ignore
     global.featureFlags = {
@@ -369,7 +365,6 @@ describe('FilterBar', () => {
     addFilterFlow();
 
     await screen.findByText('All Filters (1)');
-    expect(screen.getByTestId(getTestId('apply-button'))).toBeEnabled();
 
     await addFilterSetFlow();
 
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/state.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/state.ts
index 802a12d..7be5835 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/state.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/state.ts
@@ -19,7 +19,7 @@
 import { useSelector } from 'react-redux';
 import { NativeFiltersState } from 'src/dashboard/reducers/types';
 import { mergeExtraFormData } from '../../utils';
-import { useDataMask } from '../state';
+import { useNativeFiltersDataMask } from '../state';
 
 // eslint-disable-next-line import/prefer-default-export
 export function useCascadingFilters(id: string) {
@@ -29,7 +29,7 @@ export function useCascadingFilters(id: string) {
   const filter = filters[id];
   const cascadeParentIds: string[] = filter?.cascadeParentIds ?? [];
   let cascadedFilters = {};
-  const nativeFiltersDataMask = useDataMask();
+  const nativeFiltersDataMask = useNativeFiltersDataMask();
   cascadeParentIds.forEach(parentId => {
     const parentState = nativeFiltersDataMask[parentId] || {};
     const { extraFormData: parentExtra = {} } = parentState;
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts
index 67e50d5..0b39dd2 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts
@@ -21,7 +21,9 @@ import { DataMask } from '@superset-ui/core';
 import { Filter } from '../../types';
 
 export interface FilterProps {
-  filter: Filter;
+  filter: Filter & {
+    dataMask?: DataMask;
+  };
   icon?: React.ReactElement;
   directPathToChild?: string[];
   onFilterSelectionChange: (filter: Filter, dataMask: DataMask) => void;
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/EditSection.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/EditSection.tsx
index 6ab44b4..bd9f724 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/EditSection.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/EditSection.tsx
@@ -25,7 +25,7 @@ import { setFilterSetsConfiguration } from 'src/dashboard/actions/nativeFilters'
 import { DataMaskState } from 'src/dataMask/types';
 import { WarningOutlined } from '@ant-design/icons';
 import { ActionButtons } from './Footer';
-import { useDataMask, useFilters, useFilterSets } from '../state';
+import { useNativeFiltersDataMask, useFilters, useFilterSets } from '../state';
 import { APPLY_FILTERS_HINT, findExistingFilterSet } from './utils';
 import { useFilterSetNameDuplicated } from './state';
 import { getFilterBarTestId } from '../index';
@@ -72,7 +72,7 @@ const EditSection: FC<EditSectionProps> = ({
   dataMaskSelected,
   disabled,
 }) => {
-  const dataMaskApplied = useDataMask();
+  const dataMaskApplied = useNativeFiltersDataMask();
   const dispatch = useDispatch();
   const filterSets = useFilterSets();
   const filters = useFilters();
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/index.tsx
index 8947ceb..95676da 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/index.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterSets/index.tsx
@@ -26,7 +26,7 @@ import { Filters, FilterSet, FilterSets } from 'src/dashboard/reducers/types';
 import { areObjectsEqual } from 'src/reduxUtils';
 import { findExistingFilterSet, generateFiltersSetId } from './utils';
 import { Filter } from '../../types';
-import { useFilters, useDataMask, useFilterSets } from '../state';
+import { useFilters, useNativeFiltersDataMask, useFilterSets } from '../state';
 import Footer from './Footer';
 import FilterSetUnit from './FilterSetUnit';
 import { getFilterBarTestId } from '..';
@@ -85,7 +85,7 @@ const FilterSets: React.FC<FilterSetsProps> = ({
   const dispatch = useDispatch();
   const [filterSetName, setFilterSetName] = useState(DEFAULT_FILTER_SET_NAME);
   const [editMode, setEditMode] = useState(false);
-  const dataMaskApplied = useDataMask();
+  const dataMaskApplied = useNativeFiltersDataMask();
   const filterSets = useFilterSets();
   const filterSetFilterValues = Object.values(filterSets);
   const filters = useFilters();
@@ -111,7 +111,9 @@ const FilterSets: React.FC<FilterSetsProps> = ({
     filterSet?: FilterSet,
   ) =>
     !filterValues.find(filter => filter?.id === id) ||
-    !areObjectsEqual(filters[id], filterSet?.nativeFilters?.[id]);
+    !areObjectsEqual(filters[id], filterSet?.nativeFilters?.[id], {
+      ignoreUndefined: true,
+    });
 
   const takeFilterSet = (id: string, target?: HTMLElement) => {
     const ignoreSelectorHeader = 'ant-collapse-header';
@@ -137,13 +139,15 @@ const FilterSets: React.FC<FilterSetsProps> = ({
 
     const filterSet = filterSets[id];
 
-    Object.values(filterSet?.dataMask ?? []).forEach(dataMask => {
-      const { extraFormData, filterState, id } = dataMask as DataMaskWithId;
-      if (isFilterMissingOrContainsInvalidMetadata(id, filterSet)) {
-        return;
-      }
-      onFilterSelectionChange({ id }, { extraFormData, filterState });
-    });
+    (Object.values(filterSet?.dataMask) ?? []).forEach(
+      (dataMask: DataMaskWithId) => {
+        const { extraFormData, filterState, id } = dataMask;
+        if (isFilterMissingOrContainsInvalidMetadata(id, filterSet)) {
+          return;
+        }
+        onFilterSelectionChange({ id }, { extraFormData, filterState });
+      },
+    );
   };
 
   const handleRebuild = (id: string) => {
@@ -168,7 +172,7 @@ const FilterSets: React.FC<FilterSetsProps> = ({
       dataMask: Object.keys(newFilters).reduce(
         (prev, nextFilterId) => ({
           ...prev,
-          [nextFilterId]: filterSet.dataMask?.nativeFilters?.[nextFilterId],
+          [nextFilterId]: filterSet.dataMask?.[nextFilterId],
         }),
         {},
       ),
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
index 3829cf4..77f47d1 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
@@ -19,31 +19,38 @@
 
 /* eslint-disable no-param-reassign */
 import { HandlerFunction, styled, t } from '@superset-ui/core';
-import React, { useEffect, useMemo, useState } from 'react';
+import React, { useMemo, useState } from 'react';
 import { useDispatch } from 'react-redux';
 import cx from 'classnames';
 import Icon from 'src/components/Icon';
 import { Tabs } from 'src/common/components';
 import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
 import { updateDataMask } from 'src/dataMask/actions';
-import { DataMaskState } from 'src/dataMask/types';
+import {
+  DataMaskState,
+  DataMaskStateWithId,
+  DataMaskWithId,
+} from 'src/dataMask/types';
 import { useImmer } from 'use-immer';
 import { areObjectsEqual } from 'src/reduxUtils';
 import { testWithId } from 'src/utils/testUtils';
 import { Filter } from 'src/dashboard/components/nativeFilters/types';
-import { setFiltersInitialized } from 'src/dashboard/actions/nativeFilters';
-import { mapParentFiltersToChildren, TabIds } from './utils';
+import {
+  getOnlyExtraFormData,
+  mapParentFiltersToChildren,
+  TabIds,
+} from './utils';
 import FilterSets from './FilterSets';
 import {
-  useDataMask,
+  useNativeFiltersDataMask,
   useFilters,
   useFilterSets,
-  useFiltersInitialisation,
   useFilterUpdates,
 } from './state';
 import EditSection from './FilterSets/EditSection';
 import Header from './Header';
 import FilterControls from './FilterControls/FilterControls';
+import { getInitialDataMask } from '../../../../dataMask/reducer';
 
 const BAR_WIDTH = `250px`;
 
@@ -155,18 +162,16 @@ const FilterBar: React.FC<FiltersBarProps> = ({
   directPathToChild,
 }) => {
   const [editFilterSetId, setEditFilterSetId] = useState<string | null>(null);
-  const [dataMaskSelected, setDataMaskSelected] = useImmer<DataMaskState>({});
-  const [
-    lastAppliedFilterData,
-    setLastAppliedFilterData,
-  ] = useImmer<DataMaskState>({});
+  const [dataMaskSelected, setDataMaskSelected] = useImmer<DataMaskStateWithId>(
+    {},
+  );
   const dispatch = useDispatch();
   const filterSets = useFilterSets();
   const filterSetFilterValues = Object.values(filterSets);
   const [tab, setTab] = useState(TabIds.AllFilters);
   const filters = useFilters();
   const filterValues = Object.values<Filter>(filters);
-  const dataMaskApplied = useDataMask();
+  const dataMaskApplied: DataMaskStateWithId = useNativeFiltersDataMask();
   const [isFilterSetChanged, setIsFilterSetChanged] = useState(false);
   const cascadeChildren = useMemo(
     () => mapParentFiltersToChildren(filterValues),
@@ -185,7 +190,10 @@ const FilterBar: React.FC<FiltersBarProps> = ({
         dispatch(updateDataMask(filter.id, dataMask));
       }
 
-      draft[filter.id] = dataMask;
+      draft[filter.id] = {
+        ...(getInitialDataMask(filter.id) as DataMaskWithId),
+        ...dataMask,
+      };
     });
   };
 
@@ -196,29 +204,18 @@ const FilterBar: React.FC<FiltersBarProps> = ({
         dispatch(updateDataMask(filterId, dataMaskSelected[filterId]));
       }
     });
-    setLastAppliedFilterData(() => dataMaskSelected);
   };
 
-  const { isInitialized } = useFiltersInitialisation(
-    dataMaskSelected,
-    handleApply,
-  );
-
-  useEffect(() => {
-    if (isInitialized) {
-      dispatch(setFiltersInitialized());
-    }
-  }, [dispatch, isInitialized]);
-
-  useFilterUpdates(
-    dataMaskSelected,
-    setDataMaskSelected,
-    setLastAppliedFilterData,
-  );
+  useFilterUpdates(dataMaskSelected, setDataMaskSelected);
 
+  const dataSelectedValues = Object.values(dataMaskSelected);
+  const dataAppliedValues = Object.values(dataMaskApplied);
   const isApplyDisabled =
-    !isInitialized || areObjectsEqual(dataMaskSelected, lastAppliedFilterData);
-
+    areObjectsEqual(
+      getOnlyExtraFormData(dataMaskSelected),
+      getOnlyExtraFormData(dataMaskApplied),
+      { ignoreUndefined: true },
+    ) || dataSelectedValues.length !== dataAppliedValues.length;
   return (
     <BarWrapper {...getFilterBarTestId()} className={cx({ open: filtersOpen })}>
       <CollapsedBar
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts
index c25b5b8..a37789a 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/state.ts
@@ -22,10 +22,14 @@ import {
   Filters,
   FilterSets as FilterSetsType,
 } from 'src/dashboard/reducers/types';
-import { DataMaskState, DataMaskStateWithId } from 'src/dataMask/types';
-import { useEffect, useState } from 'react';
-import { areObjectsEqual } from 'src/reduxUtils';
-import { Filter } from '../types';
+import {
+  DataMaskState,
+  DataMaskStateWithId,
+  DataMaskWithId,
+} from 'src/dataMask/types';
+import { useEffect } from 'react';
+import { RootState } from 'src/dashboard/types';
+import { NATIVE_FILTER_PREFIX } from '../FiltersConfigModal/utils';
 
 export const useFilterSets = () =>
   useSelector<any, FilterSetsType>(
@@ -35,44 +39,27 @@ export const useFilterSets = () =>
 export const useFilters = () =>
   useSelector<any, Filters>(state => state.nativeFilters.filters);
 
-export const useDataMask = () =>
-  useSelector<any, DataMaskStateWithId>(state => state.dataMask);
-
-export const useFiltersInitialisation = (
-  dataMaskSelected: DataMaskState,
-  handleApply: () => void,
-) => {
-  const [isInitialized, setIsInitialized] = useState<boolean>(false);
-  const filters = useFilters();
-  const filterValues = Object.values<Filter>(filters);
-  useEffect(() => {
-    if (isInitialized) {
-      return;
-    }
-    const areFiltersInitialized = filterValues.every(filterValue =>
-      areObjectsEqual(
-        filterValue?.defaultValue,
-        dataMaskSelected[filterValue?.id]?.filterState?.value,
-      ),
-    );
-    if (areFiltersInitialized) {
-      handleApply();
-      setIsInitialized(true);
-    }
-  }, [filterValues, dataMaskSelected, isInitialized]);
+export const useNativeFiltersDataMask = () => {
+  const dataMask = useSelector<RootState, DataMaskStateWithId>(
+    state => state.dataMask,
+  );
 
-  return {
-    isInitialized,
-  };
+  return Object.values(dataMask)
+    .filter((item: DataMaskWithId) =>
+      String(item.id).startsWith(NATIVE_FILTER_PREFIX),
+    )
+    .reduce(
+      (prev, next: DataMaskWithId) => ({ ...prev, [next.id]: next }),
+      {},
+    ) as DataMaskStateWithId;
 };
 
 export const useFilterUpdates = (
   dataMaskSelected: DataMaskState,
   setDataMaskSelected: (arg0: (arg0: DataMaskState) => void) => void,
-  setLastAppliedFilterData: (arg0: (arg0: DataMaskState) => void) => void,
 ) => {
   const filters = useFilters();
-  const dataMaskApplied = useDataMask();
+  const dataMaskApplied = useNativeFiltersDataMask();
 
   useEffect(() => {
     // Remove deleted filters from local state
@@ -83,18 +70,5 @@ export const useFilterUpdates = (
         });
       }
     });
-    Object.keys(dataMaskApplied).forEach(appliedId => {
-      if (!filters[appliedId]) {
-        setLastAppliedFilterData(draft => {
-          delete draft[appliedId];
-        });
-      }
-    });
-  }, [
-    dataMaskApplied,
-    dataMaskSelected,
-    filters,
-    setDataMaskSelected,
-    setLastAppliedFilterData,
-  ]);
+  }, [dataMaskApplied, dataMaskSelected, filters, setDataMaskSelected]);
 };
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/utils.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/utils.ts
index dc7097a..75cda73 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/utils.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/utils.ts
@@ -17,6 +17,7 @@
  * under the License.
  */
 
+import { DataMaskStateWithId } from 'src/dataMask/types';
 import { Filter } from '../types';
 
 export enum TabIds {
@@ -39,3 +40,9 @@ export function mapParentFiltersToChildren(
   });
   return cascadeChildren;
 }
+
+export const getOnlyExtraFormData = (data: DataMaskStateWithId) =>
+  Object.values(data).reduce(
+    (prev, next) => ({ ...prev, [next.id]: next.extraFormData }),
+    {},
+  );
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ControlItems.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ControlItems.tsx
index 4310a5b..82a46bf 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ControlItems.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/ControlItems.tsx
@@ -76,7 +76,7 @@ const ControlItems: FC<ControlItemsProps> = ({
                   return;
                 }
                 setNativeFilterFieldValues(form, filterId, {
-                  defaultValue: null,
+                  defaultDataMask: null,
                 });
                 forceUpdate();
               }}
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 2eca4e8..182e1e0 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
@@ -126,9 +126,7 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
   const [metrics, setMetrics] = useState<Metric[]>([]);
   const forceUpdate = useForceUpdate();
   const [datasetDetails, setDatasetDetails] = useState<Record<string, any>>();
-
   const formFilter = form.getFieldValue('filters')?.[filterId] || {};
-
   const nativeFilterItems = getChartMetadataRegistry().items;
   const nativeFilterVizTypes = Object.entries(nativeFilterItems)
     // @ts-ignore
@@ -191,7 +189,6 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
     const formData = getFormData({
       datasetId: formFilter?.dataset?.value,
       groupby: formFilter?.column,
-      defaultValue: formFilter?.defaultValue,
       ...formFilter,
     });
     setNativeFilterFieldValues(form, filterId, {
@@ -242,7 +239,6 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
   const newFormData = getFormData({
     datasetId,
     groupby: hasColumn ? formFilter?.column : undefined,
-    defaultValue: formFilter?.defaultValue,
     ...formFilter,
   });
 
@@ -294,7 +290,7 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
             onChange={({ value }: { value: string }) => {
               setNativeFilterFieldValues(form, filterId, {
                 filterType: value,
-                defaultValue: null,
+                defaultDataMask: null,
               });
               forceUpdate();
             }}
@@ -324,7 +320,7 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
                 // We need reset column when dataset changed
                 if (datasetId && e?.value !== datasetId) {
                   setNativeFilterFieldValues(form, filterId, {
-                    defaultValue: null,
+                    defaultDataMask: null,
                     column: null,
                   });
                 }
@@ -346,10 +342,10 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
                 form={form}
                 filterId={filterId}
                 datasetId={datasetId}
-                onChange={e => {
+                onChange={() => {
                   // We need reset default value when when column changed
                   setNativeFilterFieldValues(form, filterId, {
-                    defaultValue: null,
+                    defaultDataMask: null,
                   });
                   forceUpdate();
                 }}
@@ -435,16 +431,16 @@ export const FiltersConfigForm: React.FC<FiltersConfigFormProps> = ({
           )}
         </StyledFormItem>
         <StyledFormItem
-          name={['filters', filterId, 'defaultValue']}
-          initialValue={filterToEdit?.defaultValue}
+          name={['filters', filterId, 'defaultDataMask']}
+          initialValue={filterToEdit?.defaultDataMask}
           data-test="default-input"
           label={<StyledLabel>{t('Default Value')}</StyledLabel>}
         >
           {(!hasDataset || (!isDataDirty && hasFilledDataset)) && (
             <DefaultValue
-              setDataMask={({ filterState }) => {
+              setDataMask={dataMask => {
                 setNativeFilterFieldValues(form, filterId, {
-                  defaultValue: filterState?.value,
+                  defaultDataMask: dataMask,
                 });
                 forceUpdate();
               }}
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/types.ts b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/types.ts
index 14c67e4..60051e7 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/types.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/types.ts
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { AdhocFilter } from '@superset-ui/core';
+import { AdhocFilter, DataMask } from '@superset-ui/core';
 import { Scope } from '../types';
 
 export interface NativeFiltersFormItem {
@@ -32,6 +32,7 @@ export interface NativeFiltersFormItem {
     [key: string]: any;
   };
   defaultValue: any;
+  defaultDataMask: DataMask;
   parentFilter: {
     value: string;
     label: string;
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/utils.ts b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/utils.ts
index 3b0cf2b..d9ae39d 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/utils.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/utils.ts
@@ -18,6 +18,7 @@
  */
 import { FormInstance } from 'antd/lib/form';
 import shortid from 'shortid';
+import { getInitialDataMask } from 'src/dataMask/reducer';
 import { FilterRemoval, NativeFiltersForm } from './types';
 import { Filter, FilterConfiguration, Target } from '../types';
 
@@ -148,7 +149,7 @@ export const createHandleSave = (
         filterType: formInputs.filterType,
         // for now there will only ever be one target
         targets: [target],
-        defaultValue: formInputs.defaultValue || null,
+        defaultDataMask: formInputs.defaultDataMask ?? getInitialDataMask(),
         cascadeParentIds: formInputs.parentFilter
           ? [formInputs.parentFilter.value]
           : [],
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/types.ts b/superset-frontend/src/dashboard/components/nativeFilters/types.ts
index a758935..07e347c 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/types.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/types.ts
@@ -41,8 +41,7 @@ export interface Target {
 
 export interface Filter {
   cascadeParentIds: string[];
-  defaultValue: any;
-  dataMask?: DataMask;
+  defaultDataMask: DataMask;
   isInstant: boolean;
   id: string; // randomly generated at filter creation
   name: string;
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/utils.ts b/superset-frontend/src/dashboard/components/nativeFilters/utils.ts
index 5264e70..a42540a 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/utils.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/utils.ts
@@ -35,7 +35,7 @@ export const getFormData = ({
   cascadingFilters = {},
   groupby,
   inputRef,
-  defaultValue,
+  defaultDataMask,
   controlValues,
   filterType,
   sortMetric,
@@ -73,7 +73,7 @@ export const getFormData = ({
     metrics: ['count'],
     row_limit: 10000,
     showSearch: true,
-    defaultValue,
+    defaultValue: defaultDataMask?.filterState?.value,
     time_range,
     time_range_endpoints: ['inclusive', 'exclusive'],
     url_params: {},
diff --git a/superset-frontend/src/dashboard/containers/Dashboard.ts b/superset-frontend/src/dashboard/containers/Dashboard.ts
index 526223d..398dff7 100644
--- a/superset-frontend/src/dashboard/containers/Dashboard.ts
+++ b/superset-frontend/src/dashboard/containers/Dashboard.ts
@@ -18,9 +18,7 @@
  */
 import { bindActionCreators, Dispatch } from 'redux';
 import { connect } from 'react-redux';
-
 import Dashboard from '../components/Dashboard';
-
 import {
   addSliceToDashboard,
   removeSliceFromDashboard,
@@ -66,11 +64,12 @@ function mapStateToProps(state: RootState) {
         // eslint-disable-next-line camelcase
         chartConfiguration: dashboardInfo.metadata?.chart_configuration,
         nativeFilters: nativeFilters.filters,
-        dataMask: getRelevantDataMask(dataMask, 'isApplied'),
+        dataMask,
         layout: dashboardLayout.present,
       }),
     },
-    ownDataCharts: getRelevantDataMask(dataMask, 'ownState', 'ownState'),
+    chartConfiguration: dashboardInfo.metadata?.chart_configuration,
+    ownDataCharts: getRelevantDataMask(dataMask, 'ownState'),
     slices: sliceEntities.slices,
     layout: dashboardLayout.present,
     impressionId,
diff --git a/superset-frontend/src/dashboard/reducers/nativeFilters.ts b/superset-frontend/src/dashboard/reducers/nativeFilters.ts
index e22af28..f434d69 100644
--- a/superset-frontend/src/dashboard/reducers/nativeFilters.ts
+++ b/superset-frontend/src/dashboard/reducers/nativeFilters.ts
@@ -21,7 +21,6 @@ import {
   SAVE_FILTER_SETS,
   SET_FILTER_CONFIG_COMPLETE,
   SET_FILTER_SETS_CONFIG_COMPLETE,
-  SET_FILTERS_INITIALIZED,
 } from 'src/dashboard/actions/nativeFilters';
 import { FilterSet, NativeFiltersState } from './types';
 import { FilterConfiguration } from '../components/nativeFilters/types';
@@ -36,9 +35,7 @@ export function getInitialState({
   filterConfig?: FilterConfiguration;
   state?: NativeFiltersState;
 }): NativeFiltersState {
-  const state: Partial<NativeFiltersState> = {
-    isInitialized: prevState?.isInitialized,
-  };
+  const state: Partial<NativeFiltersState> = {};
 
   const filters = {};
   if (filterConfig) {
@@ -66,7 +63,6 @@ export function getInitialState({
 
 export default function nativeFilterReducer(
   state: NativeFiltersState = {
-    isInitialized: false,
     filters: {},
     filterSets: {},
   },
@@ -95,12 +91,6 @@ export default function nativeFilterReducer(
     case SET_FILTER_CONFIG_COMPLETE:
       return getInitialState({ filterConfig: action.filterConfig, state });
 
-    case SET_FILTERS_INITIALIZED:
-      return {
-        ...state,
-        isInitialized: true,
-      };
-
     case SET_FILTER_SETS_CONFIG_COMPLETE:
       return getInitialState({
         filterSetsConfig: action.filterSetsConfig,
diff --git a/superset-frontend/src/dashboard/reducers/types.ts b/superset-frontend/src/dashboard/reducers/types.ts
index 9ded035..770d561 100644
--- a/superset-frontend/src/dashboard/reducers/types.ts
+++ b/superset-frontend/src/dashboard/reducers/types.ts
@@ -97,7 +97,6 @@ export type Filters = {
 };
 
 export type NativeFiltersState = {
-  isInitialized: boolean;
   filters: Filters;
   filterSets: FilterSets;
 };
diff --git a/superset-frontend/src/dashboard/types.ts b/superset-frontend/src/dashboard/types.ts
index 3ed1c18..f01c2ac 100644
--- a/superset-frontend/src/dashboard/types.ts
+++ b/superset-frontend/src/dashboard/types.ts
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { ChartProps, JsonObject } from '@superset-ui/core';
+import { ChartProps, ExtraFormData, JsonObject } from '@superset-ui/core';
 import { chart } from 'src/chart/chartReducer';
 import componentTypes from 'src/dashboard/util/componentTypes';
 import { DataMaskStateWithId } from '../dataMask/types';
@@ -95,7 +95,7 @@ export type LayoutItem = {
 
 type ActiveFilter = {
   scope: number[];
-  values: any[];
+  values: ExtraFormData;
 };
 
 export type ActiveFilters = {
diff --git a/superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts b/superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts
index c3210aa..2243c25 100644
--- a/superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts
+++ b/superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts
@@ -20,7 +20,7 @@ import { DataMaskStateWithId } from 'src/dataMask/types';
 import { JsonObject } from '@superset-ui/core';
 import { CHART_TYPE } from './componentTypes';
 import { Scope } from '../components/nativeFilters/types';
-import { ActiveFilters, LayoutItem } from '../types';
+import { ActiveFilters, Layout, LayoutItem } from '../types';
 import { ChartConfiguration, Filters } from '../reducers/types';
 import { DASHBOARD_ROOT_ID } from './constants';
 
@@ -51,12 +51,11 @@ export const findAffectedCharts = ({
       // eslint-disable-next-line no-param-reassign
       activeFilters[filterId] = {
         scope: [],
-        values: [],
+        values: extraFormData,
       };
     }
     // Add not excluded chart scopes(to know what charts refresh) and values(refresh only if its value changed)
     activeFilters[filterId].scope.push(chartId);
-    activeFilters[filterId].values.push(extraFormData);
     return;
   }
   // If child is not chart, recursive iterate over its children
@@ -74,11 +73,10 @@ export const findAffectedCharts = ({
 
 export const getRelevantDataMask = (
   dataMask: DataMaskStateWithId,
-  filterBy: string,
-  prop?: string,
+  prop: string,
 ): JsonObject | DataMaskStateWithId =>
   Object.values(dataMask)
-    .filter(item => item[filterBy])
+    .filter(item => item[prop])
     .reduce(
       (prev, next) => ({ ...prev, [next.id]: prop ? next[prop] : next }),
       {},
@@ -93,7 +91,7 @@ export const getAllActiveFilters = ({
   chartConfiguration: ChartConfiguration;
   dataMask: DataMaskStateWithId;
   nativeFilters: Filters;
-  layout: { [key: string]: LayoutItem };
+  layout: Layout;
 }): ActiveFilters => {
   const activeFilters = {};
 
diff --git a/superset-frontend/src/dataMask/actions.ts b/superset-frontend/src/dataMask/actions.ts
index 9d557da..7a9bb3f 100644
--- a/superset-frontend/src/dataMask/actions.ts
+++ b/superset-frontend/src/dataMask/actions.ts
@@ -42,7 +42,14 @@ export interface SetDataMaskForFilterConfigFail {
   type: typeof SET_DATA_MASK_FOR_FILTER_CONFIG_FAIL;
   filterConfig: FilterConfiguration;
 }
-
+export function setDataMaskForFilterConfigComplete(
+  filterConfig: FilterConfiguration,
+): SetDataMaskForFilterConfigComplete {
+  return {
+    type: SET_DATA_MASK_FOR_FILTER_CONFIG_COMPLETE,
+    filterConfig,
+  };
+}
 export function updateDataMask(
   filterId: string,
   dataMask: DataMask,
diff --git a/superset-frontend/src/dataMask/reducer.ts b/superset-frontend/src/dataMask/reducer.ts
index 22c3e66..c4ee71f 100644
--- a/superset-frontend/src/dataMask/reducer.ts
+++ b/superset-frontend/src/dataMask/reducer.ts
@@ -20,23 +20,57 @@
 /* eslint-disable no-param-reassign */
 // <- When we work with Immer, we need reassign, so disabling lint
 import produce from 'immer';
+import { DataMask, FeatureFlag } from '@superset-ui/core';
+import { NATIVE_FILTER_PREFIX } from 'src/dashboard/components/nativeFilters/FiltersConfigModal/utils';
+import { HYDRATE_DASHBOARD } from 'src/dashboard/actions/hydrate';
+import { isFeatureEnabled } from 'src/featureFlags';
 import { DataMaskStateWithId, DataMaskWithId } from './types';
 import {
   AnyDataMaskAction,
   SET_DATA_MASK_FOR_FILTER_CONFIG_COMPLETE,
   UPDATE_DATA_MASK,
 } from './actions';
-import { NATIVE_FILTER_PREFIX } from '../dashboard/components/nativeFilters/FiltersConfigModal/utils';
-import { Filter } from '../dashboard/components/nativeFilters/types';
+import {
+  Filter,
+  FilterConfiguration,
+} from '../dashboard/components/nativeFilters/types';
 
+export function getInitialDataMask(id?: string): DataMask;
 export function getInitialDataMask(id: string): DataMaskWithId {
+  let otherProps = {};
+  if (id) {
+    otherProps = {
+      id,
+    };
+  }
   return {
-    id,
+    ...otherProps,
     extraFormData: {},
-    filterState: {},
+    filterState: {
+      value: null,
+    },
     ownState: {},
-    isApplied: false,
-  };
+  } as DataMaskWithId;
+}
+
+function fillNativeFilters(
+  data: FilterConfiguration,
+  cleanState: DataMaskStateWithId,
+  draft: DataMaskStateWithId,
+) {
+  data.forEach((filter: Filter) => {
+    cleanState[filter.id] = {
+      ...getInitialDataMask(filter.id), // take initial data
+      ...filter.defaultDataMask, // if something new came from BE - take it
+      ...draft[filter.id], // keep local filter data
+    };
+  });
+  // Get back all other non-native filters
+  Object.values(draft).forEach(filter => {
+    if (!String(filter?.id).startsWith(NATIVE_FILTER_PREFIX)) {
+      cleanState[filter?.id] = filter;
+    }
+  });
 }
 
 const dataMaskReducer = produce(
@@ -48,21 +82,31 @@ const dataMaskReducer = produce(
           ...getInitialDataMask(action.filterId),
           ...draft[action.filterId],
           ...action.dataMask,
-          isApplied: true,
         };
         return draft;
-
+      // TODO: update hydrate to .ts
+      // @ts-ignore
+      case HYDRATE_DASHBOARD:
+        if (isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS)) {
+          Object.keys(
+            // @ts-ignore
+            action.data.dashboardInfo?.metadata?.chart_configuration,
+          ).forEach(id => {
+            cleanState[id] = {
+              ...getInitialDataMask(id), // take initial data
+            };
+          });
+        }
+        fillNativeFilters(
+          // @ts-ignore
+          action.data.dashboardInfo?.metadata?.native_filter_configuration ??
+            [],
+          cleanState,
+          draft,
+        );
+        return cleanState;
       case SET_DATA_MASK_FOR_FILTER_CONFIG_COMPLETE:
-        (action.filterConfig ?? []).forEach((filter: Filter) => {
-          cleanState[filter.id] =
-            draft[filter.id] ?? getInitialDataMask(filter.id);
-        });
-        // Get back all other non-native filters
-        Object.values(draft).forEach(filter => {
-          if (!String(filter?.id).startsWith(NATIVE_FILTER_PREFIX)) {
-            cleanState[filter?.id] = filter;
-          }
-        });
+        fillNativeFilters(action.filterConfig ?? [], cleanState, draft);
         return cleanState;
 
       default:
diff --git a/superset-frontend/src/dataMask/types.ts b/superset-frontend/src/dataMask/types.ts
index 2e335b2..95d2073 100644
--- a/superset-frontend/src/dataMask/types.ts
+++ b/superset-frontend/src/dataMask/types.ts
@@ -25,5 +25,5 @@ export enum DataMaskType {
 
 export type DataMaskState = { [id: string]: DataMask };
 
-export type DataMaskWithId = { id: string; isApplied?: boolean } & DataMask;
+export type DataMaskWithId = { id: string } & DataMask;
 export type DataMaskStateWithId = { [filterId: string]: DataMaskWithId };
diff --git a/superset-frontend/src/filters/utils.ts b/superset-frontend/src/filters/utils.ts
index 6ca88dd..ecd7268 100644
--- a/superset-frontend/src/filters/utils.ts
+++ b/superset-frontend/src/filters/utils.ts
@@ -41,17 +41,14 @@ export const getSelectExtraFormData = (
         sqlExpression: '1 = 0',
       },
     ];
-  } else {
-    extra.filters =
-      value === undefined || value === null || value.length === 0
-        ? []
-        : [
-            {
-              col,
-              op: inverseSelection ? ('NOT IN' as const) : ('IN' as const),
-              val: value,
-            },
-          ];
+  } else if (value !== undefined && value !== null && value.length !== 0) {
+    extra.filters = [
+      {
+        col,
+        op: inverseSelection ? ('NOT IN' as const) : ('IN' as const),
+        val: value,
+      },
+    ];
   }
   return extra;
 };
@@ -69,9 +66,11 @@ export const getRangeExtraFormData = (
     filters.push({ col, op: '<=', val: upper });
   }
 
-  return {
-    filters,
-  };
+  return filters.length
+    ? {
+        filters,
+      }
+    : {};
 };
 
 export interface DataRecordValueFormatter {