From 38660449383b4940e1127520af512fe2e3f9323d Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Mon, 14 Jun 2021 14:33:59 +0200 Subject: [PATCH] fix(native-filters): Don't send unnecessary PUT request on dashboard render (#15146) * fix(native-filters): Don't send unnecessary PUT request on dashboard render * Run native filters scopes only if feature flag is enabled * Change action name * Run native filters scopes only if at least 1 filter added * Fix lint --- .../src/dashboard/actions/nativeFilters.ts | 25 +++++++++++++++ .../DashboardBuilder/DashboardContainer.tsx | 32 ++++++++++++------- .../src/dashboard/reducers/nativeFilters.ts | 2 ++ 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/superset-frontend/src/dashboard/actions/nativeFilters.ts b/superset-frontend/src/dashboard/actions/nativeFilters.ts index e01a5a6724..150b8857ae 100644 --- a/superset-frontend/src/dashboard/actions/nativeFilters.ts +++ b/superset-frontend/src/dashboard/actions/nativeFilters.ts @@ -49,6 +49,11 @@ export interface SetFilterConfigFail { type: typeof SET_FILTER_CONFIG_FAIL; filterConfig: FilterConfiguration; } +export const SET_IN_SCOPE_STATUS_OF_FILTERS = 'SET_IN_SCOPE_STATUS_OF_FILTERS'; +export interface SetInScopeStatusOfFilters { + type: typeof SET_IN_SCOPE_STATUS_OF_FILTERS; + filterConfig: FilterConfiguration; +} export const SET_FILTER_SETS_CONFIG_BEGIN = 'SET_FILTER_SETS_CONFIG_BEGIN'; export interface SetFilterSetsConfigBegin { type: typeof SET_FILTER_SETS_CONFIG_BEGIN; @@ -124,6 +129,25 @@ export const setFilterConfiguration = ( } }; +export const setInScopeStatusOfFilters = ( + filterScopes: { + filterId: string; + chartsInScope: number[]; + tabsInScope: string[]; + }[], +) => async (dispatch: Dispatch, getState: () => any) => { + const filters = getState().nativeFilters?.filters; + const filtersWithScopes = filterScopes.map(scope => ({ + ...filters[scope.filterId], + chartsInScope: scope.chartsInScope, + tabsInScope: scope.tabsInScope, + })); + dispatch({ + type: SET_IN_SCOPE_STATUS_OF_FILTERS, + filterConfig: filtersWithScopes, + }); +}; + type BootstrapData = { nativeFilters: { filters: Filters; @@ -227,6 +251,7 @@ export type AnyFilterAction = | SetFilterSetsConfigBegin | SetFilterSetsConfigComplete | SetFilterSetsConfigFail + | SetInScopeStatusOfFilters | SaveFilterSets | SetBootstrapData | SetFocusedNativeFilter diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx index 00c5d73ae5..3d2f557af2 100644 --- a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx +++ b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx @@ -18,10 +18,11 @@ */ // ParentSize uses resize observer so the dashboard will update size // when its container size changes, due to e.g., builder side panel opening -import { ParentSize } from '@vx/responsive'; -import Tabs from 'src/components/Tabs'; import React, { FC, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; +import { FeatureFlag, isFeatureEnabled } from '@superset-ui/core'; +import { ParentSize } from '@vx/responsive'; +import Tabs from 'src/components/Tabs'; import DashboardGrid from 'src/dashboard/containers/DashboardGrid'; import getLeafComponentIdFromPath from 'src/dashboard/util/getLeafComponentIdFromPath'; import { DashboardLayout, LayoutItem, RootState } from 'src/dashboard/types'; @@ -33,7 +34,7 @@ import { getRootLevelTabIndex } from './utils'; import { Filters } from '../../reducers/types'; import { getChartIdsInFilterScope } from '../../util/activeDashboardFilters'; import { findTabsWithChartsInScope } from '../nativeFilters/utils'; -import { setFilterConfiguration } from '../../actions/nativeFilters'; +import { setInScopeStatusOfFilters } from '../../actions/nativeFilters'; type DashboardContainerProps = { topLevelTabs?: LayoutItem; @@ -43,9 +44,9 @@ const DashboardContainer: FC = ({ topLevelTabs }) => { const dashboardLayout = useSelector( state => state.dashboardLayout.present, ); - const nativeFilters = useSelector( - state => state.nativeFilters.filters, - ); + const nativeFilters = + useSelector(state => state.nativeFilters?.filters) ?? + {}; const directPathToChild = useSelector( state => state.dashboardState.directPathToChild, ); @@ -63,9 +64,15 @@ const DashboardContainer: FC = ({ topLevelTabs }) => { const nativeFiltersValues = Object.values(nativeFilters); const scopes = nativeFiltersValues.map(filter => filter.scope); useEffect(() => { - nativeFiltersValues.forEach(filter => { + if ( + !isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS) || + nativeFiltersValues.length === 0 + ) { + return; + } + const filterScopes = nativeFiltersValues.map(filter => { const filterScope = filter.scope; - const chartsInScope = getChartIdsInFilterScope({ + const chartsInScope: number[] = getChartIdsInFilterScope({ filterScope: { scope: filterScope.rootPath, // @ts-ignore @@ -76,12 +83,13 @@ const DashboardContainer: FC = ({ topLevelTabs }) => { dashboardLayout, chartsInScope, ); - Object.assign(filter, { - chartsInScope, + return { + filterId: filter.id, tabsInScope: Array.from(tabsInScope), - }); + chartsInScope, + }; }); - dispatch(setFilterConfiguration(nativeFiltersValues)); + dispatch(setInScopeStatusOfFilters(filterScopes)); }, [JSON.stringify(scopes), JSON.stringify(dashboardLayout)]); const childIds: string[] = topLevelTabs diff --git a/superset-frontend/src/dashboard/reducers/nativeFilters.ts b/superset-frontend/src/dashboard/reducers/nativeFilters.ts index 8587328ca6..1ed96a64c9 100644 --- a/superset-frontend/src/dashboard/reducers/nativeFilters.ts +++ b/superset-frontend/src/dashboard/reducers/nativeFilters.ts @@ -20,6 +20,7 @@ import { AnyFilterAction, SAVE_FILTER_SETS, SET_FILTER_CONFIG_COMPLETE, + SET_IN_SCOPE_STATUS_OF_FILTERS, SET_FILTER_SETS_CONFIG_COMPLETE, SET_FOCUSED_NATIVE_FILTER, UNSET_FOCUSED_NATIVE_FILTER, @@ -92,6 +93,7 @@ export default function nativeFilterReducer( }; case SET_FILTER_CONFIG_COMPLETE: + case SET_IN_SCOPE_STATUS_OF_FILTERS: return getInitialState({ filterConfig: action.filterConfig, state }); case SET_FILTER_SETS_CONFIG_COMPLETE: