mirror of
https://github.com/twentyhq/twenty.git
synced 2025-01-07 01:12:50 +03:00
Use Graphql types in FE and complete mappers removal (#348)
Fix Typescript build issues
This commit is contained in:
parent
b179d1f1f0
commit
8a330b9746
@ -1,8 +1,16 @@
|
|||||||
import { atom } from 'recoil';
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
import { User } from '@/users/interfaces/user.interface';
|
import { User, Workspace, WorkspaceMember } from '~/generated/graphql';
|
||||||
|
|
||||||
export const currentUserState = atom<User | null>({
|
type CurrentUser = Pick<User, 'id' | 'email' | 'displayName'> & {
|
||||||
|
workspaceMember?:
|
||||||
|
| (Pick<WorkspaceMember, 'id'> & {
|
||||||
|
workspace: Pick<Workspace, 'id' | 'displayName' | 'logo'>;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const currentUserState = atom<CurrentUser | null>({
|
||||||
key: 'currentUserState',
|
key: 'currentUserState',
|
||||||
default: null,
|
default: null,
|
||||||
});
|
});
|
||||||
|
@ -2,19 +2,24 @@ import { CellCommentChip } from '@/comments/components/CellCommentChip';
|
|||||||
import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer';
|
import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer';
|
||||||
import EditableChip from '@/ui/components/editable-cell/types/EditableChip';
|
import EditableChip from '@/ui/components/editable-cell/types/EditableChip';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||||
import { CommentableType } from '~/generated/graphql';
|
import {
|
||||||
|
CommentableType,
|
||||||
import { Company } from '../interfaces/company.interface';
|
GetCompaniesQuery,
|
||||||
import { updateCompany } from '../services';
|
useUpdateCompanyMutation,
|
||||||
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
import CompanyChip from './CompanyChip';
|
import CompanyChip from './CompanyChip';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
company: Company;
|
company: Pick<
|
||||||
|
GetCompaniesQuery['companies'][0],
|
||||||
|
'id' | 'name' | 'domainName' | '_commentCount' | 'accountOwner'
|
||||||
|
>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function CompanyEditableNameChipCell({ company }: OwnProps) {
|
export function CompanyEditableNameChipCell({ company }: OwnProps) {
|
||||||
const openCommentRightDrawer = useOpenCommentRightDrawer();
|
const openCommentRightDrawer = useOpenCommentRightDrawer();
|
||||||
|
const [updateCompany] = useUpdateCompanyMutation();
|
||||||
|
|
||||||
function handleCommentClick(event: React.MouseEvent<HTMLDivElement>) {
|
function handleCommentClick(event: React.MouseEvent<HTMLDivElement>) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -35,8 +40,11 @@ export function CompanyEditableNameChipCell({ company }: OwnProps) {
|
|||||||
picture={getLogoUrlFromDomainName(company.domainName)}
|
picture={getLogoUrlFromDomainName(company.domainName)}
|
||||||
changeHandler={(value: string) => {
|
changeHandler={(value: string) => {
|
||||||
updateCompany({
|
updateCompany({
|
||||||
|
variables: {
|
||||||
...company,
|
...company,
|
||||||
name: value,
|
name: value,
|
||||||
|
accountOwnerId: company.accountOwner?.id,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
ChipComponent={CompanyChip}
|
ChipComponent={CompanyChip}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import { Company as GQLCompany } from '../../../generated/graphql';
|
|
||||||
import { DeepPartial } from '../../utils/utils';
|
|
||||||
|
|
||||||
export type Company = DeepPartial<GQLCompany> & { id: string };
|
|
||||||
|
|
||||||
export type GraphqlQueryCompany = Company;
|
|
||||||
|
|
||||||
export type GraphqlMutationCompany = Company;
|
|
||||||
|
|
||||||
export const mapToCompany = (company: GraphqlQueryCompany): Company => company;
|
|
||||||
|
|
||||||
export const mapToGqlCompany = (company: Company): GraphqlMutationCompany =>
|
|
||||||
company;
|
|
@ -1,12 +1,4 @@
|
|||||||
import { FetchResult, gql } from '@apollo/client';
|
import { 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';
|
|
||||||
|
|
||||||
export const UPDATE_COMPANY = gql`
|
export const UPDATE_COMPANY = gql`
|
||||||
mutation UpdateCompany(
|
mutation UpdateCompany(
|
||||||
@ -80,36 +72,3 @@ export const DELETE_COMPANIES = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export async function updateCompany(
|
|
||||||
company: UpdateCompanyMutationVariables,
|
|
||||||
): Promise<FetchResult<Company>> {
|
|
||||||
const result = await apiClient.mutate({
|
|
||||||
mutation: UPDATE_COMPANY,
|
|
||||||
variables: company,
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function insertCompany(
|
|
||||||
company: Company,
|
|
||||||
): Promise<FetchResult<Company>> {
|
|
||||||
const result = await apiClient.mutate({
|
|
||||||
mutation: INSERT_COMPANY,
|
|
||||||
variables: mapToGqlCompany(company),
|
|
||||||
refetchQueries: [getOperationName(GET_COMPANIES) ?? ''],
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteCompanies(
|
|
||||||
peopleIds: string[],
|
|
||||||
): Promise<FetchResult<Company>> {
|
|
||||||
const result = await apiClient.mutate({
|
|
||||||
mutation: DELETE_COMPANIES,
|
|
||||||
variables: { ids: peopleIds },
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
@ -1,23 +1,17 @@
|
|||||||
import { SortOrder as Order_By } from '~/generated/graphql';
|
import { SortOrder as Order_By } from '~/generated/graphql';
|
||||||
|
|
||||||
import { BoolExpType } from '../utils/interfaces/generic.interface';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FilterableFieldsType,
|
|
||||||
FilterWhereType,
|
FilterWhereType,
|
||||||
SelectedFilterType,
|
SelectedFilterType,
|
||||||
} from './interfaces/filters/interface';
|
} from './interfaces/filters/interface';
|
||||||
import { SelectedSortType } from './interfaces/sorts/interface';
|
import { SelectedSortType } from './interfaces/sorts/interface';
|
||||||
|
|
||||||
export const reduceFiltersToWhere = <
|
export const reduceFiltersToWhere = <WhereTemplateType extends FilterWhereType>(
|
||||||
ValueType extends FilterableFieldsType,
|
filters: Array<SelectedFilterType<WhereTemplateType>>,
|
||||||
WhereTemplateType extends FilterWhereType,
|
): Record<string, any> => {
|
||||||
>(
|
|
||||||
filters: Array<SelectedFilterType<ValueType, WhereTemplateType>>,
|
|
||||||
): BoolExpType<WhereTemplateType> => {
|
|
||||||
const where = filters.reduce((acc, filter) => {
|
const where = filters.reduce((acc, filter) => {
|
||||||
return { ...acc, ...filter.operand.whereTemplate(filter.value) };
|
return { ...acc, ...filter.operand.whereTemplate(filter.value) };
|
||||||
}, {} as BoolExpType<WhereTemplateType>);
|
}, {} as Record<string, any>);
|
||||||
return where;
|
return where;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,80 +1,64 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
import { SearchConfigType } from '@/search/interfaces/interface';
|
import { SearchConfigType } from '@/search/interfaces/interface';
|
||||||
import {
|
|
||||||
AnyEntity,
|
|
||||||
BoolExpType,
|
|
||||||
UnknownType,
|
|
||||||
} from '@/utils/interfaces/generic.interface';
|
|
||||||
|
|
||||||
export type FilterableFieldsType = AnyEntity;
|
export type FilterableFieldsType = any;
|
||||||
export type FilterWhereRelationType = AnyEntity;
|
export type FilterWhereRelationType = any;
|
||||||
export type FilterWhereType = FilterWhereRelationType | string | UnknownType;
|
export type FilterWhereType = FilterWhereRelationType | string | unknown;
|
||||||
|
|
||||||
export type FilterConfigType<
|
export type FilterConfigType<WhereType extends FilterWhereType = unknown> = {
|
||||||
FilteredType extends FilterableFieldsType,
|
|
||||||
WhereType extends FilterWhereType = UnknownType,
|
|
||||||
> = {
|
|
||||||
key: string;
|
key: string;
|
||||||
label: string;
|
label: string;
|
||||||
icon: ReactNode;
|
icon: ReactNode;
|
||||||
type: WhereType extends UnknownType
|
type: WhereType extends unknown
|
||||||
? 'relation' | 'text' | 'date'
|
? 'relation' | 'text' | 'date'
|
||||||
: WhereType extends AnyEntity
|
: WhereType extends any
|
||||||
? 'relation'
|
? 'relation'
|
||||||
: WhereType extends string
|
: WhereType extends string
|
||||||
? 'text' | 'date'
|
? 'text' | 'date'
|
||||||
: never;
|
: never;
|
||||||
operands: FilterOperandType<FilteredType, WhereType>[];
|
operands: FilterOperandType<WhereType>[];
|
||||||
} & (WhereType extends UnknownType
|
} & (WhereType extends unknown
|
||||||
? { searchConfig?: SearchConfigType<UnknownType> }
|
? { searchConfig?: SearchConfigType }
|
||||||
: WhereType extends AnyEntity
|
: WhereType extends any
|
||||||
? { searchConfig: SearchConfigType<WhereType> }
|
? { searchConfig: SearchConfigType }
|
||||||
: WhereType extends string
|
: WhereType extends string
|
||||||
? object
|
? object
|
||||||
: never) &
|
: never) &
|
||||||
(WhereType extends UnknownType
|
(WhereType extends unknown
|
||||||
? { selectedValueRender?: (selected: any) => string }
|
? { selectedValueRender?: (selected: any) => string }
|
||||||
: WhereType extends AnyEntity
|
: WhereType extends any
|
||||||
? { selectedValueRender: (selected: WhereType) => string }
|
? { selectedValueRender: (selected: WhereType) => string }
|
||||||
: WhereType extends string
|
: WhereType extends string
|
||||||
? object
|
? object
|
||||||
: never);
|
: never);
|
||||||
|
|
||||||
export type FilterOperandType<
|
export type FilterOperandType<WhereType extends FilterWhereType = unknown> =
|
||||||
FilteredType extends FilterableFieldsType,
|
WhereType extends unknown
|
||||||
WhereType extends FilterWhereType = UnknownType,
|
|
||||||
> = WhereType extends UnknownType
|
|
||||||
? any
|
? any
|
||||||
: WhereType extends FilterWhereRelationType
|
: WhereType extends FilterWhereRelationType
|
||||||
? FilterOperandRelationType<FilteredType, WhereType>
|
? FilterOperandRelationType<WhereType>
|
||||||
: WhereType extends string
|
: WhereType extends string
|
||||||
? FilterOperandFieldType<FilteredType>
|
? FilterOperandFieldType
|
||||||
: never;
|
: never;
|
||||||
|
|
||||||
type FilterOperandRelationType<
|
type FilterOperandRelationType<WhereType extends FilterWhereType> = {
|
||||||
FilteredType extends FilterableFieldsType,
|
|
||||||
WhereType extends FilterWhereType,
|
|
||||||
> = {
|
|
||||||
label: 'Is' | 'Is not';
|
label: 'Is' | 'Is not';
|
||||||
id: 'is' | 'is_not';
|
id: 'is' | 'is_not';
|
||||||
whereTemplate: (value: WhereType) => BoolExpType<FilteredType>;
|
whereTemplate: (value: WhereType) => any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FilterOperandFieldType<FilteredType extends FilterableFieldsType> = {
|
type FilterOperandFieldType = {
|
||||||
label: 'Contains' | 'Does not contain' | 'Greater than' | 'Less than';
|
label: 'Contains' | 'Does not contain' | 'Greater than' | 'Less than';
|
||||||
id: 'like' | 'not_like' | 'greater_than' | 'less_than';
|
id: 'like' | 'not_like' | 'greater_than' | 'less_than';
|
||||||
whereTemplate: (value: string) => BoolExpType<FilteredType>;
|
whereTemplate: (value: string) => any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SelectedFilterType<
|
export type SelectedFilterType<WhereType> = {
|
||||||
FilteredType extends FilterableFieldsType,
|
|
||||||
WhereType extends FilterWhereType = UnknownType,
|
|
||||||
> = {
|
|
||||||
key: string;
|
key: string;
|
||||||
value: WhereType extends UnknownType ? any : WhereType;
|
value: WhereType;
|
||||||
displayValue: string;
|
displayValue: string;
|
||||||
label: string;
|
label: string;
|
||||||
icon: ReactNode;
|
icon: ReactNode;
|
||||||
operand: FilterOperandType<FilteredType, WhereType>;
|
operand: FilterOperandType<WhereType>;
|
||||||
};
|
};
|
||||||
|
@ -4,14 +4,12 @@ import styled from '@emotion/styled';
|
|||||||
import { CellCommentChip } from '@/comments/components/CellCommentChip';
|
import { CellCommentChip } from '@/comments/components/CellCommentChip';
|
||||||
import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer';
|
import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer';
|
||||||
import { EditableDoubleText } from '@/ui/components/editable-cell/types/EditableDoubleText';
|
import { EditableDoubleText } from '@/ui/components/editable-cell/types/EditableDoubleText';
|
||||||
import { CommentableType } from '~/generated/graphql';
|
import { CommentableType, Person } from '~/generated/graphql';
|
||||||
|
|
||||||
import { Person } from '../interfaces/person.interface';
|
|
||||||
|
|
||||||
import { PersonChip } from './PersonChip';
|
import { PersonChip } from './PersonChip';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
person: Person;
|
person: Pick<Person, 'id' | 'firstname' | 'lastname' | '_commentCount'>;
|
||||||
onChange: (firstname: string, lastname: string) => void;
|
onChange: (firstname: string, lastname: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,27 +4,25 @@ import { v4 } from 'uuid';
|
|||||||
import CompanyChip, {
|
import CompanyChip, {
|
||||||
CompanyChipPropsType,
|
CompanyChipPropsType,
|
||||||
} from '@/companies/components/CompanyChip';
|
} from '@/companies/components/CompanyChip';
|
||||||
import {
|
|
||||||
Company,
|
|
||||||
mapToCompany,
|
|
||||||
} from '@/companies/interfaces/company.interface';
|
|
||||||
import { SearchConfigType } from '@/search/interfaces/interface';
|
import { SearchConfigType } from '@/search/interfaces/interface';
|
||||||
import { SEARCH_COMPANY_QUERY } from '@/search/services/search';
|
import { SEARCH_COMPANY_QUERY } from '@/search/services/search';
|
||||||
import { EditableRelation } from '@/ui/components/editable-cell/types/EditableRelation';
|
import { EditableRelation } from '@/ui/components/editable-cell/types/EditableRelation';
|
||||||
import { logError } from '@/utils/logs/logError';
|
import { logError } from '@/utils/logs/logError';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||||
import {
|
import {
|
||||||
|
Company,
|
||||||
|
Person,
|
||||||
QueryMode,
|
QueryMode,
|
||||||
useInsertCompanyMutation,
|
useInsertCompanyMutation,
|
||||||
useUpdatePeopleMutation,
|
useUpdatePeopleMutation,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
import { mapToGqlPerson, Person } from '../interfaces/person.interface';
|
|
||||||
|
|
||||||
import { PeopleCompanyCreateCell } from './PeopleCompanyCreateCell';
|
import { PeopleCompanyCreateCell } from './PeopleCompanyCreateCell';
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
people: Person;
|
people: Pick<Person, 'id'> & {
|
||||||
|
company?: Pick<Company, 'id' | 'name'> | null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function PeopleCompanyCell({ people }: OwnProps) {
|
export function PeopleCompanyCell({ people }: OwnProps) {
|
||||||
@ -52,7 +50,7 @@ export function PeopleCompanyCell({ people }: OwnProps) {
|
|||||||
|
|
||||||
await updatePeople({
|
await updatePeople({
|
||||||
variables: {
|
variables: {
|
||||||
...mapToGqlPerson(people),
|
...people,
|
||||||
companyId: newCompanyId,
|
companyId: newCompanyId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -75,7 +73,7 @@ export function PeopleCompanyCell({ people }: OwnProps) {
|
|||||||
onCreate={handleCompanyCreate}
|
onCreate={handleCompanyCreate}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<EditableRelation<Company, CompanyChipPropsType>
|
<EditableRelation<any, CompanyChipPropsType>
|
||||||
relation={people.company}
|
relation={people.company}
|
||||||
searchPlaceholder="Company"
|
searchPlaceholder="Company"
|
||||||
ChipComponent={CompanyChip}
|
ChipComponent={CompanyChip}
|
||||||
@ -88,7 +86,7 @@ export function PeopleCompanyCell({ people }: OwnProps) {
|
|||||||
onChange={async (relation) => {
|
onChange={async (relation) => {
|
||||||
await updatePeople({
|
await updatePeople({
|
||||||
variables: {
|
variables: {
|
||||||
...mapToGqlPerson(people),
|
...people,
|
||||||
companyId: relation.id,
|
companyId: relation.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -101,10 +99,10 @@ export function PeopleCompanyCell({ people }: OwnProps) {
|
|||||||
name: { contains: `%${searchInput}%`, mode: QueryMode.Insensitive },
|
name: { contains: `%${searchInput}%`, mode: QueryMode.Insensitive },
|
||||||
}),
|
}),
|
||||||
resultMapper: (company) => ({
|
resultMapper: (company) => ({
|
||||||
render: (company) => company.name,
|
render: (company: any) => company.name,
|
||||||
value: mapToCompany(company),
|
value: company,
|
||||||
}),
|
}),
|
||||||
} satisfies SearchConfigType<Company>
|
} satisfies SearchConfigType
|
||||||
}
|
}
|
||||||
onCreate={() => {
|
onCreate={() => {
|
||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import { Person as GQLPerson } from '../../../generated/graphql';
|
|
||||||
import { DeepPartial } from '../../utils/utils';
|
|
||||||
|
|
||||||
export type Person = DeepPartial<GQLPerson> & { 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;
|
|
@ -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');
|
|
||||||
});
|
|
@ -1,10 +1,4 @@
|
|||||||
import { FetchResult, gql } from '@apollo/client';
|
import { 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';
|
|
||||||
|
|
||||||
export const UPDATE_PERSON = gql`
|
export const UPDATE_PERSON = gql`
|
||||||
mutation UpdatePeople(
|
mutation UpdatePeople(
|
||||||
@ -90,36 +84,3 @@ export const DELETE_PEOPLE = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export async function updatePerson(
|
|
||||||
person: Person,
|
|
||||||
): Promise<FetchResult<Person>> {
|
|
||||||
const result = await apiClient.mutate({
|
|
||||||
mutation: UPDATE_PERSON,
|
|
||||||
variables: person,
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function insertPerson(
|
|
||||||
person: Person,
|
|
||||||
): Promise<FetchResult<Person>> {
|
|
||||||
const result = await apiClient.mutate({
|
|
||||||
mutation: INSERT_PERSON,
|
|
||||||
variables: mapToGqlPerson(person),
|
|
||||||
refetchQueries: [getOperationName(GET_PEOPLE) ?? ''],
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deletePeople(
|
|
||||||
peopleIds: string[],
|
|
||||||
): Promise<FetchResult<Person>> {
|
|
||||||
const result = await apiClient.mutate({
|
|
||||||
mutation: DELETE_PEOPLE,
|
|
||||||
variables: { ids: peopleIds },
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
@ -1,26 +1,7 @@
|
|||||||
import { ReactNode } from 'react';
|
|
||||||
import { DocumentNode } from 'graphql';
|
import { DocumentNode } from 'graphql';
|
||||||
|
|
||||||
import {
|
export type SearchConfigType = {
|
||||||
AnyEntity,
|
|
||||||
BoolExpType,
|
|
||||||
GqlType,
|
|
||||||
UnknownType,
|
|
||||||
} from '@/utils/interfaces/generic.interface';
|
|
||||||
|
|
||||||
export type SearchConfigType<
|
|
||||||
SearchType extends AnyEntity | UnknownType = UnknownType,
|
|
||||||
> = SearchType extends UnknownType
|
|
||||||
? {
|
|
||||||
query: DocumentNode;
|
query: DocumentNode;
|
||||||
template: (searchInput: string) => any;
|
template: (searchInput: string) => any;
|
||||||
resultMapper: (data: any) => any;
|
resultMapper: (data: any) => any;
|
||||||
}
|
|
||||||
: {
|
|
||||||
query: DocumentNode;
|
|
||||||
template: (searchInput: string) => BoolExpType<SearchType>;
|
|
||||||
resultMapper: (data: GqlType<SearchType>) => {
|
|
||||||
value: SearchType;
|
|
||||||
render: (value: SearchType) => ReactNode;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,6 @@ import { useMemo, useState } from 'react';
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
import { gql, useQuery } from '@apollo/client';
|
||||||
|
|
||||||
import { debounce } from '@/utils/debounce';
|
import { debounce } from '@/utils/debounce';
|
||||||
import { AnyEntity, UnknownType } from '@/utils/interfaces/generic.interface';
|
|
||||||
|
|
||||||
import { SearchConfigType } from '../interfaces/interface';
|
import { SearchConfigType } from '../interfaces/interface';
|
||||||
|
|
||||||
@ -64,8 +63,7 @@ export const SEARCH_COMPANY_QUERY = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export type SearchResultsType<T extends AnyEntity | UnknownType = UnknownType> =
|
export type SearchResultsType<T> = {
|
||||||
{
|
|
||||||
results: {
|
results: {
|
||||||
render: (value: T) => string;
|
render: (value: T) => string;
|
||||||
value: T;
|
value: T;
|
||||||
@ -73,13 +71,13 @@ export type SearchResultsType<T extends AnyEntity | UnknownType = UnknownType> =
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSearch = <T extends AnyEntity | UnknownType = UnknownType>(): [
|
export const useSearch = <T>(): [
|
||||||
SearchResultsType<T>,
|
SearchResultsType<T>,
|
||||||
React.Dispatch<React.SetStateAction<string>>,
|
React.Dispatch<React.SetStateAction<string>>,
|
||||||
React.Dispatch<React.SetStateAction<SearchConfigType<T> | null>>,
|
React.Dispatch<React.SetStateAction<SearchConfigType | null>>,
|
||||||
string,
|
string,
|
||||||
] => {
|
] => {
|
||||||
const [searchConfig, setSearchConfig] = useState<SearchConfigType<T> | null>(
|
const [searchConfig, setSearchConfig] = useState<SearchConfigType | null>(
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
const [searchInput, setSearchInput] = useState<string>('');
|
const [searchInput, setSearchInput] = useState<string>('');
|
||||||
|
@ -8,7 +8,6 @@ import { useSearch } from '@/search/services/search';
|
|||||||
import { IconPlus } from '@/ui/icons/index';
|
import { IconPlus } from '@/ui/icons/index';
|
||||||
import { textInputStyle } from '@/ui/layout/styles/themes';
|
import { textInputStyle } from '@/ui/layout/styles/themes';
|
||||||
import { isSomeInputInEditModeState } from '@/ui/tables/states/isSomeInputInEditModeState';
|
import { isSomeInputInEditModeState } from '@/ui/tables/states/isSomeInputInEditModeState';
|
||||||
import { AnyEntity } from '@/utils/interfaces/generic.interface';
|
|
||||||
import { isDefined } from '@/utils/type-guards/isDefined';
|
import { isDefined } from '@/utils/type-guards/isDefined';
|
||||||
import { isNonEmptyString } from '@/utils/type-guards/isNonEmptyString';
|
import { isNonEmptyString } from '@/utils/type-guards/isNonEmptyString';
|
||||||
|
|
||||||
@ -86,13 +85,10 @@ const StyledCreateButtonText = styled.div`
|
|||||||
color: ${(props) => props.theme.text60};
|
color: ${(props) => props.theme.text60};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export type EditableRelationProps<
|
export type EditableRelationProps<RelationType, ChipComponentPropsType> = {
|
||||||
RelationType extends AnyEntity,
|
relation?: any;
|
||||||
ChipComponentPropsType,
|
|
||||||
> = {
|
|
||||||
relation?: RelationType | null;
|
|
||||||
searchPlaceholder: string;
|
searchPlaceholder: string;
|
||||||
searchConfig: SearchConfigType<RelationType>;
|
searchConfig: SearchConfigType;
|
||||||
onChange: (relation: RelationType) => void;
|
onChange: (relation: RelationType) => void;
|
||||||
onChangeSearchInput?: (searchInput: string) => void;
|
onChangeSearchInput?: (searchInput: string) => void;
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
editModeHorizontalAlign?: 'left' | 'right';
|
||||||
@ -105,10 +101,7 @@ export type EditableRelationProps<
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO: split this component
|
// TODO: split this component
|
||||||
export function EditableRelation<
|
export function EditableRelation<RelationType, ChipComponentPropsType>({
|
||||||
RelationType extends AnyEntity,
|
|
||||||
ChipComponentPropsType,
|
|
||||||
>({
|
|
||||||
relation,
|
relation,
|
||||||
searchPlaceholder,
|
searchPlaceholder,
|
||||||
searchConfig,
|
searchConfig,
|
||||||
|
@ -40,7 +40,8 @@ export const FilterDropdownButton = <TData extends FilterableFieldsType>({
|
|||||||
FilterOperandType<TData> | undefined
|
FilterOperandType<TData> | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
|
|
||||||
const [filterSearchResults, setSearchInput, setFilterSearch] = useSearch();
|
const [filterSearchResults, setSearchInput, setFilterSearch] =
|
||||||
|
useSearch<TData>();
|
||||||
|
|
||||||
const resetState = useCallback(() => {
|
const resetState = useCallback(() => {
|
||||||
setIsOperandSelectionUnfolded(false);
|
setIsOperandSelectionUnfolded(false);
|
||||||
@ -79,7 +80,7 @@ export const FilterDropdownButton = <TData extends FilterableFieldsType>({
|
|||||||
));
|
));
|
||||||
|
|
||||||
const renderSearchResults = (
|
const renderSearchResults = (
|
||||||
filterSearchResults: SearchResultsType,
|
filterSearchResults: SearchResultsType<TData>,
|
||||||
selectedFilter: FilterConfigType<TData>,
|
selectedFilter: FilterConfigType<TData>,
|
||||||
selectedFilterOperand: FilterOperandType<TData>,
|
selectedFilterOperand: FilterOperandType<TData>,
|
||||||
) => {
|
) => {
|
||||||
@ -155,7 +156,7 @@ export const FilterDropdownButton = <TData extends FilterableFieldsType>({
|
|||||||
displayValue: event.target.value,
|
displayValue: event.target.value,
|
||||||
icon: selectedFilter.icon,
|
icon: selectedFilter.icon,
|
||||||
operand: selectedFilterOperand,
|
operand: selectedFilterOperand,
|
||||||
});
|
} as SelectedFilterType<TData>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@ -172,7 +173,7 @@ export const FilterDropdownButton = <TData extends FilterableFieldsType>({
|
|||||||
displayValue: humanReadableDate(date),
|
displayValue: humanReadableDate(date),
|
||||||
icon: selectedFilter.icon,
|
icon: selectedFilter.icon,
|
||||||
operand: selectedFilterOperand,
|
operand: selectedFilterOperand,
|
||||||
});
|
} as SelectedFilterType<TData>);
|
||||||
}}
|
}}
|
||||||
customInput={<></>}
|
customInput={<></>}
|
||||||
customCalendarContainer={styled.div`
|
customCalendarContainer={styled.div`
|
||||||
@ -200,7 +201,7 @@ export const FilterDropdownButton = <TData extends FilterableFieldsType>({
|
|||||||
setIsUnfolded={setIsUnfolded}
|
setIsUnfolded={setIsUnfolded}
|
||||||
resetState={resetState}
|
resetState={resetState}
|
||||||
>
|
>
|
||||||
{selectedFilter
|
{selectedFilter && selectedFilterOperand
|
||||||
? isOperandSelectionUnfolded
|
? isOperandSelectionUnfolded
|
||||||
? renderOperandSelection
|
? renderOperandSelection
|
||||||
: renderValueSelection(selectedFilter, selectedFilterOperand)
|
: renderValueSelection(selectedFilter, selectedFilterOperand)
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import { User as GQLUser } from '../../../generated/graphql';
|
|
||||||
import { DeepPartial } from '../../utils/utils';
|
|
||||||
|
|
||||||
export type User = DeepPartial<GQLUser> & { id: string };
|
|
||||||
|
|
||||||
export type GraphqlQueryUser = User;
|
|
||||||
|
|
||||||
export type GraphqlMutationUser = User;
|
|
||||||
|
|
||||||
export const mapToUser = (user: GraphqlQueryUser): User => user;
|
|
||||||
|
|
||||||
export const mapToGqlUser = (user: User): GraphqlMutationUser => user;
|
|
@ -1,18 +0,0 @@
|
|||||||
import { WorkspaceMember as GQLWorkspaceMember } from '../../../generated/graphql';
|
|
||||||
import { DeepPartial } from '../../utils/utils';
|
|
||||||
|
|
||||||
export type WorkspaceMember = DeepPartial<GQLWorkspaceMember> & {
|
|
||||||
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;
|
|
@ -1,9 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const GET_CURRENT_USER = gql`
|
|
||||||
query getUsers {
|
|
||||||
findManyUser {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
@ -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<string, any>;
|
|
||||||
|
|
||||||
export type UnknownType = void;
|
|
||||||
|
|
||||||
export type GqlType<T> = T extends Company
|
|
||||||
? GraphqlQueryCompany
|
|
||||||
: T extends Person
|
|
||||||
? GraphqlQueryPerson
|
|
||||||
: T extends User
|
|
||||||
? GraphqlQueryUser
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type BoolExpType<T> = T extends Company
|
|
||||||
? Companies_Bool_Exp
|
|
||||||
: T extends Person
|
|
||||||
? People_Bool_Exp
|
|
||||||
: T extends User
|
|
||||||
? Users_Bool_Exp
|
|
||||||
: never;
|
|
@ -13,9 +13,3 @@ export const getLogoUrlFromDomainName = (domainName?: string): string => {
|
|||||||
export const browserPrefersDarkMode = (): boolean => {
|
export const browserPrefersDarkMode = (): boolean => {
|
||||||
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DeepPartial<T> = T extends object
|
|
||||||
? {
|
|
||||||
[P in keyof T]?: DeepPartial<T[P]>;
|
|
||||||
}
|
|
||||||
: T;
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { Workspace as GQLWorkspace } from '../../../generated/graphql';
|
|
||||||
import { DeepPartial } from '../../utils/utils';
|
|
||||||
|
|
||||||
export type Workspace = DeepPartial<GQLWorkspace> & { 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;
|
|
@ -3,14 +3,9 @@ import { useTheme } from '@emotion/react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import {
|
|
||||||
Company,
|
|
||||||
mapToCompany,
|
|
||||||
} from '@/companies/interfaces/company.interface';
|
|
||||||
import {
|
import {
|
||||||
CompaniesSelectedSortType,
|
CompaniesSelectedSortType,
|
||||||
defaultOrderBy,
|
defaultOrderBy,
|
||||||
insertCompany,
|
|
||||||
useCompaniesQuery,
|
useCompaniesQuery,
|
||||||
} from '@/companies/services';
|
} from '@/companies/services';
|
||||||
import {
|
import {
|
||||||
@ -23,8 +18,13 @@ import { EntityTable } from '@/ui/components/table/EntityTable';
|
|||||||
import { IconBuildingSkyscraper } from '@/ui/icons/index';
|
import { IconBuildingSkyscraper } from '@/ui/icons/index';
|
||||||
import { IconList } from '@/ui/icons/index';
|
import { IconList } from '@/ui/icons/index';
|
||||||
import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer';
|
import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer';
|
||||||
import { BoolExpType } from '@/utils/interfaces/generic.interface';
|
import {
|
||||||
import { CompanyOrderByWithRelationInput as Companies_Order_By } from '~/generated/graphql';
|
CompanyOrderByWithRelationInput as Companies_Order_By,
|
||||||
|
CompanyWhereInput,
|
||||||
|
GetCompaniesQuery,
|
||||||
|
InsertCompanyMutationVariables,
|
||||||
|
useInsertCompanyMutation,
|
||||||
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
import { TableActionBarButtonCreateCommentThreadCompany } from './table/TableActionBarButtonCreateCommentThreadCompany';
|
import { TableActionBarButtonCreateCommentThreadCompany } from './table/TableActionBarButtonCreateCommentThreadCompany';
|
||||||
import { TableActionBarButtonDeleteCompanies } from './table/TableActionBarButtonDeleteCompanies';
|
import { TableActionBarButtonDeleteCompanies } from './table/TableActionBarButtonDeleteCompanies';
|
||||||
@ -38,15 +38,16 @@ const StyledCompaniesContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export function Companies() {
|
export function Companies() {
|
||||||
|
const [insertCompany] = useInsertCompanyMutation();
|
||||||
const [orderBy, setOrderBy] = useState<Companies_Order_By[]>(defaultOrderBy);
|
const [orderBy, setOrderBy] = useState<Companies_Order_By[]>(defaultOrderBy);
|
||||||
const [where, setWhere] = useState<BoolExpType<Company>>({});
|
const [where, setWhere] = useState<CompanyWhereInput>({});
|
||||||
|
|
||||||
const updateSorts = useCallback((sorts: Array<CompaniesSelectedSortType>) => {
|
const updateSorts = useCallback((sorts: Array<CompaniesSelectedSortType>) => {
|
||||||
setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy);
|
setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const updateFilters = useCallback(
|
const updateFilters = useCallback(
|
||||||
(filters: Array<SelectedFilterType<Company>>) => {
|
(filters: Array<SelectedFilterType<GetCompaniesQuery['companies'][0]>>) => {
|
||||||
setWhere(reduceFiltersToWhere(filters));
|
setWhere(reduceFiltersToWhere(filters));
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
@ -54,21 +55,19 @@ export function Companies() {
|
|||||||
|
|
||||||
const { data } = useCompaniesQuery(orderBy, where);
|
const { data } = useCompaniesQuery(orderBy, where);
|
||||||
|
|
||||||
const companies = data?.companies.map(mapToCompany) ?? [];
|
const companies = data?.companies ?? [];
|
||||||
|
|
||||||
async function handleAddButtonClick() {
|
async function handleAddButtonClick() {
|
||||||
const newCompany: Company = {
|
const newCompany: InsertCompanyMutationVariables = {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
name: '',
|
name: '',
|
||||||
domainName: '',
|
domainName: '',
|
||||||
employees: null,
|
employees: null,
|
||||||
address: '',
|
address: '',
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
accountOwner: null,
|
|
||||||
__typename: 'Company',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
await insertCompany(newCompany);
|
await insertCompany({ variables: newCompany });
|
||||||
}
|
}
|
||||||
|
|
||||||
const companiesColumns = useCompaniesColumns();
|
const companiesColumns = useCompaniesColumns();
|
||||||
|
@ -2,7 +2,6 @@ import { useMemo } from 'react';
|
|||||||
import { createColumnHelper } from '@tanstack/react-table';
|
import { createColumnHelper } from '@tanstack/react-table';
|
||||||
|
|
||||||
import { CompanyEditableNameChipCell } from '@/companies/components/CompanyEditableNameCell';
|
import { CompanyEditableNameChipCell } from '@/companies/components/CompanyEditableNameCell';
|
||||||
import { updateCompany } from '@/companies/services';
|
|
||||||
import {
|
import {
|
||||||
PersonChip,
|
PersonChip,
|
||||||
PersonChipPropsType,
|
PersonChipPropsType,
|
||||||
@ -22,12 +21,16 @@ import {
|
|||||||
IconUsers,
|
IconUsers,
|
||||||
} from '@/ui/icons/index';
|
} from '@/ui/icons/index';
|
||||||
import { getCheckBoxColumn } from '@/ui/tables/utils/getCheckBoxColumn';
|
import { getCheckBoxColumn } from '@/ui/tables/utils/getCheckBoxColumn';
|
||||||
import { mapToUser, User } from '@/users/interfaces/user.interface';
|
import {
|
||||||
import { GetCompaniesQueryHookResult, QueryMode } from '~/generated/graphql';
|
GetCompaniesQuery,
|
||||||
|
QueryMode,
|
||||||
|
useUpdateCompanyMutation,
|
||||||
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<GetCompaniesQueryHookResult>();
|
const columnHelper = createColumnHelper<GetCompaniesQuery['companies'][0]>();
|
||||||
|
|
||||||
export const useCompaniesColumns = () => {
|
export const useCompaniesColumns = () => {
|
||||||
|
const [updateCompany] = useUpdateCompanyMutation();
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return [
|
return [
|
||||||
getCheckBoxColumn(),
|
getCheckBoxColumn(),
|
||||||
@ -54,7 +57,12 @@ export const useCompaniesColumns = () => {
|
|||||||
changeHandler={(value) => {
|
changeHandler={(value) => {
|
||||||
const company = { ...props.row.original };
|
const company = { ...props.row.original };
|
||||||
company.domainName = value;
|
company.domainName = value;
|
||||||
updateCompany(company);
|
updateCompany({
|
||||||
|
variables: {
|
||||||
|
...company,
|
||||||
|
accountOwnerId: company.accountOwner?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@ -71,13 +79,13 @@ export const useCompaniesColumns = () => {
|
|||||||
changeHandler={(value) => {
|
changeHandler={(value) => {
|
||||||
const company = { ...props.row.original };
|
const company = { ...props.row.original };
|
||||||
|
|
||||||
if (value === '') {
|
updateCompany({
|
||||||
company.employees = null;
|
variables: {
|
||||||
updateCompany(company);
|
...company,
|
||||||
} else if (!Number.isNaN(Number(value))) {
|
employees: value === '' ? null : Number(value),
|
||||||
company.employees = Number(value);
|
accountOwnerId: company.accountOwner?.id,
|
||||||
updateCompany(company);
|
},
|
||||||
}
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@ -94,7 +102,12 @@ export const useCompaniesColumns = () => {
|
|||||||
changeHandler={(value) => {
|
changeHandler={(value) => {
|
||||||
const company = { ...props.row.original };
|
const company = { ...props.row.original };
|
||||||
company.address = value;
|
company.address = value;
|
||||||
updateCompany(company);
|
updateCompany({
|
||||||
|
variables: {
|
||||||
|
...company,
|
||||||
|
accountOwnerId: company.accountOwner?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@ -117,7 +130,12 @@ export const useCompaniesColumns = () => {
|
|||||||
changeHandler={(value: Date) => {
|
changeHandler={(value: Date) => {
|
||||||
const company = { ...props.row.original };
|
const company = { ...props.row.original };
|
||||||
company.createdAt = value.toISOString();
|
company.createdAt = value.toISOString();
|
||||||
updateCompany(company);
|
updateCompany({
|
||||||
|
variables: {
|
||||||
|
...company,
|
||||||
|
accountOwnerId: company.accountOwner?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@ -131,21 +149,24 @@ export const useCompaniesColumns = () => {
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
cell: (props) => (
|
cell: (props) => (
|
||||||
<EditableRelation<User, PersonChipPropsType>
|
<EditableRelation<any, PersonChipPropsType>
|
||||||
relation={props.row.original.accountOwner}
|
relation={props.row.original.accountOwner}
|
||||||
searchPlaceholder="Account Owner"
|
searchPlaceholder="Account Owner"
|
||||||
ChipComponent={PersonChip}
|
ChipComponent={PersonChip}
|
||||||
chipComponentPropsMapper={(
|
chipComponentPropsMapper={(
|
||||||
accountOwner: User,
|
accountOwner: any,
|
||||||
): PersonChipPropsType => {
|
): PersonChipPropsType => {
|
||||||
return {
|
return {
|
||||||
name: accountOwner.displayName || '',
|
name: accountOwner.displayName || '',
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
onChange={(relation: User) => {
|
onChange={(relation: any) => {
|
||||||
const company = { ...props.row.original };
|
updateCompany({
|
||||||
company.accountOwnerId = relation.id;
|
variables: {
|
||||||
updateCompany(company);
|
...props.row.original,
|
||||||
|
accountOwnerId: relation.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
searchConfig={
|
searchConfig={
|
||||||
{
|
{
|
||||||
@ -156,15 +177,15 @@ export const useCompaniesColumns = () => {
|
|||||||
mode: QueryMode.Insensitive,
|
mode: QueryMode.Insensitive,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
resultMapper: (accountOwner) => ({
|
resultMapper: (accountOwner: any) => ({
|
||||||
render: (accountOwner) => accountOwner.displayName,
|
render: (accountOwner: any) => accountOwner.displayName,
|
||||||
value: mapToUser(accountOwner),
|
value: accountOwner,
|
||||||
}),
|
}),
|
||||||
} satisfies SearchConfigType<User>
|
} satisfies SearchConfigType
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
}, []);
|
}, [updateCompany]);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { Company } from '@/companies/interfaces/company.interface';
|
|
||||||
import { FilterConfigType } from '@/filters-and-sorts/interfaces/filters/interface';
|
import { FilterConfigType } from '@/filters-and-sorts/interfaces/filters/interface';
|
||||||
import { SEARCH_USER_QUERY } from '@/search/services/search';
|
import { SEARCH_USER_QUERY } from '@/search/services/search';
|
||||||
import {
|
import {
|
||||||
@ -9,8 +8,7 @@ import {
|
|||||||
IconUser,
|
IconUser,
|
||||||
IconUsers,
|
IconUsers,
|
||||||
} from '@/ui/icons/index';
|
} from '@/ui/icons/index';
|
||||||
import { mapToUser, User } from '@/users/interfaces/user.interface';
|
import { QueryMode, User } from '~/generated/graphql';
|
||||||
import { QueryMode } from '~/generated/graphql';
|
|
||||||
|
|
||||||
export const nameFilter = {
|
export const nameFilter = {
|
||||||
key: 'name',
|
key: 'name',
|
||||||
@ -21,14 +19,14 @@ export const nameFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Contains',
|
label: 'Contains',
|
||||||
id: 'like',
|
id: 'like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
name: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
name: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Does not contain',
|
label: 'Does not contain',
|
||||||
id: 'not_like',
|
id: 'not_like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
NOT: [
|
NOT: [
|
||||||
{
|
{
|
||||||
name: {
|
name: {
|
||||||
@ -40,7 +38,7 @@ export const nameFilter = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Company, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const employeesFilter = {
|
export const employeesFilter = {
|
||||||
key: 'employees',
|
key: 'employees',
|
||||||
@ -51,7 +49,7 @@ export const employeesFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Greater than',
|
label: 'Greater than',
|
||||||
id: 'greater_than',
|
id: 'greater_than',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
employees: {
|
employees: {
|
||||||
gte: isNaN(Number(searchString)) ? undefined : Number(searchString),
|
gte: isNaN(Number(searchString)) ? undefined : Number(searchString),
|
||||||
},
|
},
|
||||||
@ -60,14 +58,14 @@ export const employeesFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Less than',
|
label: 'Less than',
|
||||||
id: 'less_than',
|
id: 'less_than',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
employees: {
|
employees: {
|
||||||
lte: isNaN(Number(searchString)) ? undefined : Number(searchString),
|
lte: isNaN(Number(searchString)) ? undefined : Number(searchString),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Company, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const urlFilter = {
|
export const urlFilter = {
|
||||||
key: 'domainName',
|
key: 'domainName',
|
||||||
@ -78,7 +76,7 @@ export const urlFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Contains',
|
label: 'Contains',
|
||||||
id: 'like',
|
id: 'like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
domainName: {
|
domainName: {
|
||||||
contains: `%${searchString}%`,
|
contains: `%${searchString}%`,
|
||||||
mode: QueryMode.Insensitive,
|
mode: QueryMode.Insensitive,
|
||||||
@ -88,7 +86,7 @@ export const urlFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Does not contain',
|
label: 'Does not contain',
|
||||||
id: 'not_like',
|
id: 'not_like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
NOT: [
|
NOT: [
|
||||||
{
|
{
|
||||||
domainName: {
|
domainName: {
|
||||||
@ -100,7 +98,7 @@ export const urlFilter = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Company, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const addressFilter = {
|
export const addressFilter = {
|
||||||
key: 'address',
|
key: 'address',
|
||||||
@ -111,14 +109,14 @@ export const addressFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Contains',
|
label: 'Contains',
|
||||||
id: 'like',
|
id: 'like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
address: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
address: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Does not contain',
|
label: 'Does not contain',
|
||||||
id: 'not_like',
|
id: 'not_like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
NOT: [
|
NOT: [
|
||||||
{
|
{
|
||||||
address: {
|
address: {
|
||||||
@ -130,7 +128,7 @@ export const addressFilter = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Company, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const ccreatedAtFilter = {
|
export const ccreatedAtFilter = {
|
||||||
key: 'createdAt',
|
key: 'createdAt',
|
||||||
@ -141,7 +139,7 @@ export const ccreatedAtFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Greater than',
|
label: 'Greater than',
|
||||||
id: 'greater_than',
|
id: 'greater_than',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
createdAt: {
|
createdAt: {
|
||||||
gte: searchString,
|
gte: searchString,
|
||||||
},
|
},
|
||||||
@ -150,14 +148,14 @@ export const ccreatedAtFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Less than',
|
label: 'Less than',
|
||||||
id: 'less_than',
|
id: 'less_than',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
createdAt: {
|
createdAt: {
|
||||||
lte: searchString,
|
lte: searchString,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Company, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const accountOwnerFilter = {
|
export const accountOwnerFilter = {
|
||||||
key: 'accountOwner',
|
key: 'accountOwner',
|
||||||
@ -172,24 +170,24 @@ export const accountOwnerFilter = {
|
|||||||
mode: QueryMode.Insensitive,
|
mode: QueryMode.Insensitive,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
resultMapper: (data) => ({
|
resultMapper: (data: any) => ({
|
||||||
value: mapToUser(data),
|
value: data,
|
||||||
render: (owner) => owner.displayName,
|
render: (owner: any) => owner.displayName,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
selectedValueRender: (owner) => owner.displayName || '',
|
selectedValueRender: (owner: any) => owner.displayName || '',
|
||||||
operands: [
|
operands: [
|
||||||
{
|
{
|
||||||
label: 'Is',
|
label: 'Is',
|
||||||
id: 'is',
|
id: 'is',
|
||||||
whereTemplate: (owner) => ({
|
whereTemplate: (owner: any) => ({
|
||||||
accountOwner: { is: { displayName: { equals: owner.displayName } } },
|
accountOwner: { is: { displayName: { equals: owner.displayName } } },
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Is not',
|
label: 'Is not',
|
||||||
id: 'is_not',
|
id: 'is_not',
|
||||||
whereTemplate: (owner) => ({
|
whereTemplate: (owner: any) => ({
|
||||||
NOT: [
|
NOT: [
|
||||||
{
|
{
|
||||||
accountOwner: {
|
accountOwner: {
|
||||||
@ -200,7 +198,7 @@ export const accountOwnerFilter = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Company, User>;
|
} satisfies FilterConfigType<User>;
|
||||||
|
|
||||||
export const availableFilters = [
|
export const availableFilters = [
|
||||||
nameFilter,
|
nameFilter,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
@ -8,10 +9,9 @@ import {
|
|||||||
reduceSortsToOrderBy,
|
reduceSortsToOrderBy,
|
||||||
} from '@/filters-and-sorts/helpers';
|
} from '@/filters-and-sorts/helpers';
|
||||||
import { SelectedFilterType } from '@/filters-and-sorts/interfaces/filters/interface';
|
import { SelectedFilterType } from '@/filters-and-sorts/interfaces/filters/interface';
|
||||||
import { Person } from '@/people/interfaces/person.interface';
|
|
||||||
import {
|
import {
|
||||||
defaultOrderBy,
|
defaultOrderBy,
|
||||||
insertPerson,
|
GET_PEOPLE,
|
||||||
PeopleSelectedSortType,
|
PeopleSelectedSortType,
|
||||||
usePeopleQuery,
|
usePeopleQuery,
|
||||||
} from '@/people/services';
|
} from '@/people/services';
|
||||||
@ -19,7 +19,11 @@ import { EntityTableActionBar } from '@/ui/components/table/action-bar/EntityTab
|
|||||||
import { EntityTable } from '@/ui/components/table/EntityTable';
|
import { EntityTable } from '@/ui/components/table/EntityTable';
|
||||||
import { IconList, IconUser } from '@/ui/icons/index';
|
import { IconList, IconUser } from '@/ui/icons/index';
|
||||||
import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer';
|
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 { TableActionBarButtonCreateCommentThreadPeople } from './table/TableActionBarButtonCreateCommentThreadPeople';
|
||||||
import { TableActionBarButtonDeletePeople } from './table/TableActionBarButtonDeletePeople';
|
import { TableActionBarButtonDeletePeople } from './table/TableActionBarButtonDeletePeople';
|
||||||
@ -35,37 +39,38 @@ const StyledPeopleContainer = styled.div`
|
|||||||
|
|
||||||
export function People() {
|
export function People() {
|
||||||
const [orderBy, setOrderBy] = useState(defaultOrderBy);
|
const [orderBy, setOrderBy] = useState(defaultOrderBy);
|
||||||
const [where, setWhere] = useState<BoolExpType<Person>>({});
|
const [where, setWhere] = useState<PersonWhereInput>({});
|
||||||
|
|
||||||
const updateSorts = useCallback((sorts: Array<PeopleSelectedSortType>) => {
|
const updateSorts = useCallback((sorts: Array<PeopleSelectedSortType>) => {
|
||||||
setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy);
|
setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const updateFilters = useCallback(
|
const updateFilters = useCallback(
|
||||||
(filters: Array<SelectedFilterType<Person>>) => {
|
(filters: Array<SelectedFilterType<GetPeopleQuery['people'][0]>>) => {
|
||||||
setWhere(reduceFiltersToWhere(filters));
|
setWhere(reduceFiltersToWhere(filters));
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [insertPersonMutation] = useInsertPersonMutation();
|
||||||
|
|
||||||
const { data } = usePeopleQuery(orderBy, where);
|
const { data } = usePeopleQuery(orderBy, where);
|
||||||
|
|
||||||
const people = data?.people ?? [];
|
const people = data?.people ?? [];
|
||||||
|
|
||||||
async function handleAddButtonClick() {
|
async function handleAddButtonClick() {
|
||||||
const newPerson = {
|
await insertPersonMutation({
|
||||||
__typename: 'Person',
|
variables: {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
firstname: '',
|
firstname: '',
|
||||||
lastname: '',
|
lastname: '',
|
||||||
email: '',
|
email: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
company: null,
|
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
city: '',
|
city: '',
|
||||||
} as const;
|
},
|
||||||
|
refetchQueries: [getOperationName(GET_PEOPLE) ?? ''],
|
||||||
await insertPerson(newPerson);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const peopleColumns = usePeopleColumns();
|
const peopleColumns = usePeopleColumns();
|
||||||
|
@ -3,7 +3,6 @@ import type { Meta } from '@storybook/react';
|
|||||||
import { userEvent, within } from '@storybook/testing-library';
|
import { userEvent, within } from '@storybook/testing-library';
|
||||||
import { graphql } from 'msw';
|
import { graphql } from 'msw';
|
||||||
|
|
||||||
import { GraphqlQueryCompany } from '@/companies/interfaces/company.interface';
|
|
||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||||
import { fetchOneFromData } from '~/testing/mock-data';
|
import { fetchOneFromData } from '~/testing/mock-data';
|
||||||
import { mockedPeopleData } from '~/testing/mock-data/people';
|
import { mockedPeopleData } from '~/testing/mock-data/people';
|
||||||
@ -141,7 +140,7 @@ export const EditRelation: Story = {
|
|||||||
name: 'Airbnb',
|
name: 'Airbnb',
|
||||||
domainName: 'airbnb.com',
|
domainName: 'airbnb.com',
|
||||||
__typename: 'Company',
|
__typename: 'Company',
|
||||||
} satisfies GraphqlQueryCompany,
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -196,7 +195,7 @@ export const SelectRelationWithKeys: Story = {
|
|||||||
name: 'Aircall',
|
name: 'Aircall',
|
||||||
domainName: 'aircall.io',
|
domainName: 'aircall.io',
|
||||||
__typename: 'Company',
|
__typename: 'Company',
|
||||||
} satisfies GraphqlQueryCompany,
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
@ -4,10 +4,7 @@ describe('PeopleFilter', () => {
|
|||||||
it(`should render the filter ${companyFilter.key} which relation search`, () => {
|
it(`should render the filter ${companyFilter.key} which relation search`, () => {
|
||||||
expect(
|
expect(
|
||||||
companyFilter.operands[0].whereTemplate({
|
companyFilter.operands[0].whereTemplate({
|
||||||
id: 'test-id',
|
|
||||||
name: 'test-name',
|
name: 'test-name',
|
||||||
domainName: 'test-domain-name',
|
|
||||||
__typename: 'Company',
|
|
||||||
}),
|
}),
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,6 @@ import { createColumnHelper } from '@tanstack/react-table';
|
|||||||
|
|
||||||
import { EditablePeopleFullName } from '@/people/components/EditablePeopleFullName';
|
import { EditablePeopleFullName } from '@/people/components/EditablePeopleFullName';
|
||||||
import { PeopleCompanyCell } from '@/people/components/PeopleCompanyCell';
|
import { PeopleCompanyCell } from '@/people/components/PeopleCompanyCell';
|
||||||
import { updatePerson } from '@/people/services';
|
|
||||||
import { EditableDate } from '@/ui/components/editable-cell/types/EditableDate';
|
import { EditableDate } from '@/ui/components/editable-cell/types/EditableDate';
|
||||||
import { EditablePhone } from '@/ui/components/editable-cell/types/EditablePhone';
|
import { EditablePhone } from '@/ui/components/editable-cell/types/EditablePhone';
|
||||||
import { EditableText } from '@/ui/components/editable-cell/types/EditableText';
|
import { EditableText } from '@/ui/components/editable-cell/types/EditableText';
|
||||||
@ -17,12 +16,13 @@ import {
|
|||||||
IconUser,
|
IconUser,
|
||||||
} from '@/ui/icons/index';
|
} from '@/ui/icons/index';
|
||||||
import { getCheckBoxColumn } from '@/ui/tables/utils/getCheckBoxColumn';
|
import { getCheckBoxColumn } from '@/ui/tables/utils/getCheckBoxColumn';
|
||||||
|
import { GetPeopleQuery, useUpdatePeopleMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
import { GetPeopleQueryHookResult } from '../../generated/graphql';
|
const columnHelper = createColumnHelper<GetPeopleQuery['people'][0]>();
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<GetPeopleQueryHookResult>();
|
|
||||||
|
|
||||||
export const usePeopleColumns = () => {
|
export const usePeopleColumns = () => {
|
||||||
|
const [updatePerson] = useUpdatePeopleMutation();
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return [
|
return [
|
||||||
getCheckBoxColumn(),
|
getCheckBoxColumn(),
|
||||||
@ -36,9 +36,14 @@ export const usePeopleColumns = () => {
|
|||||||
person={props.row.original}
|
person={props.row.original}
|
||||||
onChange={async (firstName: string, lastName: string) => {
|
onChange={async (firstName: string, lastName: string) => {
|
||||||
const person = { ...props.row.original };
|
const person = { ...props.row.original };
|
||||||
person.firstname = firstName;
|
await updatePerson({
|
||||||
person.lastname = lastName;
|
variables: {
|
||||||
await updatePerson(person);
|
...person,
|
||||||
|
firstname: firstName,
|
||||||
|
lastname: lastName,
|
||||||
|
companyId: person.company?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
@ -53,10 +58,15 @@ export const usePeopleColumns = () => {
|
|||||||
<EditableText
|
<EditableText
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
content={props.row.original.email || ''}
|
content={props.row.original.email || ''}
|
||||||
changeHandler={(value: string) => {
|
changeHandler={async (value: string) => {
|
||||||
const person = props.row.original;
|
const person = props.row.original;
|
||||||
person.email = value;
|
await updatePerson({
|
||||||
updatePerson(person);
|
variables: {
|
||||||
|
...person,
|
||||||
|
email: value,
|
||||||
|
companyId: person.company?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@ -80,10 +90,15 @@ export const usePeopleColumns = () => {
|
|||||||
<EditablePhone
|
<EditablePhone
|
||||||
placeholder="Phone"
|
placeholder="Phone"
|
||||||
value={props.row.original.phone || ''}
|
value={props.row.original.phone || ''}
|
||||||
changeHandler={(value: string) => {
|
changeHandler={async (value: string) => {
|
||||||
const person = { ...props.row.original };
|
const person = { ...props.row.original };
|
||||||
person.phone = value;
|
await updatePerson({
|
||||||
updatePerson(person);
|
variables: {
|
||||||
|
...person,
|
||||||
|
phone: value,
|
||||||
|
companyId: person.company?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@ -103,10 +118,15 @@ export const usePeopleColumns = () => {
|
|||||||
? new Date(props.row.original.createdAt)
|
? new Date(props.row.original.createdAt)
|
||||||
: new Date()
|
: new Date()
|
||||||
}
|
}
|
||||||
changeHandler={(value: Date) => {
|
changeHandler={async (value: Date) => {
|
||||||
const person = { ...props.row.original };
|
const person = { ...props.row.original };
|
||||||
person.createdAt = value.toISOString();
|
await updatePerson({
|
||||||
updatePerson(person);
|
variables: {
|
||||||
|
...person,
|
||||||
|
createdAt: value.toISOString(),
|
||||||
|
companyId: person.company?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
@ -121,14 +141,19 @@ export const usePeopleColumns = () => {
|
|||||||
editModeHorizontalAlign="right"
|
editModeHorizontalAlign="right"
|
||||||
placeholder="City"
|
placeholder="City"
|
||||||
content={props.row.original.city || ''}
|
content={props.row.original.city || ''}
|
||||||
changeHandler={(value: string) => {
|
changeHandler={async (value: string) => {
|
||||||
const person = { ...props.row.original };
|
const person = { ...props.row.original };
|
||||||
person.city = value;
|
await updatePerson({
|
||||||
updatePerson(person);
|
variables: {
|
||||||
|
...person,
|
||||||
|
city: value,
|
||||||
|
companyId: person.company?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
}, []);
|
}, [updatePerson]);
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
import {
|
|
||||||
Company,
|
|
||||||
mapToCompany,
|
|
||||||
} from '@/companies/interfaces/company.interface';
|
|
||||||
import { FilterConfigType } from '@/filters-and-sorts/interfaces/filters/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 { SEARCH_COMPANY_QUERY } from '@/search/services/search';
|
||||||
import {
|
import {
|
||||||
IconBuildingSkyscraper,
|
IconBuildingSkyscraper,
|
||||||
@ -13,7 +8,7 @@ import {
|
|||||||
IconPhone,
|
IconPhone,
|
||||||
IconUser,
|
IconUser,
|
||||||
} from '@/ui/icons/index';
|
} from '@/ui/icons/index';
|
||||||
import { QueryMode } from '~/generated/graphql';
|
import { Company, QueryMode } from '~/generated/graphql';
|
||||||
|
|
||||||
export const fullnameFilter = {
|
export const fullnameFilter = {
|
||||||
key: 'fullname',
|
key: 'fullname',
|
||||||
@ -24,7 +19,7 @@ export const fullnameFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Contains',
|
label: 'Contains',
|
||||||
id: 'like',
|
id: 'like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
firstname: {
|
firstname: {
|
||||||
@ -44,7 +39,7 @@ export const fullnameFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Does not contain',
|
label: 'Does not contain',
|
||||||
id: 'not_like',
|
id: 'not_like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
NOT: [
|
NOT: [
|
||||||
{
|
{
|
||||||
AND: [
|
AND: [
|
||||||
@ -66,7 +61,7 @@ export const fullnameFilter = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Person, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const emailFilter = {
|
export const emailFilter = {
|
||||||
key: 'email',
|
key: 'email',
|
||||||
@ -77,14 +72,14 @@ export const emailFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Contains',
|
label: 'Contains',
|
||||||
id: 'like',
|
id: 'like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
email: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
email: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Does not contain',
|
label: 'Does not contain',
|
||||||
id: 'not_like',
|
id: 'not_like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
NOT: [
|
NOT: [
|
||||||
{
|
{
|
||||||
email: {
|
email: {
|
||||||
@ -96,7 +91,7 @@ export const emailFilter = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Person, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const companyFilter = {
|
export const companyFilter = {
|
||||||
key: 'company_name',
|
key: 'company_name',
|
||||||
@ -109,8 +104,8 @@ export const companyFilter = {
|
|||||||
name: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
name: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
||||||
}),
|
}),
|
||||||
resultMapper: (data) => ({
|
resultMapper: (data) => ({
|
||||||
value: mapToCompany(data),
|
value: data,
|
||||||
render: (company) => company.name,
|
render: (company: { name: string }) => company.name,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
selectedValueRender: (company) => company.name || '',
|
selectedValueRender: (company) => company.name || '',
|
||||||
@ -118,19 +113,19 @@ export const companyFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Is',
|
label: 'Is',
|
||||||
id: 'is',
|
id: 'is',
|
||||||
whereTemplate: (company) => ({
|
whereTemplate: (company: { name: string }) => ({
|
||||||
company: { is: { name: { equals: company.name } } },
|
company: { is: { name: { equals: company.name } } },
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Is not',
|
label: 'Is not',
|
||||||
id: 'is_not',
|
id: 'is_not',
|
||||||
whereTemplate: (company) => ({
|
whereTemplate: (company: { name: string }) => ({
|
||||||
NOT: [{ company: { is: { name: { equals: company.name } } } }],
|
NOT: [{ company: { is: { name: { equals: company.name } } } }],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Person, Company>;
|
} satisfies FilterConfigType<Company>;
|
||||||
|
|
||||||
export const phoneFilter = {
|
export const phoneFilter = {
|
||||||
key: 'phone',
|
key: 'phone',
|
||||||
@ -141,14 +136,14 @@ export const phoneFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Contains',
|
label: 'Contains',
|
||||||
id: 'like',
|
id: 'like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
phone: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
phone: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Does not contain',
|
label: 'Does not contain',
|
||||||
id: 'not_like',
|
id: 'not_like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
NOT: [
|
NOT: [
|
||||||
{
|
{
|
||||||
phone: {
|
phone: {
|
||||||
@ -160,7 +155,7 @@ export const phoneFilter = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Person, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const createdAtFilter = {
|
export const createdAtFilter = {
|
||||||
key: 'createdAt',
|
key: 'createdAt',
|
||||||
@ -171,7 +166,7 @@ export const createdAtFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Greater than',
|
label: 'Greater than',
|
||||||
id: 'greater_than',
|
id: 'greater_than',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
createdAt: {
|
createdAt: {
|
||||||
gte: searchString,
|
gte: searchString,
|
||||||
},
|
},
|
||||||
@ -180,14 +175,14 @@ export const createdAtFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Less than',
|
label: 'Less than',
|
||||||
id: 'less_than',
|
id: 'less_than',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
createdAt: {
|
createdAt: {
|
||||||
lte: searchString,
|
lte: searchString,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Company, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const cityFilter = {
|
export const cityFilter = {
|
||||||
key: 'city',
|
key: 'city',
|
||||||
@ -198,14 +193,14 @@ export const cityFilter = {
|
|||||||
{
|
{
|
||||||
label: 'Contains',
|
label: 'Contains',
|
||||||
id: 'like',
|
id: 'like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
city: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
city: { contains: `%${searchString}%`, mode: QueryMode.Insensitive },
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Does not contain',
|
label: 'Does not contain',
|
||||||
id: 'not_like',
|
id: 'not_like',
|
||||||
whereTemplate: (searchString) => ({
|
whereTemplate: (searchString: string) => ({
|
||||||
NOT: [
|
NOT: [
|
||||||
{
|
{
|
||||||
city: {
|
city: {
|
||||||
@ -217,7 +212,7 @@ export const cityFilter = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} satisfies FilterConfigType<Person, string>;
|
} satisfies FilterConfigType<string>;
|
||||||
|
|
||||||
export const availableFilters = [
|
export const availableFilters = [
|
||||||
fullnameFilter,
|
fullnameFilter,
|
||||||
@ -226,4 +221,4 @@ export const availableFilters = [
|
|||||||
phoneFilter,
|
phoneFilter,
|
||||||
createdAtFilter,
|
createdAtFilter,
|
||||||
cityFilter,
|
cityFilter,
|
||||||
] satisfies FilterConfigType<Person>[];
|
];
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { graphql } from 'msw';
|
import { graphql } from 'msw';
|
||||||
|
|
||||||
import { GraphqlQueryCompany } from '@/companies/interfaces/company.interface';
|
import { GET_COMPANIES } from '@/companies/services';
|
||||||
import { GraphqlQueryPerson } from '@/people/interfaces/person.interface';
|
import { GET_PEOPLE, UPDATE_PERSON } from '@/people/services';
|
||||||
import { GraphqlQueryUser } from '@/users/interfaces/user.interface';
|
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 { mockedCompaniesData } from './mock-data/companies';
|
||||||
import { mockedPeopleData } from './mock-data/people';
|
import { mockedPeopleData } from './mock-data/people';
|
||||||
@ -10,8 +22,10 @@ import { mockedUsersData } from './mock-data/users';
|
|||||||
import { filterAndSortData, updateOneFromData } from './mock-data';
|
import { filterAndSortData, updateOneFromData } from './mock-data';
|
||||||
|
|
||||||
export const graphqlMocks = [
|
export const graphqlMocks = [
|
||||||
graphql.query('GetCompanies', (req, res, ctx) => {
|
graphql.query(getOperationName(GET_COMPANIES) ?? '', (req, res, ctx) => {
|
||||||
const returnedMockedData = filterAndSortData<GraphqlQueryCompany>(
|
const returnedMockedData = filterAndSortData<
|
||||||
|
GetCompaniesQuery['companies'][0]
|
||||||
|
>(
|
||||||
mockedCompaniesData,
|
mockedCompaniesData,
|
||||||
req.variables.where,
|
req.variables.where,
|
||||||
req.variables.orderBy,
|
req.variables.orderBy,
|
||||||
@ -23,8 +37,12 @@ export const graphqlMocks = [
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
graphql.query('SearchCompany', (req, res, ctx) => {
|
graphql.query(
|
||||||
const returnedMockedData = filterAndSortData<GraphqlQueryCompany>(
|
getOperationName(SEARCH_COMPANY_QUERY) ?? '',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
const returnedMockedData = filterAndSortData<
|
||||||
|
SearchCompanyQuery['searchResults'][0]
|
||||||
|
>(
|
||||||
mockedCompaniesData,
|
mockedCompaniesData,
|
||||||
req.variables.where,
|
req.variables.where,
|
||||||
req.variables.orderBy,
|
req.variables.orderBy,
|
||||||
@ -35,9 +53,12 @@ export const graphqlMocks = [
|
|||||||
searchResults: returnedMockedData,
|
searchResults: returnedMockedData,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}),
|
},
|
||||||
graphql.query('SearchUser', (req, res, ctx) => {
|
),
|
||||||
const returnedMockedData = filterAndSortData<GraphqlQueryUser>(
|
graphql.query(getOperationName(SEARCH_USER_QUERY) ?? '', (req, res, ctx) => {
|
||||||
|
const returnedMockedData = filterAndSortData<
|
||||||
|
SearchUserQuery['searchResults'][0]
|
||||||
|
>(
|
||||||
mockedUsersData,
|
mockedUsersData,
|
||||||
req.variables.where,
|
req.variables.where,
|
||||||
req.variables.orderBy,
|
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 = {
|
const customWhere = {
|
||||||
...req.variables.where,
|
...req.variables.where,
|
||||||
id: {
|
id: {
|
||||||
@ -57,20 +78,17 @@ export const graphqlMocks = [
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const returnedMockedData = filterAndSortData<GraphqlQueryUser>(
|
const returnedMockedData = filterAndSortData<
|
||||||
mockedUsersData,
|
GetUsersQuery['findManyUser'][0]
|
||||||
customWhere,
|
>(mockedUsersData, customWhere, req.variables.orderBy, req.variables.limit);
|
||||||
req.variables.orderBy,
|
|
||||||
req.variables.limit,
|
|
||||||
);
|
|
||||||
return res(
|
return res(
|
||||||
ctx.data({
|
ctx.data({
|
||||||
users: returnedMockedData,
|
users: returnedMockedData,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
graphql.query('GetPeople', (req, res, ctx) => {
|
graphql.query(getOperationName(GET_PEOPLE) ?? '', (req, res, ctx) => {
|
||||||
const returnedMockedData = filterAndSortData<GraphqlQueryPerson>(
|
const returnedMockedData = filterAndSortData<GetPeopleQuery['people'][0]>(
|
||||||
mockedPeopleData,
|
mockedPeopleData,
|
||||||
req.variables.where,
|
req.variables.where,
|
||||||
req.variables.orderBy,
|
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(
|
return res(
|
||||||
ctx.data({
|
ctx.data({
|
||||||
updateOnePerson: updateOneFromData(
|
updateOnePerson: updateOneFromData(
|
||||||
|
@ -1,6 +1,28 @@
|
|||||||
import { CommentableType, CommentThread } from '~/generated/graphql';
|
import {
|
||||||
|
CommentableType,
|
||||||
|
CommentThread,
|
||||||
|
CommentThreadTarget,
|
||||||
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
export const mockedCommentThreads: Array<CommentThread> = [
|
type MockedCommentThread = Pick<
|
||||||
|
CommentThread,
|
||||||
|
'id' | 'createdAt' | 'updatedAt' | '__typename'
|
||||||
|
> & {
|
||||||
|
commentThreadTargets: Array<
|
||||||
|
Pick<
|
||||||
|
CommentThreadTarget,
|
||||||
|
| 'id'
|
||||||
|
| '__typename'
|
||||||
|
| 'createdAt'
|
||||||
|
| 'updatedAt'
|
||||||
|
| 'commentableType'
|
||||||
|
| 'commentableId'
|
||||||
|
| 'commentThreadId'
|
||||||
|
> & { commentThread: Pick<CommentThread, 'id' | 'createdAt' | 'updatedAt'> }
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockedCommentThreads: Array<MockedCommentThread> = [
|
||||||
{
|
{
|
||||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb230',
|
id: '89bb825c-171e-4bcc-9cf7-43448d6fb230',
|
||||||
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
||||||
|
@ -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<MockedCompany> = [
|
||||||
{
|
{
|
||||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb278',
|
id: '89bb825c-171e-4bcc-9cf7-43448d6fb278',
|
||||||
domainName: 'airbnb.com',
|
domainName: 'airbnb.com',
|
||||||
@ -83,4 +100,4 @@ export const mockedCompaniesData = [
|
|||||||
accountOwner: null,
|
accountOwner: null,
|
||||||
__typename: 'Company',
|
__typename: 'Company',
|
||||||
},
|
},
|
||||||
] as Array<Company>;
|
];
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { GraphQLVariables } from 'msw';
|
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 {
|
import {
|
||||||
CompanyOrderByWithRelationInput,
|
CompanyOrderByWithRelationInput,
|
||||||
PersonOrderByWithRelationInput,
|
PersonOrderByWithRelationInput,
|
||||||
@ -13,7 +9,7 @@ import {
|
|||||||
|
|
||||||
function filterData<DataT>(
|
function filterData<DataT>(
|
||||||
data: Array<DataT>,
|
data: Array<DataT>,
|
||||||
where: BoolExpType<Company> | BoolExpType<Person>,
|
where: Record<string, any>,
|
||||||
): Array<DataT> {
|
): Array<DataT> {
|
||||||
return data.filter((item) => {
|
return data.filter((item) => {
|
||||||
// { firstname: {contains: '%string%' }}
|
// { firstname: {contains: '%string%' }}
|
||||||
@ -76,7 +72,7 @@ function filterData<DataT>(
|
|||||||
|
|
||||||
export function filterAndSortData<DataT>(
|
export function filterAndSortData<DataT>(
|
||||||
data: Array<DataT>,
|
data: Array<DataT>,
|
||||||
where?: BoolExpType<Company> | BoolExpType<Person> | BoolExpType<User>,
|
where?: Record<string, any>,
|
||||||
orderBy?: Array<
|
orderBy?: Array<
|
||||||
PersonOrderByWithRelationInput &
|
PersonOrderByWithRelationInput &
|
||||||
CompanyOrderByWithRelationInput &
|
CompanyOrderByWithRelationInput &
|
||||||
|
@ -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<Company, 'id' | 'name' | 'domainName' | '__typename'>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockedPeopleData: Array<MockedPerson> = [
|
||||||
{
|
{
|
||||||
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
||||||
__typename: 'Person',
|
__typename: 'Person',
|
||||||
@ -73,4 +88,4 @@ export const mockedPeopleData = [
|
|||||||
|
|
||||||
city: 'Paris',
|
city: 'Paris',
|
||||||
},
|
},
|
||||||
] satisfies Array<Person>;
|
];
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
import { GraphqlQueryUser } from '@/users/interfaces/user.interface';
|
import { User, Workspace, WorkspaceMember } from '~/generated/graphql';
|
||||||
|
|
||||||
export const mockedUsersData: Array<GraphqlQueryUser> = [
|
type MockedUser = Pick<
|
||||||
|
User,
|
||||||
|
'id' | 'email' | 'displayName' | 'avatarUrl' | '__typename'
|
||||||
|
> & {
|
||||||
|
workspaceMember: Pick<WorkspaceMember, 'id' | '__typename'> & {
|
||||||
|
workspace: Pick<
|
||||||
|
Workspace,
|
||||||
|
'id' | 'displayName' | 'domainName' | 'logo' | '__typename'
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockedUsersData: Array<MockedUser> = [
|
||||||
{
|
{
|
||||||
id: '374fe3a5-df1e-4119-afe0-2a62a2ba481e',
|
id: '374fe3a5-df1e-4119-afe0-2a62a2ba481e',
|
||||||
__typename: 'User',
|
__typename: 'User',
|
||||||
@ -37,4 +49,4 @@ export const mockedUsersData: Array<GraphqlQueryUser> = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
] as GraphqlQueryUser[];
|
];
|
||||||
|
Loading…
Reference in New Issue
Block a user