diff --git a/front/src/modules/auth/states/currentUserState.ts b/front/src/modules/auth/states/currentUserState.ts index 2361c402b6..4402a67d33 100644 --- a/front/src/modules/auth/states/currentUserState.ts +++ b/front/src/modules/auth/states/currentUserState.ts @@ -1,8 +1,16 @@ import { atom } from 'recoil'; -import { User } from '@/users/interfaces/user.interface'; +import { User, Workspace, WorkspaceMember } from '~/generated/graphql'; -export const currentUserState = atom({ +type CurrentUser = Pick & { + workspaceMember?: + | (Pick & { + workspace: Pick; + }) + | null; +}; + +export const currentUserState = atom({ key: 'currentUserState', default: null, }); diff --git a/front/src/modules/companies/components/CompanyEditableNameCell.tsx b/front/src/modules/companies/components/CompanyEditableNameCell.tsx index 68426f01ad..20327a07a8 100644 --- a/front/src/modules/companies/components/CompanyEditableNameCell.tsx +++ b/front/src/modules/companies/components/CompanyEditableNameCell.tsx @@ -2,19 +2,24 @@ import { CellCommentChip } from '@/comments/components/CellCommentChip'; import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer'; import EditableChip from '@/ui/components/editable-cell/types/EditableChip'; import { getLogoUrlFromDomainName } from '@/utils/utils'; -import { CommentableType } from '~/generated/graphql'; - -import { Company } from '../interfaces/company.interface'; -import { updateCompany } from '../services'; +import { + CommentableType, + GetCompaniesQuery, + useUpdateCompanyMutation, +} from '~/generated/graphql'; import CompanyChip from './CompanyChip'; type OwnProps = { - company: Company; + company: Pick< + GetCompaniesQuery['companies'][0], + 'id' | 'name' | 'domainName' | '_commentCount' | 'accountOwner' + >; }; export function CompanyEditableNameChipCell({ company }: OwnProps) { const openCommentRightDrawer = useOpenCommentRightDrawer(); + const [updateCompany] = useUpdateCompanyMutation(); function handleCommentClick(event: React.MouseEvent) { event.preventDefault(); @@ -35,8 +40,11 @@ export function CompanyEditableNameChipCell({ company }: OwnProps) { picture={getLogoUrlFromDomainName(company.domainName)} changeHandler={(value: string) => { updateCompany({ - ...company, - name: value, + variables: { + ...company, + name: value, + accountOwnerId: company.accountOwner?.id, + }, }); }} ChipComponent={CompanyChip} diff --git a/front/src/modules/companies/interfaces/company.interface.ts b/front/src/modules/companies/interfaces/company.interface.ts deleted file mode 100644 index bc21471b06..0000000000 --- a/front/src/modules/companies/interfaces/company.interface.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Company as GQLCompany } from '../../../generated/graphql'; -import { DeepPartial } from '../../utils/utils'; - -export type Company = DeepPartial & { id: string }; - -export type GraphqlQueryCompany = Company; - -export type GraphqlMutationCompany = Company; - -export const mapToCompany = (company: GraphqlQueryCompany): Company => company; - -export const mapToGqlCompany = (company: Company): GraphqlMutationCompany => - company; diff --git a/front/src/modules/companies/services/update.ts b/front/src/modules/companies/services/update.ts index 2c65c2d033..bd00d53385 100644 --- a/front/src/modules/companies/services/update.ts +++ b/front/src/modules/companies/services/update.ts @@ -1,12 +1,4 @@ -import { FetchResult, gql } from '@apollo/client'; -import { getOperationName } from '@apollo/client/utilities'; - -import { apiClient } from '~/apollo'; - -import { UpdateCompanyMutationVariables } from '../../../generated/graphql'; -import { Company, mapToGqlCompany } from '../interfaces/company.interface'; - -import { GET_COMPANIES } from './select'; +import { gql } from '@apollo/client'; export const UPDATE_COMPANY = gql` mutation UpdateCompany( @@ -80,36 +72,3 @@ export const DELETE_COMPANIES = gql` } } `; - -export async function updateCompany( - company: UpdateCompanyMutationVariables, -): Promise> { - const result = await apiClient.mutate({ - mutation: UPDATE_COMPANY, - variables: company, - }); - return result; -} - -export async function insertCompany( - company: Company, -): Promise> { - const result = await apiClient.mutate({ - mutation: INSERT_COMPANY, - variables: mapToGqlCompany(company), - refetchQueries: [getOperationName(GET_COMPANIES) ?? ''], - }); - - return result; -} - -export async function deleteCompanies( - peopleIds: string[], -): Promise> { - const result = await apiClient.mutate({ - mutation: DELETE_COMPANIES, - variables: { ids: peopleIds }, - }); - - return result; -} diff --git a/front/src/modules/filters-and-sorts/helpers.ts b/front/src/modules/filters-and-sorts/helpers.ts index ef2198b8ce..26394ee317 100644 --- a/front/src/modules/filters-and-sorts/helpers.ts +++ b/front/src/modules/filters-and-sorts/helpers.ts @@ -1,23 +1,17 @@ import { SortOrder as Order_By } from '~/generated/graphql'; -import { BoolExpType } from '../utils/interfaces/generic.interface'; - import { - FilterableFieldsType, FilterWhereType, SelectedFilterType, } from './interfaces/filters/interface'; import { SelectedSortType } from './interfaces/sorts/interface'; -export const reduceFiltersToWhere = < - ValueType extends FilterableFieldsType, - WhereTemplateType extends FilterWhereType, ->( - filters: Array>, -): BoolExpType => { +export const reduceFiltersToWhere = ( + filters: Array>, +): Record => { const where = filters.reduce((acc, filter) => { return { ...acc, ...filter.operand.whereTemplate(filter.value) }; - }, {} as BoolExpType); + }, {} as Record); return where; }; diff --git a/front/src/modules/filters-and-sorts/interfaces/filters/interface.ts b/front/src/modules/filters-and-sorts/interfaces/filters/interface.ts index 4fbb434320..c042c5dbc8 100644 --- a/front/src/modules/filters-and-sorts/interfaces/filters/interface.ts +++ b/front/src/modules/filters-and-sorts/interfaces/filters/interface.ts @@ -1,80 +1,64 @@ import { ReactNode } from 'react'; import { SearchConfigType } from '@/search/interfaces/interface'; -import { - AnyEntity, - BoolExpType, - UnknownType, -} from '@/utils/interfaces/generic.interface'; -export type FilterableFieldsType = AnyEntity; -export type FilterWhereRelationType = AnyEntity; -export type FilterWhereType = FilterWhereRelationType | string | UnknownType; +export type FilterableFieldsType = any; +export type FilterWhereRelationType = any; +export type FilterWhereType = FilterWhereRelationType | string | unknown; -export type FilterConfigType< - FilteredType extends FilterableFieldsType, - WhereType extends FilterWhereType = UnknownType, -> = { +export type FilterConfigType = { key: string; label: string; icon: ReactNode; - type: WhereType extends UnknownType + type: WhereType extends unknown ? 'relation' | 'text' | 'date' - : WhereType extends AnyEntity + : WhereType extends any ? 'relation' : WhereType extends string ? 'text' | 'date' : never; - operands: FilterOperandType[]; -} & (WhereType extends UnknownType - ? { searchConfig?: SearchConfigType } - : WhereType extends AnyEntity - ? { searchConfig: SearchConfigType } + operands: FilterOperandType[]; +} & (WhereType extends unknown + ? { searchConfig?: SearchConfigType } + : WhereType extends any + ? { searchConfig: SearchConfigType } : WhereType extends string ? object : never) & - (WhereType extends UnknownType + (WhereType extends unknown ? { selectedValueRender?: (selected: any) => string } - : WhereType extends AnyEntity + : WhereType extends any ? { selectedValueRender: (selected: WhereType) => string } : WhereType extends string ? object : never); -export type FilterOperandType< - FilteredType extends FilterableFieldsType, - WhereType extends FilterWhereType = UnknownType, -> = WhereType extends UnknownType - ? any - : WhereType extends FilterWhereRelationType - ? FilterOperandRelationType - : WhereType extends string - ? FilterOperandFieldType - : never; +export type FilterOperandType = + WhereType extends unknown + ? any + : WhereType extends FilterWhereRelationType + ? FilterOperandRelationType + : WhereType extends string + ? FilterOperandFieldType + : never; -type FilterOperandRelationType< - FilteredType extends FilterableFieldsType, - WhereType extends FilterWhereType, -> = { +type FilterOperandRelationType = { label: 'Is' | 'Is not'; id: 'is' | 'is_not'; - whereTemplate: (value: WhereType) => BoolExpType; + whereTemplate: (value: WhereType) => any; }; -type FilterOperandFieldType = { +type FilterOperandFieldType = { label: 'Contains' | 'Does not contain' | 'Greater than' | 'Less than'; id: 'like' | 'not_like' | 'greater_than' | 'less_than'; - whereTemplate: (value: string) => BoolExpType; + whereTemplate: (value: string) => any; }; -export type SelectedFilterType< - FilteredType extends FilterableFieldsType, - WhereType extends FilterWhereType = UnknownType, -> = { +export type SelectedFilterType = { key: string; - value: WhereType extends UnknownType ? any : WhereType; + value: WhereType; displayValue: string; label: string; icon: ReactNode; - operand: FilterOperandType; + operand: FilterOperandType; }; diff --git a/front/src/modules/people/components/EditablePeopleFullName.tsx b/front/src/modules/people/components/EditablePeopleFullName.tsx index dccc667625..e32bb12ca7 100644 --- a/front/src/modules/people/components/EditablePeopleFullName.tsx +++ b/front/src/modules/people/components/EditablePeopleFullName.tsx @@ -4,14 +4,12 @@ import styled from '@emotion/styled'; import { CellCommentChip } from '@/comments/components/CellCommentChip'; import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer'; import { EditableDoubleText } from '@/ui/components/editable-cell/types/EditableDoubleText'; -import { CommentableType } from '~/generated/graphql'; - -import { Person } from '../interfaces/person.interface'; +import { CommentableType, Person } from '~/generated/graphql'; import { PersonChip } from './PersonChip'; type OwnProps = { - person: Person; + person: Pick; onChange: (firstname: string, lastname: string) => void; }; diff --git a/front/src/modules/people/components/PeopleCompanyCell.tsx b/front/src/modules/people/components/PeopleCompanyCell.tsx index bd29308978..be3cf97668 100644 --- a/front/src/modules/people/components/PeopleCompanyCell.tsx +++ b/front/src/modules/people/components/PeopleCompanyCell.tsx @@ -4,27 +4,25 @@ import { v4 } from 'uuid'; import CompanyChip, { CompanyChipPropsType, } from '@/companies/components/CompanyChip'; -import { - Company, - mapToCompany, -} from '@/companies/interfaces/company.interface'; import { SearchConfigType } from '@/search/interfaces/interface'; import { SEARCH_COMPANY_QUERY } from '@/search/services/search'; import { EditableRelation } from '@/ui/components/editable-cell/types/EditableRelation'; import { logError } from '@/utils/logs/logError'; import { getLogoUrlFromDomainName } from '@/utils/utils'; import { + Company, + Person, QueryMode, useInsertCompanyMutation, useUpdatePeopleMutation, } from '~/generated/graphql'; -import { mapToGqlPerson, Person } from '../interfaces/person.interface'; - import { PeopleCompanyCreateCell } from './PeopleCompanyCreateCell'; export type OwnProps = { - people: Person; + people: Pick & { + company?: Pick | null; + }; }; export function PeopleCompanyCell({ people }: OwnProps) { @@ -52,7 +50,7 @@ export function PeopleCompanyCell({ people }: OwnProps) { await updatePeople({ variables: { - ...mapToGqlPerson(people), + ...people, companyId: newCompanyId, }, }); @@ -75,7 +73,7 @@ export function PeopleCompanyCell({ people }: OwnProps) { onCreate={handleCompanyCreate} /> ) : ( - + relation={people.company} searchPlaceholder="Company" ChipComponent={CompanyChip} @@ -88,7 +86,7 @@ export function PeopleCompanyCell({ people }: OwnProps) { onChange={async (relation) => { await updatePeople({ variables: { - ...mapToGqlPerson(people), + ...people, companyId: relation.id, }, }); @@ -101,10 +99,10 @@ export function PeopleCompanyCell({ people }: OwnProps) { name: { contains: `%${searchInput}%`, mode: QueryMode.Insensitive }, }), resultMapper: (company) => ({ - render: (company) => company.name, - value: mapToCompany(company), + render: (company: any) => company.name, + value: company, }), - } satisfies SearchConfigType + } satisfies SearchConfigType } onCreate={() => { setIsCreating(true); diff --git a/front/src/modules/people/interfaces/person.interface.ts b/front/src/modules/people/interfaces/person.interface.ts deleted file mode 100644 index d56560f4d3..0000000000 --- a/front/src/modules/people/interfaces/person.interface.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Person as GQLPerson } from '../../../generated/graphql'; -import { DeepPartial } from '../../utils/utils'; - -export type Person = DeepPartial & { id: GQLPerson['id'] }; - -export type GraphqlQueryPerson = Person; - -export type GraphqlMutationPerson = Person; - -export const mapToPerson = (person: GraphqlQueryPerson): Person => person; - -export const mapToGqlPerson = (person: Person): GraphqlMutationPerson => person; diff --git a/front/src/modules/people/services/__tests__/update.test.ts b/front/src/modules/people/services/__tests__/update.test.ts deleted file mode 100644 index 6cc0f5f1c3..0000000000 --- a/front/src/modules/people/services/__tests__/update.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - GraphqlMutationPerson, - GraphqlQueryPerson, -} from '../../interfaces/person.interface'; -import { updatePerson } from '../update'; - -jest.mock('~/apollo', () => { - const personInterface = jest.requireActual( - '@/people/interfaces/person.interface', - ); - return { - apiClient: { - mutate: (arg: { - mutation: unknown; - variables: GraphqlMutationPerson; - }) => { - const gqlPerson = arg.variables as unknown as GraphqlQueryPerson; - return { data: personInterface.mapToPerson(gqlPerson) }; - }, - }, - }; -}); - -it('updates a person', async () => { - const result = await updatePerson({ - firstname: 'John', - lastname: 'Doe', - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6c', - email: 'john@example.com', - company: { - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: 'ACME', - domainName: 'example.com', - __typename: 'Company', - }, - phone: '+1 (555) 123-4567', - pipes: [ - { - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', - name: 'Customer', - icon: '!', - }, - ], - createdAt: new Date().toISOString(), - city: 'San Francisco', - __typename: 'Person', - }); - expect(result.data).toBeDefined(); - result.data && expect(result.data.email).toBe('john@example.com'); -}); diff --git a/front/src/modules/people/services/update.ts b/front/src/modules/people/services/update.ts index 449a4a0928..343d7c5de7 100644 --- a/front/src/modules/people/services/update.ts +++ b/front/src/modules/people/services/update.ts @@ -1,10 +1,4 @@ -import { FetchResult, gql } from '@apollo/client'; -import { getOperationName } from '@apollo/client/utilities'; - -import { apiClient } from '../../../apollo'; -import { mapToGqlPerson, Person } from '../interfaces/person.interface'; - -import { GET_PEOPLE } from './select'; +import { gql } from '@apollo/client'; export const UPDATE_PERSON = gql` mutation UpdatePeople( @@ -90,36 +84,3 @@ export const DELETE_PEOPLE = gql` } } `; - -export async function updatePerson( - person: Person, -): Promise> { - const result = await apiClient.mutate({ - mutation: UPDATE_PERSON, - variables: person, - }); - return result; -} - -export async function insertPerson( - person: Person, -): Promise> { - const result = await apiClient.mutate({ - mutation: INSERT_PERSON, - variables: mapToGqlPerson(person), - refetchQueries: [getOperationName(GET_PEOPLE) ?? ''], - }); - - return result; -} - -export async function deletePeople( - peopleIds: string[], -): Promise> { - const result = await apiClient.mutate({ - mutation: DELETE_PEOPLE, - variables: { ids: peopleIds }, - }); - - return result; -} diff --git a/front/src/modules/search/interfaces/interface.ts b/front/src/modules/search/interfaces/interface.ts index 609e0d5ecd..2423932c68 100644 --- a/front/src/modules/search/interfaces/interface.ts +++ b/front/src/modules/search/interfaces/interface.ts @@ -1,26 +1,7 @@ -import { ReactNode } from 'react'; import { DocumentNode } from 'graphql'; -import { - AnyEntity, - BoolExpType, - GqlType, - UnknownType, -} from '@/utils/interfaces/generic.interface'; - -export type SearchConfigType< - SearchType extends AnyEntity | UnknownType = UnknownType, -> = SearchType extends UnknownType - ? { - query: DocumentNode; - template: (searchInput: string) => any; - resultMapper: (data: any) => any; - } - : { - query: DocumentNode; - template: (searchInput: string) => BoolExpType; - resultMapper: (data: GqlType) => { - value: SearchType; - render: (value: SearchType) => ReactNode; - }; - }; +export type SearchConfigType = { + query: DocumentNode; + template: (searchInput: string) => any; + resultMapper: (data: any) => any; +}; diff --git a/front/src/modules/search/services/search.ts b/front/src/modules/search/services/search.ts index b0d3274696..49ef510f31 100644 --- a/front/src/modules/search/services/search.ts +++ b/front/src/modules/search/services/search.ts @@ -2,7 +2,6 @@ import { useMemo, useState } from 'react'; import { gql, useQuery } from '@apollo/client'; import { debounce } from '@/utils/debounce'; -import { AnyEntity, UnknownType } from '@/utils/interfaces/generic.interface'; import { SearchConfigType } from '../interfaces/interface'; @@ -64,22 +63,21 @@ export const SEARCH_COMPANY_QUERY = gql` } `; -export type SearchResultsType = - { - results: { - render: (value: T) => string; - value: T; - }[]; - loading: boolean; - }; +export type SearchResultsType = { + results: { + render: (value: T) => string; + value: T; + }[]; + loading: boolean; +}; -export const useSearch = (): [ +export const useSearch = (): [ SearchResultsType, React.Dispatch>, - React.Dispatch | null>>, + React.Dispatch>, string, ] => { - const [searchConfig, setSearchConfig] = useState | null>( + const [searchConfig, setSearchConfig] = useState( null, ); const [searchInput, setSearchInput] = useState(''); diff --git a/front/src/modules/ui/components/editable-cell/types/EditableRelation.tsx b/front/src/modules/ui/components/editable-cell/types/EditableRelation.tsx index 2c0713f428..c65ae92eda 100644 --- a/front/src/modules/ui/components/editable-cell/types/EditableRelation.tsx +++ b/front/src/modules/ui/components/editable-cell/types/EditableRelation.tsx @@ -8,7 +8,6 @@ import { useSearch } from '@/search/services/search'; import { IconPlus } from '@/ui/icons/index'; import { textInputStyle } from '@/ui/layout/styles/themes'; import { isSomeInputInEditModeState } from '@/ui/tables/states/isSomeInputInEditModeState'; -import { AnyEntity } from '@/utils/interfaces/generic.interface'; import { isDefined } from '@/utils/type-guards/isDefined'; import { isNonEmptyString } from '@/utils/type-guards/isNonEmptyString'; @@ -86,13 +85,10 @@ const StyledCreateButtonText = styled.div` color: ${(props) => props.theme.text60}; `; -export type EditableRelationProps< - RelationType extends AnyEntity, - ChipComponentPropsType, -> = { - relation?: RelationType | null; +export type EditableRelationProps = { + relation?: any; searchPlaceholder: string; - searchConfig: SearchConfigType; + searchConfig: SearchConfigType; onChange: (relation: RelationType) => void; onChangeSearchInput?: (searchInput: string) => void; editModeHorizontalAlign?: 'left' | 'right'; @@ -105,10 +101,7 @@ export type EditableRelationProps< }; // TODO: split this component -export function EditableRelation< - RelationType extends AnyEntity, - ChipComponentPropsType, ->({ +export function EditableRelation({ relation, searchPlaceholder, searchConfig, diff --git a/front/src/modules/ui/components/table/table-header/FilterDropdownButton.tsx b/front/src/modules/ui/components/table/table-header/FilterDropdownButton.tsx index b23d9d8a76..8b544bb090 100644 --- a/front/src/modules/ui/components/table/table-header/FilterDropdownButton.tsx +++ b/front/src/modules/ui/components/table/table-header/FilterDropdownButton.tsx @@ -40,7 +40,8 @@ export const FilterDropdownButton = ({ FilterOperandType | undefined >(undefined); - const [filterSearchResults, setSearchInput, setFilterSearch] = useSearch(); + const [filterSearchResults, setSearchInput, setFilterSearch] = + useSearch(); const resetState = useCallback(() => { setIsOperandSelectionUnfolded(false); @@ -79,7 +80,7 @@ export const FilterDropdownButton = ({ )); const renderSearchResults = ( - filterSearchResults: SearchResultsType, + filterSearchResults: SearchResultsType, selectedFilter: FilterConfigType, selectedFilterOperand: FilterOperandType, ) => { @@ -155,7 +156,7 @@ export const FilterDropdownButton = ({ displayValue: event.target.value, icon: selectedFilter.icon, operand: selectedFilterOperand, - }); + } as SelectedFilterType); } } }} @@ -172,7 +173,7 @@ export const FilterDropdownButton = ({ displayValue: humanReadableDate(date), icon: selectedFilter.icon, operand: selectedFilterOperand, - }); + } as SelectedFilterType); }} customInput={<>} customCalendarContainer={styled.div` @@ -200,7 +201,7 @@ export const FilterDropdownButton = ({ setIsUnfolded={setIsUnfolded} resetState={resetState} > - {selectedFilter + {selectedFilter && selectedFilterOperand ? isOperandSelectionUnfolded ? renderOperandSelection : renderValueSelection(selectedFilter, selectedFilterOperand) diff --git a/front/src/modules/users/interfaces/user.interface.ts b/front/src/modules/users/interfaces/user.interface.ts deleted file mode 100644 index d13578450f..0000000000 --- a/front/src/modules/users/interfaces/user.interface.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { User as GQLUser } from '../../../generated/graphql'; -import { DeepPartial } from '../../utils/utils'; - -export type User = DeepPartial & { id: string }; - -export type GraphqlQueryUser = User; - -export type GraphqlMutationUser = User; - -export const mapToUser = (user: GraphqlQueryUser): User => user; - -export const mapToGqlUser = (user: User): GraphqlMutationUser => user; diff --git a/front/src/modules/users/interfaces/workspaceMember.interface.ts b/front/src/modules/users/interfaces/workspaceMember.interface.ts deleted file mode 100644 index 8f7a63c48e..0000000000 --- a/front/src/modules/users/interfaces/workspaceMember.interface.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { WorkspaceMember as GQLWorkspaceMember } from '../../../generated/graphql'; -import { DeepPartial } from '../../utils/utils'; - -export type WorkspaceMember = DeepPartial & { - id: GQLWorkspaceMember['id']; -}; - -export type GraphqlQueryWorkspaceMember = WorkspaceMember; - -export type GraphqlMutationWorkspaceMember = WorkspaceMember; - -export const mapToWorkspaceMember = ( - workspaceMember: GraphqlQueryWorkspaceMember, -): WorkspaceMember => workspaceMember; - -export const mapToGqlWorkspaceMember = ( - workspaceMember: WorkspaceMember, -): GraphqlMutationWorkspaceMember => workspaceMember; diff --git a/front/src/modules/users/services/test.ts b/front/src/modules/users/services/test.ts deleted file mode 100644 index 426098273c..0000000000 --- a/front/src/modules/users/services/test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { gql } from '@apollo/client'; - -export const GET_CURRENT_USER = gql` - query getUsers { - findManyUser { - id - } - } -`; diff --git a/front/src/modules/utils/interfaces/generic.interface.ts b/front/src/modules/utils/interfaces/generic.interface.ts deleted file mode 100644 index d2cf8e4b29..0000000000 --- a/front/src/modules/utils/interfaces/generic.interface.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - Company, - GraphqlQueryCompany, -} from '@/companies/interfaces/company.interface'; -import { - GraphqlQueryPerson, - Person, -} from '@/people/interfaces/person.interface'; -import { GraphqlQueryUser, User } from '@/users/interfaces/user.interface'; -import { - CompanyWhereInput as Companies_Bool_Exp, - PersonWhereInput as People_Bool_Exp, - UserWhereInput as Users_Bool_Exp, -} from '~/generated/graphql'; - -export type AnyEntity = { - id: string; - __typename?: string; -} & Record; - -export type UnknownType = void; - -export type GqlType = T extends Company - ? GraphqlQueryCompany - : T extends Person - ? GraphqlQueryPerson - : T extends User - ? GraphqlQueryUser - : never; - -export type BoolExpType = T extends Company - ? Companies_Bool_Exp - : T extends Person - ? People_Bool_Exp - : T extends User - ? Users_Bool_Exp - : never; diff --git a/front/src/modules/utils/utils.ts b/front/src/modules/utils/utils.ts index 21391293e4..c05fa5ce84 100644 --- a/front/src/modules/utils/utils.ts +++ b/front/src/modules/utils/utils.ts @@ -13,9 +13,3 @@ export const getLogoUrlFromDomainName = (domainName?: string): string => { export const browserPrefersDarkMode = (): boolean => { return window.matchMedia('(prefers-color-scheme: dark)').matches; }; - -export type DeepPartial = T extends object - ? { - [P in keyof T]?: DeepPartial; - } - : T; diff --git a/front/src/modules/workspaces/interfaces/workspace.interface.ts b/front/src/modules/workspaces/interfaces/workspace.interface.ts deleted file mode 100644 index 28a6240567..0000000000 --- a/front/src/modules/workspaces/interfaces/workspace.interface.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Workspace as GQLWorkspace } from '../../../generated/graphql'; -import { DeepPartial } from '../../utils/utils'; - -export type Workspace = DeepPartial & { id: GQLWorkspace['id'] }; - -export type GraphqlQueryWorkspace = Workspace; - -export type GraphqlMutationWorkspace = Workspace; - -export const mapToWorkspace = ( - workspace: GraphqlQueryWorkspace, -): Workspace => ({ - id: workspace.id, - domainName: workspace.domainName, - displayName: workspace.displayName, - logo: workspace.logo, -}); - -export const mapToGqlWorkspace = ( - workspace: Workspace, -): GraphqlMutationWorkspace => workspace; diff --git a/front/src/pages/companies/Companies.tsx b/front/src/pages/companies/Companies.tsx index 324d20214d..c44de5900a 100644 --- a/front/src/pages/companies/Companies.tsx +++ b/front/src/pages/companies/Companies.tsx @@ -3,14 +3,9 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { v4 as uuidv4 } from 'uuid'; -import { - Company, - mapToCompany, -} from '@/companies/interfaces/company.interface'; import { CompaniesSelectedSortType, defaultOrderBy, - insertCompany, useCompaniesQuery, } from '@/companies/services'; import { @@ -23,8 +18,13 @@ import { EntityTable } from '@/ui/components/table/EntityTable'; import { IconBuildingSkyscraper } from '@/ui/icons/index'; import { IconList } from '@/ui/icons/index'; import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer'; -import { BoolExpType } from '@/utils/interfaces/generic.interface'; -import { CompanyOrderByWithRelationInput as Companies_Order_By } from '~/generated/graphql'; +import { + CompanyOrderByWithRelationInput as Companies_Order_By, + CompanyWhereInput, + GetCompaniesQuery, + InsertCompanyMutationVariables, + useInsertCompanyMutation, +} from '~/generated/graphql'; import { TableActionBarButtonCreateCommentThreadCompany } from './table/TableActionBarButtonCreateCommentThreadCompany'; import { TableActionBarButtonDeleteCompanies } from './table/TableActionBarButtonDeleteCompanies'; @@ -38,15 +38,16 @@ const StyledCompaniesContainer = styled.div` `; export function Companies() { + const [insertCompany] = useInsertCompanyMutation(); const [orderBy, setOrderBy] = useState(defaultOrderBy); - const [where, setWhere] = useState>({}); + const [where, setWhere] = useState({}); const updateSorts = useCallback((sorts: Array) => { setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy); }, []); const updateFilters = useCallback( - (filters: Array>) => { + (filters: Array>) => { setWhere(reduceFiltersToWhere(filters)); }, [], @@ -54,21 +55,19 @@ export function Companies() { const { data } = useCompaniesQuery(orderBy, where); - const companies = data?.companies.map(mapToCompany) ?? []; + const companies = data?.companies ?? []; async function handleAddButtonClick() { - const newCompany: Company = { + const newCompany: InsertCompanyMutationVariables = { id: uuidv4(), name: '', domainName: '', employees: null, address: '', createdAt: new Date().toISOString(), - accountOwner: null, - __typename: 'Company', }; - await insertCompany(newCompany); + await insertCompany({ variables: newCompany }); } const companiesColumns = useCompaniesColumns(); diff --git a/front/src/pages/companies/companies-columns.tsx b/front/src/pages/companies/companies-columns.tsx index 1eaf313946..fad8da1cc7 100644 --- a/front/src/pages/companies/companies-columns.tsx +++ b/front/src/pages/companies/companies-columns.tsx @@ -2,7 +2,6 @@ import { useMemo } from 'react'; import { createColumnHelper } from '@tanstack/react-table'; import { CompanyEditableNameChipCell } from '@/companies/components/CompanyEditableNameCell'; -import { updateCompany } from '@/companies/services'; import { PersonChip, PersonChipPropsType, @@ -22,12 +21,16 @@ import { IconUsers, } from '@/ui/icons/index'; import { getCheckBoxColumn } from '@/ui/tables/utils/getCheckBoxColumn'; -import { mapToUser, User } from '@/users/interfaces/user.interface'; -import { GetCompaniesQueryHookResult, QueryMode } from '~/generated/graphql'; +import { + GetCompaniesQuery, + QueryMode, + useUpdateCompanyMutation, +} from '~/generated/graphql'; -const columnHelper = createColumnHelper(); +const columnHelper = createColumnHelper(); export const useCompaniesColumns = () => { + const [updateCompany] = useUpdateCompanyMutation(); return useMemo(() => { return [ getCheckBoxColumn(), @@ -54,7 +57,12 @@ export const useCompaniesColumns = () => { changeHandler={(value) => { const company = { ...props.row.original }; company.domainName = value; - updateCompany(company); + updateCompany({ + variables: { + ...company, + accountOwnerId: company.accountOwner?.id, + }, + }); }} /> ), @@ -71,13 +79,13 @@ export const useCompaniesColumns = () => { changeHandler={(value) => { const company = { ...props.row.original }; - if (value === '') { - company.employees = null; - updateCompany(company); - } else if (!Number.isNaN(Number(value))) { - company.employees = Number(value); - updateCompany(company); - } + updateCompany({ + variables: { + ...company, + employees: value === '' ? null : Number(value), + accountOwnerId: company.accountOwner?.id, + }, + }); }} /> ), @@ -94,7 +102,12 @@ export const useCompaniesColumns = () => { changeHandler={(value) => { const company = { ...props.row.original }; company.address = value; - updateCompany(company); + updateCompany({ + variables: { + ...company, + accountOwnerId: company.accountOwner?.id, + }, + }); }} /> ), @@ -117,7 +130,12 @@ export const useCompaniesColumns = () => { changeHandler={(value: Date) => { const company = { ...props.row.original }; company.createdAt = value.toISOString(); - updateCompany(company); + updateCompany({ + variables: { + ...company, + accountOwnerId: company.accountOwner?.id, + }, + }); }} /> ), @@ -131,21 +149,24 @@ export const useCompaniesColumns = () => { /> ), cell: (props) => ( - + relation={props.row.original.accountOwner} searchPlaceholder="Account Owner" ChipComponent={PersonChip} chipComponentPropsMapper={( - accountOwner: User, + accountOwner: any, ): PersonChipPropsType => { return { name: accountOwner.displayName || '', }; }} - onChange={(relation: User) => { - const company = { ...props.row.original }; - company.accountOwnerId = relation.id; - updateCompany(company); + onChange={(relation: any) => { + updateCompany({ + variables: { + ...props.row.original, + accountOwnerId: relation.id, + }, + }); }} searchConfig={ { @@ -156,15 +177,15 @@ export const useCompaniesColumns = () => { mode: QueryMode.Insensitive, }, }), - resultMapper: (accountOwner) => ({ - render: (accountOwner) => accountOwner.displayName, - value: mapToUser(accountOwner), + resultMapper: (accountOwner: any) => ({ + render: (accountOwner: any) => accountOwner.displayName, + value: accountOwner, }), - } satisfies SearchConfigType + } satisfies SearchConfigType } /> ), }), ]; - }, []); + }, [updateCompany]); }; diff --git a/front/src/pages/companies/companies-filters.tsx b/front/src/pages/companies/companies-filters.tsx index 8273cebeb6..a22690a1cd 100644 --- a/front/src/pages/companies/companies-filters.tsx +++ b/front/src/pages/companies/companies-filters.tsx @@ -1,4 +1,3 @@ -import { Company } from '@/companies/interfaces/company.interface'; import { FilterConfigType } from '@/filters-and-sorts/interfaces/filters/interface'; import { SEARCH_USER_QUERY } from '@/search/services/search'; import { @@ -9,8 +8,7 @@ import { IconUser, IconUsers, } from '@/ui/icons/index'; -import { mapToUser, User } from '@/users/interfaces/user.interface'; -import { QueryMode } from '~/generated/graphql'; +import { QueryMode, User } from '~/generated/graphql'; export const nameFilter = { key: 'name', @@ -21,14 +19,14 @@ export const nameFilter = { { label: 'Contains', id: 'like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ name: { contains: `%${searchString}%`, mode: QueryMode.Insensitive }, }), }, { label: 'Does not contain', id: 'not_like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ NOT: [ { name: { @@ -40,7 +38,7 @@ export const nameFilter = { }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const employeesFilter = { key: 'employees', @@ -51,7 +49,7 @@ export const employeesFilter = { { label: 'Greater than', id: 'greater_than', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ employees: { gte: isNaN(Number(searchString)) ? undefined : Number(searchString), }, @@ -60,14 +58,14 @@ export const employeesFilter = { { label: 'Less than', id: 'less_than', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ employees: { lte: isNaN(Number(searchString)) ? undefined : Number(searchString), }, }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const urlFilter = { key: 'domainName', @@ -78,7 +76,7 @@ export const urlFilter = { { label: 'Contains', id: 'like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ domainName: { contains: `%${searchString}%`, mode: QueryMode.Insensitive, @@ -88,7 +86,7 @@ export const urlFilter = { { label: 'Does not contain', id: 'not_like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ NOT: [ { domainName: { @@ -100,7 +98,7 @@ export const urlFilter = { }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const addressFilter = { key: 'address', @@ -111,14 +109,14 @@ export const addressFilter = { { label: 'Contains', id: 'like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ address: { contains: `%${searchString}%`, mode: QueryMode.Insensitive }, }), }, { label: 'Does not contain', id: 'not_like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ NOT: [ { address: { @@ -130,7 +128,7 @@ export const addressFilter = { }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const ccreatedAtFilter = { key: 'createdAt', @@ -141,7 +139,7 @@ export const ccreatedAtFilter = { { label: 'Greater than', id: 'greater_than', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ createdAt: { gte: searchString, }, @@ -150,14 +148,14 @@ export const ccreatedAtFilter = { { label: 'Less than', id: 'less_than', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ createdAt: { lte: searchString, }, }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const accountOwnerFilter = { key: 'accountOwner', @@ -172,24 +170,24 @@ export const accountOwnerFilter = { mode: QueryMode.Insensitive, }, }), - resultMapper: (data) => ({ - value: mapToUser(data), - render: (owner) => owner.displayName, + resultMapper: (data: any) => ({ + value: data, + render: (owner: any) => owner.displayName, }), }, - selectedValueRender: (owner) => owner.displayName || '', + selectedValueRender: (owner: any) => owner.displayName || '', operands: [ { label: 'Is', id: 'is', - whereTemplate: (owner) => ({ + whereTemplate: (owner: any) => ({ accountOwner: { is: { displayName: { equals: owner.displayName } } }, }), }, { label: 'Is not', id: 'is_not', - whereTemplate: (owner) => ({ + whereTemplate: (owner: any) => ({ NOT: [ { accountOwner: { @@ -200,7 +198,7 @@ export const accountOwnerFilter = { }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const availableFilters = [ nameFilter, diff --git a/front/src/pages/people/People.tsx b/front/src/pages/people/People.tsx index 0d0196bdac..fcb5585dcf 100644 --- a/front/src/pages/people/People.tsx +++ b/front/src/pages/people/People.tsx @@ -1,4 +1,5 @@ import { useCallback, useState } from 'react'; +import { getOperationName } from '@apollo/client/utilities'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { v4 as uuidv4 } from 'uuid'; @@ -8,10 +9,9 @@ import { reduceSortsToOrderBy, } from '@/filters-and-sorts/helpers'; import { SelectedFilterType } from '@/filters-and-sorts/interfaces/filters/interface'; -import { Person } from '@/people/interfaces/person.interface'; import { defaultOrderBy, - insertPerson, + GET_PEOPLE, PeopleSelectedSortType, usePeopleQuery, } from '@/people/services'; @@ -19,7 +19,11 @@ import { EntityTableActionBar } from '@/ui/components/table/action-bar/EntityTab import { EntityTable } from '@/ui/components/table/EntityTable'; import { IconList, IconUser } from '@/ui/icons/index'; import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer'; -import { BoolExpType } from '@/utils/interfaces/generic.interface'; +import { + GetPeopleQuery, + PersonWhereInput, + useInsertPersonMutation, +} from '~/generated/graphql'; import { TableActionBarButtonCreateCommentThreadPeople } from './table/TableActionBarButtonCreateCommentThreadPeople'; import { TableActionBarButtonDeletePeople } from './table/TableActionBarButtonDeletePeople'; @@ -35,37 +39,38 @@ const StyledPeopleContainer = styled.div` export function People() { const [orderBy, setOrderBy] = useState(defaultOrderBy); - const [where, setWhere] = useState>({}); + const [where, setWhere] = useState({}); const updateSorts = useCallback((sorts: Array) => { setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy); }, []); const updateFilters = useCallback( - (filters: Array>) => { + (filters: Array>) => { setWhere(reduceFiltersToWhere(filters)); }, [], ); + const [insertPersonMutation] = useInsertPersonMutation(); + const { data } = usePeopleQuery(orderBy, where); const people = data?.people ?? []; async function handleAddButtonClick() { - const newPerson = { - __typename: 'Person', - id: uuidv4(), - firstname: '', - lastname: '', - email: '', - phone: '', - company: null, - createdAt: new Date().toISOString(), - city: '', - } as const; - - await insertPerson(newPerson); + await insertPersonMutation({ + variables: { + id: uuidv4(), + firstname: '', + lastname: '', + email: '', + phone: '', + createdAt: new Date().toISOString(), + city: '', + }, + refetchQueries: [getOperationName(GET_PEOPLE) ?? ''], + }); } const peopleColumns = usePeopleColumns(); diff --git a/front/src/pages/people/__stories__/People.inputs.stories.tsx b/front/src/pages/people/__stories__/People.inputs.stories.tsx index 3f805ecf31..21cef02ddd 100644 --- a/front/src/pages/people/__stories__/People.inputs.stories.tsx +++ b/front/src/pages/people/__stories__/People.inputs.stories.tsx @@ -3,7 +3,6 @@ import type { Meta } from '@storybook/react'; import { userEvent, within } from '@storybook/testing-library'; import { graphql } from 'msw'; -import { GraphqlQueryCompany } from '@/companies/interfaces/company.interface'; import { graphqlMocks } from '~/testing/graphqlMocks'; import { fetchOneFromData } from '~/testing/mock-data'; import { mockedPeopleData } from '~/testing/mock-data/people'; @@ -141,7 +140,7 @@ export const EditRelation: Story = { name: 'Airbnb', domainName: 'airbnb.com', __typename: 'Company', - } satisfies GraphqlQueryCompany, + }, }, }, }), @@ -196,7 +195,7 @@ export const SelectRelationWithKeys: Story = { name: 'Aircall', domainName: 'aircall.io', __typename: 'Company', - } satisfies GraphqlQueryCompany, + }, }, }, }), diff --git a/front/src/pages/people/__tests__/people-filter.test.ts b/front/src/pages/people/__tests__/people-filter.test.ts index a51e4a412e..7f53289e8e 100644 --- a/front/src/pages/people/__tests__/people-filter.test.ts +++ b/front/src/pages/people/__tests__/people-filter.test.ts @@ -4,10 +4,7 @@ describe('PeopleFilter', () => { it(`should render the filter ${companyFilter.key} which relation search`, () => { expect( companyFilter.operands[0].whereTemplate({ - id: 'test-id', name: 'test-name', - domainName: 'test-domain-name', - __typename: 'Company', }), ).toMatchSnapshot(); }); diff --git a/front/src/pages/people/people-columns.tsx b/front/src/pages/people/people-columns.tsx index 6bec020423..718dfc9503 100644 --- a/front/src/pages/people/people-columns.tsx +++ b/front/src/pages/people/people-columns.tsx @@ -3,7 +3,6 @@ import { createColumnHelper } from '@tanstack/react-table'; import { EditablePeopleFullName } from '@/people/components/EditablePeopleFullName'; import { PeopleCompanyCell } from '@/people/components/PeopleCompanyCell'; -import { updatePerson } from '@/people/services'; import { EditableDate } from '@/ui/components/editable-cell/types/EditableDate'; import { EditablePhone } from '@/ui/components/editable-cell/types/EditablePhone'; import { EditableText } from '@/ui/components/editable-cell/types/EditableText'; @@ -17,12 +16,13 @@ import { IconUser, } from '@/ui/icons/index'; import { getCheckBoxColumn } from '@/ui/tables/utils/getCheckBoxColumn'; +import { GetPeopleQuery, useUpdatePeopleMutation } from '~/generated/graphql'; -import { GetPeopleQueryHookResult } from '../../generated/graphql'; - -const columnHelper = createColumnHelper(); +const columnHelper = createColumnHelper(); export const usePeopleColumns = () => { + const [updatePerson] = useUpdatePeopleMutation(); + return useMemo(() => { return [ getCheckBoxColumn(), @@ -36,9 +36,14 @@ export const usePeopleColumns = () => { person={props.row.original} onChange={async (firstName: string, lastName: string) => { const person = { ...props.row.original }; - person.firstname = firstName; - person.lastname = lastName; - await updatePerson(person); + await updatePerson({ + variables: { + ...person, + firstname: firstName, + lastname: lastName, + companyId: person.company?.id, + }, + }); }} /> @@ -53,10 +58,15 @@ export const usePeopleColumns = () => { { + changeHandler={async (value: string) => { const person = props.row.original; - person.email = value; - updatePerson(person); + await updatePerson({ + variables: { + ...person, + email: value, + companyId: person.company?.id, + }, + }); }} /> ), @@ -80,10 +90,15 @@ export const usePeopleColumns = () => { { + changeHandler={async (value: string) => { const person = { ...props.row.original }; - person.phone = value; - updatePerson(person); + await updatePerson({ + variables: { + ...person, + phone: value, + companyId: person.company?.id, + }, + }); }} /> ), @@ -103,10 +118,15 @@ export const usePeopleColumns = () => { ? new Date(props.row.original.createdAt) : new Date() } - changeHandler={(value: Date) => { + changeHandler={async (value: Date) => { const person = { ...props.row.original }; - person.createdAt = value.toISOString(); - updatePerson(person); + await updatePerson({ + variables: { + ...person, + createdAt: value.toISOString(), + companyId: person.company?.id, + }, + }); }} /> ), @@ -121,14 +141,19 @@ export const usePeopleColumns = () => { editModeHorizontalAlign="right" placeholder="City" content={props.row.original.city || ''} - changeHandler={(value: string) => { + changeHandler={async (value: string) => { const person = { ...props.row.original }; - person.city = value; - updatePerson(person); + await updatePerson({ + variables: { + ...person, + city: value, + companyId: person.company?.id, + }, + }); }} /> ), }), ]; - }, []); + }, [updatePerson]); }; diff --git a/front/src/pages/people/people-filters.tsx b/front/src/pages/people/people-filters.tsx index c61c56054f..3bb1ecc937 100644 --- a/front/src/pages/people/people-filters.tsx +++ b/front/src/pages/people/people-filters.tsx @@ -1,9 +1,4 @@ -import { - Company, - mapToCompany, -} from '@/companies/interfaces/company.interface'; import { FilterConfigType } from '@/filters-and-sorts/interfaces/filters/interface'; -import { Person } from '@/people/interfaces/person.interface'; import { SEARCH_COMPANY_QUERY } from '@/search/services/search'; import { IconBuildingSkyscraper, @@ -13,7 +8,7 @@ import { IconPhone, IconUser, } from '@/ui/icons/index'; -import { QueryMode } from '~/generated/graphql'; +import { Company, QueryMode } from '~/generated/graphql'; export const fullnameFilter = { key: 'fullname', @@ -24,7 +19,7 @@ export const fullnameFilter = { { label: 'Contains', id: 'like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ OR: [ { firstname: { @@ -44,7 +39,7 @@ export const fullnameFilter = { { label: 'Does not contain', id: 'not_like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ NOT: [ { AND: [ @@ -66,7 +61,7 @@ export const fullnameFilter = { }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const emailFilter = { key: 'email', @@ -77,14 +72,14 @@ export const emailFilter = { { label: 'Contains', id: 'like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ email: { contains: `%${searchString}%`, mode: QueryMode.Insensitive }, }), }, { label: 'Does not contain', id: 'not_like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ NOT: [ { email: { @@ -96,7 +91,7 @@ export const emailFilter = { }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const companyFilter = { key: 'company_name', @@ -109,8 +104,8 @@ export const companyFilter = { name: { contains: `%${searchString}%`, mode: QueryMode.Insensitive }, }), resultMapper: (data) => ({ - value: mapToCompany(data), - render: (company) => company.name, + value: data, + render: (company: { name: string }) => company.name, }), }, selectedValueRender: (company) => company.name || '', @@ -118,19 +113,19 @@ export const companyFilter = { { label: 'Is', id: 'is', - whereTemplate: (company) => ({ + whereTemplate: (company: { name: string }) => ({ company: { is: { name: { equals: company.name } } }, }), }, { label: 'Is not', id: 'is_not', - whereTemplate: (company) => ({ + whereTemplate: (company: { name: string }) => ({ NOT: [{ company: { is: { name: { equals: company.name } } } }], }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const phoneFilter = { key: 'phone', @@ -141,14 +136,14 @@ export const phoneFilter = { { label: 'Contains', id: 'like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ phone: { contains: `%${searchString}%`, mode: QueryMode.Insensitive }, }), }, { label: 'Does not contain', id: 'not_like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ NOT: [ { phone: { @@ -160,7 +155,7 @@ export const phoneFilter = { }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const createdAtFilter = { key: 'createdAt', @@ -171,7 +166,7 @@ export const createdAtFilter = { { label: 'Greater than', id: 'greater_than', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ createdAt: { gte: searchString, }, @@ -180,14 +175,14 @@ export const createdAtFilter = { { label: 'Less than', id: 'less_than', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ createdAt: { lte: searchString, }, }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const cityFilter = { key: 'city', @@ -198,14 +193,14 @@ export const cityFilter = { { label: 'Contains', id: 'like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ city: { contains: `%${searchString}%`, mode: QueryMode.Insensitive }, }), }, { label: 'Does not contain', id: 'not_like', - whereTemplate: (searchString) => ({ + whereTemplate: (searchString: string) => ({ NOT: [ { city: { @@ -217,7 +212,7 @@ export const cityFilter = { }), }, ], -} satisfies FilterConfigType; +} satisfies FilterConfigType; export const availableFilters = [ fullnameFilter, @@ -226,4 +221,4 @@ export const availableFilters = [ phoneFilter, createdAtFilter, cityFilter, -] satisfies FilterConfigType[]; +]; diff --git a/front/src/testing/graphqlMocks.ts b/front/src/testing/graphqlMocks.ts index 95cf6e6618..2405ec8604 100644 --- a/front/src/testing/graphqlMocks.ts +++ b/front/src/testing/graphqlMocks.ts @@ -1,8 +1,20 @@ +import { getOperationName } from '@apollo/client/utilities'; import { graphql } from 'msw'; -import { GraphqlQueryCompany } from '@/companies/interfaces/company.interface'; -import { GraphqlQueryPerson } from '@/people/interfaces/person.interface'; -import { GraphqlQueryUser } from '@/users/interfaces/user.interface'; +import { GET_COMPANIES } from '@/companies/services'; +import { GET_PEOPLE, UPDATE_PERSON } from '@/people/services'; +import { + SEARCH_COMPANY_QUERY, + SEARCH_USER_QUERY, +} from '@/search/services/search'; +import { GET_CURRENT_USER } from '@/users/services'; +import { + GetCompaniesQuery, + GetPeopleQuery, + GetUsersQuery, + SearchCompanyQuery, + SearchUserQuery, +} from '~/generated/graphql'; import { mockedCompaniesData } from './mock-data/companies'; import { mockedPeopleData } from './mock-data/people'; @@ -10,8 +22,10 @@ import { mockedUsersData } from './mock-data/users'; import { filterAndSortData, updateOneFromData } from './mock-data'; export const graphqlMocks = [ - graphql.query('GetCompanies', (req, res, ctx) => { - const returnedMockedData = filterAndSortData( + graphql.query(getOperationName(GET_COMPANIES) ?? '', (req, res, ctx) => { + const returnedMockedData = filterAndSortData< + GetCompaniesQuery['companies'][0] + >( mockedCompaniesData, req.variables.where, req.variables.orderBy, @@ -23,21 +37,28 @@ export const graphqlMocks = [ }), ); }), - graphql.query('SearchCompany', (req, res, ctx) => { - const returnedMockedData = filterAndSortData( - mockedCompaniesData, - req.variables.where, - req.variables.orderBy, - req.variables.limit, - ); - return res( - ctx.data({ - searchResults: returnedMockedData, - }), - ); - }), - graphql.query('SearchUser', (req, res, ctx) => { - const returnedMockedData = filterAndSortData( + graphql.query( + getOperationName(SEARCH_COMPANY_QUERY) ?? '', + (req, res, ctx) => { + const returnedMockedData = filterAndSortData< + SearchCompanyQuery['searchResults'][0] + >( + mockedCompaniesData, + req.variables.where, + req.variables.orderBy, + req.variables.limit, + ); + return res( + ctx.data({ + searchResults: returnedMockedData, + }), + ); + }, + ), + graphql.query(getOperationName(SEARCH_USER_QUERY) ?? '', (req, res, ctx) => { + const returnedMockedData = filterAndSortData< + SearchUserQuery['searchResults'][0] + >( mockedUsersData, req.variables.where, req.variables.orderBy, @@ -49,7 +70,7 @@ export const graphqlMocks = [ }), ); }), - graphql.query('GetCurrentUser', (req, res, ctx) => { + graphql.query(getOperationName(GET_CURRENT_USER) ?? '', (req, res, ctx) => { const customWhere = { ...req.variables.where, id: { @@ -57,20 +78,17 @@ export const graphqlMocks = [ }, }; - const returnedMockedData = filterAndSortData( - mockedUsersData, - customWhere, - req.variables.orderBy, - req.variables.limit, - ); + const returnedMockedData = filterAndSortData< + GetUsersQuery['findManyUser'][0] + >(mockedUsersData, customWhere, req.variables.orderBy, req.variables.limit); return res( ctx.data({ users: returnedMockedData, }), ); }), - graphql.query('GetPeople', (req, res, ctx) => { - const returnedMockedData = filterAndSortData( + graphql.query(getOperationName(GET_PEOPLE) ?? '', (req, res, ctx) => { + const returnedMockedData = filterAndSortData( mockedPeopleData, req.variables.where, req.variables.orderBy, @@ -82,7 +100,7 @@ export const graphqlMocks = [ }), ); }), - graphql.mutation('UpdatePeople', (req, res, ctx) => { + graphql.mutation(getOperationName(UPDATE_PERSON) ?? '', (req, res, ctx) => { return res( ctx.data({ updateOnePerson: updateOneFromData( diff --git a/front/src/testing/mock-data/comment-threads.ts b/front/src/testing/mock-data/comment-threads.ts index a8e7e1039d..6d14913601 100644 --- a/front/src/testing/mock-data/comment-threads.ts +++ b/front/src/testing/mock-data/comment-threads.ts @@ -1,6 +1,28 @@ -import { CommentableType, CommentThread } from '~/generated/graphql'; +import { + CommentableType, + CommentThread, + CommentThreadTarget, +} from '~/generated/graphql'; -export const mockedCommentThreads: Array = [ +type MockedCommentThread = Pick< + CommentThread, + 'id' | 'createdAt' | 'updatedAt' | '__typename' +> & { + commentThreadTargets: Array< + Pick< + CommentThreadTarget, + | 'id' + | '__typename' + | 'createdAt' + | 'updatedAt' + | 'commentableType' + | 'commentableId' + | 'commentThreadId' + > & { commentThread: Pick } + >; +}; + +export const mockedCommentThreads: Array = [ { id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', createdAt: '2023-04-26T10:12:42.33625+00:00', diff --git a/front/src/testing/mock-data/companies.ts b/front/src/testing/mock-data/companies.ts index f1e544497e..5256a5dc8d 100644 --- a/front/src/testing/mock-data/companies.ts +++ b/front/src/testing/mock-data/companies.ts @@ -1,6 +1,23 @@ -import { Company } from '../../generated/graphql'; +import { Company, User } from '../../generated/graphql'; -export const mockedCompaniesData = [ +type MockedCompany = Pick< + Company, + | 'id' + | 'name' + | 'domainName' + | '__typename' + | 'createdAt' + | 'address' + | 'employees' + | '_commentCount' +> & { + accountOwner: Pick< + User, + 'id' | 'email' | 'displayName' | '__typename' + > | null; +}; + +export const mockedCompaniesData: Array = [ { id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', domainName: 'airbnb.com', @@ -83,4 +100,4 @@ export const mockedCompaniesData = [ accountOwner: null, __typename: 'Company', }, -] as Array; +]; diff --git a/front/src/testing/mock-data/index.ts b/front/src/testing/mock-data/index.ts index 97b71bb165..517fa1cdf4 100644 --- a/front/src/testing/mock-data/index.ts +++ b/front/src/testing/mock-data/index.ts @@ -1,9 +1,5 @@ import { GraphQLVariables } from 'msw'; -import { Company } from '@/companies/interfaces/company.interface'; -import { Person } from '@/people/interfaces/person.interface'; -import { User } from '@/users/interfaces/user.interface'; -import { BoolExpType } from '@/utils/interfaces/generic.interface'; import { CompanyOrderByWithRelationInput, PersonOrderByWithRelationInput, @@ -13,7 +9,7 @@ import { function filterData( data: Array, - where: BoolExpType | BoolExpType, + where: Record, ): Array { return data.filter((item) => { // { firstname: {contains: '%string%' }} @@ -76,7 +72,7 @@ function filterData( export function filterAndSortData( data: Array, - where?: BoolExpType | BoolExpType | BoolExpType, + where?: Record, orderBy?: Array< PersonOrderByWithRelationInput & CompanyOrderByWithRelationInput & diff --git a/front/src/testing/mock-data/people.ts b/front/src/testing/mock-data/people.ts index 630de23811..360abab939 100644 --- a/front/src/testing/mock-data/people.ts +++ b/front/src/testing/mock-data/people.ts @@ -1,6 +1,21 @@ -import { Person } from '../../modules/people/interfaces/person.interface'; +import { Company, Person } from '~/generated/graphql'; -export const mockedPeopleData = [ +type MockedPerson = Pick< + Person, + | 'id' + | 'firstname' + | 'lastname' + | 'email' + | '__typename' + | 'phone' + | 'city' + | '_commentCount' + | 'createdAt' +> & { + company: Pick; +}; + +export const mockedPeopleData: Array = [ { id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', __typename: 'Person', @@ -73,4 +88,4 @@ export const mockedPeopleData = [ city: 'Paris', }, -] satisfies Array; +]; diff --git a/front/src/testing/mock-data/users.ts b/front/src/testing/mock-data/users.ts index b71bdb067d..c149cac73a 100644 --- a/front/src/testing/mock-data/users.ts +++ b/front/src/testing/mock-data/users.ts @@ -1,6 +1,18 @@ -import { GraphqlQueryUser } from '@/users/interfaces/user.interface'; +import { User, Workspace, WorkspaceMember } from '~/generated/graphql'; -export const mockedUsersData: Array = [ +type MockedUser = Pick< + User, + 'id' | 'email' | 'displayName' | 'avatarUrl' | '__typename' +> & { + workspaceMember: Pick & { + workspace: Pick< + Workspace, + 'id' | 'displayName' | 'domainName' | 'logo' | '__typename' + >; + }; +}; + +export const mockedUsersData: Array = [ { id: '374fe3a5-df1e-4119-afe0-2a62a2ba481e', __typename: 'User', @@ -37,4 +49,4 @@ export const mockedUsersData: Array = [ }, }, }, -] as GraphqlQueryUser[]; +];