Skip to content

Commit 1c0dcf2

Browse files
arminmehKenanYusufMBilalShafimapache-salvaje
committed
[DataGridPro] Server side data source lazy loading (mui#13878)
Signed-off-by: Armin Mehinovic <4390250+arminmeh@users.noreply.github.com> Co-authored-by: Kenan Yusuf <kenan.m.yusuf@gmail.com> Co-authored-by: Bilal Shafi <bilalshafidev@gmail.com> Co-authored-by: Sycamore <71297412+samuelsycamore@users.noreply.github.com>
1 parent 39f2c11 commit 1c0dcf2

File tree

53 files changed

+2314
-191
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2314
-191
lines changed

docs/data/data-grid/events/events.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@
227227
{
228228
"projects": ["x-data-grid-pro", "x-data-grid-premium"],
229229
"name": "fetchRows",
230-
"description": "Fired when a new batch of rows is requested to be loaded. Called with a GridFetchRowsParams object.",
230+
"description": "Fired when a new batch of rows is requested to be loaded. Called with a GridFetchRowsParams object. Used to trigger <code>onFetchRows</code>.",
231231
"params": "GridFetchRowsParams",
232232
"event": "MuiEvent<{}>",
233233
"componentProp": "onFetchRows"

docs/data/data-grid/server-side-data/ServerSideDataGridNoCache.js

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export default function ServerSideDataGridNoCache() {
3838
...initialState,
3939
pagination: {
4040
paginationModel: { pageSize: 10, page: 0 },
41+
rowCount: 0,
4142
},
4243
}),
4344
[initialState],

docs/data/data-grid/server-side-data/ServerSideDataGridNoCache.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export default function ServerSideDataGridNoCache() {
3838
...initialState,
3939
pagination: {
4040
paginationModel: { pageSize: 10, page: 0 },
41+
rowCount: 0,
4142
},
4243
}),
4344
[initialState],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import * as React from 'react';
2+
import {
3+
DataGridPro,
4+
useGridApiRef,
5+
GridToolbar,
6+
GRID_ROOT_GROUP_ID,
7+
} from '@mui/x-data-grid-pro';
8+
import Checkbox from '@mui/material/Checkbox';
9+
import FormControlLabel from '@mui/material/FormControlLabel';
10+
import { useMockServer } from '@mui/x-data-grid-generator';
11+
import Alert from '@mui/material/Alert';
12+
import Button from '@mui/material/Button';
13+
import Snackbar from '@mui/material/Snackbar';
14+
15+
function ErrorSnackbar(props) {
16+
const { onRetry, ...rest } = props;
17+
return (
18+
<Snackbar {...rest}>
19+
<Alert
20+
severity="error"
21+
variant="filled"
22+
sx={{ width: '100%' }}
23+
action={
24+
<Button color="inherit" size="small" onClick={onRetry}>
25+
Retry
26+
</Button>
27+
}
28+
>
29+
Failed to fetch row data
30+
</Alert>
31+
</Snackbar>
32+
);
33+
}
34+
35+
function ServerSideLazyLoadingErrorHandling() {
36+
const apiRef = useGridApiRef();
37+
const [retryParams, setRetryParams] = React.useState(null);
38+
const [shouldRequestsFail, setShouldRequestsFail] = React.useState(false);
39+
40+
const { fetchRows, ...props } = useMockServer(
41+
{ rowLength: 100 },
42+
{ useCursorPagination: false, minDelay: 300, maxDelay: 800 },
43+
shouldRequestsFail,
44+
);
45+
46+
const dataSource = React.useMemo(
47+
() => ({
48+
getRows: async (params) => {
49+
const urlParams = new URLSearchParams({
50+
filterModel: JSON.stringify(params.filterModel),
51+
sortModel: JSON.stringify(params.sortModel),
52+
start: `${params.start}`,
53+
end: `${params.end}`,
54+
});
55+
const getRowsResponse = await fetchRows(
56+
`https://mui.com/x/api/data-grid?${urlParams.toString()}`,
57+
);
58+
59+
// Reset the retryParams when new rows are fetched
60+
setRetryParams(null);
61+
return {
62+
rows: getRowsResponse.rows,
63+
rowCount: getRowsResponse.rowCount,
64+
};
65+
},
66+
}),
67+
[fetchRows],
68+
);
69+
70+
return (
71+
<div style={{ width: '100%' }}>
72+
<FormControlLabel
73+
control={
74+
<Checkbox
75+
checked={shouldRequestsFail}
76+
onChange={(event) => setShouldRequestsFail(event.target.checked)}
77+
/>
78+
}
79+
label="Make the requests fail"
80+
/>
81+
<div style={{ height: 400, position: 'relative' }}>
82+
{retryParams && (
83+
<ErrorSnackbar
84+
open={!!retryParams}
85+
onRetry={() => {
86+
apiRef.current.unstable_dataSource.fetchRows(
87+
GRID_ROOT_GROUP_ID,
88+
retryParams,
89+
);
90+
setRetryParams(null);
91+
}}
92+
/>
93+
)}
94+
<DataGridPro
95+
{...props}
96+
apiRef={apiRef}
97+
unstable_dataSource={dataSource}
98+
unstable_onDataSourceError={(_, params) => setRetryParams(params)}
99+
unstable_dataSourceCache={null}
100+
unstable_lazyLoading
101+
paginationModel={{ page: 0, pageSize: 10 }}
102+
slots={{ toolbar: GridToolbar }}
103+
/>
104+
</div>
105+
</div>
106+
);
107+
}
108+
109+
export default ServerSideLazyLoadingErrorHandling;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import * as React from 'react';
2+
import {
3+
DataGridPro,
4+
useGridApiRef,
5+
GridToolbar,
6+
GridDataSource,
7+
GridGetRowsParams,
8+
GRID_ROOT_GROUP_ID,
9+
} from '@mui/x-data-grid-pro';
10+
import Checkbox from '@mui/material/Checkbox';
11+
import FormControlLabel from '@mui/material/FormControlLabel';
12+
import { useMockServer } from '@mui/x-data-grid-generator';
13+
import Alert from '@mui/material/Alert';
14+
import Button from '@mui/material/Button';
15+
import Snackbar, { SnackbarProps } from '@mui/material/Snackbar';
16+
17+
function ErrorSnackbar(props: SnackbarProps & { onRetry: () => void }) {
18+
const { onRetry, ...rest } = props;
19+
return (
20+
<Snackbar {...rest}>
21+
<Alert
22+
severity="error"
23+
variant="filled"
24+
sx={{ width: '100%' }}
25+
action={
26+
<Button color="inherit" size="small" onClick={onRetry}>
27+
Retry
28+
</Button>
29+
}
30+
>
31+
Failed to fetch row data
32+
</Alert>
33+
</Snackbar>
34+
);
35+
}
36+
37+
function ServerSideLazyLoadingErrorHandling() {
38+
const apiRef = useGridApiRef();
39+
const [retryParams, setRetryParams] = React.useState<GridGetRowsParams | null>(
40+
null,
41+
);
42+
const [shouldRequestsFail, setShouldRequestsFail] = React.useState(false);
43+
44+
const { fetchRows, ...props } = useMockServer(
45+
{ rowLength: 100 },
46+
{ useCursorPagination: false, minDelay: 300, maxDelay: 800 },
47+
shouldRequestsFail,
48+
);
49+
50+
const dataSource: GridDataSource = React.useMemo(
51+
() => ({
52+
getRows: async (params) => {
53+
const urlParams = new URLSearchParams({
54+
filterModel: JSON.stringify(params.filterModel),
55+
sortModel: JSON.stringify(params.sortModel),
56+
start: `${params.start}`,
57+
end: `${params.end}`,
58+
});
59+
const getRowsResponse = await fetchRows(
60+
`https://mui.com/x/api/data-grid?${urlParams.toString()}`,
61+
);
62+
63+
// Reset the retryParams when new rows are fetched
64+
setRetryParams(null);
65+
return {
66+
rows: getRowsResponse.rows,
67+
rowCount: getRowsResponse.rowCount,
68+
};
69+
},
70+
}),
71+
[fetchRows],
72+
);
73+
74+
return (
75+
<div style={{ width: '100%' }}>
76+
<FormControlLabel
77+
control={
78+
<Checkbox
79+
checked={shouldRequestsFail}
80+
onChange={(event) => setShouldRequestsFail(event.target.checked)}
81+
/>
82+
}
83+
label="Make the requests fail"
84+
/>
85+
<div style={{ height: 400, position: 'relative' }}>
86+
{retryParams && (
87+
<ErrorSnackbar
88+
open={!!retryParams}
89+
onRetry={() => {
90+
apiRef.current.unstable_dataSource.fetchRows(
91+
GRID_ROOT_GROUP_ID,
92+
retryParams,
93+
);
94+
setRetryParams(null);
95+
}}
96+
/>
97+
)}
98+
<DataGridPro
99+
{...props}
100+
apiRef={apiRef}
101+
unstable_dataSource={dataSource}
102+
unstable_onDataSourceError={(_, params) => setRetryParams(params)}
103+
unstable_dataSourceCache={null}
104+
unstable_lazyLoading
105+
paginationModel={{ page: 0, pageSize: 10 }}
106+
slots={{ toolbar: GridToolbar }}
107+
/>
108+
</div>
109+
</div>
110+
);
111+
}
112+
113+
export default ServerSideLazyLoadingErrorHandling;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import * as React from 'react';
2+
import { DataGridPro } from '@mui/x-data-grid-pro';
3+
import { useMockServer } from '@mui/x-data-grid-generator';
4+
5+
function ServerSideLazyLoadingInfinite() {
6+
const { fetchRows, ...props } = useMockServer(
7+
{ rowLength: 100 },
8+
{ useCursorPagination: false, minDelay: 200, maxDelay: 500 },
9+
);
10+
11+
const dataSource = React.useMemo(
12+
() => ({
13+
getRows: async (params) => {
14+
const urlParams = new URLSearchParams({
15+
filterModel: JSON.stringify(params.filterModel),
16+
sortModel: JSON.stringify(params.sortModel),
17+
start: `${params.start}`,
18+
end: `${params.end}`,
19+
});
20+
const getRowsResponse = await fetchRows(
21+
`https://mui.com/x/api/data-grid?${urlParams.toString()}`,
22+
);
23+
24+
return {
25+
rows: getRowsResponse.rows,
26+
};
27+
},
28+
}),
29+
[fetchRows],
30+
);
31+
32+
return (
33+
<div style={{ width: '100%', height: 400 }}>
34+
<DataGridPro
35+
{...props}
36+
unstable_dataSource={dataSource}
37+
unstable_lazyLoading
38+
paginationModel={{ page: 0, pageSize: 15 }}
39+
/>
40+
</div>
41+
);
42+
}
43+
44+
export default ServerSideLazyLoadingInfinite;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import * as React from 'react';
2+
import {
3+
DataGridPro,
4+
GridDataSource,
5+
GridGetRowsParams,
6+
} from '@mui/x-data-grid-pro';
7+
import { useMockServer } from '@mui/x-data-grid-generator';
8+
9+
function ServerSideLazyLoadingInfinite() {
10+
const { fetchRows, ...props } = useMockServer(
11+
{ rowLength: 100 },
12+
{ useCursorPagination: false, minDelay: 200, maxDelay: 500 },
13+
);
14+
15+
const dataSource: GridDataSource = React.useMemo(
16+
() => ({
17+
getRows: async (params: GridGetRowsParams) => {
18+
const urlParams = new URLSearchParams({
19+
filterModel: JSON.stringify(params.filterModel),
20+
sortModel: JSON.stringify(params.sortModel),
21+
start: `${params.start}`,
22+
end: `${params.end}`,
23+
});
24+
const getRowsResponse = await fetchRows(
25+
`https://mui.com/x/api/data-grid?${urlParams.toString()}`,
26+
);
27+
28+
return {
29+
rows: getRowsResponse.rows,
30+
};
31+
},
32+
}),
33+
[fetchRows],
34+
);
35+
36+
return (
37+
<div style={{ width: '100%', height: 400 }}>
38+
<DataGridPro
39+
{...props}
40+
unstable_dataSource={dataSource}
41+
unstable_lazyLoading
42+
paginationModel={{ page: 0, pageSize: 15 }}
43+
/>
44+
</div>
45+
);
46+
}
47+
48+
export default ServerSideLazyLoadingInfinite;

0 commit comments

Comments
 (0)