From 9302410f1a0e952bba5ac0f901cdba8532dce44d Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Mon, 22 Jul 2024 11:22:38 +0200 Subject: [PATCH] Lazy loading flag moved to the root props instead of it being a part of the data source model --- .../pages/x/api/data-grid/data-grid-premium.json | 1 + docs/pages/x/api/data-grid/data-grid-pro.json | 1 + .../data-grid-premium/data-grid-premium.json | 3 +++ .../data-grid/data-grid-pro/data-grid-pro.json | 3 +++ .../src/DataGridPremium/DataGridPremium.tsx | 8 +++++++- .../src/DataGridPro/DataGridPro.tsx | 8 +++++++- .../features/dataSource/useGridDataSource.ts | 16 ++++++++++------ .../useGridDataSourceLazyLoader.ts | 7 +++++-- .../useGridDataSourceLazyLoaderPreProcessors.tsx | 7 ++++--- .../src/internals/propValidation.ts | 4 ++-- .../src/models/dataGridProProps.ts | 7 +++++++ .../x-data-grid/src/models/gridDataSource.ts | 5 ----- 12 files changed, 50 insertions(+), 20 deletions(-) diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json index 1c79c35a04e6e..a4de9d4aae58a 100644 --- a/docs/pages/x/api/data-grid/data-grid-premium.json +++ b/docs/pages/x/api/data-grid/data-grid-premium.json @@ -205,6 +205,7 @@ }, "keepColumnPositionIfDraggedOutside": { "type": { "name": "bool" }, "default": "false" }, "keepNonExistentRowsSelected": { "type": { "name": "bool" }, "default": "false" }, + "lazyLoading": { "type": { "name": "bool" }, "default": "false" }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, "logger": { diff --git a/docs/pages/x/api/data-grid/data-grid-pro.json b/docs/pages/x/api/data-grid/data-grid-pro.json index c3eb24a2ffb89..80af82fd619de 100644 --- a/docs/pages/x/api/data-grid/data-grid-pro.json +++ b/docs/pages/x/api/data-grid/data-grid-pro.json @@ -182,6 +182,7 @@ }, "keepColumnPositionIfDraggedOutside": { "type": { "name": "bool" }, "default": "false" }, "keepNonExistentRowsSelected": { "type": { "name": "bool" }, "default": "false" }, + "lazyLoading": { "type": { "name": "bool" }, "default": "false" }, "loading": { "type": { "name": "bool" }, "default": "false" }, "localeText": { "type": { "name": "object" } }, "logger": { diff --git a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json index a8b79b49fb93e..f78f49e26101b 100644 --- a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json +++ b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json @@ -232,6 +232,9 @@ "keepNonExistentRowsSelected": { "description": "If true, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages." }, + "lazyLoading": { + "description": "Used together with unstable_dataSource to enable lazy loading. If enabled, the grid will stop adding paginationModel to the data requests (getRows) and start sending start and end values depending on the scroll position. A new request will be made whenever the user scrolls to the area that has skeleton rows." + }, "loading": { "description": "If true, a loading overlay is displayed." }, "localeText": { "description": "Set the locale text of the Data Grid. You can find all the translation keys supported in the source in the GitHub repository." diff --git a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json index 914817291c87f..fc283e4ed4721 100644 --- a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json +++ b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json @@ -213,6 +213,9 @@ "keepNonExistentRowsSelected": { "description": "If true, the selection model will retain selected rows that do not exist. Useful when using server side pagination and row selections need to be retained when changing pages." }, + "lazyLoading": { + "description": "Used together with unstable_dataSource to enable lazy loading. If enabled, the grid will stop adding paginationModel to the data requests (getRows) and start sending start and end values depending on the scroll position. A new request will be made whenever the user scrolls to the area that has skeleton rows." + }, "loading": { "description": "If true, a loading overlay is displayed." }, "localeText": { "description": "Set the locale text of the Data Grid. You can find all the translation keys supported in the source in the GitHub repository." diff --git a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index aaf6e5c85e0e4..334cd5fca1cbe 100644 --- a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -502,6 +502,13 @@ DataGridPremiumRaw.propTypes = { * @default false */ keepNonExistentRowsSelected: PropTypes.bool, + /** + * Used together with `unstable_dataSource` to enable lazy loading. + * If enabled, the grid will stop adding `paginationModel` to the data requests (`getRows`) and start sending `start` and `end` values depending on the scroll position. + * A new request will be made whenever the user scrolls to the area that has skeleton rows. + * @default false + */ + lazyLoading: PropTypes.bool, /** * If `true`, a loading overlay is displayed. * @default false @@ -1049,7 +1056,6 @@ DataGridPremiumRaw.propTypes = { getChildrenCount: PropTypes.func, getGroupKey: PropTypes.func, getRows: PropTypes.func.isRequired, - lazyLoaded: PropTypes.bool, updateRow: PropTypes.func, }), unstable_dataSourceCache: PropTypes.shape({ diff --git a/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx b/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx index 93744618aeeb6..0c7d0878a7f08 100644 --- a/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx +++ b/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx @@ -457,6 +457,13 @@ DataGridProRaw.propTypes = { * @default false */ keepNonExistentRowsSelected: PropTypes.bool, + /** + * Used together with `unstable_dataSource` to enable lazy loading. + * If enabled, the grid will stop adding `paginationModel` to the data requests (`getRows`) and start sending `start` and `end` values depending on the scroll position. + * A new request will be made whenever the user scrolls to the area that has skeleton rows. + * @default false + */ + lazyLoading: PropTypes.bool, /** * If `true`, a loading overlay is displayed. * @default false @@ -948,7 +955,6 @@ DataGridProRaw.propTypes = { getChildrenCount: PropTypes.func, getGroupKey: PropTypes.func, getRows: PropTypes.func.isRequired, - lazyLoaded: PropTypes.bool, updateRow: PropTypes.func, }), unstable_dataSourceCache: PropTypes.shape({ diff --git a/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSource.ts b/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSource.ts index e8267b88adafe..17e7b7d35a1cb 100644 --- a/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSource.ts +++ b/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSource.ts @@ -57,6 +57,7 @@ export const useGridDataSource = ( | 'filterMode' | 'paginationMode' | 'treeData' + | 'lazyLoading' >, ) => { const nestedDataManager = useLazyRef( @@ -64,9 +65,12 @@ export const useGridDataSource = ( ).current; const groupsToAutoFetch = useGridSelector(apiRef, gridRowGroupsToFetchSelector); const scheduledGroups = React.useRef(0); + + const isLazyLoaded = !!props.unstable_dataSource && props.lazyLoading; const rowFetchSlice = React.useRef( - props.unstable_dataSource?.lazyLoaded ? { start: 0, end: 10 } : {}, // TODO: predict the initial `end` from the viewport + isLazyLoaded ? { start: 0, end: 10 } : {}, // TODO: predict the initial `end` from the viewport ); + const onError = props.unstable_onDataSourceError; const [cache, setCache] = React.useState(() => @@ -97,7 +101,7 @@ export const useGridDataSource = ( if (cachedData !== undefined) { const rows = cachedData.rows; - if (props.unstable_dataSource?.lazyLoaded === true) { + if (isLazyLoaded) { apiRef.current.unstable_replaceRows(fetchParams.start, rows); } else { apiRef.current.setRows(rows); @@ -119,7 +123,7 @@ export const useGridDataSource = ( if (getRowsResponse.rowCount) { apiRef.current.setRowCount(getRowsResponse.rowCount); } - if (props.unstable_dataSource?.lazyLoaded === true) { + if (isLazyLoaded) { apiRef.current.unstable_replaceRows(fetchParams.start, getRowsResponse.rows); } else { apiRef.current.setRows(getRowsResponse.rows); @@ -135,7 +139,7 @@ export const useGridDataSource = ( nestedDataManager, apiRef, props.unstable_dataSource?.getRows, - props.unstable_dataSource?.lazyLoaded, + isLazyLoaded, onError, rowFetchSlice, ], @@ -143,12 +147,12 @@ export const useGridDataSource = ( const fetchRowBatch = React.useCallback( (fetchParams: GridGetRowsParams) => { - if (props.unstable_dataSource?.lazyLoaded && fetchParams.start && fetchParams.end) { + if (isLazyLoaded && fetchParams.start && fetchParams.end) { rowFetchSlice.current = { start: Number(fetchParams.start), end: fetchParams.end }; } return fetchRows(); }, - [props.unstable_dataSource?.lazyLoaded, fetchRows], + [isLazyLoaded, fetchRows], ); const fetchRowChildren = React.useCallback( diff --git a/packages/x-data-grid-pro/src/hooks/features/serverSideLazyLoader/useGridDataSourceLazyLoader.ts b/packages/x-data-grid-pro/src/hooks/features/serverSideLazyLoader/useGridDataSourceLazyLoader.ts index de86ec3642a69..338b535e06f9c 100644 --- a/packages/x-data-grid-pro/src/hooks/features/serverSideLazyLoader/useGridDataSourceLazyLoader.ts +++ b/packages/x-data-grid-pro/src/hooks/features/serverSideLazyLoader/useGridDataSourceLazyLoader.ts @@ -28,12 +28,15 @@ const INTERVAL_CACHE_INITIAL_STATE = { */ export const useGridDataSourceLazyLoader = ( privateApiRef: React.MutableRefObject, - props: Pick, + props: Pick< + DataGridProProcessedProps, + 'pagination' | 'paginationMode' | 'unstable_dataSource' | 'lazyLoading' + >, ): void => { const sortModel = useGridSelector(privateApiRef, gridSortModelSelector); const filterModel = useGridSelector(privateApiRef, gridFilterModelSelector); const renderedRowsIntervalCache = React.useRef(INTERVAL_CACHE_INITIAL_STATE); - const isDisabled = props.unstable_dataSource?.lazyLoaded !== true; + const isDisabled = !props.unstable_dataSource || props.lazyLoading !== true; const handleRenderedRowsIntervalChange = React.useCallback< GridEventListener<'renderedRowsIntervalChange'> diff --git a/packages/x-data-grid-pro/src/hooks/features/serverSideLazyLoader/useGridDataSourceLazyLoaderPreProcessors.tsx b/packages/x-data-grid-pro/src/hooks/features/serverSideLazyLoader/useGridDataSourceLazyLoaderPreProcessors.tsx index 3c39231910ddf..305f46a464629 100644 --- a/packages/x-data-grid-pro/src/hooks/features/serverSideLazyLoader/useGridDataSourceLazyLoaderPreProcessors.tsx +++ b/packages/x-data-grid-pro/src/hooks/features/serverSideLazyLoader/useGridDataSourceLazyLoaderPreProcessors.tsx @@ -10,13 +10,14 @@ const getSkeletonRowId = (index: number) => `${GRID_SKELETON_ROW_ROOT_ID}-${inde export const useGridDataSourceLazyLoaderPreProcessors = ( privateApiRef: React.MutableRefObject, - props: Pick, + props: Pick, ) => { const addSkeletonRows = React.useCallback>( (groupingParams) => { const rootGroup = groupingParams.tree[GRID_ROOT_GROUP_ID] as GridGroupNode; + const isDisabled = !props.unstable_dataSource || props.lazyLoading !== true; - if (props.unstable_dataSource?.lazyLoaded !== true) { + if (isDisabled) { return groupingParams; } @@ -46,7 +47,7 @@ export const useGridDataSourceLazyLoaderPreProcessors = ( tree, }; }, - [props.unstable_dataSource?.lazyLoaded], + [props.unstable_dataSource, props.lazyLoading], ); useGridRegisterPipeProcessor(privateApiRef, 'hydrateRows', addSkeletonRows); diff --git a/packages/x-data-grid-pro/src/internals/propValidation.ts b/packages/x-data-grid-pro/src/internals/propValidation.ts index efd2c26029ad7..e4cf9b6572b42 100644 --- a/packages/x-data-grid-pro/src/internals/propValidation.ts +++ b/packages/x-data-grid-pro/src/internals/propValidation.ts @@ -34,7 +34,7 @@ export const propValidatorsDataGridPro: PropValidator (props) => (props.signature !== GridSignature.DataGrid && props.rowsLoadingMode === 'server' && - props.unstable_dataSource?.lazyLoaded === true && - 'MUI X: Usage of the client side lazy loading (`rowsLoadingMode="server"`) cannot be used together with server side lazy loading `unstable_dataSource="{ ..., lazyLoaded: true}"`.') || + props.lazyLoading && + 'MUI X: Usage of the client side lazy loading (`rowsLoadingMode="server"`) cannot be used together with server side lazy loading `lazyLoading="true"`.') || undefined, ]; diff --git a/packages/x-data-grid-pro/src/models/dataGridProProps.ts b/packages/x-data-grid-pro/src/models/dataGridProProps.ts index 4d611b57ea069..a9ad24fa444d2 100644 --- a/packages/x-data-grid-pro/src/models/dataGridProProps.ts +++ b/packages/x-data-grid-pro/src/models/dataGridProProps.ts @@ -137,6 +137,13 @@ export interface DataGridProPropsWithDefaultValue number; - /** - * If enabled, the grid will send `start` and `end` instead of `paginationModel` to `getRows` and a new request will be made - * whenever the user scrolls to the area that has skeleton rows - */ - lazyLoaded?: boolean; } export interface GridDataSourceCache {