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