Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 35 additions & 15 deletions superset-frontend/src/dashboard/components/GroupByBadge/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
import { memo, useMemo, useState, useRef } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from '@reduxjs/toolkit';
import { t } from '@superset-ui/core';
import { styled, useTheme } from '@apache-superset/core/ui';
import { Icons, Badge, Tooltip, Tag } from '@superset-ui/core/components';
Expand All @@ -26,6 +27,26 @@ import { ChartCustomizationItem } from '../nativeFilters/ChartCustomization/type
import { RootState } from '../../types';
import { isChartWithoutGroupBy } from '../../util/charts/chartTypeLimitations';

const makeSelectChartDataset = (chartId: number) =>
createSelector(
(state: RootState) => state.charts[chartId]?.latestQueryFormData,
latestQueryFormData => {
if (!latestQueryFormData?.datasource) {
return null;
}
const chartDatasetParts = String(latestQueryFormData.datasource).split(
'__',
);
return chartDatasetParts[0];
},
);

const makeSelectChartFormData = (chartId: number) =>
createSelector(
(state: RootState) => state.charts[chartId]?.latestQueryFormData,
latestQueryFormData => latestQueryFormData,
);

export interface GroupByBadgeProps {
chartId: number;
}
Expand Down Expand Up @@ -142,16 +163,19 @@ export const GroupByBadge = ({ chartId }: GroupByBadgeProps) => {
dashboardInfo.metadata?.chart_customization_config || [],
);

const chartDataset = useSelector<RootState, string | null>(state => {
const chart = state.charts[chartId];
if (!chart?.latestQueryFormData?.datasource) {
return null;
}
const chartDatasetParts = String(
chart.latestQueryFormData.datasource,
).split('__');
return chartDatasetParts[0];
});
// Use memoized selectors for chart data
const selectChartDataset = useMemo(
() => makeSelectChartDataset(chartId),
[chartId],
);
const selectChartFormData = useMemo(
() => makeSelectChartFormData(chartId),
[chartId],
);

const chartDataset = useSelector(selectChartDataset);
const chartFormData = useSelector(selectChartFormData);
const chartType = chartFormData?.viz_type;

const applicableGroupBys = useMemo(() => {
if (!chartDataset) {
Expand All @@ -173,9 +197,6 @@ export const GroupByBadge = ({ chartId }: GroupByBadgeProps) => {
});
}, [chartCustomizationItems, chartDataset]);

const chart = useSelector<RootState, any>(state => state.charts[chartId]);
const chartType = chart?.latestQueryFormData?.viz_type;

const effectiveGroupBys = useMemo(() => {
if (!chartType || applicableGroupBys.length === 0) {
return [];
Expand All @@ -185,7 +206,6 @@ export const GroupByBadge = ({ chartId }: GroupByBadgeProps) => {
return [];
}

const chartFormData = chart?.latestQueryFormData;
if (!chartFormData) {
return applicableGroupBys;
}
Expand Down Expand Up @@ -278,7 +298,7 @@ export const GroupByBadge = ({ chartId }: GroupByBadgeProps) => {

return columnNames.length > 0;
});
}, [applicableGroupBys, chartType, chart]);
}, [applicableGroupBys, chartType, chartFormData]);

const groupByCount = effectiveGroupBys.length;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const SliceContainer = styled.div`
`;

const EMPTY_OBJECT = {};
const EMPTY_ARRAY = [];

