123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- import { FC, useEffect, useRef, useState } from 'react';
- import React from 'react';
- import { makeStyles } from '@material-ui/core/styles';
- import Table from '@material-ui/core/Table';
- import TableBody from '@material-ui/core/TableBody';
- import TableCell from '@material-ui/core/TableCell';
- import TableContainer from '@material-ui/core/TableContainer';
- import TableRow from '@material-ui/core/TableRow';
- import Checkbox from '@material-ui/core/Checkbox';
- import { TableType } from './Types';
- import { Box, Button, Typography } from '@material-ui/core';
- import EnhancedTableHead from './TableHead';
- import { stableSort, getComparator } from './Utils';
- import Copy from '../../components/copy/Copy';
- import ActionBar from './ActionBar';
- import LoadingTable from './LoadingTable';
- const useStyles = makeStyles(theme => ({
- root: {
- // minHeight: '29vh',
- width: '100%',
- flexGrow: 1,
- // flexBasis: 0,
- // change scrollbar style
- '&::-webkit-scrollbar': {
- width: '8px',
- },
- '&::-webkit-scrollbar-track': {
- backgroundColor: '#f9f9f9',
- },
- '&::-webkit-scrollbar-thumb': {
- borderRadius: '8px',
- backgroundColor: '#eee',
- },
- },
- box: {
- backgroundColor: '#fff',
- },
- paper: {
- width: '100%',
- marginBottom: theme.spacing(2),
- },
- table: {
- minWidth: 750,
- },
- tableCell: {
- background: theme.palette.common.white,
- paddingLeft: theme.spacing(2),
- },
- hoverActionCell: {
- transition: '0.2s all',
- padding: 0,
- width: '50px',
- backgroundColor: '#fff',
- '& span': {
- opacity: 0,
- },
- },
- checkbox: {
- background: theme.palette.common.white,
- },
- rowHover: {
- '&:hover': {
- backgroundColor: '#f3fcfe !important',
- '& td': {
- background: 'inherit',
- },
- '& $hoverActionCell': {
- backgroundColor: theme.palette.primary.main,
- '& span': {
- opacity: 1,
- },
- },
- },
- },
- cell: {
- '& p': {
- display: 'inline-block',
- verticalAlign: 'middle',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- whiteSpace: 'nowrap',
- maxWidth: '300px',
- fontSize: '12.8px',
- },
- '& button': {
- textTransform: 'inherit',
- justifyContent: 'flex-start',
- },
- // '& svg': {
- // color: 'rgba(0, 0, 0, 0.33)',
- // },
- },
- noData: {
- paddingTop: theme.spacing(6),
- textAlign: 'center',
- letterSpacing: '0.5px',
- color: 'rgba(0, 0, 0, 0.6)',
- },
- }));
- const EnhancedTable: FC<TableType> = props => {
- const {
- selected,
- onSelected,
- isSelected,
- onSelectedAll,
- rows = [],
- colDefinitions,
- primaryKey,
- openCheckBox = true,
- disableSelect,
- noData,
- showHoverStyle,
- isLoading,
- } = props;
- const classes = useStyles();
- const [order, setOrder] = React.useState('asc');
- const [orderBy, setOrderBy] = React.useState<string>('');
- const [tableMouseStatus, setTableMouseStatus] = React.useState<boolean[]>([]);
- const [loadingRowCount, setLoadingRowCount] = useState<number>(0);
- const containerRef = useRef(null);
- const handleRequestSort = (event: any, property: string) => {
- const isAsc = orderBy === property && order === 'asc';
- setOrder(isAsc ? 'desc' : 'asc');
- setOrderBy(property);
- };
- useEffect(() => {
- const height: number = (containerRef.current as any)!.offsetHeight;
- // table header 57px, loading row 40px
- const count = Math.floor((height - 57) / 40);
- setLoadingRowCount(count);
- }, []);
- return (
- <TableContainer ref={containerRef} className={classes.root}>
- <Box height="100%" className={classes.box}>
- <Table
- stickyHeader
- className={classes.table}
- aria-labelledby="tableTitle"
- size="medium"
- aria-label="enhanced table"
- >
- <EnhancedTableHead
- colDefinitions={colDefinitions}
- numSelected={selected.length}
- order={order}
- orderBy={orderBy}
- onSelectAllClick={onSelectedAll}
- onRequestSort={handleRequestSort}
- rowCount={rows.length}
- openCheckBox={openCheckBox}
- />
- {!isLoading && (
- <TableBody>
- {rows && rows.length ? (
- stableSort(rows, getComparator(order, orderBy)).map(
- (row, index) => {
- const isItemSelected = isSelected(row);
- const labelId = `enhanced-table-checkbox-${index}`;
- const handleMouseEnter = () => {
- setTableMouseStatus(v => {
- const copy = [...v];
- copy[index] = true;
- return copy;
- });
- };
- const handleMouseLeave = () =>
- setTableMouseStatus(v => {
- const copy = [...v];
- copy[index] = false;
- return copy;
- });
- return (
- <TableRow
- hover={showHoverStyle}
- key={'row' + row[primaryKey] + index}
- onClick={event => onSelected(event, row)}
- role="checkbox"
- aria-checked={isItemSelected}
- tabIndex={-1}
- selected={isItemSelected && !disableSelect}
- classes={{
- hover: classes.rowHover,
- }}
- onMouseEnter={handleMouseEnter}
- onMouseLeave={handleMouseLeave}
- >
- {openCheckBox && (
- <TableCell
- padding="checkbox"
- className={classes.checkbox}
- >
- <Checkbox
- checked={isItemSelected}
- color="primary"
- inputProps={{ 'aria-labelledby': labelId }}
- />
- </TableCell>
- )}
- {colDefinitions.map((colDef, i) => {
- const { actionBarConfigs = [], needCopy = false } =
- colDef;
- const cellStyle = colDef.getStyle
- ? colDef.getStyle(row[colDef.id])
- : {};
- return colDef.showActionCell ? (
- <TableCell
- className={`${classes.cell} ${
- classes.tableCell
- } ${
- colDef.isHoverAction
- ? classes.hoverActionCell
- : ''
- }`}
- key="manage"
- style={cellStyle}
- >
- <ActionBar
- showLabel={tableMouseStatus[index]}
- configs={actionBarConfigs}
- isHoverType={colDef.isHoverAction}
- row={row}
- ></ActionBar>
- </TableCell>
- ) : (
- <TableCell
- key={'cell' + row[primaryKey] + i}
- padding={i === 0 ? 'none' : 'default'}
- align={colDef.align || 'left'}
- className={`${classes.cell} ${classes.tableCell}`}
- style={cellStyle}
- >
- {row[colDef.id] &&
- typeof row[colDef.id] === 'string' ? (
- <Typography title={row[colDef.id]}>
- {colDef.onClick ? (
- <Button
- color="primary"
- data-data={row[colDef.id]}
- data-index={index}
- onClick={e => {
- colDef.onClick &&
- colDef.onClick(e, row);
- }}
- >
- {row[colDef.id]}
- </Button>
- ) : (
- row[colDef.id]
- )}
- </Typography>
- ) : (
- <>
- {colDef.onClick ? (
- <Button
- color="primary"
- data-data={row[colDef.id]}
- data-index={index}
- onClick={e => {
- colDef.onClick &&
- colDef.onClick(e, row);
- }}
- >
- {row[colDef.id]}
- </Button>
- ) : (
- row[colDef.id]
- )}
- </>
- )}
- {needCopy && row[colDef.id] && (
- <Copy data={row[colDef.id]} />
- )}
- </TableCell>
- );
- })}
- </TableRow>
- );
- }
- )
- ) : (
- <tr>
- <td
- className={classes.noData}
- colSpan={colDefinitions.length}
- >
- {noData}
- </td>
- </tr>
- )}
- </TableBody>
- )}
- </Table>
- {isLoading && <LoadingTable count={loadingRowCount} />}
- </Box>
- </TableContainer>
- );
- };
- export default EnhancedTable;
|