diff --git a/packages/backend/src/graphql/mutation-resolvers.js b/packages/backend/src/graphql/mutation-resolvers.js index b17acdd2..06449fca 100644 --- a/packages/backend/src/graphql/mutation-resolvers.js +++ b/packages/backend/src/graphql/mutation-resolvers.js @@ -1,6 +1,5 @@ // Converted mutations import executeFlow from './mutations/execute-flow.js'; -import updateUser from './mutations/update-user.ee.js'; import verifyConnection from './mutations/verify-connection.js'; import updateCurrentUser from './mutations/update-current-user.js'; import generateAuthUrl from './mutations/generate-auth-url.js'; @@ -15,7 +14,6 @@ const mutationResolvers = { resetConnection, updateConnection, updateCurrentUser, - updateUser, verifyConnection, }; diff --git a/packages/backend/src/graphql/mutations/update-user.ee.js b/packages/backend/src/graphql/mutations/update-user.ee.js deleted file mode 100644 index 0e27eedb..00000000 --- a/packages/backend/src/graphql/mutations/update-user.ee.js +++ /dev/null @@ -1,27 +0,0 @@ -import User from '../../models/user.js'; - -const updateUser = async (_parent, params, context) => { - context.currentUser.can('update', 'User'); - - const userPayload = { - email: params.input.email, - fullName: params.input.fullName, - }; - - try { - context.currentUser.can('update', 'Role'); - - userPayload.roleId = params.input.role.id; - } catch { - // void - } - - const user = await User.query().patchAndFetchById( - params.input.id, - userPayload - ); - - return user; -}; - -export default updateUser; diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index a0e394c8..710ad2e8 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -8,7 +8,6 @@ type Mutation { resetConnection(input: ResetConnectionInput): Connection updateConnection(input: UpdateConnectionInput): Connection updateCurrentUser(input: UpdateCurrentUserInput): User - updateUser(input: UpdateUserInput): User verifyConnection(input: VerifyConnectionInput): Connection } @@ -241,13 +240,6 @@ input UserRoleInput { id: String } -input UpdateUserInput { - id: String! - fullName: String - email: String - role: UserRoleInput -} - input UpdateCurrentUserInput { email: String password: String diff --git a/packages/web/src/graphql/mutations/update-user.ee.js b/packages/web/src/graphql/mutations/update-user.ee.js deleted file mode 100644 index c73d8f1d..00000000 --- a/packages/web/src/graphql/mutations/update-user.ee.js +++ /dev/null @@ -1,10 +0,0 @@ -import { gql } from '@apollo/client'; -export const UPDATE_USER = gql` - mutation UpdateUser($input: UpdateUserInput) { - updateUser(input: $input) { - id - email - fullName - } - } -`; diff --git a/packages/web/src/hooks/useAdminUpdateUser.js b/packages/web/src/hooks/useAdminUpdateUser.js new file mode 100644 index 00000000..d971f252 --- /dev/null +++ b/packages/web/src/hooks/useAdminUpdateUser.js @@ -0,0 +1,34 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import api from 'helpers/api'; +import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar'; +import useFormatMessage from 'hooks/useFormatMessage'; + +export default function useAdminUpdateUser(userId) { + const queryClient = useQueryClient(); + const enqueueSnackbar = useEnqueueSnackbar(); + const formatMessage = useFormatMessage(); + + const query = useMutation({ + mutationFn: async (payload) => { + const { data } = await api.patch(`/v1/admin/users/${userId}`, payload); + + return data; + }, + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: ['admin', 'users'], + }); + }, + onError: () => { + enqueueSnackbar(formatMessage('editUser.error'), { + variant: 'error', + persist: true, + SnackbarProps: { + 'data-test': 'snackbar-error', + }, + }); + }, + }); + + return query; +} diff --git a/packages/web/src/locales/en.json b/packages/web/src/locales/en.json index 95576fde..8e0a4d1e 100644 --- a/packages/web/src/locales/en.json +++ b/packages/web/src/locales/en.json @@ -223,11 +223,12 @@ "createUser.submit": "Create", "createUser.successfullyCreated": "The user has been created.", "createUser.invitationEmailInfo": "Invitation email will be sent if SMTP credentials are valid. Otherwise, you can share the invitation link manually: ", - "createUser.error": "Error while creating the user", + "createUser.error": "Error while creating the user.", "editUserPage.title": "Edit user", "editUser.status": "Status", "editUser.submit": "Update", "editUser.successfullyUpdated": "The user has been updated.", + "editUser.error": "Error while updating the user.", "userList.fullName": "Full name", "userList.email": "Email", "userList.role": "Role", diff --git a/packages/web/src/pages/EditUser/index.jsx b/packages/web/src/pages/EditUser/index.jsx index 779badb2..becbb854 100644 --- a/packages/web/src/pages/EditUser/index.jsx +++ b/packages/web/src/pages/EditUser/index.jsx @@ -1,4 +1,3 @@ -import { useMutation } from '@apollo/client'; import LoadingButton from '@mui/lab/LoadingButton'; import Grid from '@mui/material/Grid'; import Skeleton from '@mui/material/Skeleton'; @@ -9,7 +8,6 @@ import MuiTextField from '@mui/material/TextField'; import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar'; import * as React from 'react'; import { useNavigate, useParams } from 'react-router-dom'; -import { useQueryClient } from '@tanstack/react-query'; import Can from 'components/Can'; import Container from 'components/Container'; @@ -18,9 +16,9 @@ import Form from 'components/Form'; import PageTitle from 'components/PageTitle'; import TextField from 'components/TextField'; import * as URLS from 'config/urls'; -import { UPDATE_USER } from 'graphql/mutations/update-user.ee'; import useFormatMessage from 'hooks/useFormatMessage'; import useRoles from 'hooks/useRoles.ee'; +import useAdminUpdateUser from 'hooks/useAdminUpdateUser'; import useAdminUser from 'hooks/useAdminUser'; function generateRoleOptions(roles) { @@ -29,31 +27,23 @@ function generateRoleOptions(roles) { export default function EditUser() { const formatMessage = useFormatMessage(); - const [updateUser, { loading }] = useMutation(UPDATE_USER); const { userId } = useParams(); + const { mutateAsync: updateUser, isPending: isAdminUpdateUserPending } = + useAdminUpdateUser(userId); const { data: userData, isLoading: isUserLoading } = useAdminUser({ userId }); const user = userData?.data; const { data, isLoading: isRolesLoading } = useRoles(); const roles = data?.data; const enqueueSnackbar = useEnqueueSnackbar(); const navigate = useNavigate(); - const queryClient = useQueryClient(); const handleUserUpdate = async (userDataToUpdate) => { try { await updateUser({ - variables: { - input: { - id: userId, - fullName: userDataToUpdate.fullName, - email: userDataToUpdate.email, - role: { - id: userDataToUpdate.role?.id, - }, - }, - }, + fullName: userDataToUpdate.fullName, + email: userDataToUpdate.email, + roleId: userDataToUpdate.role?.id, }); - queryClient.invalidateQueries({ queryKey: ['admin', 'users'] }); enqueueSnackbar(formatMessage('editUser.successfullyUpdated'), { variant: 'success', @@ -142,7 +132,7 @@ export default function EditUser() { variant="contained" color="primary" sx={{ boxShadow: 2 }} - loading={loading} + loading={isAdminUpdateUserPending} data-test="update-button" > {formatMessage('editUser.submit')}