From bc49815ff0673b61bba1eb011bbd2ed51a8497ca Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Wed, 17 May 2023 14:50:49 +0200 Subject: [PATCH] Make all fields optional on entities (#121) * Make all fields optional on entities * Rewrite tests * Add test on TableHeader Cancel button --- front/src/App.tsx | 4 +- front/src/components/chips/PipeChip.tsx | 4 +- .../__stories__/EditableRelation.stories.tsx | 13 +- .../__tests__/EditableRelation.test.tsx | 21 ++-- .../__tests__/TableHeader.test.tsx | 7 +- .../__tests__/company.interface.test.ts | 84 +++++++++++++ .../__tests__/person.interface.test.ts | 80 +++++++++++++ .../__tests__/user.interface.test.ts | 71 +++++++++++ .../src/interfaces/company.interface.test.ts | 112 ------------------ front/src/interfaces/company.interface.ts | 91 +++++++------- front/src/interfaces/person.interface.test.ts | 54 --------- front/src/interfaces/person.interface.ts | 89 ++++++++------ front/src/interfaces/pipe.interface.ts | 11 +- front/src/interfaces/user.interface.test.ts | 36 ------ front/src/interfaces/user.interface.ts | 63 +++++----- front/src/interfaces/workspace.interface.ts | 43 +++++-- .../interfaces/workspace_member.interface.ts | 39 ++++++ front/src/layout/AppLayout.tsx | 2 +- .../src/layout/navbar/WorkspaceContainer.tsx | 2 +- .../navbar/__stories__/Navbar.stories.tsx | 3 +- front/src/pages/companies/Companies.tsx | 10 +- .../companies/__tests__/Companies.test.tsx | 2 +- front/src/pages/companies/companies-table.tsx | 38 +++--- front/src/pages/people/People.tsx | 6 +- .../pages/people/__tests__/People.test.tsx | 2 +- front/src/pages/people/people-table.tsx | 36 +++--- .../companies/{ => __tests__}/select.test.ts | 4 +- front/src/services/companies/update.ts | 6 +- .../people/{ => __tests__}/select.test.ts | 4 +- .../services/people/__tests__/update.test.ts | 17 +-- front/src/services/people/update.ts | 6 +- 31 files changed, 541 insertions(+), 419 deletions(-) create mode 100644 front/src/interfaces/__tests__/company.interface.test.ts create mode 100644 front/src/interfaces/__tests__/person.interface.test.ts create mode 100644 front/src/interfaces/__tests__/user.interface.test.ts delete mode 100644 front/src/interfaces/company.interface.test.ts delete mode 100644 front/src/interfaces/person.interface.test.ts delete mode 100644 front/src/interfaces/user.interface.test.ts create mode 100644 front/src/interfaces/workspace_member.interface.ts rename front/src/services/companies/{ => __tests__}/select.test.ts (78%) rename front/src/services/people/{ => __tests__}/select.test.ts (80%) diff --git a/front/src/App.tsx b/front/src/App.tsx index 6ae929665..8c69ad7c2 100644 --- a/front/src/App.tsx +++ b/front/src/App.tsx @@ -7,7 +7,7 @@ import AppLayout from './layout/AppLayout'; import { Routes, Route, Navigate } from 'react-router-dom'; import RequireAuth from './components/auth/RequireAuth'; import Opportunities from './pages/opportunities/Opportunities'; -import { User, mapUser } from './interfaces/user.interface'; +import { User, mapToUser } from './interfaces/user.interface'; import { useGetCurrentUserQuery } from './services/users'; import { getUserIdFromToken } from './services/AuthService'; @@ -19,7 +19,7 @@ function App() { useEffect(() => { if (data?.users[0]) { - setUser(mapUser(data?.users[0])); + setUser(mapToUser(data?.users[0])); } }, [data]); diff --git a/front/src/components/chips/PipeChip.tsx b/front/src/components/chips/PipeChip.tsx index 758c363d6..a30651ae5 100644 --- a/front/src/components/chips/PipeChip.tsx +++ b/front/src/components/chips/PipeChip.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; import styled from '@emotion/styled'; -import { Opportunity } from '../../interfaces/company.interface'; +import { Pipe } from '../../interfaces/pipe.interface'; type OwnProps = { - opportunity: Opportunity; + opportunity: Pipe; }; const StyledContainer = styled.span` diff --git a/front/src/components/table/editable-cell/__stories__/EditableRelation.stories.tsx b/front/src/components/table/editable-cell/__stories__/EditableRelation.stories.tsx index 995a1a666..b2553820a 100644 --- a/front/src/components/table/editable-cell/__stories__/EditableRelation.stories.tsx +++ b/front/src/components/table/editable-cell/__stories__/EditableRelation.stories.tsx @@ -3,7 +3,10 @@ import { ThemeProvider } from '@emotion/react'; import { lightTheme } from '../../../../layout/styles/themes'; import { StoryFn } from '@storybook/react'; import CompanyChip, { CompanyChipPropsType } from '../../../chips/CompanyChip'; -import { Company, mapCompany } from '../../../../interfaces/company.interface'; +import { + Company, + mapToCompany, +} from '../../../../interfaces/company.interface'; import { MockedProvider } from '@apollo/client/testing'; import { SEARCH_COMPANY_QUERY } from '../../../../services/search/search'; import styled from '@emotion/styled'; @@ -76,8 +79,10 @@ EditableRelationStory.args = { ChipComponent: CompanyChip, chipComponentPropsMapper: (company: Company): CompanyChipPropsType => { return { - name: company.name, - picture: `https://www.google.com/s2/favicons?domain=${company.domain_name}&sz=256`, + name: company.name || '', + picture: company.domainName + ? `https://www.google.com/s2/favicons?domain=${company.domainName}&sz=256` + : undefined, }; }, changeHandler: (relation: Company) => { @@ -90,7 +95,7 @@ EditableRelationStory.args = { }), resultMapper: (company) => ({ render: (company) => company.name, - value: mapCompany(company), + value: mapToCompany(company), }), } satisfies SearchConfigType, }; diff --git a/front/src/components/table/editable-cell/__tests__/EditableRelation.test.tsx b/front/src/components/table/editable-cell/__tests__/EditableRelation.test.tsx index 97ac53da3..a3c3c2819 100644 --- a/front/src/components/table/editable-cell/__tests__/EditableRelation.test.tsx +++ b/front/src/components/table/editable-cell/__tests__/EditableRelation.test.tsx @@ -49,16 +49,15 @@ it('Checks the EditableRelation editing event bubbles up', async () => { }); await waitFor(() => { - expect(func).toBeCalledWith( - expect.objectContaining({ - accountOwner: null, - address: undefined, - domain_name: 'abnb.com', - employees: undefined, - id: 'abnb', - name: 'Airbnb', - opportunities: [], - }), - ); + expect(func).toBeCalledWith({ + accountOwner: undefined, + address: undefined, + domainName: 'abnb.com', + employees: undefined, + creationDate: undefined, + id: 'abnb', + name: 'Airbnb', + pipes: [], + }); }); }); diff --git a/front/src/components/table/table-header/__tests__/TableHeader.test.tsx b/front/src/components/table/table-header/__tests__/TableHeader.test.tsx index 448dce4fa..1070e7358 100644 --- a/front/src/components/table/table-header/__tests__/TableHeader.test.tsx +++ b/front/src/components/table/table-header/__tests__/TableHeader.test.tsx @@ -3,7 +3,7 @@ import { fireEvent, render } from '@testing-library/react'; import { RegularTableHeader } from '../__stories__/TableHeader.stories'; it('Checks the TableHeader renders', async () => { - const { getByText } = render(); + const { getByText, queryByText } = render(); const sortDropdownButton = getByText('Sort'); fireEvent.click(sortDropdownButton); @@ -12,4 +12,9 @@ it('Checks the TableHeader renders', async () => { fireEvent.click(sortByCreatedAt); expect(getByText('Created at')).toBeDefined(); + + const cancelButton = getByText('Cancel'); + fireEvent.click(cancelButton); + + expect(queryByText('Created at')).toBeNull(); }); diff --git a/front/src/interfaces/__tests__/company.interface.test.ts b/front/src/interfaces/__tests__/company.interface.test.ts new file mode 100644 index 000000000..b0f99e948 --- /dev/null +++ b/front/src/interfaces/__tests__/company.interface.test.ts @@ -0,0 +1,84 @@ +import { + mapToGqlCompany, + mapToCompany, + Company, + GraphqlMutationCompany, + GraphqlQueryCompany, +} from '../company.interface'; + +describe('Company mappers', () => { + it('should map GraphQl Company to Company', () => { + const now = new Date(); + now.setMilliseconds(0); + const graphQLCompany = { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', + name: 'ACME', + domain_name: 'exmaple.com', + created_at: now.toUTCString(), + employees: '10', + address: '1 Infinite Loop, 95014 Cupertino, California, USA', + account_owner: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87', + email: 'john@example.com', + display_name: 'John Doe', + __typename: 'User', + }, + pipes: [ + { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6c', + name: 'Pipe 1', + icon: '!', + __typename: 'Pipe', + }, + ], + __typename: 'companies', + } satisfies GraphqlQueryCompany; + + const company = mapToCompany(graphQLCompany); + expect(company).toStrictEqual({ + id: graphQLCompany.id, + name: graphQLCompany.name, + domainName: graphQLCompany.domain_name, + creationDate: new Date(now.toUTCString()), + employees: graphQLCompany.employees, + address: graphQLCompany.address, + accountOwner: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87', + email: 'john@example.com', + displayName: 'John Doe', + workspaceMember: undefined, + }, + pipes: [], + } satisfies Company); + }); + + it('should map Company to GraphQLCompany', () => { + const now = new Date(); + now.setMilliseconds(0); + const company = { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', + name: 'ACME', + domainName: 'example.com', + employees: '10', + address: '1 Infinite Loop, 95014 Cupertino, California, USA', + pipes: [], + accountOwner: { + id: '522d4ec4-c46b-4360-a0a7-df8df170be81', + email: 'john@example.com', + displayName: 'John Doe', + }, + creationDate: now, + }; + const graphQLCompany = mapToGqlCompany(company); + expect(graphQLCompany).toStrictEqual({ + id: company.id, + name: company.name, + domain_name: company.domainName, + created_at: now.toUTCString(), + employees: company.employees, + address: company.address, + account_owner_id: '522d4ec4-c46b-4360-a0a7-df8df170be81', + __typename: 'companies', + } satisfies GraphqlMutationCompany); + }); +}); diff --git a/front/src/interfaces/__tests__/person.interface.test.ts b/front/src/interfaces/__tests__/person.interface.test.ts new file mode 100644 index 000000000..af091cb5c --- /dev/null +++ b/front/src/interfaces/__tests__/person.interface.test.ts @@ -0,0 +1,80 @@ +import { + mapToGqlPerson, + mapToPerson, + Person, + GraphqlMutationPerson, + GraphqlQueryPerson, +} from '../person.interface'; + +describe('Person mappers', () => { + it('should map GraphqlPerson to Person', () => { + const now = new Date(); + now.setMilliseconds(0); + const graphQLPerson = { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', + firstname: 'John', + lastname: 'Doe', + created_at: now.toUTCString(), + email: 'john.doe@gmail.com', + phone: '+1 (555) 123-4567', + city: 'Paris', + company: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87', + name: 'John Doe', + __typename: 'Company', + }, + __typename: 'people', + } satisfies GraphqlQueryPerson; + + const person = mapToPerson(graphQLPerson); + expect(person).toStrictEqual({ + id: graphQLPerson.id, + firstname: graphQLPerson.firstname, + lastname: graphQLPerson.lastname, + creationDate: new Date(now.toUTCString()), + email: graphQLPerson.email, + city: graphQLPerson.city, + phone: graphQLPerson.phone, + company: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87', + accountOwner: undefined, + address: undefined, + creationDate: undefined, + domainName: undefined, + employees: undefined, + name: 'John Doe', + pipes: [], + }, + } satisfies Person); + }); + + it('should map Person to GraphQlPerson', () => { + const now = new Date(); + now.setMilliseconds(0); + const person = { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', + firstname: 'John', + lastname: 'Doe', + creationDate: new Date(now.toUTCString()), + email: 'john.doe@gmail.com', + phone: '+1 (555) 123-4567', + city: 'Paris', + company: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87', + }, + } satisfies Person; + + const graphQLPerson = mapToGqlPerson(person); + expect(graphQLPerson).toStrictEqual({ + id: person.id, + firstname: person.firstname, + lastname: person.lastname, + created_at: now.toUTCString(), + email: person.email, + city: person.city, + phone: person.phone, + company_id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87', + __typename: 'people', + } satisfies GraphqlMutationPerson); + }); +}); diff --git a/front/src/interfaces/__tests__/user.interface.test.ts b/front/src/interfaces/__tests__/user.interface.test.ts new file mode 100644 index 000000000..28c2a4d3a --- /dev/null +++ b/front/src/interfaces/__tests__/user.interface.test.ts @@ -0,0 +1,71 @@ +import { + mapToGqlUser, + mapToUser, + User, + GraphqlMutationUser, + GraphqlQueryUser, +} from '../user.interface'; + +describe('User mappers', () => { + it('should map GraphqlUser to User', () => { + const now = new Date(); + now.setMilliseconds(0); + const graphQLUser = { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', + display_name: 'John Doe', + email: 'john.doe@gmail.com', + workspace_member: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e88', + workspace: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e89', + display_name: 'John Doe', + __typename: 'workspace', + }, + __typename: 'workspace_members', + }, + __typename: 'users', + } satisfies GraphqlQueryUser; + + const User = mapToUser(graphQLUser); + expect(User).toStrictEqual({ + id: graphQLUser.id, + displayName: graphQLUser.display_name, + email: graphQLUser.email, + workspaceMember: { + id: graphQLUser.workspace_member.id, + workspace: { + id: graphQLUser.workspace_member.workspace.id, + displayName: graphQLUser.workspace_member.workspace.display_name, + domainName: undefined, + logo: undefined, + }, + }, + } satisfies User); + }); + + it('should map User to GraphQlUser', () => { + const now = new Date(); + now.setMilliseconds(0); + const user = { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', + displayName: 'John Doe', + email: 'john.doe@gmail.com', + workspaceMember: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e88', + workspace: { + id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e89', + displayName: 'John Doe', + }, + }, + } satisfies User; + + const graphQLUser = mapToGqlUser(user); + expect(graphQLUser).toStrictEqual({ + id: user.id, + display_name: user.displayName, + email: user.email, + workspace_member_id: user.workspaceMember.id, + __typename: 'users', + } satisfies GraphqlMutationUser); + }); +}); diff --git a/front/src/interfaces/company.interface.test.ts b/front/src/interfaces/company.interface.test.ts deleted file mode 100644 index 044e69e1b..000000000 --- a/front/src/interfaces/company.interface.test.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { mapGqlCompany, mapCompany } from './company.interface'; - -describe('mapCompany', () => { - it('should map company', () => { - const now = new Date(); - now.setMilliseconds(0); - const company = mapCompany({ - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: 'ACME', - domain_name: 'exmaple.com', - created_at: now.toUTCString(), - account_owner: { - id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87', - email: 'john@example.com', - displayName: 'John Doe', - __typename: 'User', - }, - employees: 10, - address: '1 Infinite Loop, 95014 Cupertino, California, USA', - __typename: 'Company', - }); - expect(company.id).toBe('7dfbc3f7-6e5e-4128-957e-8d86808cdf6b'); - expect(company.name).toBe('ACME'); - expect(company.domain_name).toBe('exmaple.com'); - expect(company.creationDate).toEqual(now); - expect(company.accountOwner?.id).toBe( - '7af20dea-0412-4c4c-8b13-d6f0e6e09e87', - ); - expect(company.accountOwner?.email).toBe('john@example.com'); - expect(company.accountOwner?.displayName).toBe('John Doe'); - expect(company.employees).toBe(10); - expect(company.address).toBe( - '1 Infinite Loop, 95014 Cupertino, California, USA', - ); - }); - - it('should map company with no account owner', () => { - const now = new Date(); - now.setMilliseconds(0); - const company = mapCompany({ - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: 'ACME', - domain_name: 'exmaple.com', - created_at: now.toUTCString(), - employees: 10, - address: '1 Infinite Loop, 95014 Cupertino, California, USA', - __typename: 'Company', - }); - expect(company.id).toBe('7dfbc3f7-6e5e-4128-957e-8d86808cdf6b'); - expect(company.name).toBe('ACME'); - expect(company.domain_name).toBe('exmaple.com'); - expect(company.creationDate).toEqual(now); - expect(company.accountOwner).toBeNull(); - expect(company.employees).toBe(10); - expect(company.address).toBe( - '1 Infinite Loop, 95014 Cupertino, California, USA', - ); - }); - - it('should map company back', () => { - const now = new Date(); - now.setMilliseconds(0); - const company = mapGqlCompany({ - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: 'ACME', - domain_name: 'exmaple.com', - employees: 10, - address: '1 Infinite Loop, 95014 Cupertino, California, USA', - opportunities: [], - accountOwner: { - id: '522d4ec4-c46b-4360-a0a7-df8df170be81', - email: 'john@example.com', - displayName: 'John Doe', - }, - creationDate: now, - }); - expect(company.id).toBe('7dfbc3f7-6e5e-4128-957e-8d86808cdf6b'); - expect(company.name).toBe('ACME'); - expect(company.domain_name).toBe('exmaple.com'); - expect(company.created_at).toEqual(now.toUTCString()); - expect(company.account_owner_id).toBe( - '522d4ec4-c46b-4360-a0a7-df8df170be81', - ); - expect(company.employees).toBe(10); - expect(company.address).toBe( - '1 Infinite Loop, 95014 Cupertino, California, USA', - ); - }); - - it('should map company with no account owner back', () => { - const now = new Date(); - now.setMilliseconds(0); - const company = mapGqlCompany({ - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: 'ACME', - domain_name: 'exmaple.com', - employees: 10, - address: '1 Infinite Loop, 95014 Cupertino, California, USA', - opportunities: [], - creationDate: now, - }); - expect(company.id).toBe('7dfbc3f7-6e5e-4128-957e-8d86808cdf6b'); - expect(company.name).toBe('ACME'); - expect(company.domain_name).toBe('exmaple.com'); - expect(company.created_at).toEqual(now.toUTCString()); - expect(company.account_owner_id).toBeUndefined(); - expect(company.employees).toBe(10); - expect(company.address).toBe( - '1 Infinite Loop, 95014 Cupertino, California, USA', - ); - }); -}); diff --git a/front/src/interfaces/company.interface.ts b/front/src/interfaces/company.interface.ts index 3ae6397e5..bfc11e340 100644 --- a/front/src/interfaces/company.interface.ts +++ b/front/src/interfaces/company.interface.ts @@ -1,75 +1,72 @@ -import { GraphqlQueryUser, User } from './user.interface'; - -export interface Opportunity { - id: string; - name: string; - icon: string; -} +import { Pipe } from 'stream'; +import { GraphqlQueryUser, User, mapToUser } from './user.interface'; +import { GraphqlQueryPipe } from './pipe.interface'; export type Company = { id: string; - name: string; - domain_name: string; - employees: number; - address: string; - opportunities: Opportunity[]; + name?: string; + domainName?: string; + employees?: string; + address?: string; + + creationDate?: Date; + + pipes?: Pipe[]; accountOwner?: User | null; - creationDate: Date; }; export type GraphqlQueryCompany = { id: string; - name: string; - domain_name: string; + name?: string; + domain_name?: string; + employees?: string; + address?: string; + + created_at?: string; + account_owner?: GraphqlQueryUser | null; - employees: number; - address: string; - created_at: string; + pipes?: GraphqlQueryPipe[] | null; __typename: string; }; export type GraphqlMutationCompany = { id: string; - name: string; - domain_name: string; + name?: string; + domain_name?: string; + employees?: string; + address?: string; + + created_at?: string; + account_owner_id?: string; - employees: number; - address: string; - created_at: string; - account_owner?: GraphqlQueryUser | null; + __typename: string; }; -export const mapCompany = (company: GraphqlQueryCompany): Company => ({ +export const mapToCompany = (company: GraphqlQueryCompany): Company => ({ id: company.id, employees: company.employees, name: company.name, address: company.address, - domain_name: company.domain_name, + domainName: company.domain_name, + creationDate: company.created_at ? new Date(company.created_at) : undefined, + accountOwner: company.account_owner - ? { - id: company.account_owner.id, - email: company.account_owner.email, - displayName: company.account_owner.displayName, - } - : null, - creationDate: new Date(company.created_at), - opportunities: [], + ? mapToUser(company.account_owner) + : company.account_owner, + pipes: [], }); -export const mapGqlCompany = (company: Company): GraphqlMutationCompany => ({ +export const mapToGqlCompany = (company: Company): GraphqlMutationCompany => ({ + id: company.id, name: company.name, - domain_name: company.domain_name, - created_at: company.creationDate.toUTCString(), - account_owner_id: company.accountOwner?.id, + domain_name: company.domainName, address: company.address, employees: company.employees, - id: company.id, - account_owner: company.accountOwner - ? { - id: company.accountOwner?.id, - email: company.accountOwner?.email, - displayName: company.accountOwner?.displayName, - __typename: 'users', - } - : null, + + created_at: company.creationDate + ? company.creationDate.toUTCString() + : undefined, + + account_owner_id: company.accountOwner?.id, + __typename: 'companies', }); diff --git a/front/src/interfaces/person.interface.test.ts b/front/src/interfaces/person.interface.test.ts deleted file mode 100644 index 7eebcd860..000000000 --- a/front/src/interfaces/person.interface.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { mapGqlPerson, mapPerson } from './person.interface'; - -describe('mapPerson', () => { - it('should map person', () => { - const person = mapPerson({ - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - firstname: 'John', - lastname: 'Doe', - email: '', - phone: '', - city: '', - created_at: '', - company: { - __typename: '', - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: '', - domain_name: '', - employees: 0, - address: '', - created_at: '', - account_owner: null, - }, - __typename: '', - }); - expect(person.firstname).toBe('John'); - }); - - it('should map person back', () => { - const person = mapGqlPerson({ - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - firstname: 'John', - lastname: 'Doe', - email: '', - phone: '', - city: '', - company: { - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: 'Test', - domain_name: '', - opportunities: [], - employees: 0, - address: '', - creationDate: new Date(), - }, - creationDate: new Date(), - pipe: { - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6c', - name: '', - icon: '', - }, - }); - expect(person.firstname).toBe('John'); - }); -}); diff --git a/front/src/interfaces/person.interface.ts b/front/src/interfaces/person.interface.ts index d6d34e891..440f65276 100644 --- a/front/src/interfaces/person.interface.ts +++ b/front/src/interfaces/person.interface.ts @@ -1,64 +1,77 @@ -import { Company, GraphqlQueryCompany, mapCompany } from './company.interface'; +import { + Company, + GraphqlQueryCompany, + mapToCompany, +} from './company.interface'; import { Pipe } from './pipe.interface'; export type Person = { id: string; - firstname: string; - lastname: string; - picture?: string; - email: string; - company: Company | null; - phone: string; - creationDate: Date; - pipe: Pipe | null; - city: string; + firstname?: string; + lastname?: string; + picture?: string | null; + email?: string; + phone?: string; + city?: string; + + creationDate?: Date; + + company?: Company | null; + pipes?: Pipe[] | null; }; export type GraphqlQueryPerson = { - city: string; - company: GraphqlQueryCompany | null; - created_at: string; - email: string; - firstname: string; id: string; - lastname: string; - phone: string; + firstname?: string; + lastname?: string; + city?: string; + email?: string; + phone?: string; + + created_at?: string; + + company?: GraphqlQueryCompany | null; + __typename: string; }; export type GraphqlMutationPerson = { - city: string; - company_id?: string; - created_at: string; - email: string; - firstname: string; id: string; - lastname: string; - phone: string; + firstname?: string; + lastname?: string; + email?: string; + phone?: string; + city?: string; + created_at?: string; + company_id?: string; __typename: string; }; -export const mapPerson = (person: GraphqlQueryPerson): Person => ({ +export const mapToPerson = (person: GraphqlQueryPerson): Person => ({ id: person.id, + firstname: person.firstname, + lastname: person.lastname, email: person.email, phone: person.phone, city: person.city, - firstname: person.firstname, - lastname: person.lastname, - creationDate: new Date(person.created_at), - pipe: { - name: 'coucou', - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - icon: '💰', - }, - company: person.company ? mapCompany(person.company) : null, + + creationDate: person.created_at ? new Date(person.created_at) : undefined, + + company: person.company ? mapToCompany(person.company) : null, }); -export const mapGqlPerson = (person: Person): GraphqlMutationPerson => ({ - ...(person as Omit), +export const mapToGqlPerson = (person: Person): GraphqlMutationPerson => ({ + id: person.id, firstname: person.firstname, lastname: person.lastname, - created_at: person.creationDate.toUTCString(), + email: person.email, + phone: person.phone, + city: person.city, + + created_at: person.creationDate + ? person.creationDate.toUTCString() + : undefined, + company_id: person.company?.id, - __typename: 'People', + __typename: 'people', }); diff --git a/front/src/interfaces/pipe.interface.ts b/front/src/interfaces/pipe.interface.ts index fa05c3953..1032341fc 100644 --- a/front/src/interfaces/pipe.interface.ts +++ b/front/src/interfaces/pipe.interface.ts @@ -1,5 +1,12 @@ export interface Pipe { id: string; - name: string; - icon: string; + name?: string; + icon?: string | null; +} + +export interface GraphqlQueryPipe { + id: string; + name?: string; + icon?: string | null; + __typename: string; } diff --git a/front/src/interfaces/user.interface.test.ts b/front/src/interfaces/user.interface.test.ts deleted file mode 100644 index fa7c2cd03..000000000 --- a/front/src/interfaces/user.interface.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { mapUser } from './user.interface'; - -describe('mapUser', () => { - it('should map person', () => { - const graphQLUser = { - id: '16506ba8-196c-4c13-a4a7-a22cb5eccfa1', - email: 'charles@twenty.com', - displayName: 'Charles Bochet', - workspace_member: { - workspace: { - id: '7ed9d212-1c25-4d02-bf25-6aeccf7ea419', - domain_name: 'twenty.com', - display_name: 'Twenty', - logo: 'data:image/png;base64,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', - __typename: 'workspaces', - }, - __typename: 'workspace_members', - }, - __typename: 'users', - }; - const user = mapUser(graphQLUser); - expect(user).toStrictEqual({ - id: graphQLUser.id, - email: graphQLUser.email, - displayName: graphQLUser.displayName, - workspace_member: { - workspace: { - id: graphQLUser?.workspace_member?.workspace.id, - displayName: graphQLUser?.workspace_member?.workspace.display_name, - domainName: graphQLUser?.workspace_member?.workspace.domain_name, - logo: graphQLUser?.workspace_member?.workspace.logo, - }, - }, - }); - }); -}); diff --git a/front/src/interfaces/user.interface.ts b/front/src/interfaces/user.interface.ts index aaed906bd..24e7c1cdb 100644 --- a/front/src/interfaces/user.interface.ts +++ b/front/src/interfaces/user.interface.ts @@ -1,42 +1,45 @@ import { GraphqlQueryWorkspaceMember, WorkspaceMember, -} from './workspace.interface'; + mapToWorkspaceMember, +} from './workspace_member.interface'; + +export interface User { + id: string; + email?: string; + displayName?: string; + workspaceMember?: WorkspaceMember; +} export type GraphqlQueryUser = { id: string; - email: string; - displayName: string; + email?: string; + display_name?: string; workspace_member?: GraphqlQueryWorkspaceMember; __typename: string; }; -export interface User { +export type GraphqlMutationUser = { id: string; - email: string; - displayName: string; - workspace_member?: WorkspaceMember; -} - -export type PartialUser = Partial & - Pick; - -export const mapUser = (user: GraphqlQueryUser): User => { - const mappedUser = { - id: user.id, - email: user.email, - displayName: user.displayName, - } as User; - if (user.workspace_member) { - mappedUser['workspace_member'] = { - workspace: { - id: user.workspace_member.workspace.id, - displayName: user.workspace_member.workspace.display_name, - domainName: user.workspace_member.workspace.domain_name, - logo: user.workspace_member.workspace.logo, - }, - }; - } - - return mappedUser; + email?: string; + display_name?: string; + workspace_member_id?: string; + __typename: string; }; + +export const mapToUser = (user: GraphqlQueryUser): User => ({ + id: user.id, + email: user.email, + displayName: user.display_name, + workspaceMember: user.workspace_member + ? mapToWorkspaceMember(user.workspace_member) + : user.workspace_member, +}); + +export const mapToGqlUser = (user: User): GraphqlMutationUser => ({ + id: user.id, + email: user.email, + display_name: user.displayName, + workspace_member_id: user.workspaceMember?.id, + __typename: 'users', +}); diff --git a/front/src/interfaces/workspace.interface.ts b/front/src/interfaces/workspace.interface.ts index 32f9fc041..fa0ebdd80 100644 --- a/front/src/interfaces/workspace.interface.ts +++ b/front/src/interfaces/workspace.interface.ts @@ -1,22 +1,41 @@ export interface Workspace { id: string; - domainName: string; - displayName: string; - logo: string; -} - -export interface WorkspaceMember { - workspace: Workspace; + domainName?: string; + displayName?: string; + logo?: string | null; } export type GraphqlQueryWorkspace = { id: string; - display_name: string; - domain_name: string; - logo: string; + display_name?: string; + domain_name?: string; + logo?: string | null; __typename: string; }; -export type GraphqlQueryWorkspaceMember = { - workspace: GraphqlQueryWorkspace; + +export type GraphqlMutationWorkspace = { + id: string; + display_name?: string; + domain_name?: string; + logo?: string | null; __typename: string; }; + +export const mapToWorkspace = ( + workspace: GraphqlQueryWorkspace, +): Workspace => ({ + id: workspace.id, + domainName: workspace.domain_name, + displayName: workspace.display_name, + logo: workspace.logo, +}); + +export const mapToGqlWorkspace = ( + workspace: Workspace, +): GraphqlMutationWorkspace => ({ + id: workspace.id, + domain_name: workspace.domainName, + display_name: workspace.displayName, + logo: workspace.logo, + __typename: 'workspaces', +}); diff --git a/front/src/interfaces/workspace_member.interface.ts b/front/src/interfaces/workspace_member.interface.ts new file mode 100644 index 000000000..b41c3900a --- /dev/null +++ b/front/src/interfaces/workspace_member.interface.ts @@ -0,0 +1,39 @@ +import { + Workspace, + GraphqlQueryWorkspace, + mapToWorkspace, +} from './workspace.interface'; + +export interface WorkspaceMember { + id: string; + workspace: Workspace; +} + +export type GraphqlQueryWorkspaceMember = { + id: string; + workspace: GraphqlQueryWorkspace; + __typename: string; +}; + +export type GraphqlMutationWorkspaceMember = { + id: string; + workspace_id: string; + __typename: string; +}; + +export const mapToWorkspaceMember = ( + workspaceMember: GraphqlQueryWorkspaceMember, +): WorkspaceMember => ({ + id: workspaceMember.id, + workspace: workspaceMember.workspace + ? mapToWorkspace(workspaceMember.workspace) + : workspaceMember.workspace, +}); + +export const mapToGqlWorkspaceMember = ( + workspaceMember: WorkspaceMember, +): GraphqlMutationWorkspaceMember => ({ + id: workspaceMember.id, + workspace_id: workspaceMember.workspace?.id, + __typename: 'workspace_members', +}); diff --git a/front/src/layout/AppLayout.tsx b/front/src/layout/AppLayout.tsx index 4dd9f99b7..90b62d2e8 100644 --- a/front/src/layout/AppLayout.tsx +++ b/front/src/layout/AppLayout.tsx @@ -27,7 +27,7 @@ function AppLayout({ children, user }: OwnProps) { return ( - + {children} diff --git a/front/src/layout/navbar/WorkspaceContainer.tsx b/front/src/layout/navbar/WorkspaceContainer.tsx index 01a97916a..cf1cef5bc 100644 --- a/front/src/layout/navbar/WorkspaceContainer.tsx +++ b/front/src/layout/navbar/WorkspaceContainer.tsx @@ -20,7 +20,7 @@ const StyledContainer = styled.button` `; type StyledLogoProps = { - logo: string; + logo?: string | null; }; const StyledLogo = styled.div` diff --git a/front/src/layout/navbar/__stories__/Navbar.stories.tsx b/front/src/layout/navbar/__stories__/Navbar.stories.tsx index 305a04ca7..b942d4991 100644 --- a/front/src/layout/navbar/__stories__/Navbar.stories.tsx +++ b/front/src/layout/navbar/__stories__/Navbar.stories.tsx @@ -20,7 +20,8 @@ export const NavbarOnCompanies = () => { id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', email: 'charles@twenty.com', displayName: 'Charles Bochet', - workspace_member: { + workspaceMember: { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', workspace: { id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', displayName: 'Claap', diff --git a/front/src/pages/companies/Companies.tsx b/front/src/pages/companies/Companies.tsx index 97e750952..9841de0ae 100644 --- a/front/src/pages/companies/Companies.tsx +++ b/front/src/pages/companies/Companies.tsx @@ -11,7 +11,7 @@ import { useCompaniesQuery, } from '../../services/companies'; import Table from '../../components/table/Table'; -import { Company, mapCompany } from '../../interfaces/company.interface'; +import { Company, mapToCompany } from '../../interfaces/company.interface'; import { useCompaniesColumns, availableFilters, @@ -61,7 +61,7 @@ function Companies() { useEffect(() => { if (!loading) { if (data) { - setInternalData(data.companies.map(mapCompany)); + setInternalData(data.companies.map(mapToCompany)); } } }, [loading, setInternalData, data]); @@ -70,10 +70,10 @@ function Companies() { const newCompany: Company = { id: uuidv4(), name: '', - domain_name: '', - employees: 0, + domainName: '', + employees: '0', address: '', - opportunities: [], + pipes: [], creationDate: new Date(), accountOwner: null, }; diff --git a/front/src/pages/companies/__tests__/Companies.test.tsx b/front/src/pages/companies/__tests__/Companies.test.tsx index 8ecce15da..5a00322ab 100644 --- a/front/src/pages/companies/__tests__/Companies.test.tsx +++ b/front/src/pages/companies/__tests__/Companies.test.tsx @@ -18,7 +18,7 @@ jest.mock('../../../apollo', () => { variables: GraphqlMutationCompany; }) => { const gqlCompany = arg.variables as unknown as GraphqlQueryCompany; - return { data: companyInterface.mapCompany(gqlCompany) }; + return { data: companyInterface.mapToCompany(gqlCompany) }; }, }, }; diff --git a/front/src/pages/companies/companies-table.tsx b/front/src/pages/companies/companies-table.tsx index 5b5dd6cd2..d3331e5a1 100644 --- a/front/src/pages/companies/companies-table.tsx +++ b/front/src/pages/companies/companies-table.tsx @@ -1,5 +1,5 @@ import { CellContext, createColumnHelper } from '@tanstack/react-table'; -import { Company, mapCompany } from '../../interfaces/company.interface'; +import { Company, mapToCompany } from '../../interfaces/company.interface'; import { updateCompany } from '../../services/companies'; import ColumnHead from '../../components/table/ColumnHead'; import CompanyChip from '../../components/chips/CompanyChip'; @@ -29,7 +29,7 @@ import { } from '../../services/search/search'; import EditableDate from '../../components/table/editable-cell/EditableDate'; import EditableRelation from '../../components/table/editable-cell/EditableRelation'; -import { User, mapUser } from '../../interfaces/user.interface'; +import { User, mapToUser } from '../../interfaces/user.interface'; import { useMemo } from 'react'; import { SelectAllCheckbox } from '../../components/table/SelectAllCheckbox'; import Checkbox from '../../components/form/Checkbox'; @@ -79,7 +79,7 @@ export const availableFilters = [ }), resultMapper: (company) => ({ render: (company) => company.name, - value: mapCompany(company), + value: mapToCompany(company), }), }, selectedValueRender: (company) => company.name, @@ -110,24 +110,24 @@ export const availableFilters = [ name: { _ilike: `%${searchInput}%` }, }), resultMapper: (company) => ({ - render: (company) => company.domain_name, - value: mapCompany(company), + render: (company) => company.domainName, + value: mapToCompany(company), }), }, - selectedValueRender: (company) => company.domain_name, + selectedValueRender: (company) => company.domainName, operands: [ { label: 'Equal', id: 'equal', whereTemplate: (company) => ({ - domain_name: { _eq: company.domain_name }, + domain_name: { _eq: company.domainName }, }), }, { label: 'Not equal', id: 'not-equal', whereTemplate: (company) => ({ - _not: { domain_name: { _eq: company.domain_name } }, + _not: { domain_name: { _eq: company.domainName } }, }), }, ], @@ -163,9 +163,9 @@ export const useCompaniesColumns = () => { ), cell: (props) => ( { const company = props.row.original; company.name = value; @@ -181,23 +181,23 @@ export const useCompaniesColumns = () => { ), cell: (props) => ( { const company = props.row.original; - company.employees = parseInt(value); + company.employees = value; updateCompany(company); }} /> ), }), - columnHelper.accessor('domain_name', { + columnHelper.accessor('domainName', { header: () => } />, cell: (props) => ( { const company = props.row.original; - company.domain_name = value; + company.domainName = value; updateCompany(company); }} /> @@ -207,7 +207,7 @@ export const useCompaniesColumns = () => { header: () => } />, cell: (props) => ( { const company = props.row.original; company.address = value; @@ -222,7 +222,7 @@ export const useCompaniesColumns = () => { ), cell: (props) => ( { const company = props.row.original; company.creationDate = value; @@ -244,7 +244,7 @@ export const useCompaniesColumns = () => { accountOwner: User, ): PersonChipPropsType => { return { - name: accountOwner.displayName, + name: accountOwner.displayName || '', }; }} changeHandler={(relation: User) => { @@ -268,7 +268,7 @@ export const useCompaniesColumns = () => { }), resultMapper: (accountOwner) => ({ render: (accountOwner) => accountOwner.displayName, - value: mapUser(accountOwner), + value: mapToUser(accountOwner), }), } satisfies SearchConfigType } diff --git a/front/src/pages/people/People.tsx b/front/src/pages/people/People.tsx index d6453dc50..d01c1da6e 100644 --- a/front/src/pages/people/People.tsx +++ b/front/src/pages/people/People.tsx @@ -8,7 +8,7 @@ import { availableSorts, usePeopleColumns, } from './people-table'; -import { Person, mapPerson } from '../../interfaces/person.interface'; +import { Person, mapToPerson } from '../../interfaces/person.interface'; import { useCallback, useEffect, useRef, useState } from 'react'; import { PeopleSelectedSortType, @@ -58,7 +58,7 @@ function People() { useEffect(() => { if (!loading) { if (data) { - setInternalData(data.people.map(mapPerson)); + setInternalData(data.people.map(mapToPerson)); } } }, [loading, setInternalData, data]); @@ -71,7 +71,7 @@ function People() { email: '', phone: '', company: null, - pipe: null, + pipes: [], creationDate: new Date(), city: '', }; diff --git a/front/src/pages/people/__tests__/People.test.tsx b/front/src/pages/people/__tests__/People.test.tsx index b698a6f48..3b28b99b9 100644 --- a/front/src/pages/people/__tests__/People.test.tsx +++ b/front/src/pages/people/__tests__/People.test.tsx @@ -18,7 +18,7 @@ jest.mock('../../../apollo', () => { variables: GraphqlMutationPerson; }) => { const gqlPerson = arg.variables as unknown as GraphqlQueryPerson; - return { data: personInterface.mapPerson(gqlPerson) }; + return { data: personInterface.mapToPerson(gqlPerson) }; }, }, }; diff --git a/front/src/pages/people/people-table.tsx b/front/src/pages/people/people-table.tsx index 08fc465e7..de7e1b774 100644 --- a/front/src/pages/people/people-table.tsx +++ b/front/src/pages/people/people-table.tsx @@ -14,7 +14,7 @@ import Checkbox from '../../components/form/Checkbox'; import CompanyChip, { CompanyChipPropsType, } from '../../components/chips/CompanyChip'; -import { Person, mapPerson } from '../../interfaces/person.interface'; +import { Person, mapToPerson } from '../../interfaces/person.interface'; import EditableText from '../../components/table/editable-cell/EditableText'; import { FilterConfigType, @@ -26,7 +26,7 @@ import { SEARCH_COMPANY_QUERY, SEARCH_PEOPLE_QUERY, } from '../../services/search/search'; -import { Company, mapCompany } from '../../interfaces/company.interface'; +import { Company, mapToCompany } from '../../interfaces/company.interface'; import EditablePhone from '../../components/table/editable-cell/EditablePhone'; import EditableFullName from '../../components/table/editable-cell/EditableFullName'; import EditableDate from '../../components/table/editable-cell/EditableDate'; @@ -93,7 +93,7 @@ export const fullnameFilter = { }), resultMapper: (person) => ({ render: (person) => `${person.firstname} ${person.lastname}`, - value: mapPerson(person), + value: mapToPerson(person), }), }, selectedValueRender: (person) => `${person.firstname} ${person.lastname}`, @@ -133,11 +133,11 @@ export const companyFilter = { name: { _ilike: `%${searchInput}%` }, }), resultMapper: (data) => ({ - value: mapCompany(data), + value: mapToCompany(data), render: (company) => company.name, }), }, - selectedValueRender: (company) => company.name, + selectedValueRender: (company) => company.name || '', operands: [ { label: 'Equal', @@ -167,7 +167,7 @@ export const emailFilter = { }), resultMapper: (person) => ({ render: (person) => person.email, - value: mapPerson(person), + value: mapToPerson(person), }), }, operands: [ @@ -186,7 +186,7 @@ export const emailFilter = { }), }, ], - selectedValueRender: (person) => person.email, + selectedValueRender: (person) => person.email || '', } satisfies FilterConfigType; export const cityFilter = { @@ -200,7 +200,7 @@ export const cityFilter = { }), resultMapper: (person) => ({ render: (person) => person.city, - value: mapPerson(person), + value: mapToPerson(person), }), }, operands: [ @@ -219,7 +219,7 @@ export const cityFilter = { }), }, ], - selectedValueRender: (person) => person.email, + selectedValueRender: (person) => person.email || '', } satisfies FilterConfigType; export const availableFilters = [ @@ -256,8 +256,8 @@ export const usePeopleColumns = () => { header: () => } />, cell: (props) => ( { const person = props.row.original; person.firstname = firstName; @@ -272,7 +272,7 @@ export const usePeopleColumns = () => { cell: (props) => ( { const person = props.row.original; person.email = value; @@ -292,8 +292,8 @@ export const usePeopleColumns = () => { ChipComponent={CompanyChip} chipComponentPropsMapper={(company): CompanyChipPropsType => { return { - name: company.name, - picture: `https://www.google.com/s2/favicons?domain=${company.domain_name}&sz=256`, + name: company.name || '', + picture: `https://www.google.com/s2/favicons?domain=${company.domainName}&sz=256`, }; }} changeHandler={(relation) => { @@ -313,7 +313,7 @@ export const usePeopleColumns = () => { }), resultMapper: (company) => ({ render: (company) => company.name, - value: mapCompany(company), + value: mapToCompany(company), }), } satisfies SearchConfigType } @@ -325,7 +325,7 @@ export const usePeopleColumns = () => { cell: (props) => ( { const person = props.row.original; person.phone = value; @@ -340,7 +340,7 @@ export const usePeopleColumns = () => { ), cell: (props) => ( { const person = props.row.original; person.creationDate = value; @@ -355,7 +355,7 @@ export const usePeopleColumns = () => { { const person = props.row.original; person.city = value; diff --git a/front/src/services/companies/select.test.ts b/front/src/services/companies/__tests__/select.test.ts similarity index 78% rename from front/src/services/companies/select.test.ts rename to front/src/services/companies/__tests__/select.test.ts index ec884969f..b8285923b 100644 --- a/front/src/services/companies/select.test.ts +++ b/front/src/services/companies/__tests__/select.test.ts @@ -1,5 +1,5 @@ -import { reduceSortsToOrderBy } from '../../components/table/table-header/helpers'; -import { CompaniesSelectedSortType } from './select'; +import { reduceSortsToOrderBy } from '../../../components/table/table-header/helpers'; +import { CompaniesSelectedSortType } from '../select'; describe('reduceSortsToOrderBy', () => { it('should return an array of objects with the id as key and the order as value', () => { diff --git a/front/src/services/companies/update.ts b/front/src/services/companies/update.ts index c5bd64a1d..af200ce3f 100644 --- a/front/src/services/companies/update.ts +++ b/front/src/services/companies/update.ts @@ -1,5 +1,5 @@ import { FetchResult, gql } from '@apollo/client'; -import { Company, mapGqlCompany } from '../../interfaces/company.interface'; +import { Company, mapToGqlCompany } from '../../interfaces/company.interface'; import { apiClient } from '../../apollo'; export const UPDATE_COMPANY = gql` @@ -95,7 +95,7 @@ export async function updateCompany( ): Promise> { const result = await apiClient.mutate({ mutation: UPDATE_COMPANY, - variables: mapGqlCompany(company), + variables: mapToGqlCompany(company), }); return result; } @@ -105,7 +105,7 @@ export async function insertCompany( ): Promise> { const result = await apiClient.mutate({ mutation: INSERT_COMPANY, - variables: mapGqlCompany(company), + variables: mapToGqlCompany(company), }); return result; diff --git a/front/src/services/people/select.test.ts b/front/src/services/people/__tests__/select.test.ts similarity index 80% rename from front/src/services/people/select.test.ts rename to front/src/services/people/__tests__/select.test.ts index 47b134f0f..a30fdb068 100644 --- a/front/src/services/people/select.test.ts +++ b/front/src/services/people/__tests__/select.test.ts @@ -1,5 +1,5 @@ -import { reduceSortsToOrderBy } from '../../components/table/table-header/helpers'; -import { PeopleSelectedSortType } from './select'; +import { reduceSortsToOrderBy } from '../../../components/table/table-header/helpers'; +import { PeopleSelectedSortType } from '../select'; describe('reduceSortsToOrderBy', () => { it('should return an array of objects with the id as key and the order as value', () => { diff --git a/front/src/services/people/__tests__/update.test.ts b/front/src/services/people/__tests__/update.test.ts index 8b170a280..5c5223a57 100644 --- a/front/src/services/people/__tests__/update.test.ts +++ b/front/src/services/people/__tests__/update.test.ts @@ -15,7 +15,7 @@ jest.mock('../../../apollo', () => { variables: GraphqlMutationPerson; }) => { const gqlPerson = arg.variables as unknown as GraphqlQueryPerson; - return { data: personInterface.mapPerson(gqlPerson) }; + return { data: personInterface.mapToPerson(gqlPerson) }; }, }, }; @@ -30,17 +30,18 @@ it('updates a person', async () => { company: { id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', name: 'ACME', - domain_name: 'example.com', + domainName: 'example.com', }, phone: '+1 (555) 123-4567', - pipe: { - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', - name: 'Customer', - icon: '!', - }, + pipes: [ + { + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', + name: 'Customer', + icon: '!', + }, + ], creationDate: new Date(), city: 'San Francisco', - countryCode: 'US', }); expect(result.data).toBeDefined(); result.data && expect(result.data.email).toBe('john@example.com'); diff --git a/front/src/services/people/update.ts b/front/src/services/people/update.ts index 2a5a7eb73..5b688e299 100644 --- a/front/src/services/people/update.ts +++ b/front/src/services/people/update.ts @@ -1,5 +1,5 @@ import { FetchResult, gql } from '@apollo/client'; -import { Person, mapGqlPerson } from '../../interfaces/person.interface'; +import { Person, mapToGqlPerson } from '../../interfaces/person.interface'; import { apiClient } from '../../apollo'; export const UPDATE_PERSON = gql` @@ -112,7 +112,7 @@ export async function updatePerson( ): Promise> { const result = await apiClient.mutate({ mutation: UPDATE_PERSON, - variables: mapGqlPerson(person), + variables: mapToGqlPerson(person), }); return result; } @@ -122,7 +122,7 @@ export async function insertPerson( ): Promise> { const result = await apiClient.mutate({ mutation: INSERT_PERSON, - variables: mapGqlPerson(person), + variables: mapToGqlPerson(person), }); return result;