const Chart = props => {
const dispatch = useDispatch();
Expand Down Expand Up @@ -284,7 +285,8 @@ const Chart = props => {
state => state.dashboardInfo.metadata?.chart_configuration,
);
const chartCustomizationItems = useSelector(
state => state.dashboardInfo.metadata?.chart_customization_config || [],
state =>
state.dashboardInfo.metadata?.chart_customization_config || EMPTY_ARRAY,
);
const colorScheme = useSelector(state => state.dashboardState.colorScheme);
const colorNamespace = useSelector(
Expand All @@ -296,8 +298,8 @@ const Chart = props => {
const allSliceIds = useSelector(state => state.dashboardState.sliceIds);
const nativeFilters = useSelector(state => state.nativeFilters?.filters);
const dataMask = useSelector(state => state.dataMask);
const chartStates = useSelector(
state => state.dashboardState.chartStates || EMPTY_OBJECT,
const chartState = useSelector(
state => state.dashboardState.chartStates?.[props.id],
);
const labelsColor = useSelector(
state => state.dashboardInfo?.metadata?.label_colors || EMPTY_OBJECT,
Expand All @@ -314,7 +316,7 @@ const Chart = props => {
const formData = useMemo(
() =>
getFormDataWithExtraFilters({
chart,
chart: { id: chart.id, form_data: chart.form_data }, // avoid passing the whole chart object
chartConfiguration,
chartCustomizationItems,
filters: getAppliedFilterValues(props.id),
Expand All @@ -331,7 +333,8 @@ const Chart = props => {
ownColorScheme,
}),
[
chart,
chart.id,
chart.form_data,
chartConfiguration,
chartCustomizationItems,
props.id,
Expand All @@ -350,6 +353,25 @@ const Chart = props => {

formData.dashboardId = dashboardInfo.id;

const ownState = useMemo(() => {
const baseOwnState = dataMask[props.id]?.ownState || EMPTY_OBJECT;

if (hasChartStateConverter(slice.viz_type) && chartState?.state) {
return {
...baseOwnState,
...convertChartStateToOwnState(slice.viz_type, chartState.state),
chartState: chartState.state,
};
}

return baseOwnState;
}, [
dataMask[props.id]?.ownState,
props.id,
slice.viz_type,
chartState?.state,
]);

const onExploreChart = useCallback(
async clickEvent => {
const isOpenInNewTab =
Expand Down Expand Up @@ -406,13 +428,10 @@ const Chart = props => {
let ownState = dataMask[props.id]?.ownState || {};

// Convert chart-specific state to backend format using registered converter
if (
hasChartStateConverter(slice.viz_type) &&
chartStates[props.id]?.state
) {
if (hasChartStateConverter(slice.viz_type) && chartState?.state) {
const convertedState = convertChartStateToOwnState(
slice.viz_type,
chartStates[props.id].state,
chartState.state,
);
ownState = {
...ownState,
Expand All @@ -435,7 +454,7 @@ const Chart = props => {
formData,
maxRows,
dataMask[props.id]?.ownState,
chartStates,
chartState,
props.id,
boundActionCreators.logEvent,
],
Expand Down Expand Up @@ -577,19 +596,7 @@ const Chart = props => {
formData={formData}
labelsColor={labelsColor}
labelsColorMap={labelsColorMap}
ownState={{
...dataMask[props.id]?.ownState,
...(hasChartStateConverter(slice.viz_type) &&
chartStates[props.id]?.state
? {
...convertChartStateToOwnState(
slice.viz_type,
chartStates[props.id].state,
),
chartState: chartStates[props.id].state,
}
: {}),
}}
ownState={ownState}
filterState={dataMask[props.id]?.filterState}
queriesResponse={chart.queriesResponse}
timeout={timeout}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,32 @@
* specific language governing permissions and limitations
* under the License.
*/
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'src/dashboard/types';
import { ChartCustomizationItem } from './types';

export const selectChartCustomizationItems = (
state: RootState,
): ChartCustomizationItem[] => {
const { metadata } = state.dashboardInfo;
const EMPTY_ARRAY: ChartCustomizationItem[] = [];

if (
metadata?.chart_customization_config &&
metadata.chart_customization_config.length > 0
) {
return metadata.chart_customization_config;
}
export const selectChartCustomizationItems = createSelector(
(state: RootState) => state.dashboardInfo.metadata,
(metadata): ChartCustomizationItem[] => {
if (
metadata?.chart_customization_config &&
metadata.chart_customization_config.length > 0
) {
return metadata.chart_customization_config;
}

const legacyCustomization = metadata?.native_filter_configuration?.find(
(item: any) =>
item.type === 'CHART_CUSTOMIZATION' &&
item.id === 'chart_customization_groupby',
);
const legacyCustomization = metadata?.native_filter_configuration?.find(
(item: any) =>
item.type === 'CHART_CUSTOMIZATION' &&
item.id === 'chart_customization_groupby',
);

if (legacyCustomization?.chart_customization) {
return legacyCustomization.chart_customization;
}
if (legacyCustomization?.chart_customization) {
return legacyCustomization.chart_customization;
}

return [];
};
return EMPTY_ARRAY;
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import {
import { Icons } from '@superset-ui/core/components/Icons';
import { useChartIds } from 'src/dashboard/util/charts/useChartIds';
import { useChartLayoutItems } from 'src/dashboard/util/useChartLayoutItems';
import { ChartCustomizationItem } from 'src/dashboard/components/nativeFilters/ChartCustomization/types';
import { FiltersOutOfScopeCollapsible } from '../FiltersOutOfScopeCollapsible';
import { useFilterControlFactory } from '../useFilterControlFactory';
import { FiltersDropdownContent } from '../FiltersDropdownContent';
Expand Down Expand Up @@ -141,10 +140,7 @@ const FilterControls: FC<FilterControlsProps> = ({
const chartLayoutItems = useChartLayoutItems();
const verboseMaps = useChartsVerboseMaps();

const chartCustomizationItems = useSelector<
RootState,
ChartCustomizationItem[]
>(state => selectChartCustomizationItems(state));
const chartCustomizationItems = useSelector(selectChartCustomizationItems);

const selectedCrossFilters = useMemo(
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const HorizontalFilterBar: FC<HorizontalBarProps> = ({
const chartCustomizationItems = useSelector<
RootState,
ChartCustomizationItem[]
>(state => selectChartCustomizationItems(state));
>(selectChartCustomizationItems);

const hasFilters =
filterValues.length > 0 ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ const VerticalFilterBar: FC<VerticalBarProps> = ({
const chartCustomizationItems = useSelector<
RootState,
ChartCustomizationItem[]
>(state => selectChartCustomizationItems(state));
>(selectChartCustomizationItems);

const dataMask = useSelector<RootState, DataMaskStateWithId>(
state => state.dataMask,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,32 @@
*/
import { ensureIsArray, Filter } from '@superset-ui/core';
import { useSelector } from 'react-redux';
import { useMemo } from 'react';
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'src/dashboard/types';

const EMPTY_ARRAY: Filter[] = [];

const makeSelectFilterDependencies = (filterDependencyIds: string[]) =>
createSelector(
(state: RootState) => state.nativeFilters.filters,
(filters): Filter[] => {
if (filterDependencyIds.length === 0) {
return EMPTY_ARRAY;
}
return filterDependencyIds
.map(id => filters[id] as Filter)
.filter(Boolean);
},
);

export const useFilterDependencies = (filter: Filter) => {
const filterDependencyIds = ensureIsArray(filter.cascadeParentIds);
return useSelector<RootState, Filter[]>(state => {
if (filterDependencyIds.length === 0) {
return [];
}
return filterDependencyIds.reduce((acc: Filter[], filterDependencyId) => {
acc.push(state.nativeFilters.filters[filterDependencyId] as Filter);
return acc;
}, []);
});

const selectFilterDependencies = useMemo(
() => makeSelectFilterDependencies(filterDependencyIds),
[filterDependencyIds.join(',')],
);

return useSelector(selectFilterDependencies);
};
Loading
Loading