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

jli 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 f60c82e4a60 fix: charts row limit warning is missing for server 
(#37112)
f60c82e4a60 is described below

commit f60c82e4a6045245d1647f608ffc779d9bf795ab
Author: Ramiro Aquino Romero <[email protected]>
AuthorDate: Mon Feb 2 19:49:31 2026 -0400

    fix: charts row limit warning is missing for server (#37112)
---
 .../components/SliceHeader/SliceHeader.test.tsx    | 189 ++++++++++++++++++++-
 .../src/dashboard/components/SliceHeader/index.tsx |  20 ++-
 .../src/explore/components/ChartPills.tsx          |  20 ++-
 .../explore/components/ExploreChartPanel/index.tsx |   1 +
 4 files changed, 218 insertions(+), 12 deletions(-)

diff --git 
a/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx 
b/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
index b7bc53eb5a1..14007f7dda0 100644
--- 
a/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
+++ 
b/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
@@ -569,22 +569,47 @@ test('Should render RowCountLabel when row limit is hit, 
and hide it otherwise',
   const props = createProps({
     formData: {
       ...createProps().formData,
+      viz_type: VizType.Table,
       row_limit: 10,
     },
+    slice: {
+      ...createProps().slice,
+      viz_type: VizType.Table,
+      form_data: {
+        ...createProps().slice.form_data,
+        viz_type: VizType.Table,
+        row_limit: 10,
+      },
+    },
   });
   const rowCountState = {
     ...initialState,
     charts: {
       [props.slice.slice_id]: {
+        id: MOCKED_CHART_ID,
+        chartStatus: 'rendered',
         queriesResponse: [
           {
             sql_rowcount: 10,
+            data: Array(10).fill({}),
           },
         ],
       },
     },
   };
 
+  const mockUseUiConfig = useUiConfig as jest.MockedFunction<
+    typeof useUiConfig
+  >;
+  mockUseUiConfig.mockReturnValue({
+    hideTitle: false,
+    hideTab: false,
+    hideNav: false,
+    hideChartControls: false,
+    emitDataMasks: false,
+    showRowLimitWarning: true,
+  });
+
   const { rerender } = render(<SliceHeader {...props} />, {
     useRedux: true,
     useRouter: true,
@@ -592,6 +617,7 @@ test('Should render RowCountLabel when row limit is hit, 
and hide it otherwise',
   });
 
   expect(screen.getByTestId('warning')).toBeInTheDocument();
+
   rerender(
     <SliceHeader
       {...props}
@@ -600,11 +626,25 @@ test('Should render RowCountLabel when row limit is hit, 
and hide it otherwise',
   );
 
   expect(screen.queryByTestId('warning')).not.toBeInTheDocument();
+
+  mockUseUiConfig.mockRestore();
 });
 
-test('Should hide RowCountLabel in embedded by default', () => {
+test('Should hide warning in embedded by default for non-table charts', () => {
   const mockIsEmbedded = isEmbedded as jest.MockedFunction<typeof isEmbedded>;
+  const mockUseUiConfig = useUiConfig as jest.MockedFunction<
+    typeof useUiConfig
+  >;
+
   mockIsEmbedded.mockReturnValue(true);
+  mockUseUiConfig.mockReturnValue({
+    hideTitle: false,
+    hideTab: false,
+    hideNav: false,
+    hideChartControls: false,
+    emitDataMasks: false,
+    showRowLimitWarning: false,
+  });
 
   const props = createProps({
     formData: {
@@ -632,17 +672,16 @@ test('Should hide RowCountLabel in embedded by default', 
() => {
   });
 
   expect(screen.queryByTestId('warning')).not.toBeInTheDocument();
+  expect(screen.queryByTestId('row-count-label')).not.toBeInTheDocument();
 
   mockIsEmbedded.mockRestore();
+  mockUseUiConfig.mockRestore();
 });
 
-test('Should show RowCountLabel in embedded when uiConfig.showRowLimitWarning 
is true', () => {
-  const mockIsEmbedded = isEmbedded as jest.MockedFunction<typeof isEmbedded>;
+test('Should show row count badge for table chart without server pagination', 
() => {
   const mockUseUiConfig = useUiConfig as jest.MockedFunction<
     typeof useUiConfig
   >;
-
-  mockIsEmbedded.mockReturnValue(true);
   mockUseUiConfig.mockReturnValue({
     hideTitle: false,
     hideTab: false,
@@ -655,30 +694,164 @@ test('Should show RowCountLabel in embedded when 
uiConfig.showRowLimitWarning is
   const props = createProps({
     formData: {
       ...createProps().formData,
+      viz_type: VizType.Table,
       row_limit: 10,
     },
+    slice: {
+      ...createProps().slice,
+      form_data: {
+        ...createProps().slice.form_data,
+        viz_type: VizType.Table,
+        row_limit: 10,
+      },
+      viz_type: VizType.Table,
+    },
   });
-  const rowCountState = {
+  const tableState = {
+    ...initialState,
+    charts: {
+      [props.slice.slice_id]: {
+        id: MOCKED_CHART_ID,
+        chartStatus: 'rendered',
+        queriesResponse: [
+          {
+            sql_rowcount: 50,
+            data: [],
+          },
+        ],
+      },
+    },
+  };
+
+  render(<SliceHeader {...props} />, {
+    useRedux: true,
+    useRouter: true,
+    initialState: tableState,
+  });
+
+  expect(screen.getByTestId('warning')).toBeInTheDocument();
+
+  mockUseUiConfig.mockRestore();
+});
+
+test('Should show row count warning for table chart with server pagination 
when limit is reached', () => {
+  const props = createProps({
+    formData: {
+      ...createProps().formData,
+      viz_type: VizType.Table,
+      row_limit: 10,
+      server_pagination: true,
+    },
+    slice: {
+      ...createProps().slice,
+      form_data: {
+        ...createProps().slice.form_data,
+        viz_type: VizType.Table,
+        row_limit: 10,
+        server_pagination: true,
+      },
+      viz_type: VizType.Table,
+    },
+  });
+  const tableWithPaginationState = {
     ...initialState,
     charts: {
       [props.slice.slice_id]: {
+        id: MOCKED_CHART_ID,
+        chartStatus: 'rendered',
         queriesResponse: [
           {
             sql_rowcount: 10,
+            data: Array(10).fill({}),
+          },
+          {
+            data: [{ rowcount: 50 }],
           },
         ],
       },
     },
   };
 
+  const mockUseUiConfig = useUiConfig as jest.MockedFunction<
+    typeof useUiConfig
+  >;
+  mockUseUiConfig.mockReturnValue({
+    hideTitle: false,
+    hideTab: false,
+    hideNav: false,
+    hideChartControls: false,
+    emitDataMasks: false,
+    showRowLimitWarning: true,
+  });
+
   render(<SliceHeader {...props} />, {
     useRedux: true,
     useRouter: true,
-    initialState: rowCountState,
+    initialState: tableWithPaginationState,
   });
 
   expect(screen.getByTestId('warning')).toBeInTheDocument();
 
-  mockIsEmbedded.mockRestore();
+  mockUseUiConfig.mockRestore();
+});
+
+test('Should NOT show row count warning for table chart with server pagination 
when limit is NOT reached', () => {
+  const props = createProps({
+    formData: {
+      ...createProps().formData,
+      viz_type: VizType.Table,
+      row_limit: 100,
+      server_pagination: true,
+    },
+    slice: {
+      ...createProps().slice,
+      form_data: {
+        ...createProps().slice.form_data,
+        viz_type: VizType.Table,
+        row_limit: 100,
+        server_pagination: true,
+      },
+      viz_type: VizType.Table,
+    },
+  });
+  const tableWithPaginationState = {
+    ...initialState,
+    charts: {
+      [props.slice.slice_id]: {
+        id: MOCKED_CHART_ID,
+        chartStatus: 'rendered',
+        queriesResponse: [
+          {
+            sql_rowcount: 10,
+            data: Array(10).fill({}),
+          },
+          {
+            data: [{ rowcount: 30 }],
+          },
+        ],
+      },
+    },
+  };
+
+  const mockUseUiConfig = useUiConfig as jest.MockedFunction<
+    typeof useUiConfig
+  >;
+  mockUseUiConfig.mockReturnValue({
+    hideTitle: false,
+    hideTab: false,
+    hideNav: false,
+    hideChartControls: false,
+    emitDataMasks: false,
+    showRowLimitWarning: true,
+  });
+
+  render(<SliceHeader {...props} />, {
+    useRedux: true,
+    useRouter: true,
+    initialState: tableWithPaginationState,
+  });
+
+  expect(screen.queryByTestId('warning')).not.toBeInTheDocument();
+
   mockUseUiConfig.mockRestore();
 });
diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx 
b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
index 4e76ec6fe61..a0a6f702a4a 100644
--- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
@@ -190,12 +190,26 @@ const SliceHeader = forwardRef<HTMLDivElement, 
SliceHeaderProps>(
       state => state.charts[slice.slice_id].queriesResponse?.[0],
     );
 
+    const secondQueryResponse = useSelector<RootState, QueryData | undefined>(
+      state => state.charts[slice.slice_id].queriesResponse?.[1],
+    );
+
     const theme = useTheme();
 
-    const rowLimit = Number(formData.row_limit || -1);
-    const sqlRowCount = Number(firstQueryResponse?.sql_rowcount || 0);
+    const rowLimit = Number(formData.row_limit ?? 0);
+
+    const isTableChart = formData.viz_type === 'table';
+    const countFromSecondQuery =
+      isTableChart && secondQueryResponse?.data?.[0]?.rowcount;
+
+    const sqlRowCount =
+      countFromSecondQuery != null
+        ? countFromSecondQuery
+        : Number(firstQueryResponse?.sql_rowcount ?? 0);
 
     const canExplore = !editMode && supersetCanExplore;
+    const showRowLimitWarning =
+      shouldShowRowLimitWarning && sqlRowCount >= rowLimit && rowLimit > 0;
 
     useEffect(() => {
       const headerElement = headerRef.current;
@@ -304,7 +318,7 @@ const SliceHeader = forwardRef<HTMLDivElement, 
SliceHeaderProps>(
                 <FiltersBadge chartId={slice.slice_id} />
               )}
 
-              {shouldShowRowLimitWarning && sqlRowCount === rowLimit && (
+              {showRowLimitWarning && (
                 <RowCountLabel
                   rowcount={sqlRowCount}
                   limit={rowLimit}
diff --git a/superset-frontend/src/explore/components/ChartPills.tsx 
b/superset-frontend/src/explore/components/ChartPills.tsx
index 42b337cfd71..a3d26de0a57 100644
--- a/superset-frontend/src/explore/components/ChartPills.tsx
+++ b/superset-frontend/src/explore/components/ChartPills.tsx
@@ -43,6 +43,11 @@ export type ChartPillsProps = {
   refreshCachedQuery: () => void;
   rowLimit?: string | number;
   hideRowCount?: boolean;
+  formData?: {
+    viz_type?: string;
+    server_pagination?: boolean;
+    [key: string]: unknown;
+  };
 };
 
 export const ChartPills = forwardRef(
@@ -55,12 +60,25 @@ export const ChartPills = forwardRef(
       refreshCachedQuery,
       rowLimit,
       hideRowCount = false,
+      formData,
     }: ChartPillsProps,
     ref: RefObject<HTMLDivElement>,
   ) => {
     const isLoading = chartStatus === 'loading';
     const firstQueryResponse = queriesResponse?.[0];
 
+    // For table charts with server pagination, check second query for total 
count
+    const isTableChart = formData?.viz_type === 'table';
+    const hasCountQuery = queriesResponse && queriesResponse.length > 1;
+    const countFromSecondQuery = hasCountQuery
+      ? queriesResponse[1]?.data?.[0]?.rowcount
+      : null;
+
+    const actualRowCount =
+      isTableChart && countFromSecondQuery != null
+        ? countFromSecondQuery
+        : Number(firstQueryResponse?.sql_rowcount ?? 0);
+
     return (
       <div ref={ref}>
         <div
@@ -72,7 +90,7 @@ export const ChartPills = forwardRef(
         >
           {!isLoading && !hideRowCount && firstQueryResponse && (
             <RowCountLabel
-              rowcount={Number(firstQueryResponse.sql_rowcount) || 0}
+              rowcount={actualRowCount}
               limit={Number(rowLimit ?? 0)}
             />
           )}
diff --git 
a/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx 
b/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx
index c55fe306bff..9b24f282c0e 100644
--- a/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx
+++ b/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx
@@ -397,6 +397,7 @@ const ExploreChartPanel = ({
               formData?.matrixify_enable_vertical_layout === true ||
               formData?.matrixify_enable_horizontal_layout === true
             }
+            formData={formData}
           />
         </ChartHeaderExtension>
         {renderChart()}

Reply via email to