added apollo client & cache on create todo

This commit is contained in:
Sergey Yarkov 2020-06-14 15:11:12 +03:00
parent 437b18536d
commit 02ad7d86de
12 changed files with 205 additions and 77 deletions

View File

@ -7,8 +7,17 @@ import TrashContainer from './containers/TrashContainer/TrashContainer'
import NotFoundContainer from './containers/NotFoundContainer/NotFoundContainer'
import CssBaseLine from '@material-ui/core/CssBaseline'
import ApolloClient from 'apollo-boost'
import { ApolloProvider } from 'react-apollo'
const client = new ApolloClient({
uri: 'http://localhost:3001'
})
const App = ({ history }) => {
return (
<ApolloProvider client={client}>
<>
<CssBaseLine />
<Layout history={history}>
@ -21,6 +30,7 @@ const App = ({ history }) => {
</Switch>
</Layout>
</>
</ApolloProvider>
)
}

View File

@ -0,0 +1,18 @@
import gql from 'graphql-tag'
const CREATE_TODO = gql`
mutation CreateTodo($title: String! $description: String! $deadline: String! $categoryId: String!) {
createTodo(title: $title description: $description deadline: $deadline categoryId: $categoryId) {
id
title
description
status
deadline
category {
title
}
}
}
`
export default CREATE_TODO

View File

@ -0,0 +1,12 @@
import gql from 'graphql-tag'
const GET_CATEGORIES = gql`
{
categories {
id
title
}
}
`
export default GET_CATEGORIES

View File

@ -0,0 +1,18 @@
import gql from 'graphql-tag'
const GET_TODOS = gql`
query getTodos {
todos {
id
title
description
status
deadline
category {
title
}
}
}
`;
export default GET_TODOS

View File

@ -0,0 +1,22 @@
import gql from 'graphql-tag'
const GET_TODOS_BY_CATEGORY = gql`
query getTodosByCategory($id: ID!) {
category(id: $id) {
id
title
todos {
id
title
description
status
deadline
category {
title
}
}
}
}
`
export default GET_TODOS_BY_CATEGORY

View File

@ -5,8 +5,8 @@ import { ListItem, ListItemText } from '@material-ui/core'
const Categories = ({ data, history, classes }) => {
return data.map((category, i) => {
return (
<Link className={classes.link} key={i} to={`/category/${category._id.$oid}`}>
<ListItem selected={history.location.pathname === `/category/${category._id.$oid}`} button className={classes.nested}>
<Link className={classes.link} key={i} to={`/category/${category.id}`}>
<ListItem selected={history.location.pathname === `/category/${category.id}`} button className={classes.nested}>
<ListItemText primary={category.title} />
</ListItem>
</Link>

View File

@ -3,7 +3,11 @@ import useStyles from '../styles'
import { Dialog, DialogContent, DialogTitle, DialogActions, Button, TextField, Select, MenuItem, InputLabel, FormControl } from '@material-ui/core'
import AddIcon from '@material-ui/icons/Add'
import categories from '../../../db/categories.json'
import { useQuery, useMutation } from '@apollo/react-hooks'
import CREATE_TODO from '../../../apollo/mutations/todos/createTodo';
import GET_TODOS from '../../../apollo/queries/todos/todos';
import GET_CATEGORIES from '../../../apollo/queries/categories/categories'
const CreateTodoModal = ({ isModalOpen, handleCloseModal }) => {
const classes = useStyles()
@ -14,15 +18,29 @@ const CreateTodoModal = ({ isModalOpen, handleCloseModal }) => {
deadline: ''
})
// create todo mutation
const [createTodo] = useMutation(CREATE_TODO, {
update(cache, { data: { createTodo } }) {
const { todos } = cache.readQuery({ query: GET_TODOS })
cache.writeQuery({
query: GET_TODOS,
data: { todos: todos.concat([createTodo]) }
});
}
})
const handleFormSubmit = e => {
try {
e.preventDefault()
const elements = e.target.elements
const data = {
createTodo({
variables: {
title: elements.title.value,
description: elements.description.value,
categoryId: elements.category.value,
deadline: elements.deadline.value
}
})
handleCloseModal()
setFieldsData({
title: '',
@ -30,7 +48,9 @@ const CreateTodoModal = ({ isModalOpen, handleCloseModal }) => {
category: '',
deadline: ''
})
console.log('Request on create todo:', data)
} catch (error) {
console.log(error)
}
}
const handleFieldChange = e => {
@ -43,6 +63,11 @@ const CreateTodoModal = ({ isModalOpen, handleCloseModal }) => {
})
}
const { loading, error, data } = useQuery(GET_CATEGORIES);
if (loading) return null;
if (error) return `Error! ${error.message}`;
return (
<div>
<Dialog fullWidth={true} open={isModalOpen} onClose={handleCloseModal} color='default'>
@ -87,7 +112,7 @@ const CreateTodoModal = ({ isModalOpen, handleCloseModal }) => {
onChange={handleFieldChange}
label="Категория"
>
{categories.map((category, i) => <MenuItem key={i} value={category._id.$oid}>{category.title}</MenuItem>)}
{data.categories.map((category, i) => <MenuItem key={i} value={category.id}>{category.title}</MenuItem>)}
</Select>
</FormControl>
<TextField

View File

@ -12,8 +12,9 @@ import DeleteIcon from '@material-ui/icons/Delete';
import GitHubIcon from '@material-ui/icons/GitHub';
import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
import { Query } from 'react-apollo'
import categories from '../../../db/categories.json'
import GET_CATEGORIES from '../../../apollo/queries/categories/categories'
const NavContent = ({ history, handleOpenModal }) => {
const classes = useStyles()
@ -53,7 +54,13 @@ const NavContent = ({ history, handleOpenModal }) => {
</ListItem>
<Collapse in={collapseInfo.isCollapseOpen} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<Categories data={categories} history={history} classes={classes} />
<Query query={GET_CATEGORIES}>
{({ loading, error, data }) => {
if (loading) return null;
if (error) return `Error! ${error}`;
return <Categories data={data.categories} history={history} classes={classes} />
}}
</Query>
<ListItem className={classes.addCategoryItem}>
<IconButton onClick={handleOpenModal} aria-label="add">
<AddIcon />

View File

@ -11,8 +11,6 @@ import DeleteIcon from '@material-ui/icons/Delete'
import AlarmIcon from '@material-ui/icons/Alarm';
import EditIcon from '@material-ui/icons/Edit';
import categories from '../../db/categories.json'
const Todos = ({ data, fromTrashContainer }) => {
const classes = useStyles()
const [selectedTodo, setSelectedTodo] = React.useState({
@ -27,10 +25,10 @@ const Todos = ({ data, fromTrashContainer }) => {
const handleOpenModal = todo => {
const selectedTodo = {
id: todo._id.$oid,
id: todo.id,
title: todo.title,
description: todo.description,
category: todo.categoryId,
category: todo.category,
deadline: todo.deadline
}
@ -41,10 +39,10 @@ const Todos = ({ data, fromTrashContainer }) => {
const handleOpenDialog = todo => {
setSelectedTodo({
id: todo._id.$oid,
id: todo.id,
title: todo.title,
description: todo.description,
category: todo.categoryId,
category: todo.category,
deadline: todo.deadline
})
setIsOpenDialog(true)
@ -53,10 +51,10 @@ const Todos = ({ data, fromTrashContainer }) => {
const handleOpenRestoreDialog = todo => {
setSelectedTodo({
id: todo._id.$oid,
id: todo.id,
title: todo.title,
description: todo.description,
category: todo.categoryId,
category: todo.category,
deadline: todo.deadline
})
setIsOpenRestoreDialog(true)
@ -81,7 +79,7 @@ const Todos = ({ data, fromTrashContainer }) => {
<Card>
<CardContent>
<Typography className={classes.cardCategoryHeading} color="textSecondary" gutterBottom>
{categories.find(category => category._id.$oid === todo.categoryId).title}
{todo.category.title}
<span className={classes.cardAlarm}>
<AlarmIcon className={classes.alarmIcon} color='action' />
{todo.deadline}

View File

@ -3,13 +3,15 @@ import Todos from '../../components/Todos/Todos'
import UpdateCategoryModal from '../../components/Modals/Category/UpdateCategoryModal'
import DeleteCategoryDialog from '../../components/Dialogs/Category/DeleteCategoryDialog'
import Fab from '../../components/Fab/Fab'
import { Grid, Typography } from '@material-ui/core'
import { Grid, Typography, LinearProgress } from '@material-ui/core'
import todos from '../../db/todos.json'
import categories from '../../db/categories.json'
import { Query } from 'react-apollo'
import { useParams } from 'react-router-dom'
import GET_TODOS_BY_CATEGORY from '../../apollo/queries/todos/todosByCategory'
const Category = () => {
const findCategoryById = id => categories.find(category => category._id.$oid === id)
@ -28,6 +30,11 @@ const Category = () => {
const handleOpenDialog = () => setIsOpenDialog(true)
const handleCloseDialog = () => setIsOpenDialog(false)
return (
<Query query={GET_TODOS_BY_CATEGORY} variables={{ id }}>
{({ loading, error, data }) => {
if (loading) return <LinearProgress />
if (error) return `Error! ${error.message}`;
return (
<>
<UpdateCategoryModal isModalOpen={isModalOpen} handleCloseModal={handleCloseModal} selectedCategory={selectedCategory} setSelectedCategory={setSelectedCategory} />
@ -41,10 +48,13 @@ const Category = () => {
</Typography>
</Grid>
{/* Здесь берем значение slug из query и передаем полученные данные в prop data !!!! */}
<Todos data={todos} />
<Todos data={data.category.todos} />
</Grid>
</>
)
}}
</Query>
)
}
export default Category

View File

@ -2,14 +2,21 @@ import React from 'react';
import Fab from '../../components/Fab/Fab'
import Todos from '../../components/Todos/Todos'
import CreateTodoModal from '../../components/Modals/Todo/CreateTodoModal'
import { Typography, Grid } from '@material-ui/core'
import { Query } from 'react-apollo'
import { Typography, Grid, LinearProgress } from '@material-ui/core'
import todos from '../../db/todos.json'
import GET_TODOS from '../../apollo/queries/todos/todos'
const TodosContainer = () => {
const [isModalOpen, setIsModalOpen] = React.useState(false)
const handleOpenModal = () => setIsModalOpen(true)
const handleCloseModal = () => setIsModalOpen(false)
return (
<Query query={GET_TODOS}>
{({ loading, error, data }) => {
if (loading) return <LinearProgress />
if (error) return `Error! ${error.message}`;
return (
<>
<CreateTodoModal isModalOpen={isModalOpen} handleCloseModal={handleCloseModal} />
@ -20,10 +27,13 @@ const TodosContainer = () => {
Создавайте, редактируйте или удаляйте ваши повседневные дела.
</Typography>
</Grid>
<Todos data={todos} />
<Todos data={data.todos} />
</Grid>
</>
)
}}
</Query>
)
}
export default TodosContainer

View File

@ -2,8 +2,6 @@ import React from 'react';
import Todos from '../../components/Todos/Todos'
import { Grid, Typography } from '@material-ui/core'
import todos from '../../db/todos.json'
const Trash = () => {
return (
<Grid container spacing={2}>
@ -13,7 +11,7 @@ const Trash = () => {
</Typography>
</Grid>
{/* Здесь также выполняем нужный запрос на удаленные записи в БД !!!!!!!! */}
<Todos data={todos} fromTrashContainer={true} />
{/* <Todos data={todos} fromTrashContainer={true} /> */}
</Grid>
)
}