Skip to content

Commit 02b7e50

Browse files
committed
perf: Optimize native filters and cross filters
1 parent 5006f97 commit 02b7e50

23 files changed

+376
-432
lines changed

superset-frontend/src/dashboard/components/DashboardBuilder/DashboardContainer.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import {
6060
ensureSyncedSharedLabelsColors,
6161
ensureSyncedLabelsColorMap,
6262
} from 'src/dashboard/actions/dashboardState';
63+
import { CHART_TYPE } from 'src/dashboard/util/componentTypes';
6364
import { getColorNamespace, resetColors } from 'src/utils/colorScheme';
6465
import { NATIVE_FILTER_DIVIDER_PREFIX } from '../nativeFilters/FiltersConfigModal/utils';
6566
import { findTabsWithChartsInScope } from '../nativeFilters/utils';
@@ -160,14 +161,18 @@ const DashboardContainer: FC<DashboardContainerProps> = ({ topLevelTabs }) => {
160161
};
161162
}
162163

164+
const chartLayoutItems = Object.values(dashboardLayout).filter(
165+
item => item?.type === CHART_TYPE,
166+
);
167+
163168
const chartsInScope: number[] = getChartIdsInFilterScope(
164169
filterScope.scope,
165170
chartIds,
166-
dashboardLayout,
171+
chartLayoutItems,
167172
);
168173

169174
const tabsInScope = findTabsWithChartsInScope(
170-
dashboardLayout,
175+
chartLayoutItems,
171176
chartsInScope,
172177
);
173178
return {

superset-frontend/src/dashboard/components/FiltersBadge/index.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
} from '@superset-ui/core';
4040
import Icons from 'src/components/Icons';
4141
import { setDirectPathToChild } from 'src/dashboard/actions/dashboardState';
42+
import { useChartLayoutItems } from 'src/dashboard/util/useChartLayoutItems';
4243
import Badge from 'src/components/Badge';
4344
import DetailsPanelPopover from './DetailsPanel';
4445
import {
@@ -47,7 +48,7 @@ import {
4748
selectIndicatorsForChart,
4849
selectNativeIndicatorsForChart,
4950
} from '../nativeFilters/selectors';
50-
import { Chart, DashboardLayout, RootState } from '../../types';
51+
import { Chart, RootState } from '../../types';
5152

5253
export interface FiltersBadgeProps {
5354
chartId: number;
@@ -126,9 +127,7 @@ export const FiltersBadge = ({ chartId }: FiltersBadgeProps) => {
126127
state => state.dashboardInfo.metadata?.chart_configuration,
127128
);
128129
const chart = useSelector<RootState, Chart>(state => state.charts[chartId]);
129-
const present = useSelector<RootState, DashboardLayout>(
130-
state => state.dashboardLayout.present,
131-
);
130+
const chartLayoutItems = useChartLayoutItems();
132131
const dataMask = useSelector<RootState, DataMaskStateWithId>(
133132
state => state.dataMask,
134133
);
@@ -207,7 +206,7 @@ export const FiltersBadge = ({ chartId }: FiltersBadgeProps) => {
207206
]);
208207

209208
const prevNativeFilters = usePrevious(nativeFilters);
210-
const prevDashboardLayout = usePrevious(present);
209+
const prevChartLayoutItems = usePrevious(chartLayoutItems);
211210
const prevDataMask = usePrevious(dataMask);
212211
const prevChartConfig = usePrevious(chartConfiguration);
213212

@@ -221,7 +220,7 @@ export const FiltersBadge = ({ chartId }: FiltersBadgeProps) => {
221220
chart?.queriesResponse?.[0]?.applied_filters !==
222221
prevChart?.queriesResponse?.[0]?.applied_filters ||
223222
nativeFilters !== prevNativeFilters ||
224-
present !== prevDashboardLayout ||
223+
chartLayoutItems !== prevChartLayoutItems ||
225224
dataMask !== prevDataMask ||
226225
prevChartConfig !== chartConfiguration
227226
) {
@@ -231,7 +230,7 @@ export const FiltersBadge = ({ chartId }: FiltersBadgeProps) => {
231230
dataMask,
232231
chartId,
233232
chart,
234-
present,
233+
chartLayoutItems,
235234
chartConfiguration,
236235
),
237236
);
@@ -244,14 +243,14 @@ export const FiltersBadge = ({ chartId }: FiltersBadgeProps) => {
244243
dataMask,
245244
nativeFilters,
246245
nativeIndicators.length,
247-
present,
248246
prevChart?.queriesResponse,
249247
prevChartConfig,
250248
prevChartStatus,
251-
prevDashboardLayout,
252249
prevDataMask,
253250
prevNativeFilters,
254251
showIndicators,
252+
chartLayoutItems,
253+
prevChartLayoutItems,
255254
]);
256255

