diff --git a/superset-frontend/packages/superset-ui-core/src/validator/validateServerPagination.ts b/superset-frontend/packages/superset-ui-core/src/validator/validateServerPagination.ts index 02db3585a1a..202ca953990 100644 --- a/superset-frontend/packages/superset-ui-core/src/validator/validateServerPagination.ts +++ b/superset-frontend/packages/superset-ui-core/src/validator/validateServerPagination.ts @@ -21,10 +21,18 @@ import { t } from '../translation'; export default function validateServerPagination( v: unknown, serverPagination: boolean, - max: number, + maxValueWithoutServerPagination: number, + maxServer: number, ) { - if (Number(v) > +max && !serverPagination) { - return t('Server pagination needs to be enabled for values over %s', max); + if ( + Number(v) > +maxValueWithoutServerPagination && + Number(v) <= maxServer && + !serverPagination + ) { + return t( + 'Server pagination needs to be enabled for values over %s', + maxValueWithoutServerPagination, + ); } return false; } diff --git a/superset-frontend/packages/superset-ui-core/test/validator/validateServerPagination.test.ts b/superset-frontend/packages/superset-ui-core/test/validator/validateServerPagination.test.ts index 5a638e5142f..0be67f32baf 100644 --- a/superset-frontend/packages/superset-ui-core/test/validator/validateServerPagination.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/validator/validateServerPagination.test.ts @@ -20,27 +20,134 @@ import { validateServerPagination } from '@superset-ui/core'; import './setup'; -test('validateServerPagination returns warning message when server pagination is disabled and value exceeds max', () => { - expect(validateServerPagination(100001, false, 100000)).toBeTruthy(); - expect(validateServerPagination('150000', false, 100000)).toBeTruthy(); - expect(validateServerPagination(200000, false, 100000)).toBeTruthy(); +const DEFAULT_MAX_ROW = 100000; +const DEFAULT_MAX_ROW_TABLE_SERVER = 500000; + +test('validateServerPagination returns warning message only when value is between max thresholds and server pagination is disabled', () => { + // Should show warning - value between thresholds and server pagination disabled + expect( + validateServerPagination( + 200000, + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeTruthy(); + expect( + validateServerPagination( + 300000, + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeTruthy(); + + // Should not show warning - value above max server threshold + expect( + validateServerPagination( + 600000, + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); + + // Should not show warning - value below max without server threshold + expect( + validateServerPagination( + 50000, + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); }); -test('validateServerPagination returns false when server pagination is enabled', () => { - expect(validateServerPagination(100001, true, 100000)).toBeFalsy(); - expect(validateServerPagination(150000, true, 100000)).toBeFalsy(); - expect(validateServerPagination('200000', true, 100000)).toBeFalsy(); +test('validateServerPagination returns false when server pagination is enabled regardless of value', () => { + expect( + validateServerPagination( + 200000, + true, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); + expect( + validateServerPagination( + 300000, + true, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); + expect( + validateServerPagination( + 600000, + true, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); }); -test('validateServerPagination returns false when value is below max', () => { - expect(validateServerPagination(50000, false, 100000)).toBeFalsy(); - expect(validateServerPagination('75000', false, 100000)).toBeFalsy(); - expect(validateServerPagination(99999, false, 100000)).toBeFalsy(); +test('validateServerPagination handles string inputs correctly', () => { + expect( + validateServerPagination( + '200000', + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeTruthy(); + expect( + validateServerPagination( + '600000', + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); + expect( + validateServerPagination( + '50000', + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); }); test('validateServerPagination handles edge cases', () => { - expect(validateServerPagination(undefined, false, 100000)).toBeFalsy(); - expect(validateServerPagination(null, false, 100000)).toBeFalsy(); - expect(validateServerPagination(NaN, false, 100000)).toBeFalsy(); - expect(validateServerPagination('invalid', false, 100000)).toBeFalsy(); + expect( + validateServerPagination( + undefined, + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); + expect( + validateServerPagination( + null, + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); + expect( + validateServerPagination( + NaN, + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); + expect( + validateServerPagination( + 'invalid', + false, + DEFAULT_MAX_ROW, + DEFAULT_MAX_ROW_TABLE_SERVER, + ), + ).toBeFalsy(); }); diff --git a/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx b/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx index 3aacefb2f30..638031d7cd9 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/DataTable/DataTable.tsx @@ -113,6 +113,10 @@ const StyledSpace = styled(Space)` } `; +const StyledRow = styled.div` + display: flex; +`; + // Be sure to pass our updateMyData and the skipReset option export default typedMemo(function DataTable({ tableClassName, @@ -447,9 +451,9 @@ export default typedMemo(function DataTable({ > {hasGlobalControl ? (
-
+
{hasPagination ? ( ({ ) : null}
{searchInput ? ( - + {serverPagination && (
Search by: @@ -500,7 +508,7 @@ export default typedMemo(function DataTable({ {renderTimeComparisonDropdown()}
) : null} -
+
) : null} {wrapStickyTable ? wrapStickyTable(renderTable) : renderTable()} diff --git a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx index 475056c7503..8d921c3d309 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx @@ -79,7 +79,7 @@ import DataTable, { import Styles from './Styles'; import { formatColumnValue } from './utils/formatValue'; -import { PAGE_SIZE_OPTIONS } from './consts'; +import { PAGE_SIZE_OPTIONS, SERVER_PAGE_SIZE_OPTIONS } from './consts'; import { updateTableOwnState } from './DataTable/utils/externalAPIs'; import getScrollBarSize from './DataTable/utils/getScrollBarSize'; @@ -306,7 +306,9 @@ export default function TableChart( // only take relevant page size options const pageSizeOptions = useMemo(() => { const getServerPagination = (n: number) => n <= rowCount; - return PAGE_SIZE_OPTIONS.filter(([n]) => + return ( + serverPagination ? SERVER_PAGE_SIZE_OPTIONS : PAGE_SIZE_OPTIONS + ).filter(([n]) => serverPagination ? getServerPagination(n) : n <= 2 * data.length, ) as SizeOption[]; }, [data.length, rowCount, serverPagination]); diff --git a/superset-frontend/plugins/plugin-chart-table/src/consts.ts b/superset-frontend/plugins/plugin-chart-table/src/consts.ts index e370c4b0295..c2cd9dfa66f 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/consts.ts +++ b/superset-frontend/plugins/plugin-chart-table/src/consts.ts @@ -30,3 +30,7 @@ export const PAGE_SIZE_OPTIONS = formatSelectOptions([ 100, 200, ]); + +export const SERVER_PAGE_SIZE_OPTIONS = formatSelectOptions([ + 10, 20, 50, 100, 200, +]); diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx index aab66f800dd..0bd69e7cc53 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx @@ -54,7 +54,7 @@ import { } from '@superset-ui/core'; import { isEmpty, last } from 'lodash'; -import { PAGE_SIZE_OPTIONS } from './consts'; +import { PAGE_SIZE_OPTIONS, SERVER_PAGE_SIZE_OPTIONS } from './consts'; import { ColorSchemeEnum } from './types'; function getQueryMode(controls: ControlStateMapping): QueryMode { @@ -364,7 +364,7 @@ const config: ControlPanelConfig = { freeForm: true, label: t('Server Page Length'), default: 10, - choices: PAGE_SIZE_OPTIONS, + choices: SERVER_PAGE_SIZE_OPTIONS, description: t('Rows per page, 0 means no pagination'), visibility: ({ controls }: ControlPanelsContainerProps) => Boolean(controls?.server_pagination?.value), @@ -397,6 +397,7 @@ const config: ControlPanelConfig = { v, state?.server_pagination, state?.maxValueWithoutServerPagination || DEFAULT_MAX_ROW, + state?.maxValue || DEFAULT_MAX_ROW_TABLE_SERVER, ), ], // Re run the validations when this control value