Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGridPro] Server side data source lazy loading #13878

Merged
merged 121 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
8348972
row indexes query params take precedence over pagination
arminmeh Jul 18, 2024
1fb4c12
Add basic (dev) demo for server side lazy loading
arminmeh Jul 18, 2024
502aa0e
Extend data source model
arminmeh Jul 18, 2024
177aa27
Update API docs
arminmeh Jul 18, 2024
9d9e5e0
Add new event to be sent when new batch of rows should be loaded from…
arminmeh Jul 18, 2024
3c820b3
Data source cache takes start and end params into account
arminmeh Jul 18, 2024
857023d
Add server side version of lazy loading pre-processor and hook
arminmeh Jul 18, 2024
24d6e65
Prvent both client and server side lazy loading setup
arminmeh Jul 18, 2024
94e71ee
Data source hook supports new way of loading data and replaces lazy l…
arminmeh Jul 18, 2024
cd01a63
Lazy loading flag moved to the root props instead of it being a part …
arminmeh Jul 22, 2024
446b47b
Update docs
arminmeh Jul 22, 2024
3be08cf
Check for skeleton rows with the sorting and filtering enabled
arminmeh Aug 2, 2024
5ed0151
Loading overlay for the initial load only
arminmeh Aug 2, 2024
8dfc7fb
Skeleton rows should be added after data load to be able to know the …
arminmeh Aug 7, 2024
6b9e0ad
Rename and repurpose the event
arminmeh Aug 7, 2024
0755671
Publish event even for data source updates from cache
arminmeh Aug 7, 2024
4262116
Fix duplicate key issues. Add initial throttling
arminmeh Aug 7, 2024
6e431f3
Move events to pro lookup. Do not document
arminmeh Aug 8, 2024
74109be
Add default value
arminmeh Aug 8, 2024
b16d9c6
Add hook to the premium package
arminmeh Aug 8, 2024
95413f1
Update demo
arminmeh Aug 8, 2024
4c06201
Remove encoding
arminmeh Aug 14, 2024
17cc7b3
Remove non-existing import
arminmeh Aug 16, 2024
3292704
Fix the mock data slice calculation
arminmeh Aug 16, 2024
c6dec3b
Import throttle from internals package. Do not reset rendering contex…
arminmeh Aug 16, 2024
834c05e
Adjust start and end params to cover whole page(s). Cache responses i…
arminmeh Aug 16, 2024
ed89679
Do not reset render context on filtering
arminmeh Aug 16, 2024
fb6fe26
Params should always be adjusted to the whole page to allow proper ex…
arminmeh Aug 16, 2024
46fe91d
Add support for infinite loading
arminmeh Sep 6, 2024
9f26c2d
Update docs
arminmeh Sep 6, 2024
e12334a
Update docs and API. Add missing types
arminmeh Sep 6, 2024
9a443e9
Cleanup
arminmeh Sep 6, 2024
391eb6c
Change the way current row count is retrieved to support controlled r…
arminmeh Sep 12, 2024
307f932
Get current rows from the state instead of prop when data source is used
arminmeh Sep 19, 2024
2c9f9be
Make sure row count is not undefined
arminmeh Sep 19, 2024
35e44d6
Support switching between lazy loading and infinite loading mode
arminmeh Sep 19, 2024
7073989
Extend fetchRows API to enable request retries. Keep compatibility wi…
arminmeh Sep 23, 2024
7a47b41
Pagination params adjustment inside lazyLoading hook. Use the same ap…
arminmeh Oct 1, 2024
c02606f
Update prop validation
arminmeh Oct 1, 2024
0ae8b89
Clear the cache when grid is reset
arminmeh Oct 2, 2024
decd848
Show loading indicator when grid is reset
arminmeh Oct 2, 2024
274ee2c
Update existing examples
arminmeh Oct 2, 2024
d4c07ce
Update docs and add new examples
arminmeh Oct 2, 2024
3024581
Fix docs
arminmeh Oct 2, 2024
a831683
Update description
arminmeh Oct 2, 2024
8a30bb1
Fix type error
arminmeh Oct 2, 2024
b464d33
Update API docs
arminmeh Oct 3, 2024
77d1e2a
Align toolbar customization
arminmeh Oct 3, 2024
d79bdac
Update future feature links
arminmeh Oct 3, 2024
902d1c6
Do not export GridDataSourceCacheDefaultConfig
arminmeh Oct 3, 2024
c1a0d4e
Add prop to control throttling
arminmeh Oct 3, 2024
2b83584
Update API docs
arminmeh Oct 3, 2024
3081343
Fix: Sorting in viewport mode should fill the grid with skeleton rows
arminmeh Oct 4, 2024
b9161d0
Add tests
arminmeh Oct 4, 2024
4695910
Fix test
arminmeh Oct 4, 2024
44cb105
Use default delay for the mock server in the demos
arminmeh Oct 4, 2024
53d1e56
Add loading overlay on sorting
arminmeh Oct 4, 2024
c45d270
Put back a bit more delay on the mock server
arminmeh Oct 4, 2024
48d5acf
Update API docs to distinguish client and server side event
arminmeh Oct 25, 2024
278bfec
Example updates
arminmeh Oct 30, 2024
bf10c11
Remove new label from the sub-page
arminmeh Oct 30, 2024
f2f1a39
Error example updates
arminmeh Oct 30, 2024
82a0187
put back parentId param to fetchRows
arminmeh Nov 1, 2024
1ef9cbf
Update error example to work with the new fetchRows definition
arminmeh Nov 1, 2024
344c860
Fix check parent condition
arminmeh Nov 1, 2024
3312610
Update API
arminmeh Nov 4, 2024
4783c89
Add data source row update strategy
arminmeh Nov 6, 2024
7560bdc
Fix docs warning
arminmeh Nov 6, 2024
23c7819
Data source and lazy loading hook are using new strategy group to det…
arminmeh Nov 6, 2024
76ef289
Fix pages rebase
arminmeh Nov 6, 2024
6408977
Remove unnecessary variable
arminmeh Nov 6, 2024
bdf5b6e
Update start and end query param names in the mock server
arminmeh Nov 6, 2024
5bb4e28
Ignore type
arminmeh Nov 6, 2024
f15373b
Docs and demo improvements
arminmeh Nov 6, 2024
fea7cd1
Fix error demo
arminmeh Nov 6, 2024
cdcda03
Fix lint issue. Fix test
arminmeh Nov 6, 2024
a1c4d20
Clear Snackbar alert after successful data fetch
arminmeh Nov 7, 2024
533f49b
Remove events
arminmeh Nov 7, 2024
96a729d
Merge callouts
arminmeh Nov 7, 2024
7545e94
Split cache and chunk manager
arminmeh Nov 7, 2024
dce506c
Do not use cache directly in the chunk manager
arminmeh Nov 7, 2024
6c079bb
Add an additional example for lazyLoadingRequestThrottleMs
arminmeh Nov 8, 2024
47c41ad
Fix docs
arminmeh Nov 8, 2024
2969483
Allign page flags
arminmeh Nov 25, 2024
f939606
Fix build
arminmeh Nov 25, 2024
884333d
Fix data source race condition
arminmeh Nov 26, 2024
5e6c42f
Strategy group name as enum
arminmeh Nov 26, 2024
53767cb
Deprecate lazy loading and infinite loading sections for the manual r…
arminmeh Nov 26, 2024
5946b7e
Add chunk manager docs
arminmeh Nov 26, 2024
d40893a
Fix pages after rebase
arminmeh Nov 26, 2024
47c436a
Fix pages again
arminmeh Nov 26, 2024
0c0ec6a
Do not clear existing row count if the new response does not have a n…
arminmeh Nov 27, 2024
771e4e1
Align wording
arminmeh Nov 27, 2024
2f80265
Revert deprecations. They will be handled in a separate PR
arminmeh Nov 27, 2024
516d2c8
Performance improvements
arminmeh Nov 27, 2024
9aa1825
Update docs
arminmeh Nov 27, 2024
0bd329e
Code cleanup
arminmeh Nov 27, 2024
a15210c
Request identifier as a number
arminmeh Nov 27, 2024
d932f23
More code cleanup
arminmeh Nov 27, 2024
514a786
Fix build issue
arminmeh Nov 27, 2024
60621de
Static row count for better UI
arminmeh Nov 27, 2024
580f59c
Update cache manager description
arminmeh Nov 27, 2024
9c3bf3d
Remove empty space
arminmeh Nov 27, 2024
490aa90
Fix duplicate skeleton row key issue
arminmeh Nov 27, 2024
107563b
Add unstable prefix to the lazyLoading flag
arminmeh Nov 27, 2024
5a3bead
Code cleanup
arminmeh Nov 27, 2024
3e53369
Move chunk size calculation in lazyRef
arminmeh Nov 27, 2024
cfcaf2c
Fix condition
arminmeh Nov 27, 2024
653665e
Revert pagination label updates
arminmeh Nov 27, 2024
02e910f
Update test to reflect skeleton row index change
arminmeh Nov 27, 2024
c6e47f1
Fix rebase
arminmeh Nov 27, 2024
1309c7c
make lazyLoadingRequestThrottleMs unstable
arminmeh Nov 28, 2024
b5cd453
Performance improvements
arminmeh Nov 28, 2024
19302ad
Cleanup effects
arminmeh Nov 28, 2024
6425bf2
Update documentation
arminmeh Nov 29, 2024
e233143
Additional fixes to the overview page
arminmeh Nov 29, 2024
b3dee7a
Align info boxes for the mock function
arminmeh Nov 29, 2024
593c907
Improve lazy loading docs
arminmeh Nov 29, 2024
6a96423
Trigger build
arminmeh Nov 29, 2024
96063f0
Trigger build (again)
arminmeh Nov 29, 2024
78cfc73
Add icon to the title
arminmeh Dec 2, 2024
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
2 changes: 1 addition & 1 deletion docs/data/data-grid/events/events.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
{
"projects": ["x-data-grid-pro", "x-data-grid-premium"],
"name": "fetchRows",
"description": "Fired when a new batch of rows is requested to be loaded. Called with a GridFetchRowsParams object.",
"description": "Fired when a new batch of rows is requested to be loaded. Called with a GridFetchRowsParams object. Used to trigger <code>onFetchRows</code>.",
"params": "GridFetchRowsParams",
"event": "MuiEvent<{}>",
"componentProp": "onFetchRows"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default function ServerSideDataGridNoCache() {
...initialState,
pagination: {
paginationModel: { pageSize: 10, page: 0 },
rowCount: 0,
},
}),
[initialState],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default function ServerSideDataGridNoCache() {
...initialState,
pagination: {
paginationModel: { pageSize: 10, page: 0 },
rowCount: 0,
},
}),
[initialState],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import * as React from 'react';
import {
DataGridPro,
useGridApiRef,
GridToolbar,
GRID_ROOT_GROUP_ID,
} from '@mui/x-data-grid-pro';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import { useMockServer } from '@mui/x-data-grid-generator';
import Alert from '@mui/material/Alert';
import Button from '@mui/material/Button';
import Snackbar from '@mui/material/Snackbar';

