| @@ -6,6 +6,7 @@ import React, { | |||
| MouseEvent, | |||
| SetStateAction, | |||
| useCallback, | |||
| useMemo, | |||
| useState, | |||
| } from "react"; | |||
| import Paper from "@mui/material/Paper"; | |||
| @@ -29,6 +30,7 @@ import { | |||
| } from "@mui/material"; | |||
| import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline"; | |||
| import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | |||
| import { filter, remove, uniq } from "lodash"; | |||
| export interface ResultWithId { | |||
| id: string | number; | |||
| @@ -228,6 +230,19 @@ function SearchResults<T extends ResultWithId>({ | |||
| }; | |||
| // checkbox | |||
| const currItems = useMemo(() => { | |||
| return items.length > 10 ? items | |||
| .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) | |||
| .map((i) => i.id) | |||
| : items.map((i) => i.id) | |||
| }, [items, page, rowsPerPage]) | |||
| const currItemsWithChecked = useMemo(() => { | |||
| return filter(checkboxIds, function (c) { | |||
| return currItems.includes(c); | |||
| }) | |||
| }, [checkboxIds, items, page, rowsPerPage]) | |||
| const handleRowClick = useCallback( | |||
| (event: MouseEvent<unknown>, item: T, columns: Column<T>[]) => { | |||
| // check is disabled or not | |||
| @@ -269,6 +284,18 @@ function SearchResults<T extends ResultWithId>({ | |||
| [checkboxIds], | |||
| ); | |||
| const handleSelectAllClick = (event: React.ChangeEvent<HTMLInputElement>) => { | |||
| if (setCheckboxIds) { | |||
| const pageItemId = currItems | |||
| if (event.target.checked) { | |||
| setCheckboxIds((prev) => uniq([...prev, ...pageItemId])) | |||
| } else { | |||
| setCheckboxIds((prev) => filter(prev, function (p) { return !pageItemId.includes(p); })) | |||
| } | |||
| } | |||
| } | |||
| const table = ( | |||
| <> | |||
| <TableContainer sx={{ maxHeight: 440 }}> | |||
| @@ -276,15 +303,28 @@ function SearchResults<T extends ResultWithId>({ | |||
| <TableHead> | |||
| <TableRow> | |||
| {columns.map((column, idx) => ( | |||
| <TableCell | |||
| align={column.headerAlign} | |||
| sx={column.sx} | |||
| key={`${column.name.toString()}${idx}`} | |||
| > | |||
| {column.label.split('\n').map((line, index) => ( | |||
| <div key={index}>{line}</div> // Render each line in a div | |||
| ))} | |||
| </TableCell> | |||
| isCheckboxColumn(column) ? | |||
| <TableCell | |||
| align={column.headerAlign} | |||
| sx={column.sx} | |||
| key={`${column.name.toString()}${idx}`} | |||
| > | |||
| <Checkbox | |||
| color="primary" | |||
| indeterminate={currItemsWithChecked.length > 0 && currItemsWithChecked.length < currItems.length} | |||
| checked={currItems.length > 0 && currItemsWithChecked.length >= currItems.length} | |||
| onChange={handleSelectAllClick} | |||
| /> | |||
| </TableCell> | |||
| : <TableCell | |||
| align={column.headerAlign} | |||
| sx={column.sx} | |||
| key={`${column.name.toString()}${idx}`} | |||
| > | |||
| {column.label.split('\n').map((line, index) => ( | |||
| <div key={index}>{line}</div> // Render each line in a div | |||
| ))} | |||
| </TableCell> | |||
| ))} | |||
| </TableRow> | |||
| </TableHead> | |||
| @@ -299,6 +339,7 @@ function SearchResults<T extends ResultWithId>({ | |||
| tabIndex={-1} | |||
| key={item.id} | |||
| onClick={(event) => { | |||
| console.log("first") | |||
| setCheckboxIds | |||
| ? handleRowClick(event, item, columns) | |||
| : undefined | |||
| @@ -329,7 +370,19 @@ function SearchResults<T extends ResultWithId>({ | |||
| }) | |||
| : items.map((item) => { | |||
| return ( | |||
| <TableRow hover tabIndex={-1} key={item.id}> | |||
| <TableRow hover tabIndex={-1} key={item.id} | |||
| onClick={(event) => { | |||
| setCheckboxIds | |||
| ? handleRowClick(event, item, columns) | |||
| : undefined | |||
| if (onRowClick) { | |||
| onRowClick(item) | |||
| } | |||
| } | |||
| } | |||
| role={setCheckboxIds ? "checkbox" : undefined} | |||
| > | |||
| {columns.map((column, idx) => { | |||
| const columnName = column.name; | |||