BugRow.tsx

  1import React from 'react';
  2import { Link } from 'react-router-dom';
  3
  4import Grid from '@material-ui/core/Grid';
  5import TableCell from '@material-ui/core/TableCell/TableCell';
  6import TableRow from '@material-ui/core/TableRow/TableRow';
  7import Tooltip from '@material-ui/core/Tooltip/Tooltip';
  8import { makeStyles } from '@material-ui/core/styles';
  9import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline';
 10import CommentOutlinedIcon from '@material-ui/icons/CommentOutlined';
 11import ErrorOutline from '@material-ui/icons/ErrorOutline';
 12
 13import Date from 'src/components/Date';
 14import Label from 'src/components/Label';
 15import { Status } from 'src/gqlTypes';
 16
 17import { BugRowFragment } from './BugRow.generated';
 18
 19type OpenClosedProps = { className: string };
 20const Open = ({ className }: OpenClosedProps) => (
 21  <Tooltip title="Open">
 22    <ErrorOutline htmlColor="#28a745" className={className} />
 23  </Tooltip>
 24);
 25
 26const Closed = ({ className }: OpenClosedProps) => (
 27  <Tooltip title="Closed">
 28    <CheckCircleOutline htmlColor="#cb2431" className={className} />
 29  </Tooltip>
 30);
 31
 32type StatusProps = { className: string; status: Status };
 33const BugStatus: React.FC<StatusProps> = ({
 34  status,
 35  className,
 36}: StatusProps) => {
 37  switch (status) {
 38    case 'OPEN':
 39      return <Open className={className} />;
 40    case 'CLOSED':
 41      return <Closed className={className} />;
 42    default:
 43      return <p>{'unknown status ' + status}</p>;
 44  }
 45};
 46
 47const useStyles = makeStyles((theme) => ({
 48  cell: {
 49    display: 'flex',
 50    alignItems: 'center',
 51    padding: theme.spacing(1),
 52    '& a': {
 53      textDecoration: 'none',
 54    },
 55  },
 56  status: {
 57    margin: theme.spacing(1, 2),
 58  },
 59  expand: {
 60    width: '100%',
 61    lineHeight: '20px',
 62  },
 63  title: {
 64    display: 'inline',
 65    color: theme.palette.text.primary,
 66    fontSize: '1.3rem',
 67    fontWeight: 500,
 68  },
 69  details: {
 70    lineHeight: '1.5rem',
 71    color: theme.palette.text.secondary,
 72  },
 73  labels: {
 74    paddingLeft: theme.spacing(1),
 75    '& > *': {
 76      display: 'inline-block',
 77    },
 78  },
 79  commentCount: {
 80    fontSize: '1rem',
 81    marginLeft: theme.spacing(0.5),
 82  },
 83}));
 84
 85type Props = {
 86  bug: BugRowFragment;
 87};
 88
 89function BugRow({ bug }: Props) {
 90  const classes = useStyles();
 91  // Subtract 1 from totalCount as 1 comment is the bug description
 92  const commentCount = bug.comments.totalCount - 1;
 93  return (
 94    <TableRow hover>
 95      <TableCell className={classes.cell}>
 96        <BugStatus status={bug.status} className={classes.status} />
 97        <div className={classes.expand}>
 98          <Link to={'bug/' + bug.humanId}>
 99            <div className={classes.expand}>
100              <span className={classes.title}>{bug.title}</span>
101              {bug.labels.length > 0 && (
102                <span className={classes.labels}>
103                  {bug.labels.map((l) => (
104                    <Label key={l.name} label={l} />
105                  ))}
106                </span>
107              )}
108            </div>
109          </Link>
110          <div className={classes.details}>
111            {bug.humanId} opened&nbsp;
112            <Date date={bug.createdAt} />
113            &nbsp;by {bug.author.displayName}
114          </div>
115        </div>
116      </TableCell>
117      <TableCell>
118        {commentCount > 0 && (
119          <Grid container wrap="nowrap">
120            <Grid item>
121              <CommentOutlinedIcon aria-label="Comment count" />
122            </Grid>
123            <Grid item>
124              <span className={classes.commentCount}>{commentCount}</span>
125            </Grid>
126          </Grid>
127        )}
128      </TableCell>
129    </TableRow>
130  );
131}
132
133export default BugRow;