|
- "use client";
-
- import React, {useEffect, useState} from "react";
- import Paper from "@mui/material/Paper";
- import Table from "@mui/material/Table";
- import TableBody from "@mui/material/TableBody";
- import TableCell from "@mui/material/TableCell";
- import TableContainer from "@mui/material/TableContainer";
- import TableHead from "@mui/material/TableHead";
- import TablePagination from "@mui/material/TablePagination";
- import TableRow from "@mui/material/TableRow";
- import IconButton from "@mui/material/IconButton";
- import EditIcon from "@mui/icons-material/Edit";
- import SaveIcon from "@mui/icons-material/Save";
- import CancelIcon from "@mui/icons-material/Close";
- import DeleteIcon from "@mui/icons-material/Delete";
- import TextField from "@mui/material/TextField";
- import MultiSelect from "@/components/SearchBox/MultiSelect";
-
- export interface ResultWithId {
- id: string | number;
- }
-
- interface BaseColumn<T extends ResultWithId> {
- name: keyof T;
- label: string;
- type: string;
- options: T[];
- renderCell? : (T) => void;
- }
-
- interface ColumnWithAction<T extends ResultWithId> extends BaseColumn<T> {
- onClick: (item: T) => void;
- buttonIcon: React.ReactNode;
- buttonColor?: "inherit" | "default" | "primary" | "secondary";
- }
-
- export type Column<T extends ResultWithId> =
- | BaseColumn<T>
- | ColumnWithAction<T>;
-
- interface Props<T extends ResultWithId> {
- items: T[],
- columns: Column<T>[],
- noWrapper?: boolean,
- setPagingController: (value: { pageNum: number; pageSize: number; totalCount: number }) => void,
- pagingController: { pageNum: number; pageSize: number; totalCount: number },
- isAutoPaging: boolean
- }
-
- function EditableSearchResults<T extends ResultWithId>({
- items,
- columns,
- noWrapper,
- pagingController,
- setPagingController,
- isAutoPaging = true,
- }: Props<T>) {
- const [page, setPage] = useState(0);
- const [rowsPerPage, setRowsPerPage] = useState(10);
- const [editingRowId, setEditingRowId] = useState<number | null>(null);
- const [editedItems, setEditedItems] = useState<T[]>(items);
-
- useEffect(()=>{
- setEditedItems(items)
- },[items])
- const handleChangePage = (_event: unknown, newPage: number) => {
- setPage(newPage);
- setPagingController({ ...pagingController, pageNum: newPage + 1 });
- };
-
- const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
- setRowsPerPage(+event.target.value);
- setPage(0);
- setPagingController({ ...pagingController, pageSize: +event.target.value, pageNum: 1 });
- };
-
- const handleEditClick = (id: number) => {
- setEditingRowId(id);
- };
-
- const handleSaveClick = (item: T) => {
- setEditingRowId(null);
- // Call API or any save logic here
- setEditedItems((prev) =>
- prev.map((row) => (row.id === item.id ? { ...row } : row))
- );
- };
-
- const handleInputChange = (id: number, field: keyof T, value: string | number[]) => {
- setEditedItems((prev) =>
- prev.map((item) =>
- item.id === id ? { ...item, [field]: value } : item
- )
- );
- };
-
- const handleDeleteClick = (id: number) => {
- // Implement delete logic here
- setEditedItems((prev) => prev.filter(item => item.id !== id));
- };
-
- const table = (
- <>
- <TableContainer sx={{ maxHeight: 440 }}>
- <Table stickyHeader>
- <TableHead>
- <TableRow>
- <TableCell>Actions</TableCell> {/* Action Column Header */}
- {columns.map((column, idx) => (
- <TableCell key={`${column.name.toString()}${idx}`}>
- {column.label}
- </TableCell>
- ))}
- </TableRow>
- </TableHead>
- <TableBody>
- {(isAutoPaging ? editedItems.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) : editedItems).map((item) => (
- <TableRow hover tabIndex={-1} key={item.id}>
- <TableCell>
- {editingRowId === item.id ? (
- <>
- <IconButton onClick={() => handleSaveClick(item)}>
- <SaveIcon />
- </IconButton>
- <IconButton onClick={() => setEditingRowId(null)}>
- <CancelIcon />
- </IconButton>
- </>
- ) : (
- <>
- <IconButton onClick={() => handleEditClick(item.id as number)}>
- <EditIcon />
- </IconButton>
- <IconButton onClick={() => handleDeleteClick(item.id as number)}>
- <DeleteIcon />
- </IconButton>
- </>
- )}
- </TableCell>
- {columns.map((column, idx) => {
- const columnName = column.name;
-
- return (
- <TableCell key={`${columnName.toString()}-${idx}`}>
- {editingRowId === item.id ? (
- (() => {
- switch (column.type) {
- case 'input':
- return (
- <TextField
- hiddenLabel={true}
- fullWidth
- defaultValue={item[columnName] as string}
- onChange={(e) => handleInputChange(item.id as number, columnName, e.target.value)}
- />
- );
- case 'multi-select':
- return (
- <MultiSelect
- //label={column.label}
- options={column.options}
- selectedValues={[]}
- onChange={(selectedValues) => handleInputChange(item.id as number, columnName, selectedValues)}
- />
- );
- default:
- return null; // Handle any default case if needed
- }
- })()
- ) : (
- column.renderCell ?
- column.renderCell(item)
- :
- <span onDoubleClick={() => handleEditClick(item.id as number)}>
- {item[columnName] as string}
- </span>
- )}
- </TableCell>
- );
- })}
- </TableRow>
- ))}
- </TableBody>
- </Table>
- </TableContainer>
- <TablePagination
- rowsPerPageOptions={[10, 25, 100]}
- component="div"
- count={pagingController.totalCount === 0 ? editedItems.length : pagingController.totalCount}
- rowsPerPage={rowsPerPage}
- page={page}
- onPageChange={handleChangePage}
- onRowsPerPageChange={handleChangeRowsPerPage}
- />
- </>
- );
-
- return noWrapper ? table : <Paper sx={{ overflow: "hidden" }}>{table}</Paper>;
- }
-
- export default EditableSearchResults;
|