BugTitleForm.tsx

  1import React, { useState } from 'react';
  2
  3import {
  4  Button,
  5  fade,
  6  makeStyles,
  7  TextField,
  8  Typography,
  9} from '@material-ui/core';
 10
 11import { TimelineDocument } from '../../pages/bug/TimelineQuery.generated';
 12import IfLoggedIn from '../IfLoggedIn/IfLoggedIn';
 13import Author from 'src/components/Author';
 14import Date from 'src/components/Date';
 15import { BugFragment } from 'src/pages/bug/Bug.generated';
 16
 17import { useSetTitleMutation } from './SetTitle.generated';
 18
 19/**
 20 * Css in JS styles
 21 */
 22const useStyles = makeStyles((theme) => ({
 23  header: {
 24    display: 'flex',
 25    flexDirection: 'column',
 26  },
 27  headerTitle: {
 28    display: 'flex',
 29    flexDirection: 'row',
 30    justifyContent: 'space-between',
 31  },
 32  readOnlyTitle: {
 33    ...theme.typography.h5,
 34  },
 35  readOnlyId: {
 36    ...theme.typography.subtitle1,
 37    marginLeft: theme.spacing(1),
 38  },
 39  editButtonContainer: {
 40    display: 'flex',
 41    flexDirection: 'row',
 42    justifyContent: 'flex-start',
 43    alignItems: 'center',
 44    minWidth: 200,
 45    marginLeft: theme.spacing(2),
 46  },
 47  greenButton: {
 48    marginLeft: theme.spacing(1),
 49    backgroundColor: theme.palette.success.main,
 50    color: theme.palette.success.contrastText,
 51  },
 52  saveButton: {
 53    marginRight: theme.spacing(1),
 54  },
 55}));
 56
 57interface Props {
 58  bug: BugFragment;
 59}
 60
 61/**
 62 * Component for bug title change
 63 * @param bug Selected bug in list page
 64 */
 65function BugTitleForm({ bug }: Props) {
 66  const [bugTitleEdition, setbugTitleEdition] = useState(false);
 67  const [setTitle, { loading, error }] = useSetTitleMutation();
 68  const [issueTitle, setIssueTitle] = useState(bug.title);
 69  const classes = useStyles();
 70  let issueTitleInput: any;
 71
 72  function isFormValid() {
 73    if (issueTitleInput) {
 74      return issueTitleInput.value.length > 0 ? true : false;
 75    } else {
 76      return false;
 77    }
 78  }
 79
 80  function submitNewTitle() {
 81    if (!isFormValid()) return;
 82    setTitle({
 83      variables: {
 84        input: {
 85          prefix: bug.humanId,
 86          title: issueTitleInput.value,
 87        },
 88      },
 89      refetchQueries: [
 90        // TODO: update the cache instead of refetching
 91        {
 92          query: TimelineDocument,
 93          variables: {
 94            id: bug.id,
 95            first: 100,
 96          },
 97        },
 98      ],
 99      awaitRefetchQueries: true,
100    }).then(() => setbugTitleEdition(false));
101  }
102
103  function cancelChange() {
104    setIssueTitle(bug.title);
105    setbugTitleEdition(false);
106  }
107
108  function editableBugTitle() {
109    return (
110      <form className={classes.headerTitle} onSubmit={submitNewTitle}>
111        <TextField
112          inputRef={(node) => {
113            issueTitleInput = node;
114          }}
115          variant="outlined"
116          fullWidth
117          margin="dense"
118          value={issueTitle}
119          onChange={(event: any) => setIssueTitle(event.target.value)}
120        />
121        <div className={classes.editButtonContainer}>
122          <Button
123            className={classes.saveButton}
124            size="small"
125            variant="contained"
126            type="submit"
127            disabled={issueTitle.length === 0}
128          >
129            Save
130          </Button>
131          <Button size="small" onClick={() => cancelChange()}>
132            Cancel
133          </Button>
134        </div>
135      </form>
136    );
137  }
138
139  function readonlyBugTitle() {
140    return (
141      <div className={classes.headerTitle}>
142        <div>
143          <span className={classes.readOnlyTitle}>{bug.title}</span>
144          <span className={classes.readOnlyId}>{bug.humanId}</span>
145        </div>
146        <IfLoggedIn>
147          {() => (
148            <div className={classes.editButtonContainer}>
149              <Button
150                size="small"
151                variant="contained"
152                onClick={() => setbugTitleEdition(!bugTitleEdition)}
153              >
154                Edit
155              </Button>
156              <Button
157                className={classes.greenButton}
158                size="small"
159                variant="contained"
160                href="/new"
161              >
162                New issue
163              </Button>
164            </div>
165          )}
166        </IfLoggedIn>
167      </div>
168    );
169  }
170
171  if (loading) return <div>Loading...</div>;
172  if (error) return <div>Error</div>;
173
174  return (
175    <div className={classes.header}>
176      {bugTitleEdition ? editableBugTitle() : readonlyBugTitle()}
177      <div className="classes.headerSubtitle">
178        <Typography color={'textSecondary'}>
179          <Author author={bug.author} />
180          {' opened this bug '}
181          <Date date={bug.createdAt} />
182        </Typography>
183      </div>
184    </div>
185  );
186}
187
188export default BugTitleForm;