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