From bee986749de111556d1857adaa7e4594f4c884be Mon Sep 17 00:00:00 2001 From: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:59:13 +0100 Subject: [PATCH] 2472 v2 settings workspace module (#2532) * update findOneWorkspaceMember * profile picture upload is working * first name and last name working * support almost working * remove picture working * removed unused code * remove console logs and fix allowImpersonation in FIND_ONE_WORKSPACE_MEMBER_V2 * use useUpdateOneObjectRecord --- .../useMapFieldMetadataToGraphQLQuery.ts | 4 -- .../graphql/queries/findOneWorkspaceMember.ts | 4 ++ .../hooks/useUpdateOneObjectRecord.ts | 2 - .../profile/components/NameFields.tsx | 39 +++++++------ .../components/ProfilePictureUploader.tsx | 58 ++++++++++++++----- .../profile/components/ToggleField.tsx | 32 ++++++---- .../components/RelationFieldDisplay.tsx | 5 -- .../utils/getEntityChipFromFieldMetadata.ts | 5 -- .../meta-types/hooks/useRelationField.ts | 5 -- 9 files changed, 89 insertions(+), 65 deletions(-) diff --git a/front/src/modules/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery.ts b/front/src/modules/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery.ts index a005c83c44..5ef2e9a905 100644 --- a/front/src/modules/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery.ts +++ b/front/src/modules/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery.ts @@ -33,16 +33,12 @@ export const useMapFieldMetadataToGraphQLQuery = () => { fieldType === 'RELATION' && field.toRelationMetadata?.relationType === 'ONE_TO_MANY' ) { - console.log({ objectMetadataItems, field }); - const relationMetadataItem = objectMetadataItems.find( (objectMetadataItem) => objectMetadataItem.id === (field.toRelationMetadata as any)?.fromObjectMetadata?.id, ); - console.log({ relationMetadataItem }); - return `${field.name} { id diff --git a/front/src/modules/object-record/graphql/queries/findOneWorkspaceMember.ts b/front/src/modules/object-record/graphql/queries/findOneWorkspaceMember.ts index 6d89c04cc3..31c06c32bd 100644 --- a/front/src/modules/object-record/graphql/queries/findOneWorkspaceMember.ts +++ b/front/src/modules/object-record/graphql/queries/findOneWorkspaceMember.ts @@ -8,6 +8,10 @@ export const FIND_ONE_WORKSPACE_MEMBER_V2 = gql` id firstName lastName + colorScheme + avatarUrl + locale + allowImpersonation } } } diff --git a/front/src/modules/object-record/hooks/useUpdateOneObjectRecord.ts b/front/src/modules/object-record/hooks/useUpdateOneObjectRecord.ts index 95576577be..6ff8b8fbb1 100644 --- a/front/src/modules/object-record/hooks/useUpdateOneObjectRecord.ts +++ b/front/src/modules/object-record/hooks/useUpdateOneObjectRecord.ts @@ -16,8 +16,6 @@ export const useUpdateOneObjectRecord = ({ objectNameSingular, }); - console.log('update one object'); - // TODO: type this with a minimal type at least with Record const [mutate] = useMutation(updateOneMutation); diff --git a/front/src/modules/settings/profile/components/NameFields.tsx b/front/src/modules/settings/profile/components/NameFields.tsx index 2e507bb6eb..837eeae1ed 100644 --- a/front/src/modules/settings/profile/components/NameFields.tsx +++ b/front/src/modules/settings/profile/components/NameFields.tsx @@ -1,14 +1,12 @@ import { useEffect, useState } from 'react'; -import { getOperationName } from '@apollo/client/utilities'; import styled from '@emotion/styled'; import debounce from 'lodash.debounce'; -import { useRecoilValue } from 'recoil'; +import { useRecoilState, useRecoilValue } from 'recoil'; import { currentUserState } from '@/auth/states/currentUserState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; +import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord'; import { TextInput } from '@/ui/input/components/TextInput'; -import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser'; -import { useUpdateUserMutation } from '~/generated/graphql'; import { logError } from '~/utils/logError'; const StyledComboInputContainer = styled.div` @@ -31,7 +29,9 @@ export const NameFields = ({ onLastNameUpdate, }: NameFieldsProps) => { const currentUser = useRecoilValue(currentUserState); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); + const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( + currentWorkspaceMemberState, + ); const [firstName, setFirstName] = useState( currentWorkspaceMember?.firstName ?? '', @@ -40,7 +40,10 @@ export const NameFields = ({ currentWorkspaceMember?.lastName ?? '', ); - const [updateUser] = useUpdateUserMutation(); + const { updateOneObject, objectNotFoundInMetadata } = + useUpdateOneObjectRecord({ + objectNameSingular: 'workspaceMemberV2', + }); // TODO: Enhance this with react-web-hook-form (https://www.react-hook-form.com) const debouncedUpdate = debounce(async () => { @@ -52,22 +55,20 @@ export const NameFields = ({ } try { if (autoSave) { - const { data, errors } = await updateUser({ - variables: { - where: { - id: currentUser?.id, - }, - data: { - firstName, - lastName, - }, + if (!updateOneObject || objectNotFoundInMetadata) { + return; + } + await updateOneObject({ + idToUpdate: currentWorkspaceMember?.id ?? '', + input: { + firstName, + lastName, }, - refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''], }); - if (errors || !data?.updateUser) { - throw errors; - } + setCurrentWorkspaceMember( + (current) => ({ ...current, firstName, lastName } as any), + ); } } catch (error) { logError(error); diff --git a/front/src/modules/settings/profile/components/ProfilePictureUploader.tsx b/front/src/modules/settings/profile/components/ProfilePictureUploader.tsx index ac773dde4b..5b1abed63a 100644 --- a/front/src/modules/settings/profile/components/ProfilePictureUploader.tsx +++ b/front/src/modules/settings/profile/components/ProfilePictureUploader.tsx @@ -1,28 +1,31 @@ import { useState } from 'react'; import { getOperationName } from '@apollo/client/utilities'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilState } from 'recoil'; -import { currentUserState } from '@/auth/states/currentUserState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; +import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord'; import { ImageInput } from '@/ui/input/components/ImageInput'; import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser'; import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI'; -import { - useRemoveProfilePictureMutation, - useUploadProfilePictureMutation, -} from '~/generated/graphql'; +import { useUploadProfilePictureMutation } from '~/generated/graphql'; export const ProfilePictureUploader = () => { const [uploadPicture, { loading: isUploading }] = useUploadProfilePictureMutation(); - const [removePicture] = useRemoveProfilePictureMutation(); - const [currentUser] = useRecoilState(currentUserState); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); + + const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( + currentWorkspaceMemberState, + ); const [uploadController, setUploadController] = useState(null); const [errorMessage, setErrorMessage] = useState(null); + const { updateOneObject, objectNotFoundInMetadata } = + useUpdateOneObjectRecord({ + objectNameSingular: 'workspaceMemberV2', + }); + const handleUpload = async (file: File) => { if (!file) { return; @@ -46,6 +49,26 @@ export const ProfilePictureUploader = () => { setUploadController(null); setErrorMessage(null); + + const avatarUrl = result?.data?.uploadProfilePicture; + + if (!avatarUrl) { + return; + } + if (!updateOneObject || objectNotFoundInMetadata) { + return; + } + await updateOneObject({ + idToUpdate: currentWorkspaceMember?.id ?? '', + input: { + avatarUrl, + }, + }); + + setCurrentWorkspaceMember( + (current) => ({ ...current, avatarUrl } as any), + ); + return result; } catch (error) { setErrorMessage('An error occured while uploading the picture.'); @@ -60,14 +83,19 @@ export const ProfilePictureUploader = () => { }; const handleRemove = async () => { - await removePicture({ - variables: { - where: { - id: currentUser?.id, - }, + if (!updateOneObject || objectNotFoundInMetadata) { + return; + } + await updateOneObject({ + idToUpdate: currentWorkspaceMember?.id ?? '', + input: { + avatarUrl: null, }, - refetchQueries: [getOperationName(GET_CURRENT_USER) ?? ''], }); + + setCurrentWorkspaceMember( + (current) => ({ ...current, avatarUrl: null } as any), + ); }; return ( diff --git a/front/src/modules/settings/profile/components/ToggleField.tsx b/front/src/modules/settings/profile/components/ToggleField.tsx index 51153d9e5a..478a4544bd 100644 --- a/front/src/modules/settings/profile/components/ToggleField.tsx +++ b/front/src/modules/settings/profile/components/ToggleField.tsx @@ -1,28 +1,40 @@ -import { useRecoilValue } from 'recoil'; +import { useRecoilState } from 'recoil'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; +import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord'; import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar'; import { Toggle } from '@/ui/input/components/Toggle'; -import { useUpdateAllowImpersonationMutation } from '~/generated/graphql'; export const ToggleField = () => { const { enqueueSnackBar } = useSnackBar(); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); + const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( + currentWorkspaceMemberState, + ); - const [updateAllowImpersonation] = useUpdateAllowImpersonationMutation(); + const { updateOneObject, objectNotFoundInMetadata } = + useUpdateOneObjectRecord({ + objectNameSingular: 'workspaceMemberV2', + }); const handleChange = async (value: boolean) => { try { - const { data, errors } = await updateAllowImpersonation({ - variables: { + if (!updateOneObject || objectNotFoundInMetadata) { + return; + } + await updateOneObject({ + idToUpdate: currentWorkspaceMember?.id ?? '', + input: { allowImpersonation: value, }, }); - - if (errors || !data?.allowImpersonation) { - throw new Error('Error while updating user'); - } + setCurrentWorkspaceMember( + (current) => + ({ + ...current, + allowImpersonation: value, + } as any), + ); } catch (err: any) { enqueueSnackBar(err?.message, { variant: 'error', diff --git a/front/src/modules/ui/object/field/meta-types/display/components/RelationFieldDisplay.tsx b/front/src/modules/ui/object/field/meta-types/display/components/RelationFieldDisplay.tsx index 9b6806a63e..b04c82f459 100644 --- a/front/src/modules/ui/object/field/meta-types/display/components/RelationFieldDisplay.tsx +++ b/front/src/modules/ui/object/field/meta-types/display/components/RelationFieldDisplay.tsx @@ -6,11 +6,6 @@ import { useRelationField } from '../../hooks/useRelationField'; export const RelationFieldDisplay = () => { const { fieldValue, fieldDefinition } = useRelationField(); - console.log({ - fieldDefinition, - fieldValue, - }); - const entityChipProps = getEntityChipFromFieldMetadata( fieldDefinition, fieldValue, diff --git a/front/src/modules/ui/object/field/meta-types/display/utils/getEntityChipFromFieldMetadata.ts b/front/src/modules/ui/object/field/meta-types/display/utils/getEntityChipFromFieldMetadata.ts index aab6fc1409..0255b9fb0a 100644 --- a/front/src/modules/ui/object/field/meta-types/display/utils/getEntityChipFromFieldMetadata.ts +++ b/front/src/modules/ui/object/field/meta-types/display/utils/getEntityChipFromFieldMetadata.ts @@ -18,11 +18,6 @@ export const getEntityChipFromFieldMetadata = ( entityId: fieldValue?.id, }; - console.log({ - fieldName, - fieldValue, - }); - // TODO: use every if (fieldName === 'accountOwner' && fieldValue) { chipValue.name = fieldValue.firstName + ' ' + fieldValue.lastName; diff --git a/front/src/modules/ui/object/field/meta-types/hooks/useRelationField.ts b/front/src/modules/ui/object/field/meta-types/hooks/useRelationField.ts index 3457e2a3ab..a48f60a26b 100644 --- a/front/src/modules/ui/object/field/meta-types/hooks/useRelationField.ts +++ b/front/src/modules/ui/object/field/meta-types/hooks/useRelationField.ts @@ -22,11 +22,6 @@ export const useRelationField = () => { }), ); - console.log({ - fieldDefinition, - fieldValue, - }); - const fieldInitialValue = useFieldInitialValue(); const initialSearchValue = fieldInitialValue?.isEmpty