mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-15 02:01:43 +03:00
commit
fd8d11030b
181
webui/src/components/BugTitleForm/BugTitleForm.tsx
Normal file
181
webui/src/components/BugTitleForm/BugTitleForm.tsx
Normal file
@ -0,0 +1,181 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
fade,
|
||||
makeStyles,
|
||||
TextField,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
|
||||
import { TimelineDocument } from '../../pages/bug/TimelineQuery.generated';
|
||||
import Author from 'src/components/Author';
|
||||
import Date from 'src/components/Date';
|
||||
import { BugFragment } from 'src/pages/bug/Bug.generated';
|
||||
|
||||
import { useSetTitleMutation } from './SetTitle.generated';
|
||||
|
||||
/**
|
||||
* Css in JS styles
|
||||
*/
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
header: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
headerTitle: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
readOnlyTitle: {
|
||||
...theme.typography.h5,
|
||||
},
|
||||
readOnlyId: {
|
||||
...theme.typography.subtitle1,
|
||||
marginLeft: theme.spacing(1),
|
||||
},
|
||||
editButtonContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
minWidth: 200,
|
||||
marginLeft: theme.spacing(2),
|
||||
},
|
||||
titleInput: {
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
borderColor: fade(theme.palette.primary.main, 0.2),
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '1px',
|
||||
backgroundColor: fade(theme.palette.primary.main, 0.05),
|
||||
padding: theme.spacing(0, 0),
|
||||
minWidth: 336,
|
||||
transition: theme.transitions.create([
|
||||
'width',
|
||||
'borderColor',
|
||||
'backgroundColor',
|
||||
]),
|
||||
},
|
||||
}));
|
||||
|
||||
interface Props {
|
||||
bug: BugFragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component for bug title change
|
||||
* @param bug Selected bug in list page
|
||||
*/
|
||||
function BugTitleForm({ bug }: Props) {
|
||||
const [bugTitleEditable, setBugTitleEditable] = useState(false);
|
||||
const [setTitle, { loading, error }] = useSetTitleMutation();
|
||||
const [issueTitle, setIssueTitle] = useState(bug.title);
|
||||
const classes = useStyles();
|
||||
let issueTitleInput: any;
|
||||
|
||||
function isFormValid() {
|
||||
if (issueTitleInput) {
|
||||
return issueTitleInput.value.length > 0 ? true : false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function submitNewTitle() {
|
||||
if (!isFormValid()) return;
|
||||
setTitle({
|
||||
variables: {
|
||||
input: {
|
||||
prefix: bug.humanId,
|
||||
title: issueTitleInput.value,
|
||||
},
|
||||
},
|
||||
refetchQueries: [
|
||||
// TODO: update the cache instead of refetching
|
||||
{
|
||||
query: TimelineDocument,
|
||||
variables: {
|
||||
id: bug.id,
|
||||
first: 100,
|
||||
},
|
||||
},
|
||||
],
|
||||
awaitRefetchQueries: true,
|
||||
}).then(() => setBugTitleEditable(false));
|
||||
}
|
||||
|
||||
function cancelChange() {
|
||||
setIssueTitle(bug.title);
|
||||
setBugTitleEditable(false);
|
||||
}
|
||||
|
||||
function editableBugTitle() {
|
||||
return (
|
||||
<form className={classes.headerTitle} onSubmit={submitNewTitle}>
|
||||
<TextField
|
||||
inputRef={(node) => {
|
||||
issueTitleInput = node;
|
||||
}}
|
||||
className={classes.titleInput}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
margin="dense"
|
||||
value={issueTitle}
|
||||
onChange={(event: any) => setIssueTitle(event.target.value)}
|
||||
/>
|
||||
<div className={classes.editButtonContainer}>
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
type="submit"
|
||||
disabled={issueTitle.length === 0}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
<Button size="small" onClick={() => cancelChange()}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
function readonlyBugTitle() {
|
||||
return (
|
||||
<div className={classes.headerTitle}>
|
||||
<div>
|
||||
<span className={classes.readOnlyTitle}>{bug.title}</span>
|
||||
<span className={classes.readOnlyId}>{bug.humanId}</span>
|
||||
</div>
|
||||
<div className={classes.editButtonContainer}>
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setBugTitleEditable(!bugTitleEditable)}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (loading) return <div>Loading...</div>;
|
||||
if (error) return <div>Error</div>;
|
||||
|
||||
return (
|
||||
<div className={classes.header}>
|
||||
{bugTitleEditable ? editableBugTitle() : readonlyBugTitle()}
|
||||
<div className="classes.headerSubtitle">
|
||||
<Typography color={'textSecondary'}>
|
||||
<Author author={bug.author} />
|
||||
{' opened this bug '}
|
||||
<Date date={bug.createdAt} />
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default BugTitleForm;
|
7
webui/src/components/BugTitleForm/SetTitle.graphql
Normal file
7
webui/src/components/BugTitleForm/SetTitle.graphql
Normal file
@ -0,0 +1,7 @@
|
||||
mutation setTitle($input: SetTitleInput!) {
|
||||
setTitle(input: $input) {
|
||||
bug {
|
||||
humanId
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
import React from 'react';
|
||||
|
||||
import Typography from '@material-ui/core/Typography/Typography';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
import Author from 'src/components/Author';
|
||||
import Date from 'src/components/Date';
|
||||
import BugTitleForm from 'src/components/BugTitleForm/BugTitleForm';
|
||||
import Label from 'src/components/Label';
|
||||
import IfLoggedIn from 'src/layout/IfLoggedIn';
|
||||
|
||||
@ -12,21 +10,19 @@ import { BugFragment } from './Bug.generated';
|
||||
import CommentForm from './CommentForm';
|
||||
import TimelineQuery from './TimelineQuery';
|
||||
|
||||
/**
|
||||
* Css in JS Styles
|
||||
*/
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
main: {
|
||||
maxWidth: 1000,
|
||||
margin: 'auto',
|
||||
marginTop: theme.spacing(4),
|
||||
overflow: 'hidden',
|
||||
},
|
||||
header: {
|
||||
marginLeft: theme.spacing(3) + 40,
|
||||
},
|
||||
title: {
|
||||
...theme.typography.h5,
|
||||
},
|
||||
id: {
|
||||
...theme.typography.subtitle1,
|
||||
marginLeft: theme.spacing(1),
|
||||
marginRight: theme.spacing(2),
|
||||
},
|
||||
container: {
|
||||
display: 'flex',
|
||||
@ -73,17 +69,11 @@ type Props = {
|
||||
|
||||
function Bug({ bug }: Props) {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<main className={classes.main}>
|
||||
<div className={classes.header}>
|
||||
<span className={classes.title}>{bug.title}</span>
|
||||
<span className={classes.id}>{bug.humanId}</span>
|
||||
|
||||
<Typography color={'textSecondary'}>
|
||||
<Author author={bug.author} />
|
||||
{' opened this bug '}
|
||||
<Date date={bug.createdAt} />
|
||||
</Typography>
|
||||
<BugTitleForm bug={bug} />
|
||||
</div>
|
||||
|
||||
<div className={classes.container}>
|
||||
|
@ -64,9 +64,6 @@ function NewBugPage() {
|
||||
function submitNewIssue(e: FormEvent) {
|
||||
e.preventDefault();
|
||||
if (!isFormValid()) return;
|
||||
console.log('submitNewISsue');
|
||||
console.log('title: ', issueTitle);
|
||||
console.log('comment: ', issueComment);
|
||||
newBug({
|
||||
variables: {
|
||||
input: {
|
||||
@ -82,7 +79,7 @@ function NewBugPage() {
|
||||
return issueTitle.length > 0 && issueComment.length > 0 ? true : false;
|
||||
}
|
||||
|
||||
if (loading) return <div>Loading</div>;
|
||||
if (loading) return <div>Loading...</div>;
|
||||
if (error) return <div>Error</div>;
|
||||
|
||||
return (
|
||||
|
Loading…
Reference in New Issue
Block a user