From 2d0f63219f6aad1087552282ad3753a2847695fe Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 24 Nov 2023 00:07:15 +0100 Subject: [PATCH] Fix workspace prefill and remove user allowImpersonation Boolean --- front/src/generated-metadata/graphql.ts | 2 +- front/src/generated/graphql.tsx | 12 ++--- .../activities/tasks/components/TaskRow.tsx | 4 +- .../timeline/components/TimelineActivity.tsx | 5 +- .../constants/settingsFieldMetadataTypes.ts | 5 ++ .../profile/components/ToggleField.tsx | 51 ------------------- .../graphql/fragments/userQueryFragment.ts | 1 - .../users/graphql/queries/getCurrentUser.ts | 1 - .../workspace-member/types/WorkspaceMember.ts | 1 - front/src/testing/mock-data/users.ts | 6 +-- .../core/user/dtos/workspace-member.dto.ts | 3 -- server/src/core/user/services/user.service.ts | 6 +-- 12 files changed, 21 insertions(+), 76 deletions(-) delete mode 100644 front/src/modules/settings/profile/components/ToggleField.tsx diff --git a/front/src/generated-metadata/graphql.ts b/front/src/generated-metadata/graphql.ts index 607b20d92b..1a342a85a3 100644 --- a/front/src/generated-metadata/graphql.ts +++ b/front/src/generated-metadata/graphql.ts @@ -160,6 +160,7 @@ export enum FieldMetadataType { FullName = 'FULL_NAME', Link = 'LINK', Number = 'NUMBER', + Numeric = 'NUMERIC', Phone = 'PHONE', Probability = 'PROBABILITY', Relation = 'RELATION', @@ -445,7 +446,6 @@ export type UserEdge = { export type UserWorkspaceMember = { __typename?: 'UserWorkspaceMember'; - allowImpersonation: Scalars['Boolean']['output']; avatarUrl?: Maybe; colorScheme: Scalars['String']['output']; id: Scalars['ID']['output']; diff --git a/front/src/generated/graphql.tsx b/front/src/generated/graphql.tsx index f452892e2b..e5583ac1ea 100644 --- a/front/src/generated/graphql.tsx +++ b/front/src/generated/graphql.tsx @@ -126,6 +126,7 @@ export enum FieldMetadataType { FullName = 'FULL_NAME', Link = 'LINK', Number = 'NUMBER', + Numeric = 'NUMERIC', Phone = 'PHONE', Probability = 'PROBABILITY', Relation = 'RELATION', @@ -439,7 +440,6 @@ export type UserExists = { export type UserWorkspaceMember = { __typename?: 'UserWorkspaceMember'; - allowImpersonation: Scalars['Boolean']; avatarUrl?: Maybe; colorScheme: Scalars['String']; id: Scalars['ID']; @@ -609,7 +609,7 @@ export type ImpersonateMutationVariables = Exact<{ }>; -export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, allowImpersonation: boolean, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; +export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; export type RenewTokenMutationVariables = Exact<{ refreshToken: Scalars['String']; @@ -632,7 +632,7 @@ export type VerifyMutationVariables = Exact<{ }>; -export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, allowImpersonation: boolean, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; +export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; export type CheckUserExistsQueryVariables = Exact<{ email: Scalars['String']; @@ -654,7 +654,7 @@ export type UploadImageMutationVariables = Exact<{ export type UploadImageMutation = { __typename?: 'Mutation', uploadImage: string }; -export type UserQueryFragmentFragment = { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, allowImpersonation: boolean, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } }; +export type UserQueryFragmentFragment = { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } }; export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>; @@ -671,7 +671,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>; -export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, allowImpersonation: boolean, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } } }; +export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember: { __typename?: 'UserWorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'UserWorkspaceMemberName', firstName: string, lastName: string } }, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean } } }; export type DeleteCurrentWorkspaceMutationVariables = Exact<{ [key: string]: never; }>; @@ -732,7 +732,6 @@ export const UserQueryFragmentFragmentDoc = gql` colorScheme avatarUrl locale - allowImpersonation } defaultWorkspace { id @@ -1197,7 +1196,6 @@ export const GetCurrentUserDocument = gql` colorScheme avatarUrl locale - allowImpersonation } defaultWorkspace { id diff --git a/front/src/modules/activities/tasks/components/TaskRow.tsx b/front/src/modules/activities/tasks/components/TaskRow.tsx index be85620f73..4c6af3057f 100644 --- a/front/src/modules/activities/tasks/components/TaskRow.tsx +++ b/front/src/modules/activities/tasks/components/TaskRow.tsx @@ -1,5 +1,6 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; +import { isNonEmptyString } from '@sniptt/guards'; import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; @@ -71,7 +72,8 @@ export const TaskRow = ({ const theme = useTheme(); const openActivityRightDrawer = useOpenActivityRightDrawer(); - const body = JSON.parse(task.body ?? '{}')[0]?.content[0]?.text; + const body = JSON.parse(isNonEmptyString(task.body) ? task.body : '{}')[0] + ?.content[0]?.text; const { completeTask } = useCompleteTask(task); const activityTargetIds = diff --git a/front/src/modules/activities/timeline/components/TimelineActivity.tsx b/front/src/modules/activities/timeline/components/TimelineActivity.tsx index b3c6fec578..48ddd8adff 100644 --- a/front/src/modules/activities/timeline/components/TimelineActivity.tsx +++ b/front/src/modules/activities/timeline/components/TimelineActivity.tsx @@ -1,5 +1,6 @@ import { Tooltip } from 'react-tooltip'; import styled from '@emotion/styled'; +import { isNonEmptyString } from '@sniptt/guards'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; import { useCompleteTask } from '@/activities/tasks/hooks/useCompleteTask'; @@ -136,7 +137,9 @@ type TimelineActivityProps = { export const TimelineActivity = ({ activity }: TimelineActivityProps) => { const beautifiedCreatedAt = beautifyPastDateRelativeToNow(activity.createdAt); const exactCreatedAt = beautifyExactDateTime(activity.createdAt); - const body = JSON.parse(activity.body ?? '{}')[0]?.content[0]?.text; + const body = JSON.parse( + isNonEmptyString(activity.body) ? activity.body : '{}', + )[0]?.content[0]?.text; const openActivityRightDrawer = useOpenActivityRightDrawer(); const { completeTask } = useCompleteTask(activity); diff --git a/front/src/modules/settings/data-model/constants/settingsFieldMetadataTypes.ts b/front/src/modules/settings/data-model/constants/settingsFieldMetadataTypes.ts index f157d1c571..5bee581639 100644 --- a/front/src/modules/settings/data-model/constants/settingsFieldMetadataTypes.ts +++ b/front/src/modules/settings/data-model/constants/settingsFieldMetadataTypes.ts @@ -33,6 +33,11 @@ export const settingsFieldMetadataTypes: Record< defaultValue: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum magna enim, dapibus non enim in, lacinia faucibus nunc. Sed interdum ante sed felis facilisis, eget ultricies neque molestie. Mauris auctor, justo eu volutpat cursus, libero erat tempus nulla, non sodales lorem lacus a est.', }, + [FieldMetadataType.Numeric]: { + label: 'Numeric', + Icon: IconNumbers, + defaultValue: 2000, + }, [FieldMetadataType.Number]: { label: 'Number', Icon: IconNumbers, diff --git a/front/src/modules/settings/profile/components/ToggleField.tsx b/front/src/modules/settings/profile/components/ToggleField.tsx deleted file mode 100644 index 8f0813978e..0000000000 --- a/front/src/modules/settings/profile/components/ToggleField.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { useRecoilState } from 'recoil'; - -import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord'; -import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { Toggle } from '@/ui/input/components/Toggle'; - -export const ToggleField = () => { - const { enqueueSnackBar } = useSnackBar(); - - const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( - currentWorkspaceMemberState, - ); - - const { updateOneObject, objectNotFoundInMetadata } = - useUpdateOneObjectRecord({ - objectNameSingular: 'workspaceMember', - }); - - const handleChange = async (value: boolean) => { - try { - if (!updateOneObject || objectNotFoundInMetadata) { - throw new Error('Object not found in metadata'); - } - if (!currentWorkspaceMember?.id) { - throw new Error('User is not logged in'); - } - await updateOneObject({ - idToUpdate: currentWorkspaceMember?.id, - input: { - allowImpersonation: value, - }, - }); - setCurrentWorkspaceMember({ - ...currentWorkspaceMember, - allowImpersonation: value, - }); - } catch (err: any) { - enqueueSnackBar(err?.message, { - variant: 'error', - }); - } - }; - - return ( - - ); -}; diff --git a/front/src/modules/users/graphql/fragments/userQueryFragment.ts b/front/src/modules/users/graphql/fragments/userQueryFragment.ts index 9de53c9d05..8f19d338b9 100644 --- a/front/src/modules/users/graphql/fragments/userQueryFragment.ts +++ b/front/src/modules/users/graphql/fragments/userQueryFragment.ts @@ -17,7 +17,6 @@ export const USER_QUERY_FRAGMENT = gql` colorScheme avatarUrl locale - allowImpersonation } defaultWorkspace { id diff --git a/front/src/modules/users/graphql/queries/getCurrentUser.ts b/front/src/modules/users/graphql/queries/getCurrentUser.ts index f865a0b488..eba2e35848 100644 --- a/front/src/modules/users/graphql/queries/getCurrentUser.ts +++ b/front/src/modules/users/graphql/queries/getCurrentUser.ts @@ -18,7 +18,6 @@ export const GET_CURRENT_USER = gql` colorScheme avatarUrl locale - allowImpersonation } defaultWorkspace { id diff --git a/front/src/modules/workspace-member/types/WorkspaceMember.ts b/front/src/modules/workspace-member/types/WorkspaceMember.ts index 20111a3eb5..241d4f79d3 100644 --- a/front/src/modules/workspace-member/types/WorkspaceMember.ts +++ b/front/src/modules/workspace-member/types/WorkspaceMember.ts @@ -9,5 +9,4 @@ export type WorkspaceMember = { avatarUrl?: string | null; locale: string; colorScheme?: ColorScheme; - allowImpersonation: boolean; }; diff --git a/front/src/testing/mock-data/users.ts b/front/src/testing/mock-data/users.ts index 45216033c8..467745a80c 100644 --- a/front/src/testing/mock-data/users.ts +++ b/front/src/testing/mock-data/users.ts @@ -8,7 +8,7 @@ type MockedUser = Pick< User, 'id' | 'email' | 'firstName' | 'lastName' | 'canImpersonate' | '__typename' > & { - workspaceMember: Pick & { + workspaceMember: Pick & { workspace: Pick< Workspace, 'id' | 'displayName' | 'domainName' | 'inviteHash' | 'logo' | '__typename' @@ -36,7 +36,6 @@ export const mockedUsersData: Array = [ canImpersonate: false, workspaceMember: { id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - allowImpersonation: true, workspace: { __typename: 'Workspace', id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', @@ -61,7 +60,6 @@ export const mockedUsersData: Array = [ canImpersonate: false, workspaceMember: { id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - allowImpersonation: true, workspace: { __typename: 'Workspace', id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', @@ -89,7 +87,6 @@ export const mockedOnboardingUsersData: Array = [ canImpersonate: false, workspaceMember: { id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - allowImpersonation: true, workspace: { __typename: 'Workspace', id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', @@ -114,7 +111,6 @@ export const mockedOnboardingUsersData: Array = [ canImpersonate: false, workspaceMember: { id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - allowImpersonation: true, workspace: { __typename: 'Workspace', id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', diff --git a/server/src/core/user/dtos/workspace-member.dto.ts b/server/src/core/user/dtos/workspace-member.dto.ts index 0b05f7ab65..e0a268be76 100644 --- a/server/src/core/user/dtos/workspace-member.dto.ts +++ b/server/src/core/user/dtos/workspace-member.dto.ts @@ -27,7 +27,4 @@ export class UserWorkspaceMember { @Field({ nullable: false }) locale: string; - - @Field({ nullable: false }) - allowImpersonation: boolean; } diff --git a/server/src/core/user/services/user.service.ts b/server/src/core/user/services/user.service.ts index 438af946ac..c0b1c9098b 100644 --- a/server/src/core/user/services/user.service.ts +++ b/server/src/core/user/services/user.service.ts @@ -40,8 +40,6 @@ export class UserService extends TypeOrmQueryService { userWorkspaceMember.id = workspaceMembers[0].id; userWorkspaceMember.colorScheme = workspaceMembers[0].colorScheme; userWorkspaceMember.locale = workspaceMembers[0].locale; - userWorkspaceMember.allowImpersonation = - workspaceMembers[0].allowImpersonation; userWorkspaceMember.avatarUrl = workspaceMembers[0].avatarUrl; userWorkspaceMember.name = { firstName: workspaceMembers[0].nameFirstName, @@ -63,10 +61,10 @@ export class UserService extends TypeOrmQueryService { await workspaceDataSource?.query( `INSERT INTO ${dataSourceMetadata.schema}."workspaceMember" - ("nameFirstName", "nameLastName", "colorScheme", "userId", "allowImpersonation", "avatarUrl") + ("nameFirstName", "nameLastName", "colorScheme", "userId", "avatarUrl") VALUES ('${user.firstName}', '${user.lastName}', 'Light', '${ user.id - }', true, '${avatarUrl ?? ''}')`, + }', '${avatarUrl ?? ''}')`, ); }