This is an automated email from the ASF dual-hosted git repository. kgabryje pushed a commit to branch what-if in repository https://gitbox.apache.org/repos/asf/superset.git
commit 990f6b2f03bd46064f4790d32f16a2ffb9615b4d Author: Kamil Gabryjelski <[email protected]> AuthorDate: Tue Dec 16 22:51:48 2025 +0100 perf --- .../dashboard/components/WhatIfBanner/index.tsx | 14 ++++--- .../dashboard/components/WhatIfDrawer/index.tsx | 10 +++-- superset-frontend/src/dashboard/types.ts | 3 +- superset-frontend/src/dashboard/util/whatIf.ts | 49 ++++++++++------------ 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/superset-frontend/src/dashboard/components/WhatIfBanner/index.tsx b/superset-frontend/src/dashboard/components/WhatIfBanner/index.tsx index fa01d1f45a..2eca2d7b90 100644 --- a/superset-frontend/src/dashboard/components/WhatIfBanner/index.tsx +++ b/superset-frontend/src/dashboard/components/WhatIfBanner/index.tsx @@ -25,7 +25,9 @@ import { Icons } from '@superset-ui/core/components/Icons'; import { clearWhatIfModifications } from 'src/dashboard/actions/dashboardState'; import { restoreOriginalChartData } from 'src/components/Chart/chartAction'; import { getNumericColumnsForDashboard } from 'src/dashboard/util/whatIf'; -import { RootState, WhatIfModification } from 'src/dashboard/types'; +import { RootState, Slice, WhatIfModification } from 'src/dashboard/types'; + +const EMPTY_MODIFICATIONS: WhatIfModification[] = []; /** * Banner container positioned at top of dashboard content, next to the What-If panel. @@ -96,15 +98,17 @@ const WhatIfBanner = ({ topOffset }: WhatIfBannerProps) => { const dispatch = useDispatch(); const whatIfModifications = useSelector<RootState, WhatIfModification[]>( - state => state.dashboardState.whatIfModifications || [], + state => state.dashboardState.whatIfModifications ?? EMPTY_MODIFICATIONS, ); - const charts = useSelector((state: RootState) => state.charts); + const slices = useSelector( + (state: RootState) => state.sliceEntities.slices as { [id: number]: Slice }, + ); const datasources = useSelector((state: RootState) => state.datasources); const numericColumns = useMemo( - () => getNumericColumnsForDashboard(charts, datasources), - [charts, datasources], + () => getNumericColumnsForDashboard(slices, datasources), + [slices, datasources], ); const columnToChartIds = useMemo(() => { diff --git a/superset-frontend/src/dashboard/components/WhatIfDrawer/index.tsx b/superset-frontend/src/dashboard/components/WhatIfDrawer/index.tsx index 6caade5384..68a6163a68 100644 --- a/superset-frontend/src/dashboard/components/WhatIfDrawer/index.tsx +++ b/superset-frontend/src/dashboard/components/WhatIfDrawer/index.tsx @@ -29,7 +29,7 @@ import { saveOriginalChartData, } from 'src/components/Chart/chartAction'; import { getNumericColumnsForDashboard } from 'src/dashboard/util/whatIf'; -import { RootState, WhatIfColumn } from 'src/dashboard/types'; +import { RootState, Slice, WhatIfColumn } from 'src/dashboard/types'; export const WHAT_IF_PANEL_WIDTH = 300; @@ -128,12 +128,14 @@ const WhatIfPanel = ({ onClose, topOffset }: WhatIfPanelProps) => { const [selectedColumn, setSelectedColumn] = useState<string | null>(null); const [sliderValue, setSliderValue] = useState<number>(SLIDER_DEFAULT); - const charts = useSelector((state: RootState) => state.charts); + const slices = useSelector( + (state: RootState) => state.sliceEntities.slices as { [id: number]: Slice }, + ); const datasources = useSelector((state: RootState) => state.datasources); const numericColumns = useMemo( - () => getNumericColumnsForDashboard(charts, datasources), - [charts, datasources], + () => getNumericColumnsForDashboard(slices, datasources), + [slices, datasources], ); const columnOptions = useMemo( diff --git a/superset-frontend/src/dashboard/types.ts b/superset-frontend/src/dashboard/types.ts index 243f81b61a..71a534f3eb 100644 --- a/superset-frontend/src/dashboard/types.ts +++ b/superset-frontend/src/dashboard/types.ts @@ -40,6 +40,7 @@ import { } from './components/nativeFilters/ChartCustomization/types'; import { GroupByCustomizationsState } from './reducers/groupByCustomizations'; import { ChartState } from '../explore/types'; +import { SliceEntitiesState } from './actions/sliceEntities'; export type { Dashboard } from 'src/types/Dashboard'; @@ -185,7 +186,7 @@ export type DatasourcesState = { /** Root state of redux */ export type RootState = { datasources: DatasourcesState; - sliceEntities: JsonObject; + sliceEntities: SliceEntitiesState; charts: ChartsState; dashboardLayout: DashboardLayoutState; dashboardFilters: {}; diff --git a/superset-frontend/src/dashboard/util/whatIf.ts b/superset-frontend/src/dashboard/util/whatIf.ts index d170f35eb7..da3742bc66 100644 --- a/superset-frontend/src/dashboard/util/whatIf.ts +++ b/superset-frontend/src/dashboard/util/whatIf.ts @@ -19,12 +19,7 @@ import { ensureIsArray, getColumnLabel } from '@superset-ui/core'; import { GenericDataType } from '@apache-superset/core/api/core'; import { ColumnMeta } from '@superset-ui/chart-controls'; -import { - ChartsState, - DatasourcesState, - ChartQueryPayload, - WhatIfColumn, -} from '../types'; +import { DatasourcesState, Slice, WhatIfColumn } from '../types'; /** * Check if a column is numeric based on its type_generic field @@ -34,12 +29,12 @@ export function isNumericColumn(column: ColumnMeta): boolean { } /** - * Extract column names from a chart's form_data + * Extract column names from a slice's form_data * This includes columns from groupby, metrics, x_axis, series, filters, etc. */ -export function extractColumnsFromChart(chart: ChartQueryPayload): Set<string> { +export function extractColumnsFromSlice(slice: Slice): Set<string> { const columns = new Set<string>(); - const formData = chart.form_data; + const formData = slice.form_data; if (!formData) return columns; // Helper to add column - handles both physical columns (strings) and adhoc columns @@ -111,37 +106,38 @@ export function extractColumnsFromChart(chart: ChartQueryPayload): Set<string> { } /** - * Get the datasource key from a chart's form_data + * Get the datasource key from a slice's form_data * Format: "datasourceId__datasourceType" e.g., "2__table" */ -export function getDatasourceKey(chart: ChartQueryPayload): string | null { - const datasource = chart.form_data?.datasource; +export function getDatasourceKey(slice: Slice): string | null { + const datasource = slice.form_data?.datasource; if (!datasource || typeof datasource !== 'string') return null; return datasource; } /** - * Get numeric columns used by charts on a dashboard - * Returns columns grouped by their usage across charts + * Get numeric columns used by slices on a dashboard + * Returns columns grouped by their usage across slices + * + * Uses sliceEntities.slices instead of charts state because it changes less + * frequently (only on slice metadata updates, not on every query result change) */ export function getNumericColumnsForDashboard( - charts: ChartsState, + slices: { [id: number]: Slice }, datasources: DatasourcesState, ): WhatIfColumn[] { const columnMap = new Map<string, WhatIfColumn>(); - Object.values(charts).forEach(chart => { - const chartId = chart.id; - // Chart and ChartQueryPayload both have id and form_data, so we can safely access them - const chartPayload = { id: chart.id, form_data: chart.form_data }; - const datasourceKey = getDatasourceKey(chartPayload); + Object.values(slices).forEach(slice => { + const chartId = slice.slice_id; + const datasourceKey = getDatasourceKey(slice); if (!datasourceKey) return; const datasource = datasources[datasourceKey]; if (!datasource?.columns) return; - // Extract columns referenced by this chart - const referencedColumns = extractColumnsFromChart(chartPayload); + // Extract columns referenced by this slice + const referencedColumns = extractColumnsFromSlice(slice); // For each referenced column, check if it's numeric referencedColumns.forEach(colName => { @@ -173,12 +169,9 @@ export function getNumericColumnsForDashboard( } /** - * Check if a chart uses a specific column + * Check if a slice uses a specific column */ -export function chartUsesColumn( - chart: ChartQueryPayload, - columnName: string, -): boolean { - const columns = extractColumnsFromChart(chart); +export function sliceUsesColumn(slice: Slice, columnName: string): boolean { + const columns = extractColumnsFromSlice(slice); return columns.has(columnName); }
