Files
Tempest/imports/ui/util/SimpleTable.jsx

137 lines
4.0 KiB
JavaScript

import React, { 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 Paper from '@mui/material/Paper';
import classNames from 'classnames';
import Button from "@mui/material/Button";
import _ from 'lodash';
// let columns = [
// {
// name: "ID",
// value: (row) => row._id
// }
// ]
//
// let rows = [
// {
// _id: 1234,
// name: "abc",
// value: 123
// }
// ]
//
// let options = {
// key: (row) => row._id,
// editor: (row) => {return (<MyRowEditor value={row}/>)}
// }
const cssTopControls = {
display: 'flex',
flexDirection: 'row-reverse',
}
/*
* 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);
let selectRow = (e, row) => {
setSelected(row);
}
const [edited, setEdited] = useState(undefined);
let editRow = (e, row) => {
setEdited(row);
}
const closeEditor = () => {
setEdited(undefined)
}
const addRow = () => {
setEdited({});
}
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()
}
}
return (
<div className='simpleTableContainer'>
{options.add && <div style={cssTopControls}><Button variant="text" className="button" onClick={addRow}>Add</Button></div>}
<TableContainer className="simpleTable" component={Paper} style={containerStyle}>
<Table size="small" aria-label="Table" tabIndex="0" onKeyDown={keyHandler}>
<TableHead className="sticky">
<TableRow>
{columns.map((column, i) => {return (
<TableCell key={i} className="headerCell">{column.name}</TableCell>
)})}
{/*<TableCell className="headerCell">Name</TableCell>*/}
{/*<TableCell className="headerCell">Email</TableCell>*/}
{/*<TableCell className="headerCell">Roles</TableCell>*/}
</TableRow>
</TableHead>
<TableBody>
{edited && !options.key(edited) && (
<TableRow key="NewEditor" className="tableRow">
<TableCell className="editorContainer" colSpan={columns.length}>
{options.editor(edited, closeEditor)}
</TableCell>
</TableRow>
)}
{rows.map((row, i)=>{
// console.log("Rendering Row " + i)
// console.log(row);
return (
<TableRow key={options.key(row)} className={classNames({tableRow: true, selected: (!edited || options.key(edited) !== options.key(row)) && selected && options.key(selected) === options.key(row)})} onDoubleClick={(e) => {editRow(e, row)}} onClick={(e) => selectRow(e, row)}>
{edited && options.key(edited) === options.key(row) ?
<TableCell className="editorContainer" colSpan={columns.length}>
{options.editor(edited, closeEditor)}
</TableCell>
:
<>
{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.")
value = JSON.stringify(value)
}
return (
<TableCell key={ci} align="left">{value}</TableCell>
)
})}
</>
}
</TableRow>
)
})}
</TableBody>
</Table>
</TableContainer>
</div>
)
}