@material-ui/core#TableCell JavaScript Examples
The following examples show how to use
@material-ui/core#TableCell.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js From react-material-ui-table-row-drag-and-drop with Creative Commons Zero v1.0 Universal | 8 votes |
render() {
return (
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>Nr</TableCell>
<TableCell>Label</TableCell>
<TableCell align="right">Text</TableCell>
</TableRow>
</TableHead>
<TableBody component={DroppableComponent(this.onDragEnd)}>
{this.state.items.map((item, index) => (
<TableRow component={DraggableComponent(item.id, index)} key={item.id} >
<TableCell scope="row">{index + 1}</TableCell>
<TableCell>{item.primary}</TableCell>
<TableCell align="right">{item.secondary}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)
}
Example #2
Source File: LeaseRow.js From akashlytics-deploy with GNU General Public License v3.0 | 6 votes |
LeaseRow = React.memo(
function MemoLeaseRow({ lease }) {
const classes = useStyles();
return (
<TableRow>
<TableCell component="th" scope="row">
<StatusPill state={lease.state} size="small" />
</TableCell>
<TableCell>
<Link to={UrlService.deploymentDetails(lease.dseq)}>{lease.dseq}</Link>
</TableCell>
<TableCell>
<div className={classes.flexCenter}>
<PricePerMonth perBlockValue={uaktToAKT(lease.price.amount, 6)} />
<PriceEstimateTooltip value={uaktToAKT(lease.price.amount, 6)} />
<span className={classes.monthlyCost}>
<FormattedNumber value={lease.price.amount} maximumSignificantDigits={18} />
uakt ({`~${getAvgCostPerMonth(lease.price.amount)}akt/month`})
</span>
</div>
</TableCell>
</TableRow>
);
},
(prevProps, nextProps) => {
return isEqual(prevProps, nextProps);
}
)
Example #3
Source File: TableUtilRows.js From Designer-Client with GNU General Public License v3.0 | 6 votes |
/**
*
* @param props
* @param {number} props.colSpan 차지하는 Column의 개수
* @param {string} props.text Row에 들어갈 텍스트
*/
export function TableEmptyRow({ colSpan = 1, text = "Empty Row" }) {
return (
<TableRow>
<TableCell colSpan={colSpan} align="center">
{text}
</TableCell>
</TableRow>
)
}
Example #4
Source File: DataPreview.js From Otto with MIT License | 6 votes |
export default function DataPreview() {
const { state } = useState();
const classes = useStyles();
if (state.sample_dataset == null) {
return null;
}
const metadata = datasetMetadata[state.sample_dataset];
function getFormatted(label, index) {
if (metadata.units) {
return label + " (" + metadata.units[index] + ")";
}
return label;
}
return (
<Grid direction="column" container className={classes.noPadding}>
{/* Data Attributes */}
<Grid item>
<div className={classes.root}>
{chipData(state).map((data, index) => {
return (
<li key={index}>
<Chip label={data} color="primary" className={classes.chip} />
</li>
);
})}
</div>
</Grid>
{/* Table */}
<Grid item className={classes.fullWidth}>
<TableContainer component={Paper} className={classes.table}>
<Table size="small" aria-label="a dense table">
<TableHead>
<TableRow>
{metadata.columns.map((column, index) => (
<TableCell key={index}>
{getFormatted(
metadata.columnsMap
? metadata.columnsMap[column]
: column,
index
)}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{metadata.data.slice(0, 5).map((row, index) => (
<TableRow key={index}>
{metadata.columns.map((column, index) => (
<TableCell key={index} component="th" scope="row">
{row[column]}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
</Grid>
);
}
Example #5
Source File: ContentPropertiesLayout.js From Edlib with GNU General Public License v3.0 | 6 votes |
function ContentPropertiesLayout(props) {
const {
classes,
rows,
} = props;
return (
<Table className={classes.table}>
<TableBody>
{rows.map(row => {
let contentPropertiesRowClassName = 'contentpropertiesrow';
if (typeof row.cssClassName !== 'undefined') {
contentPropertiesRowClassName += ' ' + row.cssClassName;
}
let displayValue = row.value;
if (typeof row.fullValue !== 'undefined') {
displayValue = (
<Tooltip
title={row.fullValue}
classes={{ tooltip: classes.tooltip }}
placement="top"
>
<span>{row.value}</span>
</Tooltip>
);
}
return (
<TableRow className={contentPropertiesRowClassName} key={row.label}>
<TableCell className="contentpropertieslabel">{row.label}</TableCell>
<TableCell className="contentpropertiesvalue">
{displayValue}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
);
}
Example #6
Source File: table-container-head.js From horondi_admin with MIT License | 6 votes |
TableContainerHead = ({ titles }) => {
const styles = useStyles();
const { actionLabel } = tableHeadRowTitles;
const headRow = titles.map((title) => (
<TableCell
variant='head'
data-cy={title}
key={title}
className={title === actionLabel ? styles.actionCell : ''}
>
{title}
</TableCell>
));
return (
<TableHead className={styles.tableHead}>
<TableRow>{headRow}</TableRow>
</TableHead>
);
}
Example #7
Source File: certificate-table.js From horondi_client_fe with MIT License | 6 votes |
CertificateTable = ({ items }) => { const styles = useStyles(); const { t } = useTranslation(); const certificateItems = useMemo( () => [...items] .sort((a, b) => new Date(b.dateStart) - new Date(a.dateStart)) .map((item) => <CertificateItem item={item} key={item._id} />), [items] ); const headerItems = useMemo( () => ROW_FIELDS.map((item) => <TableCell key={item}>{t(`certificate.${item}`)}</TableCell>), [ROW_FIELDS, t] ); return ( <div className={styles.root}> <h2 className={styles.titleWrapper}>{t('certificate.title')}</h2> <div className={styles.table}> <Table> <TableHead> <TableRow className={styles.tableHeader}>{headerItems}</TableRow> </TableHead> <TableBody>{certificateItems}</TableBody> </Table> </div> </div> ); }
Example #8
Source File: OrderService.js From module-federation-examples with MIT License | 6 votes |
function OrderRow(props) {
return (
<TableRow key={props.order.id}>
<TableCell>{props.order.date}</TableCell>
<TableCell>{props.order.name}</TableCell>
<TableCell>{props.order.shipTo}</TableCell>
<TableCell>{props.order.paymentMethod}</TableCell>
<TableCell align="right">{props.order.amount}</TableCell>
</TableRow>
);
}
Example #9
Source File: Table.js From react-code-splitting-2021-04-26 with MIT License | 6 votes |
export default function TableComponent({ data }) {
const classes = useStyles();
var keys = Object.keys(data[0]).map(i => i.toUpperCase());
keys.shift(); // delete "id" key
return (
<Table className="mb-0">
<TableHead>
<TableRow>
{keys.map(key => (
<TableCell key={key}>{key}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{data.map(({ id, name, email, product, price, date, city, status }) => (
<TableRow key={id}>
<TableCell className="pl-3 fw-normal">{name}</TableCell>
<TableCell>{email}</TableCell>
<TableCell>{product}</TableCell>
<TableCell>{price}</TableCell>
<TableCell>{date}</TableCell>
<TableCell>{city}</TableCell>
<TableCell>
<Chip label={status} classes={{root: classes[states[status.toLowerCase()]]}}/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}
Example #10
Source File: DriverProfile.js From KEDS-Rideshare-KUHacks with MIT License | 6 votes |
StyledTableCell = withStyles((theme) => ({
head: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
body: {
fontSize: 14,
},
}))(TableCell)
Example #11
Source File: LeaderboardDialog.js From dipact with GNU General Public License v3.0 | 6 votes |
makeRow(pos, user) {
return (
<TableRow key={user.Id}>
<TableCell>{pos}</TableCell>
<TableCell>
<UserAvatar user={user} />
</TableCell>
<TableCell>{user.Name}</TableCell>
</TableRow>
);
}
Example #12
Source File: CertificateListModal.js From akashlytics-deploy with GNU General Public License v3.0 | 5 votes |
export function CertificateListModal({ onClose, revokeCertificate }) {
const classes = useStyles();
const { validCertificates, localCert, selectedCertificate } = useCertificate();
return (
<Dialog open={true} onClose={onClose} maxWidth="md" fullWidth>
<DialogTitle>Certificates</DialogTitle>
<DialogContent dividers className={classes.dialogContent}>
<TableContainer>
<Table size="small">
<TableHead>
<TableRow>
<TableCell align="center">Selected</TableCell>
<TableCell align="center">Local cert</TableCell>
<TableCell align="center">Issued on</TableCell>
<TableCell align="center">Expires</TableCell>
<TableCell align="center">Serial</TableCell>
<TableCell align="center"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{validCertificates.map((cert) => (
<TableRow key={cert.serial}>
<TableCell align="center">{cert.serial === selectedCertificate?.serial && <CheckIcon color="primary" />}</TableCell>
<TableCell align="center">{cert.parsed === localCert?.certPem && <CheckIcon color="primary" />}</TableCell>
<TableCell align="center">
<FormattedDate value={cert.pem.issuedOn} year="numeric" month="2-digit" day="2-digit" hour="2-digit" minute="2-digit" />
</TableCell>
<TableCell align="center">
<FormattedDate value={cert.pem.expiresOn} year="numeric" month="2-digit" day="2-digit" hour="2-digit" minute="2-digit" />
</TableCell>
<TableCell align="center">{cert.serial}</TableCell>
<TableCell align="center">
<Button onClick={() => revokeCertificate(cert)} color="secondary" size="small">
Revoke
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</DialogContent>
<DialogActions>
<Button variant="contained" color="primary" onClick={onClose}>
Close
</Button>
</DialogActions>
</Dialog>
);
}
Example #13
Source File: BorderedTable.js From Designer-Client with GNU General Public License v3.0 | 5 votes |
/**
*
* @param {{container: Component, size: number, headers: string[], rows: Object[]}} props
*/
export default function BorderedTable({ container, size, headers, rows }) {
const classes = useStyles();
return (
<TableContainer component={container}>
<Table size={size}>
{headers && (
<TableHead>
<TableRow>
{headers.map((header) => {
return (
<TableCell key={`table-header-cell-${header}`} className={classes.borderedCell}>
{header}
</TableCell>
);
})}
</TableRow>
</TableHead>
)}
<TableBody>
{rows.map((row) => {
return (
<TableRow key={`table-row-${row[0]}`}>
{row.map((col) => {
return (
<TableCell className={classes.borderedCell} key={`table-cell-${col}`}>
{col}
</TableCell>
);
})}
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
);
}
Example #14
Source File: KailonaTable.js From ehr with GNU Affero General Public License v3.0 | 5 votes |
HeadCell = withStyles(theme => ({
root: {
fontWeight: 'bold',
fontSize: '14px',
},
}))(TableCell)
Example #15
Source File: FreshnessBlip.jsx From archeage-tools with The Unlicense | 5 votes |
render() {
const { name, profitLevels } = this.props;
const standard = profitLevels.filter(pL => !pL.aged);
const aged = profitLevels.filter(pL => pL.aged);
const hasAged = aged.length > 0;
return (
<Tooltip
title={<Table size="small" className="freshness-table">
<TableHead>
<TableRow>
<TableCell colSpan={hasAged ? 4 : 2} align="center" className={`freshness ${name}`}>
{name} Packs
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{hasAged &&
<TableRow>
<TableCell colSpan={2} align="center">Regular</TableCell>
<TableCell colSpan={2} align="center">Aged</TableCell>
</TableRow>}
{standard.map((standardPL, i) => {
const agedPL = aged[i];
return (
<TableRow key={`profit-${name}-${standardPL.name}`} className="profit-row">
<TableCell>
{standardPL.name} Profit
</TableCell>
<TableCell>
{percentModifier(standardPL.modifier)} {standardPL.time}
</TableCell>
{hasAged && agedPL &&
<>
<TableCell>
{agedPL.name} Profit
</TableCell>
<TableCell>
{percentModifier(agedPL.modifier)} {agedPL.time}
</TableCell>
</>}
</TableRow>
);
})}
</TableBody>
</Table>}
classes={{ tooltip: 'freshness-tip-container' }}
>
<Typography variant="overline" className="freshness-tip">
<span className={`blip freshness ${name}`} /> {name}
</Typography>
</Tooltip>
);
}
Example #16
Source File: UserListHead.js From course-manager with MIT License | 5 votes |
export default function UserListHead({
order,
orderBy,
rowCount,
headLabel,
numSelected,
onRequestSort,
onSelectAllClick
}) {
const createSortHandler = (property) => (event) => {
onRequestSort(event, property);
};
return (
<TableHead>
<TableRow>
<TableCell padding="checkbox">
<Checkbox
indeterminate={numSelected > 0 && numSelected < rowCount}
checked={rowCount > 0 && numSelected === rowCount}
onChange={onSelectAllClick}
/>
</TableCell>
{headLabel.map((headCell) => (
<TableCell
key={headCell.id}
align={headCell.alignRight ? 'right' : 'left'}
sortDirection={orderBy === headCell.id ? order : false}
>
<TableSortLabel
hideSortIcon
active={orderBy === headCell.id}
direction={orderBy === headCell.id ? order : 'asc'}
onClick={createSortHandler(headCell.id)}
>
{headCell.label}
{orderBy === headCell.id ? (
<Box sx={{ ...visuallyHidden }}>
{order === 'desc' ? 'sorted descending' : 'sorted ascending'}
</Box>
) : null}
</TableSortLabel>
</TableCell>
))}
</TableRow>
</TableHead>
);
}
Example #17
Source File: events.js From dscbppimt-official-website with MIT License | 5 votes |
function Events() {
const classes = useStyles()
const [ Events, setEvents] = useState([]);
const [ upcomingEvents, setUpcomingEvents ] = useState([])
const [ isLoading, setLoading ] = useState(false)
const URL = "https://dscbppimt-cms.herokuapp.com/files/"
useEffect(() => {
const today = new Date()
const todayDate = today.toISOString()
console.log(todayDate)
// 2020-10-11T09:10:30.698Z
setLoading(true);
Axios.get(`https://dscbppimt-cms.herokuapp.com/our-events?Date_gte=${todayDate}&_sort=Date:desc&_limit=2`).then(res => {
console.log(res.data);
setUpcomingEvents(res.data);
setLoading(false)
});
Axios.get(`https://dscbppimt-cms.herokuapp.com/our-events?Date_lt=${todayDate}&_sort=Date:desc`).then(res => {
console.log(res.data);
setEvents(res.data);
setLoading(false)
});
},[])
return (
<Layout>
<Box>
<Container style={{marginBottom : '4em'}}>
<Typography variant="h4" style={{fontWeight : '500', margin : '1em 0px'}}>Our Events</Typography>
<Grid container spacing={2}>
{isLoading ? <Skeleton variant="rect" width="100%" height="150px"/> : upcomingEvents.length !== 0 ? upcomingEvents.map(event => (
<Grid item xs={12} sm={6} md={12} key={event._id}>
<EventCard
Image={URL+(event.Image.formats.thumbnail.url)}
title={event.Title}
speaker={event.Speaker === 'None' ? null : event.Speaker }
description={event.Description}
date={event.Date}
data={event.Image}
register={event.Register}
learn={event.Learn}
/>
</Grid>
)) : <Container style={{width: '100%', textAlign: 'center', margin: '4em 0'}}><Typography align="center" >No Upcoming Events</Typography></Container>}
</Grid>
</Container>
</Box>
<Container style={{padding : '2em'}}>
<Box style={{display : 'flex', justifyContent : 'space-between'}}>
<Typography variant="h6">Past Events</Typography>
</Box>
<TableContainer component={Paper} className={classes.tableContainer}>
<Table className={classes.table} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell align="center">Event</TableCell>
<TableCell align="center">Speaker</TableCell>
<TableCell align="center">Date</TableCell>
</TableRow>
</TableHead>
<TableBody>
{Events.map((row) => (
<TableRow key={row.Title}>
<TableCell component="th" scope="row" align="center">{row.Title}</TableCell>
<TableCell align="center">{row.Speaker}</TableCell>
<TableCell align="center">{row.Date}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Container>
</Layout>
)
}
Example #18
Source File: SystemStatus.jsx From Edlib with GNU General Public License v3.0 | 5 votes |
SystemStatus = ({ name, loading, error, data }) => {
const [isExpanded, setIsExpanded] = React.useState(false);
if (loading) {
return (
<Paper>
<h2>{name}</h2>
</Paper>
);
}
if (error) {
return (
<Paper>
<Box display="flex" justifyContent="space-between">
<div>{name}</div>
<div>
<i className="fa fa-caret-down" />
</div>
</Box>
<Collapse in={isExpanded} timeout="auto">
<Typography>
Could not get service status. This might be because the
service is not set up properly or that you have no
internet connection.
</Typography>
</Collapse>
</Paper>
);
}
return (
<Paper>
<Box
display="flex"
justifyContent="space-between"
bgcolor={data.color + '.main'}
onClick={() => setIsExpanded(!isExpanded)}
>
<div>{name}</div>
<div>
<i className="fa fa-caret-down" />
</div>
</Box>
<Collapse in={isExpanded}>
<Table>
<TableHead>
<tr>
<th width={35} />
<th>Subservice name</th>
<th>Status</th>
<th>Parameters</th>
</tr>
</TableHead>
<TableBody>
{data.systems.map((s, index) => (
<TableRow key={index}>
<TableCell className={'bg-' + s.color} />
<TableCell>{s.name}</TableCell>
<TableCell>{s.statusMessage}</TableCell>
<TableCell>
{s.parameters &&
Object.entries(s.parameters).map(
([key, value]) => (
<div>
<strong>{key}: </strong>
{value}
</div>
)
)}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Collapse>
</Paper>
);
}
Example #19
Source File: HospitalList.jsx From frontend with MIT License | 5 votes |
HospitalList = () => {
const [requests, setRequests] = useState([]);
const getData = () => {
fetch(`${apiUrl}/resources`)
.then((x) => x.json())
.then((x) => x.list.filter((a) => a.name))
.then((x) => {
setRequests([...x]);
});
};
const [showAppModal, handleAppModal] = useState(false);
const [requestId, setRequestId] = useState(null);
const toggleModal = () => {
handleAppModal(!showAppModal);
};
const init = useRef(false);
useEffect(() => {
if (!init.current) {
getData();
init.current = true;
}
}, [init]);
return (
<Paper elevation={2}>
<TableFilter />
<Table>
<TableHead>
<TableRow>
{columns.map((col) => (
<TableCell key={col.label}>{col.label}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{requests.map((data) => (
<TableRow key={data.id}>
<TableCell>{data.beneficiary.name}</TableCell>
<TableCell>{data.name}</TableCell>
<TableCell>{data.quantity}</TableCell>
<TableCell>{data.deadline}</TableCell>
<TableCell>
<PersonCell person={data.contactPerson} />
</TableCell>
<TableCell>
<Button
color="secondary"
variant="contained"
onClick={() => {
setRequestId(data.id);
toggleModal(true);
}}
>
Apply
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<VolunteerJoin open={showAppModal} id={requestId} onClose={toggleModal} />
</Paper>
);
}
Example #20
Source File: certificate-item.js From horondi_client_fe with MIT License | 5 votes |
CertificateItem = ({ item }) => {
const styles = useStyles();
const { t } = useTranslation();
const dateHandler = (date) => date.slice(0, 10).split('-').reverse().join('/');
return (
<TableRow className={styles.root} data-cy='certificate-item'>
<TableCell data-cy='certificate-item-img'>
<img
src={CertificateImages[`image${item.value}`]}
className={styles.itemImg}
alt='certificate img'
/>
</TableCell>
<TableCell data-cy='certificate-item-code'>
<div className={styles.name}>
<textarea className={styles.area} type='text' defaultValue={item.name} />
<Tooltip title={t('certificate.copy')}>
<button
className={styles.copyBtn}
onClick={() => navigator.clipboard.writeText(item.name)}
>
<CertificateCodeCopy alt='certificate-copy-icon' className={styles.copyIcon} />
</button>
</Tooltip>
</div>
</TableCell>
<TableCell data-cy='certificate-item-price'>
<div className={styles.price}>
{item.value}
{` ${t('certificate.currency')}`}
</div>
</TableCell>
<TableCell data-cy='certificate-item-expiration'>
<div className={styles.date}>{`${dateHandler(item.dateStart)} - ${dateHandler(
item.dateEnd
)}`}</div>
</TableCell>
<TableCell data-cy='certificate-item-status'>
{item.isActivated && <div className={styles.statusGreen}>{t(`certificate.active`)}</div>}
{item.isUsed && <div className={styles.statusRed}>{t(`certificate.used`)}</div>}
{item.isUsed === false && item.isActivated === false && (
<div className={styles.statusBlue}>{t(`certificate.expired`)}</div>
)}
</TableCell>
</TableRow>
);
}
Example #21
Source File: positions.jsx From GraphVega with MIT License | 5 votes |
Positions = props => {
return (
<Row>
<Col sm={{span:12}}>
<Card>
<CardContent>
<Typography variant="h6" display="block" gutterBottom>
Positions
</Typography>
<Table>
<TableHead>
<TableRow>
<TableCell>TYPE</TableCell>
<TableCell>QTY</TableCell>
<TableCell>MARK</TableCell>
<TableCell>STRIKE</TableCell>
<TableCell>EXPIRY</TableCell>
<TableCell>IMP VOL</TableCell>
<TableCell>VEGA</TableCell>
<TableCell>THETA</TableCell>
<TableCell>DELTA</TableCell>
<TableCell>GAMMA</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.positions.map((option) => (
<TableRow>
<TableCell>
<Chip label={option.option_type} color={chipStyle(option.option_type)}/>
</TableCell>
<TableCell>{option.quantity}</TableCell>
<TableCell>{(option.bid + option.ask)/2}</TableCell>
<TableCell>{option.strike}</TableCell>
<TableCell>{expiry(option.expiration_date)}</TableCell>
<TableCell>{roundOne(option.greeks.smv_vol*100)}%</TableCell>
<TableCell>{option.greeks.vega}</TableCell>
<TableCell>{option.greeks.theta}</TableCell>
<TableCell>{option.greeks.delta}</TableCell>
<TableCell>{option.greeks.gamma}</TableCell>
</TableRow>
))}
{(props.quantity && props.quantity !== 0) ?
<TableRow>
<TableCell>
<Chip label={"shares"} />
</TableCell>
<TableCell>{props.quantity}</TableCell>
<TableCell>{(props.quote.ask + props.quote.bid)/2}</TableCell>
<TableCell>--</TableCell>
<TableCell>--</TableCell>
<TableCell>--</TableCell>
<TableCell>--</TableCell>
<TableCell>--</TableCell>
<TableCell>{props.quantity}</TableCell>
<TableCell>--</TableCell>
</TableRow>
: ""
}
</TableBody>
</Table>
</CardContent>
</Card>
</Col>
</Row>
)
}
Example #22
Source File: ViewTransactions.js From Pharma-Chain with MIT License | 5 votes |
export default function ViewTransactions(props) {
const classes = useStyles();
const [ account ] = useState(props.location.query.account);
const [ txnAddress ] = useState(props.location.query.address);
const [ web3 ] = useState(props.location.query.web3);
const [ details, setDetails ] = useState({});
const [ loading, isLoading ] = useState(true);
async function getTxnData() {
const transaction = new web3.eth.Contract(Transactions.abi, txnAddress);
let txns = await transaction.methods.getAllTransactions().call({ from: account });
const txnsList = txns.map(data => {
return (
<TableRow key={data[ 0 ]} className={classes.tableBodyRow}>
<TableCell multiline className={classes.tableCell} style={{ maxWidth: "75px" }}>{data[ 0 ]}</TableCell>
<TableCell multiline className={classes.tableCell} style={{ maxWidth: "50px" }}>{data[ 1 ]}</TableCell>
<TableCell multiline className={classes.tableCell} style={{ maxWidth: "50px" }}>{data[ 2 ]}</TableCell>
<TableCell multiline className={classes.tableCell} style={{ maxWidth: "75px" }}>{data[ 3 ]}</TableCell>
<TableCell multiline className={classes.tableCell} style={{ maxWidth: "10px" }}>{data[ 4 ]}</TableCell>
<TableCell multiline className={classes.tableCell} style={{ maxWidth: "10px" }}>{data[ 5 ]}</TableCell>
<TableCell multiline className={classes.tableCell} style={{ maxWidth: "40px" }}>{new Date(data[ 6 ] * 1000).toString()}</TableCell>
</TableRow>
)
});
setDetails(txnsList);
isLoading(false);
}
if (loading) {
getTxnData();
return (
<Loader></Loader>
);
} else {
return (
<Card>
<CardHeader color="danger">
<h4 className={classes.cardTitleWhite}>Transactions List</h4>
<p className={classes.cardCategoryWhite}>
View all transactions for this Medicine
</p>
</CardHeader>
<CardBody>
<div className={classes.tableResponsive}>
<Table className={classes.table}>
<TableHead className={classes[ "dangerTableHeader" ]}>
<TableRow className={classes.tableHeadRow}>
<TableCell className={classes.tableCell + " " + classes.tableHeadCell} style={{ maxWidth: "75px" }}>TxnHash</TableCell>
<TableCell className={classes.tableCell + " " + classes.tableHeadCell} style={{ maxWidth: "50px" }} >From</TableCell>
<TableCell className={classes.tableCell + " " + classes.tableHeadCell} style={{ maxWidth: "50px" }} >To</TableCell>
<TableCell className={classes.tableCell + " " + classes.tableHeadCell} style={{ maxWidth: "75px" }} >Previous TxnHash</TableCell>
<TableCell className={classes.tableCell + " " + classes.tableHeadCell} style={{ maxWidth: "10px" }} >Lat</TableCell>
<TableCell className={classes.tableCell + " " + classes.tableHeadCell} style={{ maxWidth: "10px" }} >Lng</TableCell>
<TableCell className={classes.tableCell + " " + classes.tableHeadCell} style={{ maxWidth: "40px" }} >Timestamp</TableCell>
</TableRow>
</TableHead>
<TableBody>
{details}
</TableBody>
</Table>
</div>
</CardBody>
</Card>
);
}
}
Example #23
Source File: ResultRow.js From qasong with ISC License | 5 votes |
export default function ResultRow({ video, setNowPlaying, nowPlaying, queue, setQueue }) {
const classes = useStyles();
const [playing, setPlaying] = useState(false);
useEffect(() => {
if (nowPlaying && nowPlaying.videoId === video.videoId) {
setPlaying(true);
} else {
setPlaying(false);
}
}, [nowPlaying]);
function handlePlayButton(event) {
event.stopPropagation();
if (!playing) {
setNowPlaying(video);
setPlaying(true);
} else {
setNowPlaying({});
setPlaying(false);
}
}
function handleAddQueue(event) {
event.stopPropagation();
setQueue(
queue.concat({
...video,
qid: uuid(),
})
);
}
return (
<TableRow
className={classes.row}
key={video.videoId}
style={{ backgroundColor: playing && qasongOrange }}
>
<TableCell>
<IconButton onClick={handlePlayButton} aria-label="Play">
<PlayArrowIcon />
</IconButton>
</TableCell>
<TableCell>
<AddToQueueButton {...{ handleAddQueue }} />
</TableCell>
<TableCell>{video.title}</TableCell>
<TableCell>{video.author.name}</TableCell>
<TableCell>{numberWithCommas(video.views)}</TableCell>
<TableCell>
<CardMedia
onClick={handlePlayButton}
className={classes.media}
image={video.thumbnail}
/>
</TableCell>
</TableRow>
);
}
Example #24
Source File: SortableTable.js From covid-19 with MIT License | 5 votes |
SortableTable = (props) => {
const classes = useStyles();
const theme = useTheme();
const squish = useMediaQuery(theme.breakpoints.down('xs'));
const {columns, rows, defaultSortColumn} = props;
const [orderingBy, setOrderingBy] = React.useState(defaultSortColumn);
const [direction, setDirection] = React.useState(orderingBy.defaultDirection);
const sortFn = (a, b) =>
compareStable(
a, b, orderingBy.key, columns, direction === orderingBy.defaultDirection);
const sorted = [...rows].sort((a, b) =>
direction === 'asc' ? sortFn(a, b) : sortFn(b, a));
const createUpdateSort = (column) => () => {
setOrderingBy(column);
setDirection(
orderingBy === column
? opposite(direction) : column.defaultDirection);
};
return (
<Table size="small" className={squish ? classes.squishText : ''}>
<TableHead>
<TableRow>
{columns.map((column) =>
<TableCell key={column.key}>
<TableSortLabel
active={orderingBy.key === column.key}
direction={
orderingBy === column ? direction : column.defaultDirection}
hideSortIcon={squish}
onClick={createUpdateSort(column)}
>
{squish ? column.shortLabel || column.label : column.label}
</TableSortLabel>
</TableCell>
)}
</TableRow>
</TableHead>
<TableBody>
{sorted.map((row) =>
<TableRow key={row.id}>
{columns.map(({key, contextKey, renderShortNumber}) =>
<TableCell key={key}>
{render(row[key], renderShortNumber)}
{row[contextKey] && ` (${row[contextKey]})`}
</TableCell>
)}
</TableRow>
)}
</TableBody>
</Table>
);
}
Example #25
Source File: StatsDialog.js From dipact with GNU General Public License v3.0 | 5 votes |
makeRow(label, value) {
return (
<TableRow>
<TableCell>{label}</TableCell>
<TableCell>{value}</TableCell>
</TableRow>
);
}
Example #26
Source File: ProviderDetailContent.js From akashlytics-deploy with GNU General Public License v3.0 | 4 votes |
ProviderDetailContent = ({ provider, address }) => {
const classes = useStyles();
const activeResources = getTotalProviderResource(provider.active);
const availableResources = getTotalProviderResource(provider.available);
const pendingResources = getTotalProviderResource(provider.pending);
return (
<>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} size="small">
<TableBody>
<TableRow>
<TableCell component="th" scope="row">
<strong>Name</strong>
</TableCell>
<TableCell align="center">{provider.name}</TableCell>
</TableRow>
{address && (
<TableRow>
<TableCell component="th" scope="row">
<strong>Address</strong>
</TableCell>
<TableCell align="center">
<Address address={address} isCopyable />
</TableCell>
</TableRow>
)}
<TableRow>
<TableCell component="th" scope="row">
<strong>Email</strong>
</TableCell>
<TableCell align="center">{provider.email}</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row">
<strong>Website</strong>
</TableCell>
<TableCell align="center">{provider.website}</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row">
<strong>Akash version</strong>
</TableCell>
<TableCell align="center">{provider.akash?.version || "< 0.16.0"}</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row">
<strong>Kube version</strong>
</TableCell>
<TableCell align="center">{provider.kube ? `${provider.kube?.major}.${provider.kube?.minor}` : "unkown"}</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row">
<strong>Platform</strong>
</TableCell>
<TableCell align="center">{provider.kube?.platform || "unkown"}</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row">
<strong>Orders</strong>
</TableCell>
<TableCell align="center">{provider.orderCount}</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row">
<strong>Deployments</strong>
</TableCell>
<TableCell align="center">{provider.deploymentCount}</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row">
<strong>Leases</strong>
</TableCell>
<TableCell align="center">{provider.leaseCount}</TableCell>
</TableRow>
{provider.error && (
<TableRow>
<TableCell component="th" scope="row">
<strong>Error</strong>
</TableCell>
<TableCell align="center">{provider.error}</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<Box marginTop="1rem">
<Box marginBottom={1}>
<Typography variant="body2">
<strong>Immediately available resources</strong>
</Typography>
</Box>
<SpecDetail
cpuAmount={roundDecimal(availableResources.cpu - pendingResources.cpu)}
memoryAmount={availableResources.memory - pendingResources.memory}
storageAmount={availableResources.storage - pendingResources.storage}
size="medium"
color="primary"
/>
</Box>
<Box marginTop="1rem">
<Box marginBottom={1}>
<Typography variant="body2">
<Box component="strong" display="flex" alignItems="center">
Available resources{" "}
<Tooltip
classes={{ tooltip: classes.tooltip }}
arrow
interactive
title="Some of these resources might not be available right away because there might be open bids that haven't timed out yet."
>
<InfoIcon className={clsx(classes.tooltipIcon, classes.marginLeft)} />
</Tooltip>
</Box>
</Typography>
</Box>
<SpecDetail
cpuAmount={roundDecimal(availableResources.cpu)}
memoryAmount={availableResources.memory}
storageAmount={availableResources.storage}
size="small"
color="primary"
/>
</Box>
<Box marginTop="1rem">
<Box marginBottom={1}>
<Typography variant="body2">
<strong>Active resources</strong>
</Typography>
</Box>
<SpecDetail
cpuAmount={roundDecimal(activeResources.cpu)}
memoryAmount={activeResources.memory}
storageAmount={activeResources.storage}
size="small"
color="default"
/>
</Box>
<Box marginTop="1rem">
<Box marginBottom={1}>
<Typography variant="body2">
<strong>Pending resources</strong>
</Typography>
</Box>
<SpecDetail
cpuAmount={roundDecimal(pendingResources.cpu)}
memoryAmount={pendingResources.memory}
storageAmount={pendingResources.storage}
size="small"
color="default"
/>
</Box>
<Box marginTop="1rem">
<ProviderAttributes provider={provider} />
</Box>
</>
);
}
Example #27
Source File: Index.js From Designer-Client with GNU General Public License v3.0 | 4 votes |
export function ApiIndex(props) {
const dispatch = useDispatch();
const history = useHistory();
const classes = useStyles();
const apisStore = useSelector(state => state.apis);
const loading = useSelector(state => state.apis.loading);
// pagination 관련 state
const {page, perPage} = queryString.parse(props.location.search);
const [currentPage, setCurrentPage] = useState(page ? page : 1);
const [currentPerPage, setCurrentPerpage] = useState(perPage ? perPage : 10);
// 버전관리 관련 state
const [versionModalOpen, setVersionModalOpen] = useState(false);
const [applicationId, setApplicationId] = useState(null);
useEffect(() => {
dispatch(apiActions.getIndex(currentPage, currentPerPage)).then((response) => {
if(response.error) {
alertActions.handleError(dispatch, response.error);
return;
}
history.push(`/apis?page=${currentPage}&perPage=${currentPerPage}`)
})
}, [currentPage, currentPerPage])
const handlePageChange = (event, value) => {
if(value*currentPerPage > apisStore.totalCount) return;
setCurrentPage(value);
}
const handleVersionModal = (applicationId, open, rerender=false) => {
setApplicationId(applicationId);
setVersionModalOpen(open);
if(rerender) {
dispatch(apiActions.getIndex(currentPage, currentPerPage))
}
}
return (
<Container>
<PageTitle text="API 목록" />
<VersionDialog applicationId={applicationId} handleModal={handleVersionModal} setOpen={setVersionModalOpen} open={versionModalOpen} />
<TableContainer component={Paper}>
<Table aria-label="custom pagination table">
<TableHead>
<TableRow>
<TableCell align="center">id</TableCell>
<TableCell align="center">API 명</TableCell>
<TableCell align="center">버전</TableCell>
<TableCell align="center">호출주소</TableCell>
<TableCell align="center">Operation 갯수</TableCell>
<TableCell align="center">상태</TableCell>
{/* TODO: 최종 호출 시간 구현 후 변경 */}
<TableCell align="center">업데이트일</TableCell>
{/* TODO: 배포일 */}
<TableCell align="center">생성일</TableCell>
<TableCell/>
</TableRow>
</TableHead>
<TableBody>
{ loading &&
<TableLodingProgress colSpan={9}/>
}
{ !loading && apisStore.index && Array.isArray(apisStore.index) && apisStore.index.length <= 0 &&
<TableEmptyRow colSpan={9} text={"등록된 API가 없습니다. 신규 API를 추가해주세요."}/>
}
{ !loading && apisStore.index && Array.isArray(apisStore.index) && apisStore.index.map(apiId => {
const api = apisStore.dict[apiId];
return (
<TableRow key={`apis-index-table-${api.id}`}>
<TableCell align="center">{api.id}</TableCell>
<TableCell align="center">
<Link to={{ pathname: `/apis/${api.id}`, state: {api: api}}}>
{api.application.title}
</Link>
</TableCell>
<TableCell align="center">v{api.name}</TableCell>
<TableCell align="center">{`/${api.application.nameSpace}/v${api.name}`}</TableCell>
<TableCell align="center">{api.metas.length}</TableCell>
<TableCell align="center">{api.status}</TableCell>
<TableCell align="center">{moment(api.updatedAt).format('YYYY-MM-DD HH:mm:ss')}</TableCell>
<TableCell align="center">{moment(api.updatedAt).format('YYYY-MM-DD HH:mm:ss')}</TableCell>
<TableCell>
<Button
variant="outlined"
size="small"
color="primary"
component={Link}
className={classes.btnMargin}
to={{ pathname: `/apis/${api.id}`, state: {api: api}}}
>
API 관리
</Button>
<Button
variant="outlined"
size="small"
color="secondary"
onClick={() => handleVersionModal(api.applicationId, true)}
>
버전 관리
</Button>
</TableCell>
</TableRow>
)
})
}
</TableBody>
</Table>
</TableContainer>
<Box mt={4} alignItems="center" flexWrap="wrap" style={{textAlign: "center", display: "flex", alignItems: "center", justifyContent: "center"}}>
<Pagination
count={parseInt(apisStore.totalCount/apisStore.perPage) + (((apisStore.totalCount%apisStore.perPage) === 0) ? 0 : 1 )}
showFirstButton
showLastButton
variant="outlined"
shape="rounded"
size="large"
page={Number(currentPage)}
onChange={handlePageChange}/>
</Box>
<Grid container direction="column" justify="flex-end" alignItems="flex-end">
<Grid item>
<Button variant="outlined" color="primary" component={Link} to='/apis/new'>
신규 API 추가
</Button>
</Grid>
</Grid>
</Container>
)
}
Example #28
Source File: Dashboard.js From Registration-Login-and-CRUD-Action-using-MERN-stack with GNU General Public License v3.0 | 4 votes |
render() {
return (
<div>
{this.state.loading && <LinearProgress size={40} />}
<div>
<h2>Dashboard</h2>
<Button
className="button_style"
variant="contained"
color="primary"
size="small"
onClick={this.handleProductOpen}
>
Add Product
</Button>
<Button
className="button_style"
variant="contained"
size="small"
onClick={this.logOut}
>
Log Out
</Button>
</div>
{/* Edit Product */}
<Dialog
open={this.state.openProductEditModal}
onClose={this.handleProductClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">Edit Product</DialogTitle>
<DialogContent>
<TextField
id="standard-basic"
type="text"
autoComplete="off"
name="name"
value={this.state.name}
onChange={this.onChange}
placeholder="Product Name"
required
/><br />
<TextField
id="standard-basic"
type="text"
autoComplete="off"
name="desc"
value={this.state.desc}
onChange={this.onChange}
placeholder="Description"
required
/><br />
<TextField
id="standard-basic"
type="number"
autoComplete="off"
name="price"
value={this.state.price}
onChange={this.onChange}
placeholder="Price"
required
/><br />
<TextField
id="standard-basic"
type="number"
autoComplete="off"
name="discount"
value={this.state.discount}
onChange={this.onChange}
placeholder="Discount"
required
/><br /><br />
<Button
variant="contained"
component="label"
> Upload
<input
id="standard-basic"
type="file"
accept="image/*"
name="file"
value={this.state.file}
onChange={this.onChange}
id="fileInput"
placeholder="File"
hidden
/>
</Button>
{this.state.fileName}
</DialogContent>
<DialogActions>
<Button onClick={this.handleProductEditClose} color="primary">
Cancel
</Button>
<Button
disabled={this.state.name == '' || this.state.desc == '' || this.state.discount == '' || this.state.price == ''}
onClick={(e) => this.updateProduct()} color="primary" autoFocus>
Edit Product
</Button>
</DialogActions>
</Dialog>
{/* Add Product */}
<Dialog
open={this.state.openProductModal}
onClose={this.handleProductClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">Add Product</DialogTitle>
<DialogContent>
<TextField
id="standard-basic"
type="text"
autoComplete="off"
name="name"
value={this.state.name}
onChange={this.onChange}
placeholder="Product Name"
required
/><br />
<TextField
id="standard-basic"
type="text"
autoComplete="off"
name="desc"
value={this.state.desc}
onChange={this.onChange}
placeholder="Description"
required
/><br />
<TextField
id="standard-basic"
type="number"
autoComplete="off"
name="price"
value={this.state.price}
onChange={this.onChange}
placeholder="Price"
required
/><br />
<TextField
id="standard-basic"
type="number"
autoComplete="off"
name="discount"
value={this.state.discount}
onChange={this.onChange}
placeholder="Discount"
required
/><br /><br />
<Button
variant="contained"
component="label"
> Upload
<input
id="standard-basic"
type="file"
accept="image/*"
// inputProps={{
// accept: "image/*"
// }}
name="file"
value={this.state.file}
onChange={this.onChange}
id="fileInput"
placeholder="File"
hidden
required
/>
</Button>
{this.state.fileName}
</DialogContent>
<DialogActions>
<Button onClick={this.handleProductClose} color="primary">
Cancel
</Button>
<Button
disabled={this.state.name == '' || this.state.desc == '' || this.state.discount == '' || this.state.price == '' || this.state.file == null}
onClick={(e) => this.addProduct()} color="primary" autoFocus>
Add Product
</Button>
</DialogActions>
</Dialog>
<br />
<TableContainer>
<TextField
id="standard-basic"
type="search"
autoComplete="off"
name="search"
value={this.state.search}
onChange={this.onChange}
placeholder="Search by product name"
required
/>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell align="center">Name</TableCell>
<TableCell align="center">Image</TableCell>
<TableCell align="center">Description</TableCell>
<TableCell align="center">Price</TableCell>
<TableCell align="center">Discount</TableCell>
<TableCell align="center">Action</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.products.map((row) => (
<TableRow key={row.name}>
<TableCell align="center" component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="center"><img src={`http://localhost:2000/${row.image}`} width="70" height="70" /></TableCell>
<TableCell align="center">{row.desc}</TableCell>
<TableCell align="center">{row.price}</TableCell>
<TableCell align="center">{row.discount}</TableCell>
<TableCell align="center">
<Button
className="button_style"
variant="outlined"
color="primary"
size="small"
onClick={(e) => this.handleProductEditOpen(row)}
>
Edit
</Button>
<Button
className="button_style"
variant="outlined"
color="secondary"
size="small"
onClick={(e) => this.deleteProduct(row._id)}
>
Delete
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<br />
<Pagination count={this.state.pages} page={this.state.page} onChange={this.pageChange} color="primary" />
</TableContainer>
</div>
);
}
Example #29
Source File: CaptureTable.js From treetracker-admin-client with GNU Affero General Public License v3.0 | 4 votes |
CaptureTable = () => {
const {
filter,
rowsPerPage,
page,
order,
orderBy,
captures,
capture,
captureCount,
isLoading,
setPage,
setRowsPerPage,
setOrder,
setOrderBy,
setCapture,
getCaptureAsync,
} = useContext(CapturesContext);
const speciesContext = useContext(SpeciesContext);
const tagsContext = useContext(TagsContext);
const [isDetailsPaneOpen, setIsDetailsPaneOpen] = useState(false);
const [speciesLookup, setSpeciesLookup] = useState({});
const [tagLookup, setTagLookup] = useState({});
const [captureTagLookup, setCaptureTagLookup] = useState({});
const [isOpenExport, setOpenExport] = useState(false);
const [disableHoverListener, setDisableHoverListener] = useState(false);
const classes = useStyle();
useEffect(() => {
populateSpeciesLookup();
}, [speciesContext.speciesList]);
useEffect(() => {
populateTagLookup();
}, [tagsContext.tagList]);
const getCaptureTags = async () => {
// Don't do anything if there are no captures
if (!captures?.length) {
return;
}
// Get the capture tags for all of the displayed captures
const captureTags = await api.getCaptureTags({
captureIds: captures.map((c) => c.id),
});
// Populate a lookup for quick access when rendering the table
let lookup = {};
captureTags.forEach((captureTag) => {
if (!lookup[captureTag.treeId]) {
lookup[captureTag.treeId] = [];
}
lookup[captureTag.treeId].push(tagLookup[captureTag.tagId]);
});
setCaptureTagLookup(lookup);
};
useEffect(() => {
getCaptureTags();
}, [captures, tagLookup]);
const populateSpeciesLookup = async () => {
let species = {};
speciesContext.speciesList.forEach((s) => {
species[s.id] = s.name;
});
setSpeciesLookup(species);
};
const populateTagLookup = async () => {
let tags = {};
tagsContext.tagList.forEach((t) => {
tags[t.id] = t.tagName;
});
setTagLookup(tags);
};
const toggleDrawer = (id) => {
getCaptureAsync(id);
setIsDetailsPaneOpen(!isDetailsPaneOpen);
};
const createToggleDrawerHandler = (id) => {
return () => {
toggleDrawer(id);
};
};
const closeDrawer = () => {
setIsDetailsPaneOpen(false);
setDisableHoverListener(false);
setCapture({});
};
const handleOpenExport = () => {
setOpenExport(true);
};
const handlePageChange = (e, page) => {
setPage(page);
};
const handleRowsPerPageChange = (e) => {
setRowsPerPage(parseInt(e.target.value));
};
const createSortHandler = (attr) => {
return () => {
const newOrder = orderBy === attr && order === 'asc' ? 'desc' : 'asc';
const newOrderBy = attr;
setOrder(newOrder);
setOrderBy(newOrderBy);
};
};
const tablePagination = () => {
return (
<TablePagination
rowsPerPageOptions={[25, 50, 100, 250, 500]}
component="div"
count={captureCount || 0}
page={page}
rowsPerPage={rowsPerPage}
onChangePage={handlePageChange}
onChangeRowsPerPage={handleRowsPerPageChange}
/>
);
};
const enableTooltips = process.env.REACT_APP_ENABLE_TOOLTIPS === 'true';
return (
<Grid style={{ height: '100%', overflow: 'auto', textAlign: 'center' }}>
<Grid
container
direction="row"
justify="space-between"
alignItems="center"
>
<Typography variant="h5" className={classes.title}>
Captures
</Typography>
<Grid className={classes.cornerTable}>
<Button
variant="outlined"
color="primary"
startIcon={<GetApp />}
className={classes.buttonCsv}
onClick={handleOpenExport}
>
Export Captures
</Button>
<ExportCaptures
isOpen={isOpenExport}
handleClose={() => setOpenExport(false)}
columns={columns}
filter={filter}
speciesLookup={speciesLookup}
captureTagLookup={captureTagLookup}
/>
{tablePagination()}
</Grid>
</Grid>
<Table data-testid="captures-table">
<TableHead>
<TableRow>
{columns.map(({ attr, label, noSort }) => (
<TableCell
key={attr}
sortDirection={orderBy === attr ? order : false}
>
<TableSortLabel
active={orderBy === attr}
direction={orderBy === attr ? order : 'asc'}
onClick={createSortHandler(attr)}
disabled={noSort}
>
{label}
</TableSortLabel>
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody data-testid="captures-table-body">
{isLoading && !captures?.length ? (
<TableRow className={classes.loadingIndicator}>
<TableCell className={classes.loadingIndicator}>
<CircularProgress />
</TableCell>
</TableRow>
) : (
<>
{captures &&
captures.map((capture) => (
<Tooltip
key={capture.id}
placement="top"
arrow={true}
interactive={!disableHoverListener}
enterDelay={500}
enterNextDelay={500}
disableFocusListener={true}
disableHoverListener={disableHoverListener}
classes={{
tooltipPlacementTop: classes.tooltipTop,
arrow: classes.arrow,
}}
title={
enableTooltips ? (
<CaptureTooltip
capture={capture}
toggleDrawer={createToggleDrawerHandler}
/>
) : (
''
)
}
>
<TableRow
key={capture.id}
onClick={createToggleDrawerHandler(capture.id)}
className={classes.tableRow}
>
{columns.map(({ attr, renderer }, i) => (
<TableCell key={`${attr}_${i}`}>
{formatCell(
capture,
speciesLookup,
captureTagLookup[capture.id] || [],
attr,
renderer
)}
</TableCell>
))}
</TableRow>
</Tooltip>
))}
</>
)}
</TableBody>
</Table>
{tablePagination()}
<CaptureDetailProvider>
<CaptureDetailDialog
open={isDetailsPaneOpen}
capture={capture}
onClose={closeDrawer}
/>
</CaptureDetailProvider>
</Grid>
);
}