CommentForm.tsx

  1import { useState, useRef } from 'react';
  2import * as React from 'react';
  3
  4import Button from '@material-ui/core/Button';
  5import Paper from '@material-ui/core/Paper';
  6import { makeStyles, Theme } from '@material-ui/core/styles';
  7
  8import CommentInput from '../../components/CommentInput/CommentInput';
  9import CloseBugButton from 'src/components/CloseBugButton';
 10import CloseBugWithCommentButton from 'src/components/CloseBugWithCommentButton';
 11import ReopenBugButton from 'src/components/ReopenBugButton';
 12import ReopenBugWithCommentButton from 'src/components/ReopenBugWithCommentButton';
 13
 14import { BugFragment } from './Bug.generated';
 15import { useAddCommentMutation } from './CommentForm.generated';
 16import { TimelineDocument } from './TimelineQuery.generated';
 17
 18type StyleProps = { loading: boolean };
 19const useStyles = makeStyles<Theme, StyleProps>((theme) => ({
 20  container: {
 21    padding: theme.spacing(0, 2, 2, 2),
 22  },
 23  actions: {
 24    display: 'flex',
 25    gap: '1em',
 26    justifyContent: 'flex-end',
 27  },
 28  greenButton: {
 29    marginLeft: '8px',
 30    backgroundColor: theme.palette.success.main,
 31    color: theme.palette.success.contrastText,
 32    '&:hover': {
 33      backgroundColor: theme.palette.success.dark,
 34      color: theme.palette.primary.contrastText,
 35    },
 36  },
 37}));
 38
 39type Props = {
 40  bug: BugFragment;
 41};
 42
 43function CommentForm({ bug }: Props) {
 44  const [addComment, { loading }] = useAddCommentMutation();
 45  const [issueComment, setIssueComment] = useState('');
 46  const [inputProp, setInputProp] = useState<any>('');
 47  const classes = useStyles({ loading });
 48  const form = useRef<HTMLFormElement>(null);
 49
 50  const submit = () => {
 51    addComment({
 52      variables: {
 53        input: {
 54          prefix: bug.id,
 55          message: issueComment,
 56        },
 57      },
 58      refetchQueries: [
 59        // TODO: update the cache instead of refetching
 60        {
 61          query: TimelineDocument,
 62          variables: {
 63            id: bug.id,
 64            first: 100,
 65          },
 66        },
 67      ],
 68      awaitRefetchQueries: true,
 69    }).then(() => resetForm());
 70  };
 71
 72  function resetForm() {
 73    setInputProp({
 74      value: '',
 75    });
 76  }
 77
 78  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
 79    e.preventDefault();
 80    if (issueComment.length > 0) submit();
 81  };
 82
 83  function getBugStatusButton() {
 84    if (bug.status === 'OPEN' && issueComment.length > 0) {
 85      return (
 86        <CloseBugWithCommentButton
 87          bug={bug}
 88          comment={issueComment}
 89          postClick={resetForm}
 90        />
 91      );
 92    }
 93    if (bug.status === 'OPEN') {
 94      return <CloseBugButton bug={bug} />;
 95    }
 96    if (bug.status === 'CLOSED' && issueComment.length > 0) {
 97      return (
 98        <ReopenBugWithCommentButton
 99          bug={bug}
100          comment={issueComment}
101          postClick={resetForm}
102        />
103      );
104    }
105    return <ReopenBugButton bug={bug} />;
106  }
107
108  return (
109    <Paper className={classes.container}>
110      <form onSubmit={handleSubmit} ref={form}>
111        <CommentInput
112          inputProps={inputProp}
113          loading={loading}
114          onChange={(comment: string) => setIssueComment(comment)}
115        />
116        <div className={classes.actions}>
117          {getBugStatusButton()}
118          <Button
119            className={classes.greenButton}
120            variant="contained"
121            color="primary"
122            type="submit"
123            disabled={loading || issueComment.length === 0}
124          >
125            Comment
126          </Button>
127        </div>
128      </form>
129    </Paper>
130  );
131}
132
133export default CommentForm;