From e5e5d2c65e583493870bc0b62fb185c5e757c13f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 7 Jul 2021 16:27:49 +0200 Subject: ui: Migrate project APIs to React Query This change updates the OpenDC frontend to use React Query for fetching and mutating project data. Previously, this state was tracked and synchronized via Redux. Migrating to React Query greatly simplifies the state synchronization logic necessary in the frontend. --- .../src/containers/projects/NewProjectContainer.js | 13 +++++++++---- .../opendc-web-ui/src/containers/projects/ProjectActions.js | 13 +++++++++---- .../src/containers/projects/ProjectListContainer.js | 5 +++-- 3 files changed, 21 insertions(+), 10 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/projects') diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js index e03b5c07..c844fe2d 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js @@ -1,20 +1,25 @@ import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import { addProject } from '../../redux/actions/projects' import TextInputModal from '../../components/modals/TextInputModal' import { Button } from 'reactstrap' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faPlus } from '@fortawesome/free-solid-svg-icons' +import { useMutation, useQueryClient } from 'react-query' +import { addProject } from '../../api/projects' +import { useAuth } from '../../auth' /** * A container for creating a new project. */ const NewProjectContainer = () => { const [isVisible, setVisible] = useState(false) - const dispatch = useDispatch() + const auth = useAuth() + const queryClient = useQueryClient() + const mutation = useMutation((data) => addProject(auth, data), { + onSuccess: (result) => queryClient.setQueryData('projects', (old) => [...(old || []), result]), + }) const callback = (text) => { if (text) { - dispatch(addProject(text)) + mutation.mutate({ name: text }) } setVisible(false) } diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js index bdb422dc..eba388d6 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js @@ -1,13 +1,18 @@ import React from 'react' -import { useDispatch } from 'react-redux' -import { deleteProject } from '../../redux/actions/projects' import ProjectActionButtons from '../../components/projects/ProjectActionButtons' +import { useMutation, useQueryClient } from 'react-query' +import { useAuth } from '../../auth' +import { deleteProject } from '../../api/projects' const ProjectActions = (props) => { - const dispatch = useDispatch() + const auth = useAuth() + const queryClient = useQueryClient() + const mutation = useMutation((projectId) => deleteProject(auth, projectId), { + onSuccess: () => queryClient.invalidateQueries('projects'), + }) const actions = { onViewUsers: (id) => {}, // TODO implement user viewing - onDelete: (id) => dispatch(deleteProject(id)), + onDelete: (id) => mutation.mutate(id), } return } diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js index 6632a8b5..91e8ac5a 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import ProjectList from '../../components/projects/ProjectList' import { useAuth } from '../../auth' import { useProjects } from '../../data/project' +import { useQueryClient } from 'react-query' const getVisibleProjects = (projects, filter, userId) => { switch (filter) { @@ -23,8 +24,8 @@ const getVisibleProjects = (projects, filter, userId) => { const ProjectListContainer = ({ filter }) => { const { user } = useAuth() - const projects = useProjects() - return + const { data: projects } = useProjects() + return } ProjectListContainer.propTypes = { -- cgit v1.2.3 From 02a2f0f89cb1f39a5f8856bca1971a4e1b12374f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 7 Jul 2021 20:13:30 +0200 Subject: ui: Use React Query defaults to reduce duplication --- .../src/containers/projects/NewProjectContainer.js | 12 +++--------- .../opendc-web-ui/src/containers/projects/ProjectActions.js | 12 +++--------- .../src/containers/projects/ProjectListContainer.js | 1 - 3 files changed, 6 insertions(+), 19 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/projects') diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js index c844fe2d..ac0edae4 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js @@ -3,23 +3,17 @@ import TextInputModal from '../../components/modals/TextInputModal' import { Button } from 'reactstrap' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faPlus } from '@fortawesome/free-solid-svg-icons' -import { useMutation, useQueryClient } from 'react-query' -import { addProject } from '../../api/projects' -import { useAuth } from '../../auth' +import { useMutation } from 'react-query' /** * A container for creating a new project. */ const NewProjectContainer = () => { const [isVisible, setVisible] = useState(false) - const auth = useAuth() - const queryClient = useQueryClient() - const mutation = useMutation((data) => addProject(auth, data), { - onSuccess: (result) => queryClient.setQueryData('projects', (old) => [...(old || []), result]), - }) + const { mutate: addProject } = useMutation('addProject') const callback = (text) => { if (text) { - mutation.mutate({ name: text }) + addProject({ name: text }) } setVisible(false) } diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js index eba388d6..62985742 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js @@ -1,18 +1,12 @@ import React from 'react' import ProjectActionButtons from '../../components/projects/ProjectActionButtons' -import { useMutation, useQueryClient } from 'react-query' -import { useAuth } from '../../auth' -import { deleteProject } from '../../api/projects' +import { useMutation } from 'react-query' const ProjectActions = (props) => { - const auth = useAuth() - const queryClient = useQueryClient() - const mutation = useMutation((projectId) => deleteProject(auth, projectId), { - onSuccess: () => queryClient.invalidateQueries('projects'), - }) + const { mutate: deleteProject } = useMutation('deleteProject') const actions = { onViewUsers: (id) => {}, // TODO implement user viewing - onDelete: (id) => mutation.mutate(id), + onDelete: (id) => deleteProject(id), } return } diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js index 91e8ac5a..b5c5dd68 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types' import ProjectList from '../../components/projects/ProjectList' import { useAuth } from '../../auth' import { useProjects } from '../../data/project' -import { useQueryClient } from 'react-query' const getVisibleProjects = (projects, filter, userId) => { switch (filter) { -- cgit v1.2.3