Partial commit for #158

- It´s possible to create new issue with title and first message from webui
- form simple validation
- Extraction from CommentForm to create a generic component for Comments

Next steps
- Styles
- Readme update about codegen usage and enforcing playground usage
This commit is contained in:
Cláudio 2021-01-29 18:39:19 -03:00
parent d673eb97fe
commit a5e0deeec1
2 changed files with 141 additions and 11 deletions

View File

@ -0,0 +1,101 @@
import React, { useState, useRef, useEffect } from 'react';
import Button from '@material-ui/core/Button';
import Paper from '@material-ui/core/Paper';
import Tab from '@material-ui/core/Tab';
import Tabs from '@material-ui/core/Tabs';
import TextField from '@material-ui/core/TextField';
import { makeStyles, Theme } from '@material-ui/core/styles';
import Content from 'src/components/Content';
import { useAddCommentMutation } from './CommentForm.generated';
import { TimelineDocument } from './TimelineQuery.generated';
const useStyles = makeStyles((theme) => ({
container: {
margin: theme.spacing(2, 0),
padding: theme.spacing(0, 2, 2, 2),
},
textarea: {},
tabContent: {
margin: theme.spacing(2, 0),
},
preview: {
borderBottom: `solid 3px ${theme.palette.grey['200']}`,
minHeight: '5rem',
},
actions: {
display: 'flex',
justifyContent: 'flex-end',
},
}));
type TabPanelProps = {
children: React.ReactNode;
value: number;
index: number;
} & React.HTMLProps<HTMLDivElement>;
function TabPanel({ children, value, index, ...props }: TabPanelProps) {
return (
<div
role="tabpanel"
hidden={value !== index}
id={`editor-tabpanel-${index}`}
aria-labelledby={`editor-tab-${index}`}
{...props}
>
{value === index && children}
</div>
);
}
const a11yProps = (index: number) => ({
id: `editor-tab-${index}`,
'aria-controls': `editor-tabpanel-${index}`,
});
type Props = {
loading: boolean;
onChange: (comment: string) => void;
};
function CommentInput({ loading, onChange }: Props) {
const [input, setInput] = useState<string>('');
const [tab, setTab] = useState(0);
const classes = useStyles();
useEffect(() => {
onChange(input);
}, [input]);
return (
<div>
<Tabs value={tab} onChange={(_, t) => setTab(t)}>
<Tab label="Write" {...a11yProps(0)} />
<Tab label="Preview" {...a11yProps(1)} />
</Tabs>
<div className={classes.tabContent}>
<TabPanel value={tab} index={0}>
<TextField
fullWidth
label="Comment"
placeholder="Leave a comment"
className={classes.textarea}
multiline
value={input}
variant="filled"
rows="4" // TODO: rowsMin support
onChange={(e: any) => setInput(e.target.value)}
disabled={loading}
/>
</TabPanel>
<TabPanel value={tab} index={1} className={classes.preview}>
<Content markdown={input} />
</TabPanel>
</div>
</div>
);
}
export default CommentInput;

View File

@ -1,13 +1,16 @@
import React, { FormEvent } from 'react'; import React, { FormEvent, useState } from 'react';
import { Button } from '@material-ui/core';
import Paper from '@material-ui/core/Paper'; import Paper from '@material-ui/core/Paper';
import TextField from '@material-ui/core/TextField/TextField'; import TextField from '@material-ui/core/TextField/TextField';
import { fade, makeStyles, Theme } from '@material-ui/core/styles'; import { fade, makeStyles, Theme } from '@material-ui/core/styles';
import CommentInput from '../bug/CommentInput';
import { useNewBugMutation } from './NewBug.generated'; import { useNewBugMutation } from './NewBug.generated';
/** /**
* Styles * Css in JS styles
*/ */
const useStyles = makeStyles((theme: Theme) => ({ const useStyles = makeStyles((theme: Theme) => ({
main: { main: {
@ -33,8 +36,10 @@ const useStyles = makeStyles((theme: Theme) => ({
}, },
form: { form: {
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'column',
flexWrap: 'wrap', },
actions: {
display: 'flex',
justifyContent: 'flex-end', justifyContent: 'flex-end',
}, },
})); }));
@ -43,21 +48,31 @@ const useStyles = makeStyles((theme: Theme) => ({
* Form to create a new issue * Form to create a new issue
*/ */
function NewBugPage() { function NewBugPage() {
const classes = useStyles();
let inputField: any;
const [newBug, { loading, error }] = useNewBugMutation(); const [newBug, { loading, error }] = useNewBugMutation();
const [issueTitle, setIssueTitle] = useState('');
const [issueComment, setIssueComment] = useState('');
const classes = useStyles();
let issueTitleInput: any;
function submitNewIssue(e: FormEvent) { function submitNewIssue(e: FormEvent) {
e.preventDefault(); e.preventDefault();
if (!isFormValid()) return;
console.log('submitNewISsue');
console.log('title: ', issueTitle);
console.log('comment: ', issueComment);
newBug({ newBug({
variables: { variables: {
input: { input: {
title: String(inputField.value), title: issueTitle,
message: 'Message', //TODO message: issueComment,
}, },
}, },
}); });
inputField.value = ''; issueTitleInput.value = '';
}
function isFormValid() {
return issueTitle.length > 0 && issueComment.length > 0 ? true : false;
} }
if (loading) return <div>Loading</div>; if (loading) return <div>Loading</div>;
@ -68,15 +83,29 @@ function NewBugPage() {
<form className={classes.form} onSubmit={submitNewIssue}> <form className={classes.form} onSubmit={submitNewIssue}>
<TextField <TextField
inputRef={(node) => { inputRef={(node) => {
inputField = node; issueTitleInput = node;
}} }}
label="Title" label="Title"
className={classes.titleInput} className={classes.titleInput}
variant="outlined" variant="outlined"
fullWidth fullWidth
margin="dense" margin="dense"
onChange={(event: any) => setIssueTitle(event.target.value)}
/> />
<button type="submit">Submit</button> <CommentInput
loading={false}
onChange={(comment: string) => setIssueComment(comment)}
/>
<div className={classes.actions}>
<Button
variant="contained"
color="primary"
type="submit"
disabled={isFormValid() ? false : true}
>
Submit new issue
</Button>
</div>
</form> </form>
</Paper> </Paper>
); );