function ErrorSnackbar(props) {
const { onRetry, ...rest } = props;
return (
<Snackbar {...rest}>
<Alert
severity="error"
variant="filled"
sx={{ width: '100%' }}
action={
<Button color="inherit" size="small" onClick={onRetry}>
Retry
</Button>
}
>
Failed to fetch row data
</Alert>
</Snackbar>
);
}

function ServerSideLazyLoadingErrorHandling() {
const apiRef = useGridApiRef();
const [retryParams, setRetryParams] = React.useState(null);
const [shouldRequestsFail, setShouldRequestsFail] = React.useState(false);

const { fetchRows, ...props } = useMockServer(
{ rowLength: 100 },
{ useCursorPagination: false, minDelay: 300, maxDelay: 800 },
shouldRequestsFail,
);

const dataSource = React.useMemo(
() => ({
getRows: async (params) => {
const urlParams = new URLSearchParams({
filterModel: JSON.stringify(params.filterModel),
sortModel: JSON.stringify(params.sortModel),
start: `${params.start}`,
end: `${params.end}`,
});
const getRowsResponse = await fetchRows(
`https://mui.com/x/api/data-grid?${urlParams.toString()}`,
);

// Reset the retryParams when new rows are fetched
setRetryParams(null);
return {
rows: getRowsResponse.rows,
rowCount: getRowsResponse.rowCount,
};
},
}),
[fetchRows],
);

return (
<div style={{ width: '100%' }}>
<FormControlLabel
control={
<Checkbox
checked={shouldRequestsFail}
onChange={(event) => setShouldRequestsFail(event.target.checked)}
/>
}
label="Make the requests fail"
/>
<div style={{ height: 400, position: 'relative' }}>
{retryParams && (
<ErrorSnackbar
open={!!retryParams}
onRetry={() => {
apiRef.current.unstable_dataSource.fetchRows(
GRID_ROOT_GROUP_ID,
retryParams,
);
setRetryParams(null);
}}
/>
)}
<DataGridPro
{...props}
apiRef={apiRef}
unstable_dataSource={dataSource}
unstable_onDataSourceError={(_, params) => setRetryParams(params)}
unstable_dataSourceCache={null}
unstable_lazyLoading
paginationModel={{ page: 0, pageSize: 10 }}
slots={{ toolbar: GridToolbar }}
/>
</div>
</div>
);
}

