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