From 02ad7d86ded33529cddb224360bc5332d5d1f7f7 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Sun, 14 Jun 2020 15:11:12 +0300 Subject: [PATCH] added apollo client & cache on create todo --- client/src/App.js | 34 +++++++---- .../src/apollo/mutations/todos/createTodo.js | 18 ++++++ .../apollo/queries/categories/categories.js | 12 ++++ client/src/apollo/queries/todos/todos.js | 18 ++++++ .../apollo/queries/todos/todosByCategory.js | 22 +++++++ .../src/components/Categories/Categories.js | 4 +- .../components/Modals/Todo/CreateTodoModal.js | 61 +++++++++++++------ .../components/Nav/NavContent/NavContent.js | 11 +++- client/src/components/Todos/Todos.js | 16 +++-- .../CategoryContainer/CategoryContainer.js | 44 +++++++------ .../TodosContainer/TodosContainer.js | 38 +++++++----- .../TrashContainer/TrashContainer.js | 4 +- 12 files changed, 205 insertions(+), 77 deletions(-) create mode 100644 client/src/apollo/mutations/todos/createTodo.js create mode 100644 client/src/apollo/queries/categories/categories.js create mode 100644 client/src/apollo/queries/todos/todos.js create mode 100644 client/src/apollo/queries/todos/todosByCategory.js diff --git a/client/src/App.js b/client/src/App.js index 90cfb83..598cca1 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -7,20 +7,30 @@ 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 ( - <> - - - - - - - - - - - + + <> + + + + + + + + + + + + ) } diff --git a/client/src/apollo/mutations/todos/createTodo.js b/client/src/apollo/mutations/todos/createTodo.js new file mode 100644 index 0000000..dbc19c6 --- /dev/null +++ b/client/src/apollo/mutations/todos/createTodo.js @@ -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 \ No newline at end of file diff --git a/client/src/apollo/queries/categories/categories.js b/client/src/apollo/queries/categories/categories.js new file mode 100644 index 0000000..f6d687b --- /dev/null +++ b/client/src/apollo/queries/categories/categories.js @@ -0,0 +1,12 @@ +import gql from 'graphql-tag' + +const GET_CATEGORIES = gql` + { + categories { + id + title + } + } +` + +export default GET_CATEGORIES \ No newline at end of file diff --git a/client/src/apollo/queries/todos/todos.js b/client/src/apollo/queries/todos/todos.js new file mode 100644 index 0000000..f5f29e9 --- /dev/null +++ b/client/src/apollo/queries/todos/todos.js @@ -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 \ No newline at end of file diff --git a/client/src/apollo/queries/todos/todosByCategory.js b/client/src/apollo/queries/todos/todosByCategory.js new file mode 100644 index 0000000..ce084cf --- /dev/null +++ b/client/src/apollo/queries/todos/todosByCategory.js @@ -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 \ No newline at end of file diff --git a/client/src/components/Categories/Categories.js b/client/src/components/Categories/Categories.js index 9cf6739..70ac9f4 100644 --- a/client/src/components/Categories/Categories.js +++ b/client/src/components/Categories/Categories.js @@ -5,8 +5,8 @@ import { ListItem, ListItemText } from '@material-ui/core' const Categories = ({ data, history, classes }) => { return data.map((category, i) => { return ( - - + + diff --git a/client/src/components/Modals/Todo/CreateTodoModal.js b/client/src/components/Modals/Todo/CreateTodoModal.js index 812dd8c..7e8cde3 100644 --- a/client/src/components/Modals/Todo/CreateTodoModal.js +++ b/client/src/components/Modals/Todo/CreateTodoModal.js @@ -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,23 +18,39 @@ const CreateTodoModal = ({ isModalOpen, handleCloseModal }) => { deadline: '' }) - const handleFormSubmit = e => { - e.preventDefault() - const elements = e.target.elements - const data = { - title: elements.title.value, - description: elements.description.value, - categoryId: elements.category.value, - deadline: elements.deadline.value + // 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 + createTodo({ + variables: { + title: elements.title.value, + description: elements.description.value, + categoryId: elements.category.value, + deadline: elements.deadline.value + } + }) + handleCloseModal() + setFieldsData({ + title: '', + description: '', + category: '', + deadline: '' + }) + } catch (error) { + console.log(error) } - handleCloseModal() - setFieldsData({ - title: '', - description: '', - category: '', - deadline: '' - }) - console.log('Request on create todo:', data) } 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 (
@@ -87,7 +112,7 @@ const CreateTodoModal = ({ isModalOpen, handleCloseModal }) => { onChange={handleFieldChange} label="Категория" > - {categories.map((category, i) => {category.title})} + {data.categories.map((category, i) => {category.title})} { const classes = useStyles() @@ -53,7 +54,13 @@ const NavContent = ({ history, handleOpenModal }) => { - + + {({ loading, error, data }) => { + if (loading) return null; + if (error) return `Error! ${error}`; + return + }} + diff --git a/client/src/components/Todos/Todos.js b/client/src/components/Todos/Todos.js index 4ed107b..6ee0bf1 100644 --- a/client/src/components/Todos/Todos.js +++ b/client/src/components/Todos/Todos.js @@ -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 }) => { - {categories.find(category => category._id.$oid === todo.categoryId).title} + {todo.category.title} {todo.deadline} diff --git a/client/src/containers/CategoryContainer/CategoryContainer.js b/client/src/containers/CategoryContainer/CategoryContainer.js index 5a3454c..b90fa05 100644 --- a/client/src/containers/CategoryContainer/CategoryContainer.js +++ b/client/src/containers/CategoryContainer/CategoryContainer.js @@ -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) @@ -29,21 +31,29 @@ const Category = () => { const handleCloseDialog = () => setIsOpenDialog(false) return ( - <> - - - - - - - - Сортируйте свои повседневные дела используя категории. - - - {/* Здесь берем значение slug из query и передаем полученные данные в prop data !!!! */} - - - + + {({ loading, error, data }) => { + if (loading) return + if (error) return `Error! ${error.message}`; + return ( + <> + + + + + + + + Сортируйте свои повседневные дела используя категории. + + + {/* Здесь берем значение slug из query и передаем полученные данные в prop data !!!! */} + + + + ) + }} + ) } diff --git a/client/src/containers/TodosContainer/TodosContainer.js b/client/src/containers/TodosContainer/TodosContainer.js index 669ac1b..0757e6a 100644 --- a/client/src/containers/TodosContainer/TodosContainer.js +++ b/client/src/containers/TodosContainer/TodosContainer.js @@ -2,27 +2,37 @@ 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 ( - <> - - - - - - Создавайте, редактируйте или удаляйте ваши повседневные дела. - - - - - + + {({ loading, error, data }) => { + if (loading) return + if (error) return `Error! ${error.message}`; + return ( + <> + + + + + + Создавайте, редактируйте или удаляйте ваши повседневные дела. + + + + + + ) + }} + ) } diff --git a/client/src/containers/TrashContainer/TrashContainer.js b/client/src/containers/TrashContainer/TrashContainer.js index ed6c5ff..e6231ef 100644 --- a/client/src/containers/TrashContainer/TrashContainer.js +++ b/client/src/containers/TrashContainer/TrashContainer.js @@ -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 ( @@ -13,7 +11,7 @@ const Trash = () => { {/* Здесь также выполняем нужный запрос на удаленные записи в БД !!!!!!!! */} - + {/* */} ) }