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}));
 53
 54interface Props {
 55  bug: BugFragment;
 56}
 57
 58/**
 59 * Component for bug title change
 60 * @param bug Selected bug in list page
 61 */
 62function BugTitleForm({ bug }: Props) {
 63  const [bugTitleEdition, setbugTitleEdition] = useState(false);
 64  const [setTitle, { loading, error }] = useSetTitleMutation();
 65  const [issueTitle, setIssueTitle] = useState(bug.title);
 66  const classes = useStyles();
 67  let issueTitleInput: any;
 68
 69  function isFormValid() {
 70    if (issueTitleInput) {
 71      return issueTitleInput.value.length > 0 ? true : false;
 72    } else {
 73      return false;
 74    }
 75  }
 76
 77  function submitNewTitle() {
 78    if (!isFormValid()) return;
 79    setTitle({
 80      variables: {
 81        input: {
 82          prefix: bug.humanId,
 83          title: issueTitleInput.value,
 84        },
 85      },
 86      refetchQueries: [
 87        // TODO: update the cache instead of refetching
 88        {
 89          query: TimelineDocument,
 90          variables: {
 91            id: bug.id,
 92            first: 100,
 93          },
 94        },
 95      ],
 96      awaitRefetchQueries: true,
 97    }).then(() => setbugTitleEdition(false));
 98  }
 99
100  function cancelChange() {
101    setIssueTitle(bug.title);
102    setbugTitleEdition(false);
103  }
104
105  function editableBugTitle() {
106    return (
107      <form className={classes.headerTitle} onSubmit={submitNewTitle}>
108        <TextField
109          inputRef={(node) => {
110            issueTitleInput = node;
111          }}
112          variant="outlined"
113          fullWidth
114          margin="dense"
115          value={issueTitle}
116          onChange={(event: any) => setIssueTitle(event.target.value)}
117        />
118        <div className={classes.editButtonContainer}>
119          <Button
120            size="small"
121            variant="contained"
122            type="submit"
123            disabled={issueTitle.length === 0}
124          >
125            Save
126          </Button>
127          <Button size="small" onClick={() => cancelChange()}>
128            Cancel
129          </Button>
130        </div>
131      </form>
132    );
133  }
134
135  function readonlyBugTitle() {
136    return (
137      <div className={classes.headerTitle}>
138        <div>
139          <span className={classes.readOnlyTitle}>{bug.title}</span>
140          <span className={classes.readOnlyId}>{bug.humanId}</span>
141        </div>
142        <IfLoggedIn>
143          {() => (
144            <div className={classes.editButtonContainer}>
145              <Button
146                size="small"
147                variant="contained"
148                onClick={() => setbugTitleEdition(!bugTitleEdition)}
149              >
150                Edit
151              </Button>
152              <Button
153                className={classes.greenButton}
154                size="small"
155                variant="contained"
156                href="/new"
157              >
158                New issue
159              </Button>
160            </div>
161          )}
162        </IfLoggedIn>
163      </div>
164    );
165  }
166
167  if (loading) return <div>Loading...</div>;
168  if (error) return <div>Error</div>;
169
170  return (
171    <div className={classes.header}>
172      {bugTitleEdition ? editableBugTitle() : readonlyBugTitle()}
173      <div className="classes.headerSubtitle">
174        <Typography color={'textSecondary'}>
175          <Author author={bug.author} />
176          {' opened this bug '}
177          <Date date={bug.createdAt} />
178        </Typography>
179      </div>
180    </div>
181  );
182}
183
184export default BugTitleForm;