137 lines
4.0 KiB
React
137 lines
4.0 KiB
React
|
|
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>
|
||
|
|
)
|
||
|
|
}
|