import {
Paper,
Skeleton,
Table as MuiTable,
TablePagination,
TableSortLabel,
} from "@mui/material";
import { styled } from "@mui/material/styles";
import TableBody from "@mui/material/TableBody";
import TableCell, { tableCellClasses } from "@mui/material/TableCell";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import {
ColumnDef,
flexRender,
getCoreRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import React, { memo, useState } from "react";
import { BaseEntity } from "../types/users";
interface TableProps<T> {
data: T[];
columns: ColumnDef<T, unknown>[];
isFetching?: boolean;
rowsPerPage: number;
setRowsPerPage: React.Dispatch<React.SetStateAction<number>>;
setLastRowId: React.Dispatch<React.SetStateAction<number | undefined>>;
rowCount: number;
setDirection: React.Dispatch<React.SetStateAction<string>>;
}
const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: {
backgroundColor: "lightgray",
fontWeight: "bold",
},
[`&.${tableCellClasses.body}`]: {
fontSize: 14,
},
}));
function Table<T extends BaseEntity>(props: TableProps<T>) {
const {
data,
columns,
isFetching,
rowsPerPage,
setRowsPerPage,
setLastRowId,
rowCount,
setDirection,
} = props;
const { getHeaderGroups, getRowModel, getAllColumns } = useReactTable<T>({
data,
columns,
getCoreRowModel: getCoreRowModel(),
manualPagination: true,
getSortedRowModel: getSortedRowModel(),
});
const handleChangePage = (
event: React.MouseEvent<HTMLButtonElement> | null,
newPage: number
) => {
if (newPage >= page) {
const id = data[data.length - 1].id;
setLastRowId(id);
setDirection("desc");
} else {
const id = data[0].id;
setLastRowId(id);
setDirection("asc");
}
setPage(newPage);
};
const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setRowsPerPage(parseInt(event.target.value, 10));
setLastRowId(undefined);
setDirection("desc");
setPage(0);
};
const skeletons = Array.from({ length: data.length }, (x, i) => i);
const columnCount = getAllColumns().length;
const [page, setPage] = useState(0);
return (
<Paper sx={{ overflowX: "auto" }}>
<MuiTable
style={{
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
<TableHead>
{getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<StyledTableCell key={header.id}>
<>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
{header.column.getCanSort() ? (
<TableSortLabel
active={header.column.getIsSorted() ? true : false}
onClick={header.column.getToggleSortingHandler()}
direction={
header.column.getIsSorted() === "asc"
? "asc"
: header.column.getIsSorted() === "desc"
? "desc"
: undefined
}
/>
) : null}
</>
</StyledTableCell>
))}
</TableRow>
))}
</TableHead>
<TableBody>
{!isFetching ? (
getRowModel().rows.map((row) => (
<TableRow key={row.id}>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : (
<>
{skeletons.map((skeleton) => (
<TableRow key={skeleton}>
{Array.from({ length: columnCount }, (x, i) => i).map(
(elm) => (
<TableCell key={elm}>
<Skeleton />
</TableCell>
)
)}
</TableRow>
))}
</>
)}
</TableBody>
</MuiTable>
<TablePagination
component="div"
count={-1}
page={page}
onPageChange={handleChangePage}
rowsPerPageOptions={[3, 5, 10, 25, 50, 100]}
rowsPerPage={rowsPerPage}
onRowsPerPageChange={handleChangeRowsPerPage}
labelRowsPerPage="Wiersze na stronę"
labelDisplayedRows={({ from, to }) => `${from}-${to} elementów`}
nextIconButtonProps={{
disabled: data.length >= rowCount && page !== 0,
}}
/>
</Paper>
);
}
export default memo(Table);
Paste Hosted With By Wklejamy.pl