import React, {useRef, useState} from 'react'; 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 TableRow from '@mui/material/TableRow'; import TableSortLabel from '@mui/material/TableSortLabel'; import Paper from '@mui/material/Paper'; import classNames from 'classnames'; import Button from "@mui/material/Button"; import { visuallyHidden } from '@mui/utils'; import _ from 'lodash'; import Box from "@mui/material/Box"; // let columns = [ // { // name: "ID", // value: (row) => row._id, // descendingComparator: (a, b) => {return value(b) < value(a) ? 1 : value(b) > value(a) ? -1 : 0} // } // ] // // let rows = [ // { // _id: 1234, // name: "abc", // value: 123 // } // ] // // let options = { // key: (row) => row._id, // editor: (row) => {return ()} // add: true, // maxHeight: "40rem", // remove: (row) => { /* show dialog and/or perform remove */ } // } const cssTopControls = { display: 'flex', flexDirection: 'row', justifyContent: 'flex-end', } /* * Separate the Meteor calls as much as possible to avoid them being run repeatedly unnecessarily (were being run on every selection in the table). */ export default ({columns, rows, options}) => { const [selected, setSelected] = useState(undefined); const tableContainer = useRef(null) let selectRow = (e, row) => { setSelected(row); } const [edited, setEdited] = useState(undefined); const [order, setOrder] = useState('asc') //'asc' or 'desc' const [orderBy, setOrderBy] = useState(undefined); //Column name being sorted. let editRow = (e, row) => { setEdited(row); } const closeEditor = () => { setEdited(undefined) } const addRow = () => { setEdited({}); setTimeout(() => tableContainer.current.scrollTo({top: 0, left: 0, behavior: "smooth"}),0) } let containerStyle = options.maxHeight ? {maxHeight: options.maxHeight} : {} let keyHandler = (e) => { !edited && options.keyHandler && options.keyHandler(e, selected) // Close the editor if the user hits escape. if(edited && e.key === 'Escape') { setEdited(undefined) e.stopPropagation() } if(!edited && e.key === 'Insert') { setEdited({}) e.stopPropagation() } if(!edited && e.key === 'Delete' && selected && options.delete && _.isFunction(options.delete)) { options.delete(selected) } } const sort = (e, column) => { const isAscending = orderBy === column && order === 'asc' //Descending if this is the first click on the column or toggling from ascending. setOrder(isAscending ? 'desc' : 'asc') setOrderBy(column) } const descendingComparator = (a, b, orderBy) => { let av = orderBy.value(a) let bv = orderBy.value(b) if(bv < av) return -1 else if(bv > av) return 1 else return 0 } const getComparator = (order, orderBy) => { if(!orderBy) return undefined else if(orderBy.descendingComparator) return order === 'desc' ? (a,b) => orderBy.descendingComparator(a,b) : (a,b) => -orderBy.descendingComparator(a,b) else return order === 'desc' ? (a, b) => descendingComparator(a, b, orderBy) : (a, b) => -descendingComparator(a, b, orderBy); } const stableSort = (array, comparator) => { if(comparator) { const stabilizedThis = array.map((el, index) => [el, index]); stabilizedThis.sort((a, b) => { const order = comparator(a[0], b[0]); if (order !== 0) { return order; } return a[1] - b[1]; }); return stabilizedThis.map((el) => el[0]); } else return array } // console.log(rows) return (
{options.add && } {options.remove && _.isFunction(options.remove) && }
{columns.map((column, i) => {return ( {sort(e, column)}}> {column.name} {orderBy === column.name && ( {order === 'desc' ? 'sorted descending' : 'sorted ascending'} )} )})} {edited && !options.key(edited) && ( {options.editor(edited, closeEditor)} )} {stableSort(rows, getComparator(order, orderBy)).map((row, i) => { return ( {editRow(e, row)}} onClick={(e) => selectRow(e, row)}> {edited && options.key(edited) === options.key(row) ? {options.editor(edited, closeEditor)} : <> {columns.map((column, ci) => { // console.log("Rendering Cell") // console.log(column); // console.log(column.value(row)); let value = column.value(row); if(_.isObject(value)) { console.error("Cannot have an object returned as the value in a table.") console.log("Cell value: ") console.log(value) value = JSON.stringify(value) } return ( {value} ) })} } ) })}
) }