Skip to content

Commit

Permalink
Update EuiDataGrid pagination props to accept 'all'
Browse files Browse the repository at this point in the history
- type updates and either `'all'` or `typeof 'number'` checks (note that I generally prefer 'all' but fall back to typeof number if accounting for pagination undefined at the same time)
  • Loading branch information
cee-chen committed Feb 11, 2022
1 parent 8efabe6 commit c476dc8
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 32 deletions.
26 changes: 11 additions & 15 deletions src/components/datagrid/data_grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -353,23 +353,20 @@ export const EuiDataGrid = forwardRef<EuiDataGridRefProps, EuiDataGridProps>(
const interactiveCellId = useGeneratedHtmlId();
const ariaLabelledById = useGeneratedHtmlId();

const ariaPage = pagination ? pagination.pageIndex + 1 : 1;
const ariaPageCount =
typeof pagination?.pageSize === 'number'
? Math.ceil(rowCount / pagination.pageSize)
: 1;
const ariaLabel = useEuiI18n(
'euiDataGrid.ariaLabel',
'{label}; Page {page} of {pageCount}.',
{
label: rest['aria-label'],
page: pagination ? pagination.pageIndex + 1 : 0,
pageCount: pagination ? Math.ceil(rowCount / pagination.pageSize) : 0,
}
{ label: rest['aria-label'], page: ariaPage, pageCount: ariaPageCount }
);

const ariaLabelledBy = useEuiI18n(
'euiDataGrid.ariaLabelledBy',
'Page {page} of {pageCount}.',
{
page: pagination ? pagination.pageIndex + 1 : 0,
pageCount: pagination ? Math.ceil(rowCount / pagination.pageSize) : 0,
}
{ page: ariaPage, pageCount: ariaPageCount }
);

// extract aria-label and/or aria-labelledby from `rest`
Expand Down Expand Up @@ -422,11 +419,10 @@ export const EuiDataGrid = forwardRef<EuiDataGridRefProps, EuiDataGridProps>(
renderCellValue={renderCellValue}
columns={columns}
rowCount={
inMemory.level === 'enhancements'
? // if `inMemory.level === enhancements` then we can only be sure the pagination's pageSize is available in memory
pagination?.pageSize || rowCount
: // otherwise, all of the data is present and usable
rowCount
inMemory.level === 'enhancements' && // if `inMemory.level === enhancements` then we can only be sure the pagination's pageSize is available in memory
typeof pagination?.pageSize === 'number' // If pageSize is set to 'all' instead of a number, then all rows are being displayed
? pagination?.pageSize || rowCount
: rowCount // otherwise, all of the data is present and usable
}
onCellRender={onCellRender}
/>
Expand Down
12 changes: 7 additions & 5 deletions src/components/datagrid/data_grid_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -722,18 +722,20 @@ export interface EuiDataGridPaginationProps {
*/
pageIndex: number;
/**
* How many rows should initially be shown per page
* How many rows should initially be shown per page.
* Pass `'all'` to display the selected "Show all" option and hide the pagination.
*/
pageSize: number;
pageSize: number | 'all';
/**
* An array of page sizes the user can select from.
* Leave this prop undefined or use an empty array to hide "Rows per page" select button
* Pass `'all'` as one of the options to create a "Show all" option.
* Leave this prop undefined or use an empty array to hide "Rows per page" select button.
*/
pageSizeOptions?: number[];
pageSizeOptions?: Array<number | 'all'>;
/**
* A callback for when the user changes the page size selection
*/
onChangeItemsPerPage: (itemsPerPage: number) => void;
onChangeItemsPerPage: (itemsPerPage: number | 'all') => void;
/**
* A callback for when the current page index changes
*/
Expand Down
33 changes: 33 additions & 0 deletions src/components/datagrid/utils/data_grid_pagination.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,39 @@ describe('EuiDataGridPaginationRenderer', () => {
`);
});

it('handles the "all" page size option', () => {
const component = shallow(
<EuiDataGridPaginationRenderer
{...props}
pageSize="all"
pageSizeOptions={[10, 25, 'all']}
/>
);
expect(component).toMatchInlineSnapshot(`
<div
className="euiDataGrid__pagination"
>
<EuiTablePagination
activePage={0}
aria-controls="data-grid-id"
aria-label="Pagination for preceding grid"
itemsPerPage="all"
itemsPerPageOptions={
Array [
10,
25,
"all",
]
}
onChangeItemsPerPage={[MockFunction]}
onChangePage={[Function]}
pageCount={1}
showPerPageOptions={true}
/>
</div>
`);
});

it('does not render if there are fewer rows than the smallest page size option', () => {
const component = shallow(
<EuiDataGridPaginationRenderer
Expand Down
12 changes: 10 additions & 2 deletions src/components/datagrid/utils/data_grid_pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,17 @@ export const EuiDataGridPaginationRenderer = ({
[setFocusedCell, _onChangePage]
);

const pageCount = Math.ceil(rowCount / pageSize);
const pageCount =
typeof pageSize === 'number' ? Math.ceil(rowCount / pageSize) : 1;
const minSizeOption =
pageSizeOptions && [...pageSizeOptions].sort((a, b) => a - b)[0];
pageSizeOptions?.length &&
[...pageSizeOptions].reduce((a, b) => {
// Account for 'all' strings
if (typeof b !== 'number') return a;
if (typeof a !== 'number') return b;
// Find the smallest number
return Math.min(a, b);
});

if (rowCount < (minSizeOption || pageSize)) {
/**
Expand Down
7 changes: 3 additions & 4 deletions src/components/datagrid/utils/focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,18 +215,17 @@ export const createKeyDownHandler = ({
setFocusedCell([x + 1, y]);
}
} else if (key === keys.PAGE_DOWN) {
if (pagination) {
if (pagination && pagination.pageSize !== 'all') {
event.preventDefault();
const pageSize = pagination.pageSize;
const pageCount = Math.ceil(rowCount / pageSize);
const pageCount = Math.ceil(rowCount / pagination.pageSize);
const pageIndex = pagination.pageIndex;
if (pageIndex < pageCount - 1) {
pagination.onChangePage(pageIndex + 1);
}
setFocusedCell([focusedCell[0], 0]);
}
} else if (key === keys.PAGE_UP) {
if (pagination) {
if (pagination && pagination.pageSize !== 'all') {
event.preventDefault();
const pageIndex = pagination.pageIndex;
if (pageIndex > 0) {
Expand Down
3 changes: 2 additions & 1 deletion src/components/datagrid/utils/grid_height_width.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useEffect, useState, useContext, MutableRefObject } from 'react';
import { IS_JEST_ENVIRONMENT } from '../../../test';
import { useUpdateEffect, useForceRender } from '../../../services';
import { useResizeObserver } from '../../observer/resize_observer';
import { EuiTablePaginationProps } from '../../table/table_pagination';
import { EuiDataGridRowHeightsOptions } from '../data_grid_types';
import { RowHeightUtils } from './row_heights';
import { DataGridSortingContext } from './sorting';
Expand Down Expand Up @@ -162,7 +163,7 @@ export const useUnconstrainedHeight = ({
export const useVirtualizeContainerWidth = (
virtualizeContainer: HTMLDivElement | null,
gridWidth: number,
pageSize: number | undefined
pageSize: EuiTablePaginationProps['itemsPerPage']
) => {
const [virtualizeContainerWidth, setVirtualizeContainerWidth] = useState(0);
useResizeObserver(virtualizeContainer);
Expand Down
2 changes: 1 addition & 1 deletion src/components/datagrid/utils/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export const useSortPageCheck = (
: rowIndex;

// Account for pagination
if (pagination) {
if (pagination && pagination.pageSize !== 'all') {
const pageIndex = Math.floor(visibleRowIndex / pagination.pageSize);
// If the targeted row is on a different page than the current page,
// we should automatically navigate the user to the correct page
Expand Down
12 changes: 8 additions & 4 deletions src/components/datagrid/utils/row_count.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ export const computeVisibleRows = ({
pagination: EuiDataGridProps['pagination'];
rowCount: EuiDataGridProps['rowCount'];
}): EuiDataGridVisibleRows => {
const startRow = pagination ? pagination.pageIndex * pagination.pageSize : 0;
const startRow =
pagination && pagination.pageSize !== 'all'
? pagination.pageIndex * pagination.pageSize
: 0;

let endRow = pagination
? (pagination.pageIndex + 1) * pagination.pageSize
: rowCount;
let endRow =
pagination && pagination.pageSize !== 'all'
? (pagination.pageIndex + 1) * pagination.pageSize
: rowCount;
endRow = Math.min(endRow, rowCount);

const visibleRowCount = endRow - startRow;
Expand Down

0 comments on commit c476dc8

Please sign in to comment.