export default ServerSideLazyLoadingErrorHandling;
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import * as React from 'react';
import {
DataGridPro,
useGridApiRef,
GridToolbar,
GridDataSource,
GridGetRowsParams,
GRID_ROOT_GROUP_ID,
} from '@mui/x-data-grid-pro';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import { useMockServer } from '@mui/x-data-grid-generator';
import Alert from '@mui/material/Alert';
import Button from '@mui/material/Button';
import Snackbar, { SnackbarProps } from '@mui/material/Snackbar';

function ErrorSnackbar(props: SnackbarProps & { onRetry: () => void }) {
const { onRetry, ...rest } = props;
return (
<Snackbar {...rest}>
<Alert
severity="error"
variant="filled"
sx={{ width: '100%' }}
action={
<Button color="inherit" size="small" onClick={onRetry}>
Retry
</Button>
}
>
Failed to fetch row data
</Alert>
</Snackbar>
);
}

function ServerSideLazyLoadingErrorHandling() {
const apiRef = useGridApiRef();
const [retryParams, setRetryParams] = React.useState<GridGetRowsParams | null>(
arminmeh marked this conversation as resolved.
Show resolved Hide resolved
null,
);
const [shouldRequestsFail, setShouldRequestsFail] = React.useState(false);

const { fetchRows, ...props } = useMockServer(
{ rowLength: 100 },
{ useCursorPagination: false, minDelay: 300, maxDelay: 800 },
shouldRequestsFail,
);

const dataSource: GridDataSource = React.useMemo(
() => ({
getRows: async (params) => {
const urlParams = new URLSearchParams({
filterModel: JSON.stringify(params.filterModel),
sortModel: JSON.stringify(params.sortModel),
start: `${params.start}`,
end: `${params.end}`,
});
const getRowsResponse = await fetchRows(
`https://mui.com/x/api/data-grid?${urlParams.toString()}`,
);

// Reset the retryParams when new rows are fetched
setRetryParams(null);
return {
rows: getRowsResponse.rows,
rowCount: getRowsResponse.rowCount,
};
},
}),
[fetchRows],
);

return (
<div style={{ width: '100%' }}>
<FormControlLabel
control={
<Checkbox
checked={shouldRequestsFail}
onChange={(event) => setShouldRequestsFail(event.target.checked)}
/>
}
label="Make the requests fail"
/>
<div style={{ height: 400, position: 'relative' }}>
{retryParams && (
<ErrorSnackbar
arminmeh marked this conversation as resolved.
Show resolved Hide resolved
open={!!retryParams}
onRetry={() => {
apiRef.current.unstable_dataSource.fetchRows(
GRID_ROOT_GROUP_ID,
retryParams,
);
setRetryParams(null);
}}
/>
)}
<DataGridPro
{...props}
apiRef={apiRef}
unstable_dataSource={dataSource}
unstable_onDataSourceError={(_, params) => setRetryParams(params)}
unstable_dataSourceCache={null}
unstable_lazyLoading
paginationModel={{ page: 0, pageSize: 10 }}
slots={{ toolbar: GridToolbar }}
/>
</div>
</div>
);
}

