From 6d5a2eebb609da67239ea37d12d6b2d3bbfef76e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 28 Oct 2020 16:41:53 +0100 Subject: ui: Do not clutter component tree with Redux connects This change refactors the frontend to use hooks for obtaining state within the Redux store as opposed to using Higher-Order Components (HOCs). This eliminates a lot of clutter in the components. --- .../src/containers/projects/FilterLink.js | 18 +++++---------- .../projects/NewProjectButtonContainer.js | 12 +++++----- .../src/containers/projects/ProjectActions.js | 17 +++++--------- .../containers/projects/VisibleProjectAuthList.js | 26 +++++++++++----------- 4 files changed, 30 insertions(+), 43 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/projects') diff --git a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js index dfd6affe..26f95c55 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js @@ -1,19 +1,13 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { setAuthVisibilityFilter } from '../../actions/projects' import FilterButton from '../../components/projects/FilterButton' -const mapStateToProps = (state, ownProps) => { - return { - active: state.projectList.authVisibilityFilter === ownProps.filter, - } -} +const FilterLink = (props) => { + const active = useSelector((state) => state.projectList.authVisibilityFilter === props.filter) + const dispatch = useDispatch() -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onClick: () => dispatch(setAuthVisibilityFilter(ownProps.filter)), - } + return dispatch(setAuthVisibilityFilter(props.filter))} active={active} /> } -const FilterLink = connect(mapStateToProps, mapDispatchToProps)(FilterButton) - export default FilterLink diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js index ffd4a4a3..b8f6fef5 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { openNewProjectModal } from '../../actions/modals/projects' import NewProjectButtonComponent from '../../components/projects/NewProjectButtonComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(openNewProjectModal()), - } +const NewProjectButtonContainer = (props) => { + const dispatch = useDispatch() + return dispatch(openNewProjectModal())} /> } -const NewProjectButtonContainer = connect(undefined, mapDispatchToProps)(NewProjectButtonComponent) - export default NewProjectButtonContainer 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 8bcbb7fd..a13034e9 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js @@ -1,20 +1,15 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { deleteProject } from '../../actions/projects' import ProjectActionButtons from '../../components/projects/ProjectActionButtons' -const mapStateToProps = (state, ownProps) => { - return { - projectId: ownProps.projectId, - } -} - -const mapDispatchToProps = (dispatch) => { - return { +const ProjectActions = (props) => { + const dispatch = useDispatch() + const actions = { onViewUsers: (id) => {}, // TODO implement user viewing onDelete: (id) => dispatch(deleteProject(id)), } + return } -const ProjectActions = connect(mapStateToProps, mapDispatchToProps)(ProjectActionButtons) - export default ProjectActions diff --git a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js index f0010540..b869775c 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js @@ -1,4 +1,5 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import ProjectList from '../../components/projects/ProjectAuthList' const getVisibleProjectAuths = (projectAuths, filter) => { @@ -14,19 +15,18 @@ const getVisibleProjectAuths = (projectAuths, filter) => { } } -const mapStateToProps = (state) => { - const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => { - const authorization = state.objects.authorization[authorizationIds] - authorization.user = state.objects.user[authorization.userId] - authorization.project = state.objects.project[authorization.projectId] - return authorization - }) +const VisibleProjectAuthList = (props) => { + const authorizations = useSelector((state) => { + const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => { + const authorization = state.objects.authorization[authorizationIds] + authorization.user = state.objects.user[authorization.userId] + authorization.project = state.objects.project[authorization.projectId] + return authorization + }) - return { - authorizations: getVisibleProjectAuths(denormalizedAuthorizations, state.projectList.authVisibilityFilter), - } + return getVisibleProjectAuths(denormalizedAuthorizations, state.projectList.authVisibilityFilter) + }) + return } -const VisibleProjectAuthList = connect(mapStateToProps)(ProjectList) - export default VisibleProjectAuthList -- cgit v1.2.3 From 1891a6f3963d3ddeae0ea093f9a7e3608a97b4d7 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 13 May 2021 16:35:01 +0200 Subject: ui: Simplify projects page This change simplifies the logic and components of the projects page and reduces its dependency on Redux for simple operations. --- .../src/containers/projects/FilterLink.js | 13 --------- .../projects/NewProjectButtonContainer.js | 11 -------- .../src/containers/projects/NewProjectContainer.js | 33 ++++++++++++++++++++++ .../containers/projects/VisibleProjectAuthList.js | 13 ++++++--- 4 files changed, 42 insertions(+), 28 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js (limited to 'opendc-web/opendc-web-ui/src/containers/projects') diff --git a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js deleted file mode 100644 index 26f95c55..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { setAuthVisibilityFilter } from '../../actions/projects' -import FilterButton from '../../components/projects/FilterButton' - -const FilterLink = (props) => { - const active = useSelector((state) => state.projectList.authVisibilityFilter === props.filter) - const dispatch = useDispatch() - - return dispatch(setAuthVisibilityFilter(props.filter))} active={active} /> -} - -export default FilterLink diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js deleted file mode 100644 index b8f6fef5..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { openNewProjectModal } from '../../actions/modals/projects' -import NewProjectButtonComponent from '../../components/projects/NewProjectButtonComponent' - -const NewProjectButtonContainer = (props) => { - const dispatch = useDispatch() - return dispatch(openNewProjectModal())} /> -} - -export default NewProjectButtonContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js new file mode 100644 index 00000000..5a8a2dcf --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js @@ -0,0 +1,33 @@ +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' +import { addProject } from '../../actions/projects' +import TextInputModal from '../../components/modals/TextInputModal' +import { Button } from 'reactstrap' + +/** + * A container for creating a new project. + */ +const NewProjectContainer = () => { + const [isVisible, setVisible] = useState(false) + const dispatch = useDispatch() + const callback = (text) => { + if (text) { + dispatch(addProject(text)) + } + setVisible(false) + } + + return ( + <> +
+ +
+ + + ) +} + +export default NewProjectContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js index b869775c..8e1d063b 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js @@ -1,6 +1,7 @@ import React from 'react' +import PropTypes from 'prop-types' import { useSelector } from 'react-redux' -import ProjectList from '../../components/projects/ProjectAuthList' +import ProjectList from '../../components/projects/ProjectList' const getVisibleProjectAuths = (projectAuths, filter) => { switch (filter) { @@ -15,7 +16,7 @@ const getVisibleProjectAuths = (projectAuths, filter) => { } } -const VisibleProjectAuthList = (props) => { +const VisibleProjectAuthList = ({ filter }) => { const authorizations = useSelector((state) => { const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => { const authorization = state.objects.authorization[authorizationIds] @@ -24,9 +25,13 @@ const VisibleProjectAuthList = (props) => { return authorization }) - return getVisibleProjectAuths(denormalizedAuthorizations, state.projectList.authVisibilityFilter) + return getVisibleProjectAuths(denormalizedAuthorizations, filter) }) - return + return +} + +VisibleProjectAuthList.propTypes = { + filter: PropTypes.string.isRequired, } export default VisibleProjectAuthList -- cgit v1.2.3 From d9e65dceb38cdb8dc4e464d388755f9456620566 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 16 May 2021 17:07:58 +0200 Subject: ui: Restructure OpenDC frontend This change updates the structure of the OpenDC frontend in order to improve the maintainability of the frontend. --- opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js | 2 +- opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js | 2 +- 2 files changed, 2 insertions(+), 2 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 5a8a2dcf..a0e607b2 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js @@ -1,6 +1,6 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' -import { addProject } from '../../actions/projects' +import { addProject } from '../../redux/actions/projects' import TextInputModal from '../../components/modals/TextInputModal' import { Button } from 'reactstrap' 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 a13034e9..bdb422dc 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { deleteProject } from '../../actions/projects' +import { deleteProject } from '../../redux/actions/projects' import ProjectActionButtons from '../../components/projects/ProjectActionButtons' const ProjectActions = (props) => { -- cgit v1.2.3 From a6865b86cc8d710374fc0b6cfcbd2b863f1942a9 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 16 May 2021 23:18:02 +0200 Subject: ui: Migrate to Auth0 as Identity Provider This change updates the frontend codebase to move away from the Google login and instead use Auth0 as generic Identity Provider. This allows users to login with other accounts as well. Since Auth0 has a free tier, users can experiment themselves with OpenDC locally without having to pay for the login functionality. The code has been written so that we should be able to migrate away from Auth0 once it is not a suitable Identity Provider for OpenDC anymore. --- .../containers/projects/ProjectListContainer.js | 34 ++++++++++++++++++++ .../containers/projects/VisibleProjectAuthList.js | 37 ---------------------- 2 files changed, 34 insertions(+), 37 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js (limited to 'opendc-web/opendc-web-ui/src/containers/projects') diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js new file mode 100644 index 00000000..6632a8b5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js @@ -0,0 +1,34 @@ +import React from 'react' +import PropTypes from 'prop-types' +import ProjectList from '../../components/projects/ProjectList' +import { useAuth } from '../../auth' +import { useProjects } from '../../data/project' + +const getVisibleProjects = (projects, filter, userId) => { + switch (filter) { + case 'SHOW_ALL': + return projects + case 'SHOW_OWN': + return projects.filter((project) => + project.authorizations.some((a) => a.userId === userId && a.level === 'OWN') + ) + case 'SHOW_SHARED': + return projects.filter((project) => + project.authorizations.some((a) => a.userId === userId && a.level !== 'OWN') + ) + default: + return projects + } +} + +const ProjectListContainer = ({ filter }) => { + const { user } = useAuth() + const projects = useProjects() + return +} + +ProjectListContainer.propTypes = { + filter: PropTypes.string.isRequired, +} + +export default ProjectListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js deleted file mode 100644 index 8e1d063b..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import ProjectList from '../../components/projects/ProjectList' - -const getVisibleProjectAuths = (projectAuths, filter) => { - switch (filter) { - case 'SHOW_ALL': - return projectAuths - case 'SHOW_OWN': - return projectAuths.filter((projectAuth) => projectAuth.authorizationLevel === 'OWN') - case 'SHOW_SHARED': - return projectAuths.filter((projectAuth) => projectAuth.authorizationLevel !== 'OWN') - default: - return projectAuths - } -} - -const VisibleProjectAuthList = ({ filter }) => { - const authorizations = useSelector((state) => { - const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => { - const authorization = state.objects.authorization[authorizationIds] - authorization.user = state.objects.user[authorization.userId] - authorization.project = state.objects.project[authorization.projectId] - return authorization - }) - - return getVisibleProjectAuths(denormalizedAuthorizations, filter) - }) - return -} - -VisibleProjectAuthList.propTypes = { - filter: PropTypes.string.isRequired, -} - -export default VisibleProjectAuthList -- cgit v1.2.3 From 53623fad76274e39206b8e073e371775ea96946b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 17 May 2021 12:16:10 +0200 Subject: ui: Migrate to FontAwesome 5 React library This change updates the frontend to use the FontAwesome 5 React library that renders SVG icons as opposed to CSS icon fonts. This migration resolves a couple of issues we had with server-side rendering of the previous FontAwesome icons. --- .../opendc-web-ui/src/containers/projects/NewProjectContainer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (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 a0e607b2..e03b5c07 100644 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js @@ -3,6 +3,8 @@ 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' /** * A container for creating a new project. @@ -21,7 +23,7 @@ const NewProjectContainer = () => { <>
-- cgit v1.2.3 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 From 803e13b32cf0ff8b496649fb0a4d6e32400e98a4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 14 Jul 2021 22:23:40 +0200 Subject: feat(ui): Migrate to PatternFly 4 design framework This change is a rewrite of the existing OpenDC frontend in order to migrate to the PatternFly 4 design framework. PatternFly is used by Red Hat for various computing related services such as OpenShift, Red Hat Virtualization and Cockpit. Since their design requirements are very similar to those of OpenDC (modeling computing services), migrating to PatternFly 4 allows us to re-use design choices from these services. See https://www.patternfly.org/v4/ for more information about PatternFly. --- .../src/containers/projects/NewProjectContainer.js | 34 ---------------------- .../src/containers/projects/ProjectActions.js | 14 --------- .../containers/projects/ProjectListContainer.js | 34 ---------------------- 3 files changed, 82 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js (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 deleted file mode 100644 index ac0edae4..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useState } from 'react' -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 } from 'react-query' - -/** - * A container for creating a new project. - */ -const NewProjectContainer = () => { - const [isVisible, setVisible] = useState(false) - const { mutate: addProject } = useMutation('addProject') - const callback = (text) => { - if (text) { - addProject({ name: text }) - } - setVisible(false) - } - - return ( - <> -
- -
- - - ) -} - -export default NewProjectContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js deleted file mode 100644 index 62985742..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import ProjectActionButtons from '../../components/projects/ProjectActionButtons' -import { useMutation } from 'react-query' - -const ProjectActions = (props) => { - const { mutate: deleteProject } = useMutation('deleteProject') - const actions = { - onViewUsers: (id) => {}, // TODO implement user viewing - onDelete: (id) => deleteProject(id), - } - return -} - -export default ProjectActions diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js deleted file mode 100644 index b5c5dd68..00000000 --- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectListContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import ProjectList from '../../components/projects/ProjectList' -import { useAuth } from '../../auth' -import { useProjects } from '../../data/project' - -const getVisibleProjects = (projects, filter, userId) => { - switch (filter) { - case 'SHOW_ALL': - return projects - case 'SHOW_OWN': - return projects.filter((project) => - project.authorizations.some((a) => a.userId === userId && a.level === 'OWN') - ) - case 'SHOW_SHARED': - return projects.filter((project) => - project.authorizations.some((a) => a.userId === userId && a.level !== 'OWN') - ) - default: - return projects - } -} - -const ProjectListContainer = ({ filter }) => { - const { user } = useAuth() - const { data: projects } = useProjects() - return -} - -ProjectListContainer.propTypes = { - filter: PropTypes.string.isRequired, -} - -export default ProjectListContainer -- cgit v1.2.3