diff --git a/front/src/generated-metadata/graphql.ts b/front/src/generated-metadata/graphql.ts index 607b20d92..1a342a85a 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 f452892e2..e5583ac1e 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 be85620f7..4c6af3057 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 b3c6fec57..48ddd8adf 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 f157d1c57..5bee58163 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 8f0813978..000000000 --- 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 9de53c9d0..8f19d338b 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 f865a0b48..eba2e3584 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 20111a3eb..241d4f79d 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 45216033c..467745a80 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 0b05f7ab6..e0a268be7 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 438af946a..c0b1c9098 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 ?? ''}')`, ); }