import React, { useReducer, useEffect } from 'react'; import classNames from 'classnames'; import { Button, ButtonGroup, Intent, HTMLSelect } from '@blueprintjs/core'; import { FormattedMessage as T } from 'components'; import intl from 'react-intl-universal'; import PropTypes from 'prop-types'; import { range } from 'lodash'; import { Icon } from 'components'; import 'style/components/DataTable/Pagination.scss'; const TYPE = { PAGE_CHANGE: 'PAGE_CHANGE', PAGE_SIZE_CHANGE: 'PAGE_SIZE_CHANGE', INITIALIZE: 'INITIALIZE', }; const getState = ({ currentPage, size, total }) => { const totalPages = Math.ceil(total / size); const visibleItems = 5; const halfVisibleItems = Math.ceil(visibleItems / 2); // create an array of pages to ng-repeat in the pager control let startPage, endPage; if (totalPages <= visibleItems) { // less than {visibleItems} total pages so show startPage = 1; endPage = totalPages; } else { // more than {visibleItems} total pages so calculate start and end pages if (currentPage <= halfVisibleItems) { startPage = 1; endPage = visibleItems; } else if (currentPage + (halfVisibleItems - 1) >= totalPages) { startPage = totalPages - (visibleItems - 1); endPage = totalPages; } else { startPage = currentPage - halfVisibleItems; endPage = currentPage + halfVisibleItems - 1; } } const pages = [...Array(endPage + 1 - startPage).keys()].map( (i) => startPage + i, ); // Too large or small currentPage let correctCurrentpage = currentPage; if (currentPage > totalPages) correctCurrentpage = totalPages; if (currentPage <= 0) correctCurrentpage = 1; return { currentPage: correctCurrentpage, size, total, pages, totalPages, }; }; const reducer = (state, action) => { switch (action.type) { case TYPE.PAGE_CHANGE: return getState({ currentPage: action.page, size: state.size, total: state.total, }); case TYPE.PAGE_SIZE_CHANGE: return getState({ currentPage: state.currentPage, size: action.size, total: state.total, }); case TYPE.INITIALIZE: return getState({ currentPage: action.page, size: action.size, total: action.total, }); default: throw new Error(); } }; function Pagination({ currentPage, total, size, pageSizesOptions = [20, 30, 50, 75, 100, 150], onPageChange, onPageSizeChange, }) { const [state, dispatch] = useReducer( reducer, { currentPage, total, size }, getState, ); useEffect(() => { dispatch({ type: TYPE.INITIALIZE, total, size, page: currentPage, }); }, [total, size, currentPage]); return ( ); } Pagination.propTypes = { currentPage: PropTypes.number.isRequired, size: PropTypes.number.isRequired, total: PropTypes.number.isRequired, onPageChange: PropTypes.func, onPageSizeChange: PropTypes.func, }; Pagination.defaultProps = { currentPage: 1, size: 25, }; export default Pagination;