From d6710d118e406f7f320159eba5961cfd78e8ccb8 Mon Sep 17 00:00:00 2001 From: damien Date: Thu, 23 Jul 2020 15:41:41 +0200 Subject: [PATCH 01/15] implemented server pagination --- .../grid/x-grid-modules/src/gridComponent.tsx | 2 +- .../src/hooks/features/usePagination.ts | 60 +++++++++------ .../x-grid-modules/src/models/gridOptions.tsx | 8 +- .../src/models/params/pageChangedParams.ts | 6 ++ .../src/stories/grid-pagination.stories.tsx | 74 +++++++++++++++++-- 5 files changed, 119 insertions(+), 31 deletions(-) diff --git a/packages/grid/x-grid-modules/src/gridComponent.tsx b/packages/grid/x-grid-modules/src/gridComponent.tsx index 5fc56c04597e..300cdd367145 100644 --- a/packages/grid/x-grid-modules/src/gridComponent.tsx +++ b/packages/grid/x-grid-modules/src/gridComponent.tsx @@ -219,7 +219,7 @@ export const GridComponent: React.FC = React.memo( /> )) } - rowCount={internalRows.length} + rowCount={internalOptions.rowCount == null ? internalRows.length : internalOptions.rowCount } options={internalOptions} /> )} diff --git a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts index adc2e4d122de..1018a8f2a559 100644 --- a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts +++ b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts @@ -1,18 +1,14 @@ -import { useCallback, useEffect, useReducer, useRef } from 'react'; -import { useLogger } from '../utils'; -import { - PAGE_CHANGED_EVENT, - PAGESIZE_CHANGED_EVENT, - RESIZE, -} from '../../constants/eventsConstants'; -import { useApiMethod } from '../root/useApiMethod'; -import { useApiEventHandler } from '../root/useApiEventHandler'; -import { PageChangedParams } from '../../models/params/pageChangedParams'; -import { Rows } from '../../models/rows'; -import { InternalColumns } from '../../models/colDef/colDef'; -import { GridOptions } from '../../models/gridOptions'; -import { PaginationApi } from '../../models/api/paginationApi'; -import { ApiRef } from '../../models/api'; +import {useCallback, useEffect, useReducer, useRef} from 'react'; +import {useLogger} from '../utils'; +import {PAGE_CHANGED_EVENT, PAGESIZE_CHANGED_EVENT, RESIZE,} from '../../constants/eventsConstants'; +import {useApiMethod} from '../root/useApiMethod'; +import {useApiEventHandler} from '../root/useApiEventHandler'; +import {PageChangedParams, PaginationMode} from '../../models/params/pageChangedParams'; +import {Rows} from '../../models/rows'; +import {InternalColumns} from '../../models/colDef/colDef'; +import {GridOptions} from '../../models/gridOptions'; +import {PaginationApi} from '../../models/api/paginationApi'; +import {ApiRef} from '../../models/api'; export interface PaginationProps { page: number; @@ -54,10 +50,11 @@ export const usePagination = ( const logger = useLogger('usePagination'); const initialState: PaginationState = { + paginationMode: options.paginationMode!, pageSize: options.paginationPageSize || 0, - rowCount: rows.length, - page: 1, - pageCount: getPageCount(options.paginationPageSize, rows.length), + rowCount: options.rowCount == null ? rows.length : options.rowCount, + page: options.page || 1, + pageCount: getPageCount(options.paginationPageSize, options.rowCount == null ? rows.length : options.rowCount), }; const stateRef = useRef(initialState); const [state, dispatch] = useReducer(paginationReducer, initialState); @@ -74,7 +71,9 @@ export const usePagination = ( const setPage = useCallback( (page: number) => { if (apiRef && apiRef.current) { - apiRef.current!.renderPage(page); + page = stateRef.current.pageCount >= page ? page : stateRef.current.pageCount; + apiRef.current!.renderPage(stateRef.current.paginationMode === PaginationMode.Client ? page : 1); + const params: PageChangedParams = { ...stateRef.current, page, @@ -148,17 +147,32 @@ export const usePagination = ( stateRef.current = state; }, [state]); + useEffect(()=> { + if(apiRef.current?.isInitialised) { + apiRef.current!.emit(PAGE_CHANGED_EVENT, stateRef.current); + } + }, [apiRef, stateRef, apiRef.current?.isInitialised]); + + useEffect(()=> { + updateState({paginationMode: options.paginationMode!}); + }, [options.paginationMode]); + + useEffect(()=> { + setPage(options.page != null ? options.page : 1); + }, [options.page]); + useEffect(() => { - if (rows.length !== state.rowCount) { + const rowCount = options.rowCount == null ? rows.length : options.rowCount; + if (rowCount !== state.rowCount) { logger.info(`Options or rows changed, recalculating pageCount and rowCount`); - const newPageCount = getPageCount(state.pageSize, rows.length); + const newPageCount = getPageCount(state.pageSize, rowCount); - updateState({ pageCount: newPageCount, rowCount: rows.length }); + updateState({ pageCount: newPageCount, rowCount }); if (state.page > newPageCount) { setPage(newPageCount); } } - }, [rows.length, logger, updateState, state.rowCount, state.pageSize, setPage, state.page]); + }, [rows.length, options.rowCount, logger, updateState, state.rowCount, state.pageSize, setPage, state.page]); useEffect(() => { if ( diff --git a/packages/grid/x-grid-modules/src/models/gridOptions.tsx b/packages/grid/x-grid-modules/src/models/gridOptions.tsx index 849e334ed99d..ce2cacf0df56 100644 --- a/packages/grid/x-grid-modules/src/models/gridOptions.tsx +++ b/packages/grid/x-grid-modules/src/models/gridOptions.tsx @@ -8,7 +8,7 @@ import { RowClickedParam } from './params/rowClickedParams'; import { CellClickedParam } from './params/cellClickedParams'; import { RowSelectedParams } from './params/rowSelectedParams'; import { SelectionChangedParams } from './params/selectionChangedParams'; -import { PageChangedParams } from './params/pageChangedParams'; +import {PageChangedParams, PaginationMode} from './params/pageChangedParams'; import { ColumnTypesRecord, DEFAULT_COLUMN_TYPES } from './colDef'; /** @@ -109,6 +109,11 @@ export interface GridOptions { * @default [25, 50, 100] */ paginationRowsPerPageOptions?: number[]; + + paginationMode?: PaginationMode; + rowCount?: number; + page?: number; + /** * Toggle footer component visibility. * @default false @@ -215,6 +220,7 @@ export const DEFAULT_GRID_OPTIONS: GridOptions = { enableMultipleColumnsSorting: true, paginationRowsPerPageOptions: [25, 50, 100], paginationPageSize: 100, + paginationMode: PaginationMode.Client, extendRowFullWidth: true, sortingOrder: ['asc', 'desc', null], columnTypes: DEFAULT_COLUMN_TYPES, diff --git a/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts b/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts index fe357a6d85df..c17b0987a6dd 100644 --- a/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts +++ b/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts @@ -18,4 +18,10 @@ export interface PageChangedParams { * The total number of rows */ rowCount: number; + + paginationMode: PaginationMode; } +export enum PaginationMode { + Client='Client', + Server='Server' +} \ No newline at end of file diff --git a/packages/storybook/src/stories/grid-pagination.stories.tsx b/packages/storybook/src/stories/grid-pagination.stories.tsx index 15e3c8905c81..0113b4c2d132 100644 --- a/packages/storybook/src/stories/grid-pagination.stories.tsx +++ b/packages/storybook/src/stories/grid-pagination.stories.tsx @@ -1,11 +1,13 @@ import * as React from 'react'; -import { XGrid, ApiRef, useApiRef } from '@material-ui/x-grid'; +import {useState} from 'react'; +import {ApiRef, PaginationMode, useApiRef, XGrid, PageChangedParams, RowsProp} from '@material-ui/x-grid'; import Button from '@material-ui/core/Button'; import Pagination from '@material-ui/lab/Pagination'; -import { action } from '@storybook/addon-actions'; -import { array, boolean, number, withKnobs } from '@storybook/addon-knobs'; -import { withA11y } from '@storybook/addon-a11y'; -import { useData } from '../hooks/useData'; +import {action} from '@storybook/addon-actions'; +import {array, boolean, number, withKnobs} from '@storybook/addon-knobs'; +import {withA11y} from '@storybook/addon-a11y'; +import {useData} from '../hooks/useData'; +import {getData, GridData} from "../data/data-service"; export default { title: 'X-Grid Tests/Pagination', @@ -50,7 +52,7 @@ export function PageSize100() { } export function PaginationKnobs() { - const data = useData(2000, 200); + const data = useData(100, 200); const rowsPerPageOptions = array('Rows per page options', ['10', '20', '50', '100', '200'], ', '); return ( @@ -60,6 +62,8 @@ export function PaginationKnobs() { options={{ pagination: true, paginationPageSize: number('PageSize', 100), + page: number('Page', 1), + rowCount: number('RowCount', 2000), paginationAutoPageSize: boolean('Auto page size', false), paginationRowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), hideFooterRowCount: boolean('Hide row count', false), @@ -206,3 +210,61 @@ export function AutoPagination() { ); } + +function loadServerRows(params: PageChangedParams): Promise { + return new Promise(resolve => { + getData(params.pageSize, 10).then(data => { + setTimeout(() => { + const minId = (params.page - 1) * params.pageSize; + data.rows.forEach(row=> { + row.id = (Number(row.id) + minId).toString(); + } ); + resolve(data); + }, 500); + }); + }); +} + +export function ServerPagination() { + const apiRef: ApiRef = useApiRef(); + const data = useData(100, 10); + const [rows, setRows] = useState([]); + const [isLoading, setLoading] = useState(false); + + React.useEffect(() => { + let unsubscribe; + if (apiRef && apiRef.current) { + unsubscribe = apiRef.current.onPageChanged((params)=> { + action('onPageChanged')(params); + setLoading(true); + loadServerRows(params).then(newData => { + setRows(newData.rows); + setLoading(false); + }) + }); + } + return () => { + if (unsubscribe) { + unsubscribe(); + } + }; + }, [apiRef, data]); + + + return ( +
+ +
+ ); +} From 2f7d35889955e5ffd3faeb2a75e08620048878fc Mon Sep 17 00:00:00 2001 From: damien Date: Thu, 23 Jul 2020 17:16:48 +0200 Subject: [PATCH 02/15] rename pagination options, doc, prettier --- .../app/demos/grid/real-data-grid.demo.tsx | 8 +- packages/grid/data-grid/src/data-grid.tsx | 4 +- .../grid/x-grid-modules/src/gridComponent.tsx | 12 +- .../src/hooks/features/usePagination.ts | 77 +++++++----- .../src/hooks/root/useContainerProps.ts | 8 +- .../src/hooks/root/useKeyboard.ts | 6 +- .../hooks/virtualization/useVirtualRows.ts | 12 +- .../x-grid-modules/src/models/featureMode.ts | 4 + .../x-grid-modules/src/models/gridOptions.tsx | 31 +++-- .../x-grid-modules/src/models/params/index.ts | 1 + .../src/models/params/pageChangedParams.ts | 8 +- .../src/models/renderContextProps.ts | 2 +- .../src/documentation/pages/api.stories.mdx | 9 +- .../demos/pagination/autoPageSize.demo.tsx | 2 +- .../pagination/customPagination.demo.tsx | 4 +- .../pagination/serverPagination.demo.tsx | 74 +++++++++++ .../pages/demos/pagination/setPage.demo.tsx | 4 +- .../pagination/simplePagination.demo.tsx | 4 +- .../pages/pagination.stories.mdx | 97 ++++++++++----- .../src/stories/grid-pagination.stories.tsx | 117 ++++++++++++------ .../customize-components.stories.tsx | 6 +- .../playground/data-grid.options.stories.tsx | 8 +- .../stories/playground/options.stories.tsx | 8 +- .../playground/real-data-demo.stories.tsx | 8 +- 24 files changed, 354 insertions(+), 160 deletions(-) create mode 100644 packages/grid/x-grid-modules/src/models/featureMode.ts create mode 100644 packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx diff --git a/packages/demo-app/src/app/demos/grid/real-data-grid.demo.tsx b/packages/demo-app/src/app/demos/grid/real-data-grid.demo.tsx index f5e4eeab18c0..60dbde131c8e 100644 --- a/packages/demo-app/src/app/demos/grid/real-data-grid.demo.tsx +++ b/packages/demo-app/src/app/demos/grid/real-data-grid.demo.tsx @@ -100,15 +100,15 @@ export const RealDataGridDemo: React.FC<{ toggleTheme: () => void; themeId: stri const newPagination: Partial = { pagination: settings.pagesize !== -1, - paginationAutoPageSize: settings.pagesize === 0, - paginationPageSize: settings.pagesize > 0 ? settings.pagesize : undefined, + autoPageSize: settings.pagesize === 0, + pageSize: settings.pagesize > 0 ? settings.pagesize : undefined, }; setPagination((p) => { if ( p.pagination === newPagination.pagination && - p.paginationAutoPageSize === newPagination.paginationAutoPageSize && - p.paginationPageSize === newPagination.paginationPageSize + p.autoPageSize === newPagination.autoPageSize && + p.pageSize === newPagination.pageSize ) { return p; } diff --git a/packages/grid/data-grid/src/data-grid.tsx b/packages/grid/data-grid/src/data-grid.tsx index 8498c60a4bae..0e5324d910c1 100644 --- a/packages/grid/data-grid/src/data-grid.tsx +++ b/packages/grid/data-grid/src/data-grid.tsx @@ -26,9 +26,9 @@ export const DataGrid: React.FC = React.memo(function DataGrid( props: DataGridProps, ) { const validateOptions = React.useCallback((options: DataGridOptionsProp) => { - if (options && options.paginationPageSize && options.paginationPageSize > MAX_PAGE_SIZE) { + if (options && options.pageSize && options.pageSize > MAX_PAGE_SIZE) { throw new Error( - `Material-UI: Option 'paginationPageSize' cannot be above ${MAX_PAGE_SIZE}. Use the @material-ui/x-grid to unlock this feature`, + `Material-UI: Option 'pageSize' cannot be above ${MAX_PAGE_SIZE}. Use the @material-ui/x-grid to unlock this feature`, ); } return options; diff --git a/packages/grid/x-grid-modules/src/gridComponent.tsx b/packages/grid/x-grid-modules/src/gridComponent.tsx index 300cdd367145..57c6657074a3 100644 --- a/packages/grid/x-grid-modules/src/gridComponent.tsx +++ b/packages/grid/x-grid-modules/src/gridComponent.tsx @@ -84,8 +84,8 @@ export const GridComponent: React.FC = React.memo( React.useEffect(() => { setInternalOptions((previousState) => { - if (previousState.paginationPageSize !== paginationProps.pageSize) { - return { ...previousState, paginationPageSize: paginationProps.pageSize }; + if (previousState.pageSize !== paginationProps.pageSize) { + return { ...previousState, pageSize: paginationProps.pageSize }; } return previousState; }); @@ -215,11 +215,15 @@ export const GridComponent: React.FC = React.memo( pageSize={paginationProps.pageSize} rowCount={paginationProps.rowCount} setPageSize={paginationProps.setPageSize} - rowsPerPageOptions={internalOptions.paginationRowsPerPageOptions} + rowsPerPageOptions={internalOptions.rowsPerPageOptions} /> )) } - rowCount={internalOptions.rowCount == null ? internalRows.length : internalOptions.rowCount } + rowCount={ + internalOptions.rowCount == null + ? internalRows.length + : internalOptions.rowCount + } options={internalOptions} /> )} diff --git a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts index 1018a8f2a559..06ac144af727 100644 --- a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts +++ b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts @@ -1,14 +1,19 @@ -import {useCallback, useEffect, useReducer, useRef} from 'react'; -import {useLogger} from '../utils'; -import {PAGE_CHANGED_EVENT, PAGESIZE_CHANGED_EVENT, RESIZE,} from '../../constants/eventsConstants'; -import {useApiMethod} from '../root/useApiMethod'; -import {useApiEventHandler} from '../root/useApiEventHandler'; -import {PageChangedParams, PaginationMode} from '../../models/params/pageChangedParams'; -import {Rows} from '../../models/rows'; -import {InternalColumns} from '../../models/colDef/colDef'; -import {GridOptions} from '../../models/gridOptions'; -import {PaginationApi} from '../../models/api/paginationApi'; -import {ApiRef} from '../../models/api'; +import { useCallback, useEffect, useReducer, useRef } from 'react'; +import { useLogger } from '../utils'; +import { + PAGE_CHANGED_EVENT, + PAGESIZE_CHANGED_EVENT, + RESIZE, +} from '../../constants/eventsConstants'; +import { useApiMethod } from '../root/useApiMethod'; +import { useApiEventHandler } from '../root/useApiEventHandler'; +import { PageChangedParams } from '../../models/params/pageChangedParams'; +import { Rows } from '../../models/rows'; +import { InternalColumns } from '../../models/colDef/colDef'; +import { GridOptions } from '../../models/gridOptions'; +import { PaginationApi } from '../../models/api/paginationApi'; +import { ApiRef } from '../../models/api'; +import { FeatureMode } from '../../models/featureMode'; export interface PaginationProps { page: number; @@ -51,10 +56,13 @@ export const usePagination = ( const initialState: PaginationState = { paginationMode: options.paginationMode!, - pageSize: options.paginationPageSize || 0, + pageSize: options.pageSize || 0, rowCount: options.rowCount == null ? rows.length : options.rowCount, page: options.page || 1, - pageCount: getPageCount(options.paginationPageSize, options.rowCount == null ? rows.length : options.rowCount), + pageCount: getPageCount( + options.pageSize, + options.rowCount == null ? rows.length : options.rowCount, + ), }; const stateRef = useRef(initialState); const [state, dispatch] = useReducer(paginationReducer, initialState); @@ -72,7 +80,9 @@ export const usePagination = ( (page: number) => { if (apiRef && apiRef.current) { page = stateRef.current.pageCount >= page ? page : stateRef.current.pageCount; - apiRef.current!.renderPage(stateRef.current.paginationMode === PaginationMode.Client ? page : 1); + apiRef.current!.renderPage( + stateRef.current.paginationMode === FeatureMode.Client ? page : 1, + ); const params: PageChangedParams = { ...stateRef.current, @@ -147,17 +157,17 @@ export const usePagination = ( stateRef.current = state; }, [state]); - useEffect(()=> { - if(apiRef.current?.isInitialised) { + useEffect(() => { + if (apiRef.current?.isInitialised) { apiRef.current!.emit(PAGE_CHANGED_EVENT, stateRef.current); } }, [apiRef, stateRef, apiRef.current?.isInitialised]); - useEffect(()=> { - updateState({paginationMode: options.paginationMode!}); + useEffect(() => { + updateState({ paginationMode: options.paginationMode! }); }, [options.paginationMode]); - useEffect(()=> { + useEffect(() => { setPage(options.page != null ? options.page : 1); }, [options.page]); @@ -172,32 +182,41 @@ export const usePagination = ( setPage(newPageCount); } } - }, [rows.length, options.rowCount, logger, updateState, state.rowCount, state.pageSize, setPage, state.page]); + }, [ + rows.length, + options.rowCount, + logger, + updateState, + state.rowCount, + state.pageSize, + setPage, + state.page, + ]); useEffect(() => { if ( - !options.paginationAutoPageSize && - options.paginationPageSize && - options.paginationPageSize !== stateRef.current.pageSize + !options.autoPageSize && + options.pageSize && + options.pageSize !== stateRef.current.pageSize ) { - setPageSize(options.paginationPageSize); + setPageSize(options.pageSize); } - }, [options.paginationAutoPageSize, options.paginationPageSize, logger, setPageSize]); + }, [options.autoPageSize, options.pageSize, logger, setPageSize]); useEffect(() => { - if (options.paginationAutoPageSize && columns.visible.length > 0) { + if (options.autoPageSize && columns.visible.length > 0) { resetAutopageSize(); } - }, [options.paginationAutoPageSize, resetAutopageSize, columns.visible.length]); + }, [options.autoPageSize, resetAutopageSize, columns.visible.length]); useApiEventHandler(apiRef, PAGE_CHANGED_EVENT, options.onPageChanged); useApiEventHandler(apiRef, PAGESIZE_CHANGED_EVENT, options.onPageSizeChanged); const onResize = useCallback(() => { - if (options.paginationAutoPageSize) { + if (options.autoPageSize) { resetAutopageSize(); } - }, [options.paginationAutoPageSize, resetAutopageSize]); + }, [options.autoPageSize, resetAutopageSize]); useApiEventHandler(apiRef, RESIZE, onResize); diff --git a/packages/grid/x-grid-modules/src/hooks/root/useContainerProps.ts b/packages/grid/x-grid-modules/src/hooks/root/useContainerProps.ts index 7ffbe7c61e2a..79447a4b953e 100644 --- a/packages/grid/x-grid-modules/src/hooks/root/useContainerProps.ts +++ b/packages/grid/x-grid-modules/src/hooks/root/useContainerProps.ts @@ -27,7 +27,7 @@ export const useContainerProps = (windowRef: React.RefObject): R const rowHeight = options.rowHeight; const hasScrollY = - options.paginationAutoPageSize || options.autoHeight + options.autoPageSize || options.autoHeight ? false : windowSizesRef.current.height < rowsCount * rowHeight; const hasScrollX = columnsTotalWidth > windowSizesRef.current.width; @@ -50,9 +50,7 @@ export const useContainerProps = (windowRef: React.RefObject): R // We multiply by 2 for virtualization // TODO allow buffer with fixed nb rows const rzPageSize = viewportPageSize * 2; - const viewportMaxPage = options.paginationAutoPageSize - ? 1 - : Math.ceil(rowsCount / viewportPageSize); + const viewportMaxPage = options.autoPageSize ? 1 : Math.ceil(rowsCount / viewportPageSize); logger.debug( `viewportPageSize: ${viewportPageSize}, rzPageSize: ${rzPageSize}, viewportMaxPage: ${viewportMaxPage}`, @@ -60,7 +58,7 @@ export const useContainerProps = (windowRef: React.RefObject): R const renderingZoneHeight = rzPageSize * rowHeight + rowHeight + scrollBarSize.x; const dataContainerWidth = columnsTotalWidth - scrollBarSize.y; let totalHeight = - (options.paginationAutoPageSize ? 1 : rowsCount / viewportPageSize) * viewportSize.height + + (options.autoPageSize ? 1 : rowsCount / viewportPageSize) * viewportSize.height + (hasScrollY ? scrollBarSize.x : 0); if (options.autoHeight) { diff --git a/packages/grid/x-grid-modules/src/hooks/root/useKeyboard.ts b/packages/grid/x-grid-modules/src/hooks/root/useKeyboard.ts index b7589b64ce4d..475ba24b7665 100644 --- a/packages/grid/x-grid-modules/src/hooks/root/useKeyboard.ts +++ b/packages/grid/x-grid-modules/src/hooks/root/useKeyboard.ts @@ -69,9 +69,7 @@ export const useKeyboard = (options: GridOptions, initialised: boolean, apiRef: const currentRowIndex = Number(getDataFromElem(cellEl, 'rowindex')); const autoPageSize = apiRef.current!.getContainerPropsState()!.viewportPageSize; const pageSize = - options.pagination && options.paginationPageSize != null - ? options.paginationPageSize - : autoPageSize; + options.pagination && options.pageSize != null ? options.pageSize : autoPageSize; const rowCount = options.pagination ? pageSize : apiRef.current!.getRowsCount(); const colCount = apiRef.current!.getVisibleColumns().length; @@ -120,7 +118,7 @@ export const useKeyboard = (options: GridOptions, initialised: boolean, apiRef: return nextCellIndexes; }, - [apiRef, options.pagination, options.paginationPageSize], + [apiRef, options.pagination, options.pageSize], ); const selectActiveRow = React.useCallback(() => { diff --git a/packages/grid/x-grid-modules/src/hooks/virtualization/useVirtualRows.ts b/packages/grid/x-grid-modules/src/hooks/virtualization/useVirtualRows.ts index 70c59915b2f9..7fcdb2d80024 100644 --- a/packages/grid/x-grid-modules/src/hooks/virtualization/useVirtualRows.ts +++ b/packages/grid/x-grid-modules/src/hooks/virtualization/useVirtualRows.ts @@ -62,9 +62,9 @@ export const useVirtualRows = ( } const containerProps = containerPropsRef.current!; let minRowIdx = 0; - if (optionsRef.current.pagination && optionsRef.current.paginationPageSize != null) { + if (optionsRef.current.pagination && optionsRef.current.pageSize != null) { minRowIdx = - optionsRef.current.paginationPageSize * + optionsRef.current.pageSize * (paginationCurrentPage.current - 1 > 0 ? paginationCurrentPage.current - 1 : 0); } @@ -96,7 +96,7 @@ export const useVirtualRows = ( ...renderedRow, ...{ paginationCurrentPage: paginationCurrentPage.current, - paginationPageSize: optionsRef.current.paginationPageSize, + pageSize: optionsRef.current.pageSize, }, }; logger.debug(':: getRenderCtxState - returning state ', newRenderCtx); @@ -174,8 +174,8 @@ export const useVirtualRows = ( const totalRowsCount = apiRef?.current?.getRowsCount() || 0; // we ensure we call with latest length const currentPage = paginationCurrentPage.current; let pageRowCount = - optionsRef.current.pagination && optionsRef.current.paginationPageSize - ? optionsRef.current.paginationPageSize + optionsRef.current.pagination && optionsRef.current.pageSize + ? optionsRef.current.pageSize : null; pageRowCount = @@ -190,7 +190,7 @@ export const useVirtualRows = ( columnTotalWidthRef.current, rowsCount.current, ); - if (optionsRef.current.paginationAutoPageSize && containerPropsRef.current) { + if (optionsRef.current.autoPageSize && containerPropsRef.current) { rowsCount.current = containerPropsRef.current.viewportPageSize; } updateViewport(); diff --git a/packages/grid/x-grid-modules/src/models/featureMode.ts b/packages/grid/x-grid-modules/src/models/featureMode.ts new file mode 100644 index 000000000000..bdbc3336dc56 --- /dev/null +++ b/packages/grid/x-grid-modules/src/models/featureMode.ts @@ -0,0 +1,4 @@ +export enum FeatureMode { + Client = 'Client', + Server = 'Server', +} diff --git a/packages/grid/x-grid-modules/src/models/gridOptions.tsx b/packages/grid/x-grid-modules/src/models/gridOptions.tsx index ce2cacf0df56..6efd22c1afd1 100644 --- a/packages/grid/x-grid-modules/src/models/gridOptions.tsx +++ b/packages/grid/x-grid-modules/src/models/gridOptions.tsx @@ -8,8 +8,9 @@ import { RowClickedParam } from './params/rowClickedParams'; import { CellClickedParam } from './params/cellClickedParams'; import { RowSelectedParams } from './params/rowSelectedParams'; import { SelectionChangedParams } from './params/selectionChangedParams'; -import {PageChangedParams, PaginationMode} from './params/pageChangedParams'; +import { PageChangedParams } from './params/pageChangedParams'; import { ColumnTypesRecord, DEFAULT_COLUMN_TYPES } from './colDef'; +import { FeatureMode } from './featureMode'; /** * Set of icons used in the grid component UI. @@ -98,20 +99,32 @@ export interface GridOptions { * Set the number of rows in one page. * @default 100 */ - paginationPageSize?: number; + pageSize?: number; /** * Auto-scale the pageSize with the container size to the max number of rows to avoid rendering a vertical scroll bar. * @default false */ - paginationAutoPageSize?: boolean; + autoPageSize?: boolean; /** - * Select the paginationPageSize dynamically using the component UI. + * Select the pageSize dynamically using the component UI. * @default [25, 50, 100] */ - paginationRowsPerPageOptions?: number[]; + rowsPerPageOptions?: number[]; - paginationMode?: PaginationMode; + /** + * Pagination can be processed on the server or client side. + * Set it to FeatureMode.Client or `Client` if you would like to handle the pagination on the client side. + * Set it to FeatureMode.Server or `Server` if you would like to handle the pagination on the server side. + */ + paginationMode?: FeatureMode; + /** + * Set the total number of rows, if it is different than the length of the value `rows` prop + */ rowCount?: number; + /** + * Set the current page. + * Default 1 + */ page?: number; /** @@ -218,9 +231,9 @@ export const DEFAULT_GRID_OPTIONS: GridOptions = { columnBuffer: 2, enableMultipleSelection: true, enableMultipleColumnsSorting: true, - paginationRowsPerPageOptions: [25, 50, 100], - paginationPageSize: 100, - paginationMode: PaginationMode.Client, + rowsPerPageOptions: [25, 50, 100], + pageSize: 100, + paginationMode: FeatureMode.Client, extendRowFullWidth: true, sortingOrder: ['asc', 'desc', null], columnTypes: DEFAULT_COLUMN_TYPES, diff --git a/packages/grid/x-grid-modules/src/models/params/index.ts b/packages/grid/x-grid-modules/src/models/params/index.ts index 02e4c9472988..f185b59d4c17 100644 --- a/packages/grid/x-grid-modules/src/models/params/index.ts +++ b/packages/grid/x-grid-modules/src/models/params/index.ts @@ -8,3 +8,4 @@ export * from './pageChangedParams'; export * from './rowClickedParams'; export * from './rowSelectedParams'; export * from './selectionChangedParams'; +export { FeatureMode } from '../featureMode'; diff --git a/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts b/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts index c17b0987a6dd..299a0686e3de 100644 --- a/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts +++ b/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts @@ -1,3 +1,5 @@ +import { FeatureMode } from '../featureMode'; + /** * Object passed as parameter of the page changed event handler. */ @@ -19,9 +21,5 @@ export interface PageChangedParams { */ rowCount: number; - paginationMode: PaginationMode; + paginationMode: FeatureMode; } -export enum PaginationMode { - Client='Client', - Server='Server' -} \ No newline at end of file diff --git a/packages/grid/x-grid-modules/src/models/renderContextProps.ts b/packages/grid/x-grid-modules/src/models/renderContextProps.ts index 2616b13a277f..545ef01eb20d 100644 --- a/packages/grid/x-grid-modules/src/models/renderContextProps.ts +++ b/packages/grid/x-grid-modules/src/models/renderContextProps.ts @@ -51,7 +51,7 @@ export interface RenderPaginationProps { /** * The current page size if pagination is enabled */ - paginationPageSize?: number; + pageSize?: number; } /** diff --git a/packages/storybook/src/documentation/pages/api.stories.mdx b/packages/storybook/src/documentation/pages/api.stories.mdx index 18e16e91f385..a87b77ff9e3b 100644 --- a/packages/storybook/src/documentation/pages/api.stories.mdx +++ b/packages/storybook/src/documentation/pages/api.stories.mdx @@ -6,7 +6,7 @@ import { XGrid } from '@material-ui/x-grid'; ## How to use ApiRef? -The `ApiRef` allows you to manipulate the grid outside the React component context. This can be very handy in a streaming api to update rows with changes from the server. +The `ApiRef` allows you to manipulate the grid outside the React component scope. To enable ApiRef, you need to use the `useApiRef` hook and pass the ref to the component prop as below. ```tsx @@ -17,7 +17,12 @@ return ``` -Generated? +## Use cases + +If you would like to manipulate the grid outside the component rendering the XGrid, for example if you are building some custom filters. +You could pass the apiRef using the React Context or as a React Prop. + +This can also be very handy in a streaming api to update rows with changes from the server as we have exposed in our Rows section [here](). ## GridAPI diff --git a/packages/storybook/src/documentation/pages/demos/pagination/autoPageSize.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/autoPageSize.demo.tsx index 1a3b6bac9e20..2a038200c07a 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/autoPageSize.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/autoPageSize.demo.tsx @@ -90,7 +90,7 @@ export default function AutoPageSizeDemo() { diff --git a/packages/storybook/src/documentation/pages/demos/pagination/customPagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/customPagination.demo.tsx index 2dd7d8da0f2b..8cd2bd7941af 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/customPagination.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/customPagination.demo.tsx @@ -103,8 +103,8 @@ export default function CustomPaginationDemo() { columns={columns} options={{ pagination: true, - paginationPageSize: 5, - paginationRowsPerPageOptions: [5, 10], + pageSize: 5, + rowsPerPageOptions: [5, 10], autoHeight: true, }} className="demo" diff --git a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx new file mode 100644 index 000000000000..31e9fc9e4810 --- /dev/null +++ b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx @@ -0,0 +1,74 @@ +import { Columns, FeatureMode, PageChangedParams, RowsProp, XGrid } from '@material-ui/x-grid'; +import { useCallback, useState } from 'react'; +import * as React from 'react'; +import { + randomCreatedDate, + randomEmail, + randomId, + randomInt, + randomTraderName, + randomUpdatedDate, +} from '@material-ui/x-grid-data-generator'; + +const newRow = () => ({ + id: randomId(), + name: randomTraderName(), + email: randomEmail(), + age: randomInt(10, 100), + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), +}); + +const columns: Columns = [ + { field: 'id', hide: true }, + { field: 'name', type: 'string' }, + { field: 'email', type: 'string' }, + { field: 'age', type: 'number' }, + { field: 'dateCreated', type: 'date', width: 180 }, + { field: 'lastLogin', type: 'dateTime', width: 180 }, +]; + +function loadServerRows(params: PageChangedParams): Promise { + return new Promise((resolve) => { + const rows: any[] = []; + while (rows.length < params.pageSize) { + rows.push(newRow()); + } + + setTimeout(() => { + resolve(rows); + }, 800); + }); +} + +export default function ServerPaginationDemo() { + const [rows, setRows] = useState([]); + const [isLoading, setLoading] = useState(false); + + const onPageChanged = useCallback( + (params) => { + setLoading(true); + loadServerRows(params).then((rows) => { + setRows(rows); + setLoading(false); + }); + }, + [setRows, setLoading], + ); + + return ( + + ); +} diff --git a/packages/storybook/src/documentation/pages/demos/pagination/setPage.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/setPage.demo.tsx index 8ec1ec7598ab..6c8281b53df5 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/setPage.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/setPage.demo.tsx @@ -97,8 +97,8 @@ export default function SetPageDemo() { columns={columns} options={{ pagination: true, - paginationPageSize: 5, - paginationRowsPerPageOptions: [5, 10], + pageSize: 5, + rowsPerPageOptions: [5, 10], autoHeight: true, }} className="demo" diff --git a/packages/storybook/src/documentation/pages/demos/pagination/simplePagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/simplePagination.demo.tsx index b664ce106c56..d33aa16c31ad 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/simplePagination.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/simplePagination.demo.tsx @@ -91,8 +91,8 @@ export default function SimplePaginationDemo() { columns={columns} options={{ pagination: true, - paginationPageSize: 5, - paginationRowsPerPageOptions: [5, 10], + pageSize: 5, + rowsPerPageOptions: [5, 10], autoHeight: true, }} className="demo" diff --git a/packages/storybook/src/documentation/pages/pagination.stories.mdx b/packages/storybook/src/documentation/pages/pagination.stories.mdx index cc52781a65ad..6020ea900e14 100644 --- a/packages/storybook/src/documentation/pages/pagination.stories.mdx +++ b/packages/storybook/src/documentation/pages/pagination.stories.mdx @@ -3,6 +3,7 @@ import SimplePaginationDemo from './demos/pagination/simplePagination.demo'; import AutoPageSizeDemo from './demos/pagination/autoPageSize.demo'; import SetPageDemo from './demos/pagination/setPage.demo'; import CustomPaginationDemo from './demos/pagination/customPagination.demo'; +import ServerPaginationDemo from './demos/pagination/serverPagination.demo'; @@ -19,20 +20,20 @@ To turn it on, toggle the `pagination` boolean property of the `options` React p - **Set page size** -Our default `pageSize` is set to `100`. You can change this value by setting the `paginationPageSize` property of the `options` React prop as below. +Our default `pageSize` is set to `100`. You can change this value by setting the `pageSize` property of the `options` React prop as below. ```tsx ``` - **Set Rows per page options** -Along with the `paginationPageSize` property, we added the `paginationRowsPerPageOptions` that let you select the `paginationPageSize` dynamically using XGrid UI. -Our default `paginationRowsPerPageOptions` is set to `[25, 50, 100]`. You can change this value by setting the `paginationRowsPerPageOptions` property of the `options` React prop as below. +Along with the `pageSize` property, we added the `rowsPerPageOptions` that let you select the `pageSize` dynamically using XGrid UI. +Our default `rowsPerPageOptions` is set to `[25, 50, 100]`. You can change this value by setting the `rowsPerPageOptions` property of the `options` React prop as below. ```tsx ``` @@ -50,20 +51,36 @@ Please find below an example of a grid with pagination using the options prop de +- ** Set the current page** + +Finally, we exposed the `page` property, which let you select the current page rendered by XGrid. Default value is 1. +If you would like to render the second page, then you can set this property to `2` as below + +```tsx + +``` + ## Auto pagination -The property `paginationAutoPageSize` is available as an option to auto-scale the `pageSize` with the container size to the max number of rows to avoid rendering a vertical scroll bar. -By default, this feature is off and can be turned on, by toggling the `paginationAutoPageSize` boolean property of the `options` React prop as below. +The property `autoPageSize` is available as an option to auto-scale the `pageSize` with the container size to the max number of rows to avoid rendering a vertical scroll bar. +By default, this feature is off and can be turned on, by toggling the `autoPageSize` boolean property of the `options` React prop as below. ```tsx ``` -Please find below an example of grid with `paginationAutoPageSize` turned on as described above. +Please find below an example of grid with `autoPageSize` turned on as described above. @@ -80,7 +97,7 @@ To achieve this, just set the pagination property of the `components` react prop columns={columns} options={{ pagination: true, - paginationPageSize: 50, + pageSize: 50, }} components={{ pagination: PaginationComponent, @@ -90,10 +107,45 @@ To achieve this, just set the pagination property of the `components` react prop -## Pagination API +## Server-side Pagination + +XGrid supports both client and server side pagination. By default, pagination works on the client side. To switch it to server side, +set the property `paginationMode` to `Server` as string or you can use our `FeatureMode` enum. +**Note**: You also need to set the `rowCount` property to override the number of rows in the grid so XGrid can calculate the total number of pages. + +Finally, you're going to need to handle the `onPageChanged` event, to load the rows for the corresponding page. + +```tsx +const [rows, setRows] = useState([]); +const onPageChanged = useCallback( + (params) => { + loadServerRows(params).then((newRows) => { + setRows(newRows); + }); + }, + [setRows], +); + +; +``` + + -Now that you understand how to implement the pagination feature of the grid. You might want to manipulate the page or set a listener when the current page change. -To achieve this, you should use our `apiRef` as below; +### Pagination API + +We exposed a set of methods that will let you achieve all the above features using the `ApiRef` object. More info on our Api page [here](??). + +Below is an example on how you can reset the page using the `setPage` method of the API. ```tsx const apiRef = useApiRef(); @@ -102,30 +154,15 @@ React.useEffect(() => { apiRef.current?.setPage(2); }, [apiRef]); -// Set rows, columns ... - ; ``` - -### How to implement server pagination? - -How to set row count / page count? On pageChange...? -=> set pageCount then onPageChange((page)=> serverQuery(page).then(data=> setRows(data)) - -// TODO - -- expose pageCount in options, needed for server api -- expose page or currentPage in options, avoid using apiRef -- add setRows (RowData) method to replace rows on pageChange ?? You can just use useState - -// TODO implement example with react Query? diff --git a/packages/storybook/src/stories/grid-pagination.stories.tsx b/packages/storybook/src/stories/grid-pagination.stories.tsx index 0113b4c2d132..fca4352d44dc 100644 --- a/packages/storybook/src/stories/grid-pagination.stories.tsx +++ b/packages/storybook/src/stories/grid-pagination.stories.tsx @@ -1,13 +1,20 @@ import * as React from 'react'; -import {useState} from 'react'; -import {ApiRef, PaginationMode, useApiRef, XGrid, PageChangedParams, RowsProp} from '@material-ui/x-grid'; +import { useCallback, useState } from 'react'; +import { + ApiRef, + FeatureMode, + useApiRef, + XGrid, + PageChangedParams, + RowsProp, +} from '@material-ui/x-grid'; import Button from '@material-ui/core/Button'; import Pagination from '@material-ui/lab/Pagination'; -import {action} from '@storybook/addon-actions'; -import {array, boolean, number, withKnobs} from '@storybook/addon-knobs'; -import {withA11y} from '@storybook/addon-a11y'; -import {useData} from '../hooks/useData'; -import {getData, GridData} from "../data/data-service"; +import { action } from '@storybook/addon-actions'; +import { array, boolean, number, withKnobs } from '@storybook/addon-knobs'; +import { withA11y } from '@storybook/addon-a11y'; +import { useData } from '../hooks/useData'; +import { getData, GridData } from '../data/data-service'; export default { title: 'X-Grid Tests/Pagination', @@ -44,7 +51,7 @@ export function PageSize100() { columns={data.columns} options={{ pagination: true, - paginationPageSize: 100, + pageSize: 100, }} /> @@ -61,11 +68,11 @@ export function PaginationKnobs() { columns={data.columns} options={{ pagination: true, - paginationPageSize: number('PageSize', 100), + pageSize: number('PageSize', 100), page: number('Page', 1), rowCount: number('RowCount', 2000), - paginationAutoPageSize: boolean('Auto page size', false), - paginationRowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), + autoPageSize: boolean('Auto page size', false), + rowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), hideFooterRowCount: boolean('Hide row count', false), hideFooterPagination: boolean('Hide footer pagination', false), hideFooter: boolean('Hide footer', false), @@ -83,7 +90,7 @@ export function HiddenPagination() { columns={data.columns} options={{ pagination: true, - paginationPageSize: 100, + pageSize: 100, hideFooterPagination: true, }} /> @@ -154,8 +161,8 @@ export function PaginationApiTests() { apiRef={apiRef} options={{ pagination: true, - paginationPageSize: myPageSize, - paginationAutoPageSize: autosize, + pageSize: myPageSize, + autoPageSize: autosize, }} components={{ pagination: ({ paginationProps }) => ( @@ -203,7 +210,7 @@ export function AutoPagination() { columns={data.columns} options={{ pagination: true, - paginationAutoPageSize: true, + autoPageSize: true, }} /> @@ -212,20 +219,20 @@ export function AutoPagination() { } function loadServerRows(params: PageChangedParams): Promise { - return new Promise(resolve => { - getData(params.pageSize, 10).then(data => { + return new Promise((resolve) => { + getData(params.pageSize, 10).then((data) => { setTimeout(() => { const minId = (params.page - 1) * params.pageSize; - data.rows.forEach(row=> { + data.rows.forEach((row) => { row.id = (Number(row.id) + minId).toString(); - } ); + }); resolve(data); }, 500); }); }); } -export function ServerPagination() { +export function ServerPaginationWithApi() { const apiRef: ApiRef = useApiRef(); const data = useData(100, 10); const [rows, setRows] = useState([]); @@ -234,13 +241,13 @@ export function ServerPagination() { React.useEffect(() => { let unsubscribe; if (apiRef && apiRef.current) { - unsubscribe = apiRef.current.onPageChanged((params)=> { + unsubscribe = apiRef.current.onPageChanged((params) => { action('onPageChanged')(params); setLoading(true); - loadServerRows(params).then(newData => { + loadServerRows(params).then((newData) => { setRows(newData.rows); setLoading(false); - }) + }); }); } return () => { @@ -250,21 +257,57 @@ export function ServerPagination() { }; }, [apiRef, data]); + return ( +
+ +
+ ); +} + +export function ServerPaginationWithEventHandler() { + const apiRef: ApiRef = useApiRef(); + const data = useData(100, 10); + const [rows, setRows] = useState([]); + const [isLoading, setLoading] = useState(false); + + const onPageChange = useCallback( + (params) => { + action('onPageChanged')(params); + setLoading(true); + loadServerRows(params).then((newData) => { + setRows(newData.rows); + setLoading(false); + }); + }, + [setRows, setLoading], + ); return ( -
- -
+
+ +
); } diff --git a/packages/storybook/src/stories/playground/customize-components.stories.tsx b/packages/storybook/src/stories/playground/customize-components.stories.tsx index 847a51946141..595fe3fcaeb0 100644 --- a/packages/storybook/src/stories/playground/customize-components.stories.tsx +++ b/packages/storybook/src/stories/playground/customize-components.stories.tsx @@ -130,7 +130,7 @@ export function CustomPagination() { apiRef={apiRef} options={{ pagination: true, - paginationPageSize: 50, + pageSize: 50, }} components={{ pagination: PaginationComponent, @@ -167,7 +167,7 @@ export function CustomFooter() { columns={data.columns} options={{ pagination: true, - paginationPageSize: 33, + pageSize: 33, hideFooterPagination: true, hideFooter: true, }} @@ -205,7 +205,7 @@ export function HeaderAndFooter() { columns={data.columns} options={{ pagination: true, - paginationPageSize: 33, + pageSize: 33, hideFooterPagination: true, }} components={{ diff --git a/packages/storybook/src/stories/playground/data-grid.options.stories.tsx b/packages/storybook/src/stories/playground/data-grid.options.stories.tsx index 7d8c62595d08..df38d5f552eb 100644 --- a/packages/storybook/src/stories/playground/data-grid.options.stories.tsx +++ b/packages/storybook/src/stories/playground/data-grid.options.stories.tsx @@ -19,7 +19,7 @@ export default { export const Options = () => { const data = useData(2000, 200); - const rowsPerPageOptions = array('paginationRowsPerPageOptions', ['25', '50', '100'], ', '); + const rowsPerPageOptions = array('rowsPerPageOptions', ['25', '50', '100'], ', '); const sortingOrder = array('sortingOrder', ['asc', 'desc', 'null'], ', '); const dataGridOptionsProp: DataGridOptionsProp = { @@ -32,9 +32,9 @@ export const Options = () => { onPageChanged: (params) => action('onPageChanged')(params), onPageSizeChanged: (params) => action('onPageSizeChanged')(params), - paginationPageSize: number('paginationPageSize', 100), - paginationAutoPageSize: boolean('paginationAutoPageSize', false), - paginationRowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), + pageSize: number('pageSize', 100), + autoPageSize: boolean('autoPageSize', false), + rowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), hideFooterRowCount: boolean('hideFooterRowCount', false), hideFooterPagination: boolean('hideFooterPagination', false), hideFooter: boolean('hideFooter', false), diff --git a/packages/storybook/src/stories/playground/options.stories.tsx b/packages/storybook/src/stories/playground/options.stories.tsx index c183e3b18f43..1803958cd084 100644 --- a/packages/storybook/src/stories/playground/options.stories.tsx +++ b/packages/storybook/src/stories/playground/options.stories.tsx @@ -19,7 +19,7 @@ export default { export const Options = () => { const data = useData(2000, 200); - const rowsPerPageOptions = array('paginationRowsPerPageOptions', ['25', '50', '100'], ', '); + const rowsPerPageOptions = array('rowsPerPageOptions', ['25', '50', '100'], ', '); const sortingOrder = array('sortingOrder', ['asc', 'desc', 'null'], ', '); return ( @@ -38,9 +38,9 @@ export const Options = () => { autoHeight: boolean('autoHeight', false), pagination: boolean('pagination', true), - paginationPageSize: number('paginationPageSize', 100), - paginationAutoPageSize: boolean('paginationAutoPageSize', false), - paginationRowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), + pageSize: number('pageSize', 100), + autoPageSize: boolean('autoPageSize', false), + rowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), hideFooterRowCount: boolean('hideFooterRowCount', false), hideFooterPagination: boolean('hideFooterPagination', false), hideFooter: boolean('hideFooter', false), diff --git a/packages/storybook/src/stories/playground/real-data-demo.stories.tsx b/packages/storybook/src/stories/playground/real-data-demo.stories.tsx index d05667136ad5..25c7c50c7356 100644 --- a/packages/storybook/src/stories/playground/real-data-demo.stories.tsx +++ b/packages/storybook/src/stories/playground/real-data-demo.stories.tsx @@ -22,7 +22,7 @@ export default { }; const getGridOptions: () => GridOptionsProp = () => { - const rowsPerPageOptions = array('paginationRowsPerPageOptions', ['25', '50', '100'], ', '); + const rowsPerPageOptions = array('rowsPerPageOptions', ['25', '50', '100'], ', '); const sortingOrder = array('sortingOrder', ['asc', 'desc', 'null'], ', '); return { @@ -39,9 +39,9 @@ const getGridOptions: () => GridOptionsProp = () => { onPageSizeChanged: (params) => action('onPageSizeChanged')(params), pagination: boolean('pagination', false), - paginationPageSize: number('paginationPageSize', 100), - paginationAutoPageSize: boolean('paginationAutoPageSize', false), - paginationRowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), + pageSize: number('pageSize', 100), + autoPageSize: boolean('autoPageSize', false), + rowsPerPageOptions: rowsPerPageOptions.map((value) => parseInt(value, 10)), hideFooterRowCount: boolean('hideFooterRowCount', false), hideFooterPagination: boolean('hideFooterPagination', false), hideFooter: boolean('hideFooter', false), From 6a0c975399350875c652a748dac6e72c805131d6 Mon Sep 17 00:00:00 2001 From: damien Date: Thu, 23 Jul 2020 17:24:25 +0200 Subject: [PATCH 03/15] fix lint --- .../pages/demos/pagination/serverPagination.demo.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx index 31e9fc9e4810..eaf9875296c0 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx @@ -48,8 +48,8 @@ export default function ServerPaginationDemo() { const onPageChanged = useCallback( (params) => { setLoading(true); - loadServerRows(params).then((rows) => { - setRows(rows); + loadServerRows(params).then((newRows) => { + setRows(newRows); setLoading(false); }); }, @@ -66,7 +66,7 @@ export default function ServerPaginationDemo() { pageSize: 5, rowCount: 50, paginationMode: FeatureMode.Server, - onPageChanged: onPageChanged, + onPageChanged, }} loading={isLoading} /> From 42727d1f8a5008cddd799a4c9d48d44975748fee Mon Sep 17 00:00:00 2001 From: damien tassone Date: Fri, 24 Jul 2020 11:03:55 +0200 Subject: [PATCH 04/15] Apply suggestions from code review Co-authored-by: Olivier Tassinari --- packages/grid/x-grid-modules/src/models/gridOptions.tsx | 6 ++---- .../x-grid-modules/src/models/params/pageChangedParams.ts | 1 - .../grid/x-grid-modules/src/models/renderContextProps.ts | 2 +- packages/storybook/src/documentation/pages/api.stories.mdx | 2 +- .../pages/demos/pagination/serverPagination.demo.tsx | 3 ++- .../src/documentation/pages/pagination.stories.mdx | 4 ++-- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/grid/x-grid-modules/src/models/gridOptions.tsx b/packages/grid/x-grid-modules/src/models/gridOptions.tsx index 6efd22c1afd1..5f6fe28626e6 100644 --- a/packages/grid/x-grid-modules/src/models/gridOptions.tsx +++ b/packages/grid/x-grid-modules/src/models/gridOptions.tsx @@ -110,7 +110,6 @@ export interface GridOptions { * @default [25, 50, 100] */ rowsPerPageOptions?: number[]; - /** * Pagination can be processed on the server or client side. * Set it to FeatureMode.Client or `Client` if you would like to handle the pagination on the client side. @@ -118,15 +117,14 @@ export interface GridOptions { */ paginationMode?: FeatureMode; /** - * Set the total number of rows, if it is different than the length of the value `rows` prop + * Set the total number of rows, if it is different than the length of the value `rows` prop. */ rowCount?: number; /** * Set the current page. - * Default 1 + * @default 1 */ page?: number; - /** * Toggle footer component visibility. * @default false diff --git a/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts b/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts index 299a0686e3de..c32fff5781db 100644 --- a/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts +++ b/packages/grid/x-grid-modules/src/models/params/pageChangedParams.ts @@ -20,6 +20,5 @@ export interface PageChangedParams { * The total number of rows */ rowCount: number; - paginationMode: FeatureMode; } diff --git a/packages/grid/x-grid-modules/src/models/renderContextProps.ts b/packages/grid/x-grid-modules/src/models/renderContextProps.ts index 545ef01eb20d..acf6d7ac0649 100644 --- a/packages/grid/x-grid-modules/src/models/renderContextProps.ts +++ b/packages/grid/x-grid-modules/src/models/renderContextProps.ts @@ -49,7 +49,7 @@ export interface RenderPaginationProps { */ paginationCurrentPage?: number; /** - * The current page size if pagination is enabled + * The current page size if pagination is enabled. */ pageSize?: number; } diff --git a/packages/storybook/src/documentation/pages/api.stories.mdx b/packages/storybook/src/documentation/pages/api.stories.mdx index a87b77ff9e3b..6293c75b4ed4 100644 --- a/packages/storybook/src/documentation/pages/api.stories.mdx +++ b/packages/storybook/src/documentation/pages/api.stories.mdx @@ -20,7 +20,7 @@ return ## Use cases If you would like to manipulate the grid outside the component rendering the XGrid, for example if you are building some custom filters. -You could pass the apiRef using the React Context or as a React Prop. +You could pass the apiRef using the context or as a prop. This can also be very handy in a streaming api to update rows with changes from the server as we have exposed in our Rows section [here](). diff --git a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx index eaf9875296c0..54cbb751504a 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx @@ -10,7 +10,8 @@ import { randomUpdatedDate, } from '@material-ui/x-grid-data-generator'; -const newRow = () => ({ +function newRow() { + return ( id: randomId(), name: randomTraderName(), email: randomEmail(), diff --git a/packages/storybook/src/documentation/pages/pagination.stories.mdx b/packages/storybook/src/documentation/pages/pagination.stories.mdx index 6020ea900e14..ccff79a3dd58 100644 --- a/packages/storybook/src/documentation/pages/pagination.stories.mdx +++ b/packages/storybook/src/documentation/pages/pagination.stories.mdx @@ -107,7 +107,7 @@ To achieve this, just set the pagination property of the `components` react prop -## Server-side Pagination +## Server-side pagination XGrid supports both client and server side pagination. By default, pagination works on the client side. To switch it to server side, set the property `paginationMode` to `Server` as string or you can use our `FeatureMode` enum. @@ -143,7 +143,7 @@ const onPageChanged = useCallback( ### Pagination API -We exposed a set of methods that will let you achieve all the above features using the `ApiRef` object. More info on our Api page [here](??). +We exposed a set of methods that will let you achieve all the above features using the `ApiRef` object. More info on our API page [here](??). Below is an example on how you can reset the page using the `setPage` method of the API. From 23f8251d378dac99b6a372df62928ee79b2c8f70 Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 24 Jul 2020 11:52:19 +0200 Subject: [PATCH 05/15] change casing value in featureMode and remove apiref check --- .../x-grid-modules/src/models/featureMode.ts | 4 ++-- .../x-grid-modules/src/models/gridOptions.tsx | 4 ++-- .../documentation/pages/pagination.stories.mdx | 4 ++-- .../src/stories/grid-pagination.stories.tsx | 17 +++++++---------- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/packages/grid/x-grid-modules/src/models/featureMode.ts b/packages/grid/x-grid-modules/src/models/featureMode.ts index bdbc3336dc56..fd775dd1b007 100644 --- a/packages/grid/x-grid-modules/src/models/featureMode.ts +++ b/packages/grid/x-grid-modules/src/models/featureMode.ts @@ -1,4 +1,4 @@ export enum FeatureMode { - Client = 'Client', - Server = 'Server', + Client = 'client', + Server = 'server', } diff --git a/packages/grid/x-grid-modules/src/models/gridOptions.tsx b/packages/grid/x-grid-modules/src/models/gridOptions.tsx index 6efd22c1afd1..4b5299868728 100644 --- a/packages/grid/x-grid-modules/src/models/gridOptions.tsx +++ b/packages/grid/x-grid-modules/src/models/gridOptions.tsx @@ -113,8 +113,8 @@ export interface GridOptions { /** * Pagination can be processed on the server or client side. - * Set it to FeatureMode.Client or `Client` if you would like to handle the pagination on the client side. - * Set it to FeatureMode.Server or `Server` if you would like to handle the pagination on the server side. + * Set it to FeatureMode.client or `client` if you would like to handle the pagination on the client side. + * Set it to FeatureMode.server or `server` if you would like to handle the pagination on the server side. */ paginationMode?: FeatureMode; /** diff --git a/packages/storybook/src/documentation/pages/pagination.stories.mdx b/packages/storybook/src/documentation/pages/pagination.stories.mdx index 6020ea900e14..3275d5a934ab 100644 --- a/packages/storybook/src/documentation/pages/pagination.stories.mdx +++ b/packages/storybook/src/documentation/pages/pagination.stories.mdx @@ -110,7 +110,7 @@ To achieve this, just set the pagination property of the `components` react prop ## Server-side Pagination XGrid supports both client and server side pagination. By default, pagination works on the client side. To switch it to server side, -set the property `paginationMode` to `Server` as string or you can use our `FeatureMode` enum. +set the property `paginationMode` to `server` as string or you can use our `FeatureMode` enum. **Note**: You also need to set the `rowCount` property to override the number of rows in the grid so XGrid can calculate the total number of pages. Finally, you're going to need to handle the `onPageChanged` event, to load the rows for the corresponding page. @@ -132,7 +132,7 @@ const onPageChanged = useCallback( options={{ pagination: true, pageSize: 5, - paginationMode: 'Server', + paginationMode: 'server', rowCount: 50, onPageChanged: onPageChanged, }} diff --git a/packages/storybook/src/stories/grid-pagination.stories.tsx b/packages/storybook/src/stories/grid-pagination.stories.tsx index fca4352d44dc..1e9a4ac2591d 100644 --- a/packages/storybook/src/stories/grid-pagination.stories.tsx +++ b/packages/storybook/src/stories/grid-pagination.stories.tsx @@ -239,17 +239,14 @@ export function ServerPaginationWithApi() { const [isLoading, setLoading] = useState(false); React.useEffect(() => { - let unsubscribe; - if (apiRef && apiRef.current) { - unsubscribe = apiRef.current.onPageChanged((params) => { - action('onPageChanged')(params); - setLoading(true); - loadServerRows(params).then((newData) => { - setRows(newData.rows); - setLoading(false); - }); + const unsubscribe = apiRef.current!.onPageChanged((params) => { + action('onPageChanged')(params); + setLoading(true); + loadServerRows(params).then((newData) => { + setRows(newData.rows); + setLoading(false); }); - } + }); return () => { if (unsubscribe) { unsubscribe(); From 804eed4ad737f21d5d6685ef4fd804622a544da3 Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 24 Jul 2020 11:54:40 +0200 Subject: [PATCH 06/15] added missing dep in useEffect --- .../grid/x-grid-modules/src/hooks/features/usePagination.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts index 06ac144af727..ce41003440b9 100644 --- a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts +++ b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts @@ -165,11 +165,11 @@ export const usePagination = ( useEffect(() => { updateState({ paginationMode: options.paginationMode! }); - }, [options.paginationMode]); + }, [options.paginationMode, updateState]); useEffect(() => { setPage(options.page != null ? options.page : 1); - }, [options.page]); + }, [options.page, setPage]); useEffect(() => { const rowCount = options.rowCount == null ? rows.length : options.rowCount; From dd362a06f1411f5c03bde0e9a7d4fec15c4403f8 Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 24 Jul 2020 11:59:16 +0200 Subject: [PATCH 07/15] fix broken suggestion code --- .../grid/x-grid-modules/src/models/index.ts | 1 + .../demos/pagination/serverPagination.demo.tsx | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/grid/x-grid-modules/src/models/index.ts b/packages/grid/x-grid-modules/src/models/index.ts index 67ec9c501345..700d2c3b0566 100644 --- a/packages/grid/x-grid-modules/src/models/index.ts +++ b/packages/grid/x-grid-modules/src/models/index.ts @@ -1,6 +1,7 @@ export * from './colDef'; export * from './containerProps'; export * from './elementSize'; +export * from './featureMode'; export * from './gridOptions'; export * from './rootContainerRef'; export * from './renderContextProps'; diff --git a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx index 54cbb751504a..0aca92fd0bc9 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx @@ -11,14 +11,15 @@ import { } from '@material-ui/x-grid-data-generator'; function newRow() { - return ( - id: randomId(), - name: randomTraderName(), - email: randomEmail(), - age: randomInt(10, 100), - dateCreated: randomCreatedDate(), - lastLogin: randomUpdatedDate(), -}); + return { + id: randomId(), + name: randomTraderName(), + email: randomEmail(), + age: randomInt(10, 100), + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }; +} const columns: Columns = [ { field: 'id', hide: true }, From e03fc932d6e6327f95b0cee38ffd46b8f599290f Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 24 Jul 2020 12:02:21 +0200 Subject: [PATCH 08/15] fix doc comments --- packages/grid/x-grid-modules/src/models/gridOptions.tsx | 6 +++--- .../src/documentation/pages/pagination.stories.mdx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/grid/x-grid-modules/src/models/gridOptions.tsx b/packages/grid/x-grid-modules/src/models/gridOptions.tsx index 541449cd3ef5..885582793e0d 100644 --- a/packages/grid/x-grid-modules/src/models/gridOptions.tsx +++ b/packages/grid/x-grid-modules/src/models/gridOptions.tsx @@ -111,9 +111,9 @@ export interface GridOptions { */ rowsPerPageOptions?: number[]; /** - * Pagination can be processed on the server or client side. - * Set it to FeatureMode.client or `client` if you would like to handle the pagination on the client side. - * Set it to FeatureMode.server or `server` if you would like to handle the pagination on the server side. + * Pagination can be processed on the server or client-side. + * Set it to FeatureMode.client or `client` if you would like to handle the pagination on the client-side. + * Set it to FeatureMode.server or `server` if you would like to handle the pagination on the server-side. */ paginationMode?: FeatureMode; /** diff --git a/packages/storybook/src/documentation/pages/pagination.stories.mdx b/packages/storybook/src/documentation/pages/pagination.stories.mdx index d9692cd40a1d..6a2ac724be2d 100644 --- a/packages/storybook/src/documentation/pages/pagination.stories.mdx +++ b/packages/storybook/src/documentation/pages/pagination.stories.mdx @@ -109,7 +109,7 @@ To achieve this, just set the pagination property of the `components` react prop ## Server-side pagination -XGrid supports both client and server side pagination. By default, pagination works on the client side. To switch it to server side, +XGrid supports both client and server-side pagination. By default, pagination works on the client-side. To switch it to server-side, set the property `paginationMode` to `server` as string or you can use our `FeatureMode` enum. **Note**: You also need to set the `rowCount` property to override the number of rows in the grid so XGrid can calculate the total number of pages. From 7619ffa78722d5f0f331ca3f669501116b3bd79e Mon Sep 17 00:00:00 2001 From: damien tassone Date: Fri, 24 Jul 2020 12:56:24 +0200 Subject: [PATCH 09/15] Apply suggestions from code review Co-authored-by: Olivier Tassinari --- .../storybook/src/documentation/pages/pagination.stories.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storybook/src/documentation/pages/pagination.stories.mdx b/packages/storybook/src/documentation/pages/pagination.stories.mdx index 6a2ac724be2d..9fce0173ee0b 100644 --- a/packages/storybook/src/documentation/pages/pagination.stories.mdx +++ b/packages/storybook/src/documentation/pages/pagination.stories.mdx @@ -33,7 +33,7 @@ Our default `pageSize` is set to `100`. You can change this value by setting the - **Set Rows per page options** Along with the `pageSize` property, we added the `rowsPerPageOptions` that let you select the `pageSize` dynamically using XGrid UI. -Our default `rowsPerPageOptions` is set to `[25, 50, 100]`. You can change this value by setting the `rowsPerPageOptions` property of the `options` React prop as below. +The default `rowsPerPageOptions` is set to `[25, 50, 100]`. You can change this value by setting the `rowsPerPageOptions` property of the `options` prop as below. ```tsx Date: Fri, 24 Jul 2020 12:57:33 +0200 Subject: [PATCH 10/15] Fix FeatureMode enum and remove useCallback in demo --- .../src/hooks/features/usePagination.ts | 2 +- .../x-grid-modules/src/models/featureMode.ts | 4 ++-- .../x-grid-modules/src/models/gridOptions.tsx | 2 +- .../pagination/serverPagination.demo.tsx | 21 ++++++++----------- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts index ce41003440b9..79fcdda19adb 100644 --- a/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts +++ b/packages/grid/x-grid-modules/src/hooks/features/usePagination.ts @@ -81,7 +81,7 @@ export const usePagination = ( if (apiRef && apiRef.current) { page = stateRef.current.pageCount >= page ? page : stateRef.current.pageCount; apiRef.current!.renderPage( - stateRef.current.paginationMode === FeatureMode.Client ? page : 1, + stateRef.current.paginationMode === FeatureMode.client ? page : 1, ); const params: PageChangedParams = { diff --git a/packages/grid/x-grid-modules/src/models/featureMode.ts b/packages/grid/x-grid-modules/src/models/featureMode.ts index fd775dd1b007..024bf94186c9 100644 --- a/packages/grid/x-grid-modules/src/models/featureMode.ts +++ b/packages/grid/x-grid-modules/src/models/featureMode.ts @@ -1,4 +1,4 @@ export enum FeatureMode { - Client = 'client', - Server = 'server', + client = 'client', + server = 'server', } diff --git a/packages/grid/x-grid-modules/src/models/gridOptions.tsx b/packages/grid/x-grid-modules/src/models/gridOptions.tsx index 885582793e0d..5ca0c9e315d2 100644 --- a/packages/grid/x-grid-modules/src/models/gridOptions.tsx +++ b/packages/grid/x-grid-modules/src/models/gridOptions.tsx @@ -231,7 +231,7 @@ export const DEFAULT_GRID_OPTIONS: GridOptions = { enableMultipleColumnsSorting: true, rowsPerPageOptions: [25, 50, 100], pageSize: 100, - paginationMode: FeatureMode.Client, + paginationMode: FeatureMode.client, extendRowFullWidth: true, sortingOrder: ['asc', 'desc', null], columnTypes: DEFAULT_COLUMN_TYPES, diff --git a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx index 0aca92fd0bc9..a4509c400d7f 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx @@ -1,5 +1,5 @@ import { Columns, FeatureMode, PageChangedParams, RowsProp, XGrid } from '@material-ui/x-grid'; -import { useCallback, useState } from 'react'; +import { useState } from 'react'; import * as React from 'react'; import { randomCreatedDate, @@ -47,16 +47,13 @@ export default function ServerPaginationDemo() { const [rows, setRows] = useState([]); const [isLoading, setLoading] = useState(false); - const onPageChanged = useCallback( - (params) => { - setLoading(true); - loadServerRows(params).then((newRows) => { - setRows(newRows); - setLoading(false); - }); - }, - [setRows, setLoading], - ); + const onPageChanged = (params) => { + setLoading(true); + loadServerRows(params).then((newRows) => { + setRows(newRows); + setLoading(false); + }); + }; return ( Date: Fri, 24 Jul 2020 13:00:50 +0200 Subject: [PATCH 11/15] fix import order --- .../pages/demos/pagination/serverPagination.demo.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx index a4509c400d7f..c0858be6c74a 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx @@ -1,6 +1,5 @@ -import { Columns, FeatureMode, PageChangedParams, RowsProp, XGrid } from '@material-ui/x-grid'; -import { useState } from 'react'; import * as React from 'react'; +import { Columns, FeatureMode, PageChangedParams, RowsProp, XGrid } from '@material-ui/x-grid'; import { randomCreatedDate, randomEmail, @@ -44,8 +43,8 @@ function loadServerRows(params: PageChangedParams): Promise { } export default function ServerPaginationDemo() { - const [rows, setRows] = useState([]); - const [isLoading, setLoading] = useState(false); + const [rows, setRows] = React.useState([]); + const [isLoading, setLoading] = React.useState(false); const onPageChanged = (params) => { setLoading(true); From aca6d785bddf60114e454f70b757615af13b252b Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 24 Jul 2020 13:04:08 +0200 Subject: [PATCH 12/15] added namespace to function call to remove import --- .../storybook/src/stories/grid-pagination.stories.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/storybook/src/stories/grid-pagination.stories.tsx b/packages/storybook/src/stories/grid-pagination.stories.tsx index 1e9a4ac2591d..21dd664cb004 100644 --- a/packages/storybook/src/stories/grid-pagination.stories.tsx +++ b/packages/storybook/src/stories/grid-pagination.stories.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { useCallback, useState } from 'react'; import { ApiRef, FeatureMode, @@ -235,8 +234,8 @@ function loadServerRows(params: PageChangedParams): Promise { export function ServerPaginationWithApi() { const apiRef: ApiRef = useApiRef(); const data = useData(100, 10); - const [rows, setRows] = useState([]); - const [isLoading, setLoading] = useState(false); + const [rows, setRows] = React.useState([]); + const [isLoading, setLoading] = React.useState(false); React.useEffect(() => { const unsubscribe = apiRef.current!.onPageChanged((params) => { @@ -275,10 +274,10 @@ export function ServerPaginationWithApi() { export function ServerPaginationWithEventHandler() { const apiRef: ApiRef = useApiRef(); const data = useData(100, 10); - const [rows, setRows] = useState([]); - const [isLoading, setLoading] = useState(false); + const [rows, setRows] = React.useState([]); + const [isLoading, setLoading] = React.useState(false); - const onPageChange = useCallback( + const onPageChange = React.useCallback( (params) => { action('onPageChanged')(params); setLoading(true); From 9f6ab77ccaf08fdff62eedbe5341f90e93492e59 Mon Sep 17 00:00:00 2001 From: damien Date: Fri, 24 Jul 2020 13:08:40 +0200 Subject: [PATCH 13/15] remove useCallback and add react. to mdx code --- .../documentation/pages/pagination.stories.mdx | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/storybook/src/documentation/pages/pagination.stories.mdx b/packages/storybook/src/documentation/pages/pagination.stories.mdx index 9fce0173ee0b..53da11467f6d 100644 --- a/packages/storybook/src/documentation/pages/pagination.stories.mdx +++ b/packages/storybook/src/documentation/pages/pagination.stories.mdx @@ -116,15 +116,12 @@ set the property `paginationMode` to `server` as string or you can use our `Feat Finally, you're going to need to handle the `onPageChanged` event, to load the rows for the corresponding page. ```tsx -const [rows, setRows] = useState([]); -const onPageChanged = useCallback( - (params) => { - loadServerRows(params).then((newRows) => { - setRows(newRows); - }); - }, - [setRows], -); +const [rows, setRows] = React.useState([]); +const onPageChanged = (params) => { + loadServerRows(params).then((newRows) => { + setRows(newRows); + }); +}; Date: Fri, 24 Jul 2020 16:02:03 +0200 Subject: [PATCH 14/15] add concurrency in server pagination demo --- .../pages/demos/pagination/serverPagination.demo.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx index c0858be6c74a..81019e36d41f 100644 --- a/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx +++ b/packages/storybook/src/documentation/pages/demos/pagination/serverPagination.demo.tsx @@ -37,7 +37,7 @@ function loadServerRows(params: PageChangedParams): Promise { } setTimeout(() => { - resolve(rows); + resolve({ response: { rows }, request: { params } }); }, 800); }); } @@ -45,12 +45,16 @@ function loadServerRows(params: PageChangedParams): Promise { export default function ServerPaginationDemo() { const [rows, setRows] = React.useState([]); const [isLoading, setLoading] = React.useState(false); + const currentPage = React.useRef(1); const onPageChanged = (params) => { + currentPage.current = params.page; setLoading(true); - loadServerRows(params).then((newRows) => { - setRows(newRows); - setLoading(false); + loadServerRows(params).then(({ response, request }) => { + if (currentPage.current === request.params.page) { + setRows(response.rows); + setLoading(false); + } }); }; From 0b7afd66afe4e13511b612dc14f41fe462afc1a6 Mon Sep 17 00:00:00 2001 From: damien Date: Mon, 27 Jul 2020 10:59:26 +0200 Subject: [PATCH 15/15] fix feature mode export --- packages/grid/x-grid-modules/src/models/params/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/grid/x-grid-modules/src/models/params/index.ts b/packages/grid/x-grid-modules/src/models/params/index.ts index f185b59d4c17..02e4c9472988 100644 --- a/packages/grid/x-grid-modules/src/models/params/index.ts +++ b/packages/grid/x-grid-modules/src/models/params/index.ts @@ -8,4 +8,3 @@ export * from './pageChangedParams'; export * from './rowClickedParams'; export * from './rowSelectedParams'; export * from './selectionChangedParams'; -export { FeatureMode } from '../featureMode';