export default ServerSideLazyLoadingErrorHandling;
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as React from 'react';
import { DataGridPro } from '@mui/x-data-grid-pro';
import { useMockServer } from '@mui/x-data-grid-generator';

function ServerSideLazyLoadingInfinite() {
const { fetchRows, ...props } = useMockServer(
{ rowLength: 100 },
{ useCursorPagination: false, minDelay: 200, maxDelay: 500 },
);

const dataSource = React.useMemo(
() => ({
getRows: async (params) => {
const urlParams = new URLSearchParams({
filterModel: JSON.stringify(params.filterModel),
sortModel: JSON.stringify(params.sortModel),
start: `${params.start}`,
end: `${params.end}`,
});
const getRowsResponse = await fetchRows(
`https://mui.com/x/api/data-grid?${urlParams.toString()}`,
);

return {
rows: getRowsResponse.rows,
};
},
}),
[fetchRows],
);

return (
<div style={{ width: '100%', height: 400 }}>
<DataGridPro
{...props}
unstable_dataSource={dataSource}
unstable_lazyLoading
paginationModel={{ page: 0, pageSize: 15 }}
/>
</div>
);
}

export default ServerSideLazyLoadingInfinite;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from 'react';
import {
DataGridPro,
GridDataSource,
GridGetRowsParams,
} from '@mui/x-data-grid-pro';
import { useMockServer } from '@mui/x-data-grid-generator';

function ServerSideLazyLoadingInfinite() {
const { fetchRows, ...props } = useMockServer(
{ rowLength: 100 },
{ useCursorPagination: false, minDelay: 200, maxDelay: 500 },
);

const dataSource: GridDataSource = React.useMemo(
() => ({
getRows: async (params: GridGetRowsParams) => {
const urlParams = new URLSearchParams({
filterModel: JSON.stringify(params.filterModel),
sortModel: JSON.stringify(params.sortModel),
start: `${params.start}`,
end: `${params.end}`,
});
const getRowsResponse = await fetchRows(
`https://mui.com/x/api/data-grid?${urlParams.toString()}`,
);

return {
rows: getRowsResponse.rows,
};
},
}),
[fetchRows],
);

return (
<div style={{ width: '100%', height: 400 }}>
<DataGridPro
{...props}
unstable_dataSource={dataSource}
unstable_lazyLoading
paginationModel={{ page: 0, pageSize: 15 }}
/>
</div>
);
}

export default ServerSideLazyLoadingInfinite;
Loading
Loading