1import React, { useState } from 'react';
2
3import { Button, makeStyles, Typography } from '@material-ui/core';
4
5import { TimelineDocument } from '../../pages/bug/TimelineQuery.generated';
6import IfLoggedIn from '../IfLoggedIn/IfLoggedIn';
7import Author from 'src/components/Author';
8import Date from 'src/components/Date';
9import { BugFragment } from 'src/pages/bug/Bug.generated';
10
11import BugTitleInput from './BugTitleInput';
12import { useSetTitleMutation } from './SetTitle.generated';
13
14/**
15 * Css in JS styles
16 */
17const useStyles = makeStyles((theme) => ({
18 header: {
19 display: 'flex',
20 flexDirection: 'column',
21 },
22 headerTitle: {
23 display: 'flex',
24 flexDirection: 'row',
25 justifyContent: 'space-between',
26 },
27 readOnlyTitle: {
28 ...theme.typography.h5,
29 },
30 readOnlyId: {
31 ...theme.typography.subtitle1,
32 marginLeft: theme.spacing(1),
33 },
34 editButtonContainer: {
35 display: 'flex',
36 flexDirection: 'row',
37 justifyContent: 'flex-start',
38 alignItems: 'center',
39 minWidth: 200,
40 marginLeft: theme.spacing(2),
41 },
42 greenButton: {
43 marginLeft: theme.spacing(1),
44 backgroundColor: theme.palette.success.main,
45 color: theme.palette.success.contrastText,
46 '&:hover': {
47 backgroundColor: theme.palette.success.dark,
48 color: theme.palette.primary.contrastText,
49 },
50 },
51 saveButton: {
52 marginRight: theme.spacing(1),
53 },
54}));
55
56interface Props {
57 bug: BugFragment;
58}
59
60/**
61 * Component for bug title change
62 * @param bug Selected bug in list page
63 */
64function BugTitleForm({ bug }: Props) {
65 const [bugTitleEdition, setbugTitleEdition] = useState(false);
66 const [setTitle, { loading, error }] = useSetTitleMutation();
67 const [issueTitle, setIssueTitle] = useState(bug.title);
68 const classes = useStyles();
69 let issueTitleInput: any;
70
71 function isFormValid() {
72 if (issueTitleInput) {
73 return issueTitleInput.value.length > 0;
74 } else {
75 return false;
76 }
77 }
78
79 function submitNewTitle() {
80 if (!isFormValid()) return;
81 setTitle({
82 variables: {
83 input: {
84 prefix: bug.humanId,
85 title: issueTitleInput.value,
86 },
87 },
88 refetchQueries: [
89 // TODO: update the cache instead of refetching
90 {
91 query: TimelineDocument,
92 variables: {
93 id: bug.id,
94 first: 100,
95 },
96 },
97 ],
98 awaitRefetchQueries: true,
99 }).then(() => setbugTitleEdition(false));
100 }
101
102 function cancelChange() {
103 setIssueTitle(bug.title);
104 setbugTitleEdition(false);
105 }
106
107 function editableBugTitle() {
108 return (
109 <form className={classes.headerTitle} onSubmit={submitNewTitle}>
110 <BugTitleInput
111 inputRef={(node) => {
112 issueTitleInput = node;
113 }}
114 label="Title"
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 bug
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;