257256
const indicators = useMemo(

superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CrossFilters/ScopingModal/ScopingModal.test.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const INITIAL_STATE = {
3939
3: { id: 3 },
4040
4: { id: 4 },
4141
},
42+
dashboardState: {
43+
sliceIds: [1, 2, 3, 4],
44+
},
4245
dashboardInfo: {
4346
id: 1,
4447
metadata: {

superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CrossFilters/ScopingModal/ScopingModal.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { isDefined, NativeFilterScope, t } from '@superset-ui/core';
2222
import Modal from 'src/components/Modal';
2323
import {
2424
ChartConfiguration,
25-
Layout,
2625
RootState,
2726
isCrossFilterScopeGlobal,
2827
GlobalChartCrossFilterConfig,
@@ -32,6 +31,7 @@ import { getChartIdsInFilterScope } from 'src/dashboard/util/getChartIdsInFilter
3231
import { useChartIds } from 'src/dashboard/util/charts/useChartIds';
3332
import { saveChartConfiguration } from 'src/dashboard/actions/dashboardInfo';
3433
import { DEFAULT_CROSS_FILTER_SCOPING } from 'src/dashboard/constants';
34+
import { useChartLayoutItems } from 'src/dashboard/util/useChartLayoutItems';
3535
import { ScopingModalContent } from './ScopingModalContent';
3636
import { NEW_CHART_SCOPING_ID } from './constants';
3737

@@ -76,9 +76,7 @@ export const ScopingModal = ({
7676
closeModal,
7777
}: ScopingModalProps) => {
7878
const dispatch = useDispatch();
79-
const layout = useSelector<RootState, Layout>(
80-
state => state.dashboardLayout.present,
81-
);
79+
const chartLayoutItems = useChartLayoutItems();
8280
const chartIds = useChartIds();
8381
const [currentChartId, setCurrentChartId] = useState(initialChartId);
8482
const initialChartConfig = useSelector<RootState, ChartConfiguration>(
@@ -154,15 +152,19 @@ export const ScopingModal = ({
154152
id: currentChartId,
155153
crossFilters: {
156154
scope,
157-
chartsInScope: getChartIdsInFilterScope(scope, chartIds, layout),
155+
chartsInScope: getChartIdsInFilterScope(
156+
scope,
157+
chartIds,
158+
chartLayoutItems,
159+
),
158160
},
159161
},
160162
}));
161163
} else {
162164
const globalChartsInScope = getChartIdsInFilterScope(
163165
scope,
164166
chartIds,
165-
layout,
167+
chartLayoutItems,
166168
);
167169
setGlobalChartConfig({
168170
scope,
@@ -176,7 +178,7 @@ export const ScopingModal = ({
176178
);
177179
}
178180
},
179-
[currentChartId, chartIds, layout],
181+
[currentChartId, chartIds, chartLayoutItems],
180182
);
181183

182184
const removeCustomScope = useCallback(
@@ -241,7 +243,11 @@ export const ScopingModal = ({
241243
id: newChartId,
242244
crossFilters: {
243245
scope: newScope,
244-
chartsInScope: getChartIdsInFilterScope(newScope, chartIds, layout),
246+
chartsInScope: getChartIdsInFilterScope(
247+
newScope,
248+
chartIds,
249+
chartLayoutItems,
250+
),
245251
},
246252
};
247253

@@ -275,7 +281,7 @@ export const ScopingModal = ({
275281
currentChartId,
276282
globalChartConfig.chartsInScope,
277283
globalChartConfig.scope,
278-
layout,
284+
chartLayoutItems,
279285
],
280286
);
281287

superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CrossFilters/Vertical.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
* under the License.
1818
*/
1919

20-
import { DataMaskStateWithId, JsonObject } from '@superset-ui/core';
20+
import { DataMaskStateWithId } from '@superset-ui/core';
2121
import { useSelector } from 'react-redux';
22-
import { DashboardLayout, RootState } from 'src/dashboard/types';
22+
import { RootState } from 'src/dashboard/types';
23+
import { useChartLayoutItems } from 'src/dashboard/util/useChartLayoutItems';
24+
import { useChartIds } from 'src/dashboard/util/charts/useChartIds';
2325
import crossFiltersSelector from './selectors';
2426
import VerticalCollapse from './VerticalCollapse';
2527
import { useChartsVerboseMaps } from '../utils';
@@ -28,17 +30,13 @@ const CrossFiltersVertical = () => {
2830
const dataMask = useSelector<RootState, DataMaskStateWithId>(
2931
state => state.dataMask,
3032
);
31-
const chartConfiguration = useSelector<RootState, JsonObject>(
32-
state => state.dashboardInfo.metadata?.chart_configuration,
33-
);
34-
const dashboardLayout = useSelector<RootState, DashboardLayout>(
35-
state => state.dashboardLayout.present,
36-
);
33+
const chartIds = useChartIds();
34+
const chartLayoutItems = useChartLayoutItems();
3735
const verboseMaps = useChartsVerboseMaps();
3836
const selectedCrossFilters = crossFiltersSelector({
3937
dataMask,
40-
chartConfiguration,
41-
dashboardLayout,
38+
chartIds,
39+
chartLayoutItems,
4240
verboseMaps,
4341
});
4442

superset-frontend/src/dashboard/components/nativeFilters/FilterBar/CrossFilters/selectors.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,37 @@ import {
2121
DataMaskStateWithId,
2222
getColumnLabel,
2323
isDefined,
24-
JsonObject,
2524
} from '@superset-ui/core';
26-
import { DashboardLayout } from 'src/dashboard/types';
25+
import { LayoutItem } from 'src/dashboard/types';
2726
import { CrossFilterIndicator, getCrossFilterIndicator } from '../../selectors';
2827

2928
export const crossFiltersSelector = (props: {
3029
dataMask: DataMaskStateWithId;
31-
chartConfiguration: JsonObject;
32-
dashboardLayout: DashboardLayout;
30+
chartIds: number[];
31+
chartLayoutItems: LayoutItem[];
3332
verboseMaps: { [key: string]: Record<string, string> };
3433
}): CrossFilterIndicator[] => {
35-
const { dataMask, chartConfiguration, dashboardLayout, verboseMaps } = props;
36-
const chartsIds = Object.keys(chartConfiguration || {});
34+
const { dataMask, chartIds, chartLayoutItems, verboseMaps } = props;
3735

38-
return chartsIds
36+
return chartIds
3937
.map(chartId => {
40-
const id = Number(chartId);
4138
const filterIndicator = getCrossFilterIndicator(
42-
id,
43-
dataMask[id],
44-
dashboardLayout,
39+
chartId,
40+
dataMask[chartId],
41+
chartLayoutItems,
4542
);
4643
if (
4744
isDefined(filterIndicator.column) &&
4845
isDefined(filterIndicator.value)
4946
) {
5047
const verboseColName =
51-
verboseMaps[id]?.[getColumnLabel(filterIndicator.column)] ||
48+
verboseMaps[chartId]?.[getColumnLabel(filterIndicator.column)] ||
5249
filterIndicator.column;
53-
return { ...filterIndicator, column: verboseColName, emitterId: id };
50+
return {
51+
...filterIndicator,
52+
column: verboseColName,
53+
emitterId: chartId,
54+
};
5455
}
5556
return null;
5657
})

0 commit comments

Comments
 (0)