import CloseIcon from '@material-ui/icons/Close'; import FilterListIcon from '@material-ui/icons/FilterList'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import Hidden from '@material-ui/core/Hidden'; import Paper from '@material-ui/core/Paper'; import PropTypes from 'prop-types'; import React from 'react'; import Table from '@material-ui/core/Table'; import TableBody from '@material-ui/core/TableBody'; import TableCell from '@material-ui/core/TableCell'; import TableHead from '@material-ui/core/TableHead'; import TableRow from '@material-ui/core/TableRow'; import TableSortLabel from '@material-ui/core/TableSortLabel'; import TextField from '@material-ui/core/TextField'; import Toolbar from '@material-ui/core/Toolbar'; import Tooltip from '@material-ui/core/Tooltip'; import Typography from '@material-ui/core/Typography'; import _find from 'lodash/find'; import _get from 'lodash/get'; import _isNil from 'lodash/isNil'; import _orderBy from 'lodash/orderBy'; import classNames from 'classnames'; import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons/faQuestionCircle'; import { withStyles } from '@material-ui/core/styles'; const styles = theme => ({ root: { width: '100%', marginTop: theme.spacing.unit * 3, marginBottom: theme.spacing.unit * 3, overflowX: 'auto', }, activeSortIcon: { opacity: 1, }, toolbar: { paddingLeft: "24px" }, toolbarIcon: { cursor: "pointer", opacity: 0.8 }, inactiveSortIcon: { opacity: 0.4, }, denseTable: { paddingRight: "8px" }, title: { flexGrow: 1 } }); class BaseTable extends React.Component { constructor(props) { super(props); this.state = { order: this.props.defaultOrder || "asc", orderBy: this.props.defaultOrderBy, filterBy: "" }; this.handleFilterInputChange = this.handleFilterInputChange.bind(this); this.handleFilterToggle = this.handleFilterToggle.bind(this); } createSortHandler = col => () => { let orderBy = col.dataIndex; let order = col.defaultSortOrder || 'asc'; if (this.state.orderBy === orderBy && this.state.order === order) { order = order === 'asc' ? 'desc' : 'asc'; } this.setState({ order, orderBy }); }; handleFilterInputChange = e => { let input = e.target.value.replace(/[^A-Z0-9/.\-_]/gi, "").toLowerCase(); let swapWildCard = /[*]/g; // replace "*" in input with wildcard let filterBy = new RegExp(input.replace(swapWildCard, ".+"), "i"); if (filterBy !== this.state.filterBy) { this.setState({ filterBy }); } } handleFilterToggle = () => { let newFilterStatus = !this.state.showFilter; this.setState({ showFilter: newFilterStatus, filterBy: "" }); } generateRows = (tableRows, tableColumns, order, orderBy, filterBy) => { let rows = tableRows; let col = _find(tableColumns, d => d.dataIndex === orderBy); if (orderBy && col.sorter) { rows = _orderBy(rows, row => col.sorter(row), order); } if (filterBy) { let columnsToFilter = tableColumns.filter(col => col.filter); let filteredRows = rows.filter(row => { return columnsToFilter.some(col => { let rowText = col.filter(row); return rowText.match(filterBy); }); }); rows = filteredRows; } return rows; } renderHeaderCell = (col, order, orderBy) => { let active = orderBy === col.dataIndex; const { classes, padding } = this.props; let tableCell; if (col.sorter) { tableCell = ( {col.title} ); } else { tableCell = ( {col.title} ); } return _isNil(col.tooltip) ? tableCell : {tableCell}; } renderToolbar = (classes, title) => { return ( {title} {this.props.showTitleTooltip && } {this.state.showFilter && } {!this.state.showFilter && } {this.state.showFilter && } ); } render() { const { classes, enableFilter, tableRows, tableColumns, tableClassName, title, rowKey, padding} = this.props; const {order, orderBy, filterBy} = this.state; const sortedTableRows = tableRows.length > 0 ? this.generateRows(tableRows, tableColumns, order, orderBy, filterBy) : tableRows; return ( {enableFilter && this.renderToolbar(classes, title)} { tableColumns.map(c => ( this.renderHeaderCell(c, order, orderBy) ))} { sortedTableRows.map(d => { let key = !rowKey ? d.key : rowKey(d); let tableRow = ( { tableColumns.map(c => ( {c.render ? c.render(d) : _get(d, c.dataIndex)} ) )} ); return _isNil(d.tooltip) ? tableRow : {tableRow}; } )}
); } } BaseTable.propTypes = { classes: PropTypes.shape({}).isRequired, defaultOrder: PropTypes.string, defaultOrderBy: PropTypes.string, enableFilter: PropTypes.bool, padding: PropTypes.string, rowKey: PropTypes.func, showTitleTooltip: PropTypes.bool, tableClassName: PropTypes.string, tableColumns: PropTypes.arrayOf(PropTypes.shape({ dataIndex: PropTypes.string, defaultSortOrder: PropTypes.string, isNumeric: PropTypes.bool, render: PropTypes.func, sorter: PropTypes.func, title: PropTypes.string })).isRequired, tableRows: PropTypes.arrayOf(PropTypes.shape({})), title: PropTypes.string, titleTooltipText: PropTypes.string }; BaseTable.defaultProps = { defaultOrder: "asc", defaultOrderBy: null, enableFilter: false, padding: "default", rowKey: null, tableClassName: "", tableRows: [], title: "", showTitleTooltip: false, titleTooltipText: "" }; export default withStyles(styles)(BaseTable);