DataTablePage.tsx (2200B)
1 import { Page, Pageable } from "../../api/types/Page"; 2 import Table from "react-bootstrap/Table"; 3 import DataTableBody from "./DataTableBody"; 4 import { ColumnDef, RowDef } from "./ColumnDef"; 5 import Pagination from "react-bootstrap/Pagination"; 6 import update from "immutability-helper"; 7 import { ChangeEvent } from "react"; 8 9 type Props<T> = { 10 page: Page<T>, 11 columns: ColumnDef<T>[], 12 rows: RowDef<T>, 13 pageable: Pageable, 14 onPageableChange: (pageable: Pageable) => void 15 }; 16 17 export default function DataTablePage<T>({ page, columns, rows, pageable, onPageableChange }: Props<T>) { 18 const start = page.number * page.size; 19 const end = Math.min((page.number + 1) * page.size, page.totalElements); 20 21 const firstPage: number = 0; 22 const lastPage: number = Math.floor(page.totalElements / page.size); 23 24 const handlePageSizeChange = (event: ChangeEvent<HTMLSelectElement>): void => { 25 onPageableChange(update(pageable, { 26 size: { $set: parseInt(event.target.value) }, 27 page: { $set: 0 } 28 })); 29 } 30 const setPage = (pageNumber: number): void => { 31 onPageableChange(update(pageable, { page: { $set: pageNumber } })); 32 }; 33 34 const listPages: React.JSX.Element[] = []; 35 if (firstPage != lastPage) { 36 for (let pageNumber: number = firstPage; pageNumber <= lastPage; pageNumber++) { 37 listPages.push(<Pagination.Item key={pageNumber} active={pageNumber == page.number} onClick={() => setPage(pageNumber)}>{pageNumber}</Pagination.Item>); 38 } 39 } 40 41 return ( 42 <> 43 <div> 44 Show <select value={pageable.size} onChange={handlePageSizeChange}> 45 <option value="10">10</option> 46 <option value="25">25</option> 47 <option value="50">50</option> 48 <option value="100">100</option> 49 </select> entries 50 </div> 51 52 <Table> 53 <thead> 54 <tr> 55 {columns.map(column => ( 56 <td key={column.key}> 57 {column.header} 58 </td> 59 ))} 60 </tr> 61 </thead> 62 <DataTableBody data={page.content} columns={columns} rows={rows} /> 63 <tfoot> 64 <tr> 65 <td colSpan={columns.length}> 66 <Pagination size="sm" className="float-end mb-0">{listPages}</Pagination> 67 {start + 1}-{end} of {page.totalElements} 68 </td> 69 </tr> 70 </tfoot> 71 </Table> 72 </> 73 ); 74 }