1import React, { useState } from 'react';
2import { Link } from 'react-router-dom';
3
4import { Button, makeStyles, Typography } from '@material-ui/core';
5
6import { TimelineDocument } from '../../pages/bug/TimelineQuery.generated';
7import IfLoggedIn from '../IfLoggedIn/IfLoggedIn';
8import Author from 'src/components/Author';
9import Date from 'src/components/Date';
10import { BugFragment } from 'src/pages/bug/Bug.generated';
11
12import BugTitleInput from './BugTitleInput';
13import { useSetTitleMutation } from './SetTitle.generated';
14
15/**
16 * Css in JS styles
17 */
18const useStyles = makeStyles((theme) => ({
19 header: {
20 display: 'flex',
21 flexDirection: 'column',
22 },
23 headerTitle: {
24 display: 'flex',
25 flexDirection: 'row',
26 justifyContent: 'space-between',
27 },
28 readOnlyTitle: {
29 ...theme.typography.h5,
30 },
31 readOnlyId: {
32 ...theme.typography.subtitle1,
33 marginLeft: theme.spacing(1),
34 },
35 editButtonContainer: {
36 display: 'flex',
37 flexDirection: 'row',
38 justifyContent: 'flex-start',
39 alignItems: 'center',
40 minWidth: 200,
41 marginLeft: theme.spacing(2),
42 },
43 greenButton: {
44 marginLeft: theme.spacing(1),
45 backgroundColor: theme.palette.success.main,
46 color: theme.palette.success.contrastText,
47 '&:hover': {
48 backgroundColor: theme.palette.success.dark,
49 color: theme.palette.primary.contrastText,
50 },
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;
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 <BugTitleInput
112 inputRef={(node) => {
113 issueTitleInput = node;
114 }}
115 label="Title"
116 variant="outlined"
117 fullWidth
118 margin="dense"
119 value={issueTitle}
120 onChange={(event: any) => setIssueTitle(event.target.value)}
121 />
122 <div className={classes.editButtonContainer}>
123 <Button
124 className={classes.saveButton}
125 size="small"
126 variant="contained"
127 type="submit"
128 disabled={issueTitle.length === 0}
129 >
130 Save
131 </Button>
132 <Button size="small" onClick={() => cancelChange()}>
133 Cancel
134 </Button>
135 </div>
136 </form>
137 );
138 }
139
140 function readonlyBugTitle() {
141 return (
142 <div className={classes.headerTitle}>
143 <div>
144 <span className={classes.readOnlyTitle}>{bug.title}</span>
145 <span className={classes.readOnlyId}>{bug.humanId}</span>
146 </div>
147 <IfLoggedIn>
148 {() => (
149 <div className={classes.editButtonContainer}>
150 <Button
151 size="small"
152 variant="contained"
153 onClick={() => setbugTitleEdition(!bugTitleEdition)}
154 >
155 Edit
156 </Button>
157 <Button
158 className={classes.greenButton}
159 size="small"
160 variant="contained"
161 component={Link}
162 to="/new"
163 >
164 New bug
165 </Button>
166 </div>
167 )}
168 </IfLoggedIn>
169 </div>
170 );
171 }
172
173 if (loading) return <div>Loading...</div>;
174 if (error) return <div>Error</div>;
175
176 return (
177 <div className={classes.header}>
178 {bugTitleEdition ? editableBugTitle() : readonlyBugTitle()}
179 <div className="classes.headerSubtitle">
180 <Typography color={'textSecondary'}>
181 <Author author={bug.author} />
182 {' opened this bug '}
183 <Date date={bug.createdAt} />
184 </Typography>
185 </div>
186 </div>
187 );
188}
189
190export default BugTitleForm;