Reorganize frontend and install Craco to alias modules (#190)
This commit is contained in:
@ -0,0 +1,63 @@
|
||||
import { useState } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { CellCommentChip } from '@/comments/components/comments/CellCommentChip';
|
||||
import { EditableDoubleText } from '@/ui/components/editable-cell/EditableDoubleText';
|
||||
|
||||
import { PersonChip } from './PersonChip';
|
||||
|
||||
type OwnProps = {
|
||||
firstname: string;
|
||||
lastname: string;
|
||||
onChange: (firstname: string, lastname: string) => void;
|
||||
};
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export function EditablePeopleFullName({
|
||||
firstname,
|
||||
lastname,
|
||||
onChange,
|
||||
}: OwnProps) {
|
||||
const [firstnameValue, setFirstnameValue] = useState(firstname);
|
||||
const [lastnameValue, setLastnameValue] = useState(lastname);
|
||||
|
||||
function handleDoubleTextChange(
|
||||
firstValue: string,
|
||||
secondValue: string,
|
||||
): void {
|
||||
setFirstnameValue(firstValue);
|
||||
setLastnameValue(secondValue);
|
||||
|
||||
onChange(firstValue, secondValue);
|
||||
}
|
||||
|
||||
function handleCommentClick(event: React.MouseEvent<HTMLDivElement>) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
console.log('comment clicked');
|
||||
}
|
||||
|
||||
return (
|
||||
<EditableDoubleText
|
||||
firstValue={firstnameValue}
|
||||
secondValue={lastnameValue}
|
||||
firstValuePlaceholder="First name"
|
||||
secondValuePlaceholder="Last name"
|
||||
onChange={handleDoubleTextChange}
|
||||
nonEditModeContent={
|
||||
<>
|
||||
<StyledDiv>
|
||||
<PersonChip name={firstname + ' ' + lastname} />
|
||||
</StyledDiv>
|
||||
<CellCommentChip count={12} onClick={handleCommentClick} />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
113
front/src/modules/people/components/PeopleCompanyCell.tsx
Normal file
113
front/src/modules/people/components/PeopleCompanyCell.tsx
Normal file
@ -0,0 +1,113 @@
|
||||
import { useState } from 'react';
|
||||
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/EditableRelation';
|
||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||
import {
|
||||
QueryMode,
|
||||
useInsertCompanyMutation,
|
||||
useUpdatePeopleMutation,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
import { mapToGqlPerson, Person } from '../interfaces/person.interface';
|
||||
|
||||
import { PeopleCompanyCreateCell } from './PeopleCompanyCreateCell';
|
||||
|
||||
export type OwnProps = {
|
||||
people: Person;
|
||||
};
|
||||
|
||||
export function PeopleCompanyCell({ people }: OwnProps) {
|
||||
const [isCreating, setIsCreating] = useState(false);
|
||||
const [insertCompany] = useInsertCompanyMutation();
|
||||
const [updatePeople] = useUpdatePeopleMutation();
|
||||
const [initialCompanyName, setInitialCompanyName] = useState('');
|
||||
|
||||
async function handleCompanyCreate(
|
||||
companyName: string,
|
||||
companyDomainName: string,
|
||||
) {
|
||||
const newCompanyId = v4();
|
||||
|
||||
try {
|
||||
await insertCompany({
|
||||
variables: {
|
||||
id: newCompanyId,
|
||||
name: companyName,
|
||||
domainName: companyDomainName,
|
||||
address: '',
|
||||
createdAt: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
|
||||
await updatePeople({
|
||||
variables: {
|
||||
...mapToGqlPerson(people),
|
||||
companyId: newCompanyId,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
// TODO: handle error better
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
setIsCreating(false);
|
||||
}
|
||||
|
||||
// TODO: should be replaced with search context
|
||||
function handleChangeSearchInput(searchInput: string) {
|
||||
setInitialCompanyName(searchInput);
|
||||
}
|
||||
|
||||
return isCreating ? (
|
||||
<PeopleCompanyCreateCell
|
||||
initialCompanyName={initialCompanyName}
|
||||
onCreate={handleCompanyCreate}
|
||||
/>
|
||||
) : (
|
||||
<EditableRelation<Company, CompanyChipPropsType>
|
||||
relation={people.company}
|
||||
searchPlaceholder="Company"
|
||||
ChipComponent={CompanyChip}
|
||||
chipComponentPropsMapper={(company): CompanyChipPropsType => {
|
||||
return {
|
||||
name: company.name || '',
|
||||
picture: getLogoUrlFromDomainName(company.domainName),
|
||||
};
|
||||
}}
|
||||
onChange={async (relation) => {
|
||||
await updatePeople({
|
||||
variables: {
|
||||
...mapToGqlPerson(people),
|
||||
companyId: relation.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
onChangeSearchInput={handleChangeSearchInput}
|
||||
searchConfig={
|
||||
{
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
name: { contains: `%${searchInput}%`, mode: QueryMode.Insensitive },
|
||||
}),
|
||||
resultMapper: (company) => ({
|
||||
render: (company) => company.name,
|
||||
value: mapToCompany(company),
|
||||
}),
|
||||
} satisfies SearchConfigType<Company>
|
||||
}
|
||||
onCreate={() => {
|
||||
setIsCreating(true);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
import { CellBaseContainer } from '@/ui/components/editable-cell/CellBaseContainer';
|
||||
import { CellEditModeContainer } from '@/ui/components/editable-cell/CellEditModeContainer';
|
||||
import { DoubleTextInput } from '@/ui/components/inputs/DoubleTextInput';
|
||||
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
||||
|
||||
type OwnProps = {
|
||||
initialCompanyName: string;
|
||||
onCreate: (companyName: string, companyDomainName: string) => void;
|
||||
};
|
||||
|
||||
export function PeopleCompanyCreateCell({
|
||||
initialCompanyName,
|
||||
onCreate,
|
||||
}: OwnProps) {
|
||||
const [companyName, setCompanyName] = useState(initialCompanyName);
|
||||
const [companyDomainName, setCompanyDomainName] = useState('');
|
||||
|
||||
const containerRef = useRef(null);
|
||||
|
||||
useListenClickOutsideArrayOfRef([containerRef], () => {
|
||||
onCreate(companyName, companyDomainName);
|
||||
});
|
||||
|
||||
useHotkeys(
|
||||
'enter, escape',
|
||||
() => {
|
||||
onCreate(companyName, companyDomainName);
|
||||
},
|
||||
{
|
||||
enableOnFormTags: true,
|
||||
enableOnContentEditable: true,
|
||||
preventDefault: true,
|
||||
},
|
||||
[containerRef, companyName, companyDomainName, onCreate],
|
||||
);
|
||||
|
||||
function handleDoubleTextChange(leftValue: string, rightValue: string): void {
|
||||
setCompanyDomainName(leftValue);
|
||||
setCompanyName(rightValue);
|
||||
}
|
||||
|
||||
return (
|
||||
<CellBaseContainer ref={containerRef}>
|
||||
<CellEditModeContainer editModeVerticalPosition="over">
|
||||
<DoubleTextInput
|
||||
leftValue={companyDomainName}
|
||||
rightValue={companyName}
|
||||
leftValuePlaceholder="URL"
|
||||
rightValuePlaceholder="Name"
|
||||
onChange={handleDoubleTextChange}
|
||||
/>
|
||||
</CellEditModeContainer>
|
||||
</CellBaseContainer>
|
||||
);
|
||||
}
|
||||
46
front/src/modules/people/components/PersonChip.tsx
Normal file
46
front/src/modules/people/components/PersonChip.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import * as React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import PersonPlaceholder from './person-placeholder.png';
|
||||
|
||||
export type PersonChipPropsType = {
|
||||
name: string;
|
||||
picture?: string;
|
||||
};
|
||||
|
||||
const StyledContainer = styled.span`
|
||||
background-color: ${(props) => props.theme.tertiaryBackground};
|
||||
border-radius: ${(props) => props.theme.spacing(1)};
|
||||
color: ${(props) => props.theme.text80};
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: ${(props) => props.theme.spacing(1)};
|
||||
gap: ${(props) => props.theme.spacing(1)};
|
||||
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
:hover {
|
||||
filter: brightness(95%);
|
||||
}
|
||||
|
||||
img {
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
border-radius: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
`;
|
||||
|
||||
export function PersonChip({ name, picture }: PersonChipPropsType) {
|
||||
return (
|
||||
<StyledContainer data-testid="person-chip">
|
||||
<img
|
||||
data-testid="person-chip-image"
|
||||
src={picture ? picture.toString() : PersonPlaceholder.toString()}
|
||||
alt="person"
|
||||
/>
|
||||
{name}
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
BIN
front/src/modules/people/components/person-placeholder.png
Normal file
BIN
front/src/modules/people/components/person-placeholder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,82 @@
|
||||
import {
|
||||
GraphqlMutationPerson,
|
||||
GraphqlQueryPerson,
|
||||
mapToGqlPerson,
|
||||
mapToPerson,
|
||||
Person,
|
||||
} from '../person.interface';
|
||||
|
||||
describe('Person mappers', () => {
|
||||
it('should map GraphqlPerson to Person', () => {
|
||||
const now = new Date();
|
||||
now.setMilliseconds(0);
|
||||
const graphQLPerson = {
|
||||
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
createdAt: now.toUTCString(),
|
||||
email: 'john.doe@gmail.com',
|
||||
phone: '+1 (555) 123-4567',
|
||||
city: 'Paris',
|
||||
company: {
|
||||
id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87',
|
||||
name: 'John Doe',
|
||||
__typename: 'Company',
|
||||
},
|
||||
__typename: 'people',
|
||||
} satisfies GraphqlQueryPerson;
|
||||
|
||||
const person = mapToPerson(graphQLPerson);
|
||||
expect(person).toStrictEqual({
|
||||
__typename: 'people',
|
||||
id: graphQLPerson.id,
|
||||
firstname: graphQLPerson.firstname,
|
||||
lastname: graphQLPerson.lastname,
|
||||
createdAt: new Date(now.toUTCString()),
|
||||
email: graphQLPerson.email,
|
||||
city: graphQLPerson.city,
|
||||
phone: graphQLPerson.phone,
|
||||
company: {
|
||||
__typename: 'companies',
|
||||
id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87',
|
||||
accountOwner: undefined,
|
||||
address: undefined,
|
||||
createdAt: undefined,
|
||||
domainName: undefined,
|
||||
employees: undefined,
|
||||
name: 'John Doe',
|
||||
pipes: [],
|
||||
},
|
||||
} satisfies Person);
|
||||
});
|
||||
|
||||
it('should map Person to GraphQlPerson', () => {
|
||||
const now = new Date();
|
||||
now.setMilliseconds(0);
|
||||
const person = {
|
||||
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
createdAt: new Date(now.toUTCString()),
|
||||
email: 'john.doe@gmail.com',
|
||||
phone: '+1 (555) 123-4567',
|
||||
city: 'Paris',
|
||||
company: {
|
||||
id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87',
|
||||
},
|
||||
} satisfies Person;
|
||||
|
||||
const graphQLPerson = mapToGqlPerson(person);
|
||||
expect(graphQLPerson).toStrictEqual({
|
||||
id: person.id,
|
||||
firstname: person.firstname,
|
||||
lastname: person.lastname,
|
||||
createdAt: now.toUTCString(),
|
||||
email: person.email,
|
||||
city: person.city,
|
||||
phone: person.phone,
|
||||
companyId: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87',
|
||||
__typename: 'people',
|
||||
} satisfies GraphqlMutationPerson);
|
||||
});
|
||||
});
|
||||
77
front/src/modules/people/interfaces/person.interface.ts
Normal file
77
front/src/modules/people/interfaces/person.interface.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import {
|
||||
Company,
|
||||
GraphqlQueryCompany,
|
||||
mapToCompany,
|
||||
} from '@/companies/interfaces/company.interface';
|
||||
import { Pipeline } from '@/pipelines/interfaces/pipeline.interface';
|
||||
|
||||
export type Person = {
|
||||
__typename: 'people';
|
||||
id: string;
|
||||
firstname?: string;
|
||||
lastname?: string;
|
||||
picture?: string | null;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
city?: string;
|
||||
|
||||
createdAt?: Date;
|
||||
|
||||
company?: Company | null;
|
||||
pipes?: Pipeline[] | null;
|
||||
};
|
||||
|
||||
export type GraphqlQueryPerson = {
|
||||
id: string;
|
||||
firstname?: string;
|
||||
lastname?: string;
|
||||
city?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
|
||||
createdAt?: string;
|
||||
|
||||
company?: GraphqlQueryCompany | null;
|
||||
|
||||
__typename: string;
|
||||
};
|
||||
|
||||
export type GraphqlMutationPerson = {
|
||||
id: string;
|
||||
firstname?: string;
|
||||
lastname?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
city?: string;
|
||||
createdAt?: string;
|
||||
companyId?: string;
|
||||
__typename: 'people';
|
||||
};
|
||||
|
||||
export const mapToPerson = (person: GraphqlQueryPerson): Person => ({
|
||||
__typename: 'people',
|
||||
id: person.id,
|
||||
firstname: person.firstname,
|
||||
lastname: person.lastname,
|
||||
email: person.email,
|
||||
phone: person.phone,
|
||||
city: person.city,
|
||||
|
||||
createdAt: person.createdAt ? new Date(person.createdAt) : undefined,
|
||||
|
||||
company: person.company ? mapToCompany(person.company) : null,
|
||||
});
|
||||
|
||||
export const mapToGqlPerson = (person: Person): GraphqlMutationPerson => ({
|
||||
id: person.id,
|
||||
firstname: person.firstname,
|
||||
lastname: person.lastname,
|
||||
email: person.email,
|
||||
phone: person.phone,
|
||||
city: person.city,
|
||||
|
||||
createdAt: person.createdAt ? person.createdAt.toUTCString() : undefined,
|
||||
|
||||
companyId: person.company?.id,
|
||||
__typename: 'people',
|
||||
});
|
||||
24
front/src/modules/people/services/__tests__/select.test.ts
Normal file
24
front/src/modules/people/services/__tests__/select.test.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { reduceSortsToOrderBy } from '@/filters-and-sorts/helpers';
|
||||
|
||||
import { PeopleSelectedSortType } from '../select';
|
||||
|
||||
describe('reduceSortsToOrderBy', () => {
|
||||
it('should return an array of objects with the id as key and the order as value', () => {
|
||||
const sorts = [
|
||||
{
|
||||
key: 'firstname',
|
||||
label: 'firstname',
|
||||
order: 'asc',
|
||||
_type: 'default_sort',
|
||||
},
|
||||
{
|
||||
key: 'lastname',
|
||||
label: 'lastname',
|
||||
order: 'desc',
|
||||
_type: 'default_sort',
|
||||
},
|
||||
] satisfies PeopleSelectedSortType[];
|
||||
const result = reduceSortsToOrderBy(sorts);
|
||||
expect(result).toEqual([{ firstname: 'asc' }, { lastname: 'desc' }]);
|
||||
});
|
||||
});
|
||||
50
front/src/modules/people/services/__tests__/update.test.ts
Normal file
50
front/src/modules/people/services/__tests__/update.test.ts
Normal file
@ -0,0 +1,50 @@
|
||||
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: 'companies',
|
||||
},
|
||||
phone: '+1 (555) 123-4567',
|
||||
pipes: [
|
||||
{
|
||||
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d',
|
||||
name: 'Customer',
|
||||
icon: '!',
|
||||
},
|
||||
],
|
||||
createdAt: new Date(),
|
||||
city: 'San Francisco',
|
||||
__typename: 'people',
|
||||
});
|
||||
expect(result.data).toBeDefined();
|
||||
result.data && expect(result.data.email).toBe('john@example.com');
|
||||
});
|
||||
2
front/src/modules/people/services/index.ts
Normal file
2
front/src/modules/people/services/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './select';
|
||||
export * from './update';
|
||||
50
front/src/modules/people/services/select.ts
Normal file
50
front/src/modules/people/services/select.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { gql, QueryResult, useQuery } from '@apollo/client';
|
||||
|
||||
import { SelectedSortType } from '@/filters-and-sorts/interfaces/sorts/interface';
|
||||
import {
|
||||
PersonOrderByWithRelationInput as People_Order_By,
|
||||
PersonWhereInput as People_Bool_Exp,
|
||||
SortOrder,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
import { GraphqlQueryPerson } from '../interfaces/person.interface';
|
||||
|
||||
export type PeopleSelectedSortType = SelectedSortType<People_Order_By>;
|
||||
|
||||
export const GET_PEOPLE = gql`
|
||||
query GetPeople(
|
||||
$orderBy: [PersonOrderByWithRelationInput!]
|
||||
$where: PersonWhereInput
|
||||
$limit: Int
|
||||
) {
|
||||
people: findManyPerson(orderBy: $orderBy, where: $where, take: $limit) {
|
||||
id
|
||||
phone
|
||||
email
|
||||
city
|
||||
firstname
|
||||
lastname
|
||||
createdAt
|
||||
company {
|
||||
id
|
||||
name
|
||||
domainName
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function usePeopleQuery(
|
||||
orderBy: People_Order_By[],
|
||||
where: People_Bool_Exp,
|
||||
): QueryResult<{ people: GraphqlQueryPerson[] }> {
|
||||
return useQuery<{ people: GraphqlQueryPerson[] }>(GET_PEOPLE, {
|
||||
variables: { orderBy, where },
|
||||
});
|
||||
}
|
||||
|
||||
export const defaultOrderBy: People_Order_By[] = [
|
||||
{
|
||||
createdAt: SortOrder.Desc,
|
||||
},
|
||||
];
|
||||
122
front/src/modules/people/services/update.ts
Normal file
122
front/src/modules/people/services/update.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import { FetchResult, gql } from '@apollo/client';
|
||||
|
||||
import { apiClient } from '../../../apollo';
|
||||
import { mapToGqlPerson, Person } from '../interfaces/person.interface';
|
||||
|
||||
export const UPDATE_PERSON = gql`
|
||||
mutation UpdatePeople(
|
||||
$id: String
|
||||
$firstname: String
|
||||
$lastname: String
|
||||
$phone: String
|
||||
$city: String
|
||||
$companyId: String
|
||||
$email: String
|
||||
$createdAt: DateTime
|
||||
) {
|
||||
updateOnePerson(
|
||||
where: { id: $id }
|
||||
data: {
|
||||
city: { set: $city }
|
||||
company: { connect: { id: $companyId } }
|
||||
email: { set: $email }
|
||||
firstname: { set: $firstname }
|
||||
id: { set: $id }
|
||||
lastname: { set: $lastname }
|
||||
phone: { set: $phone }
|
||||
createdAt: { set: $createdAt }
|
||||
}
|
||||
) {
|
||||
city
|
||||
company {
|
||||
domainName
|
||||
name
|
||||
id
|
||||
}
|
||||
email
|
||||
firstname
|
||||
id
|
||||
lastname
|
||||
phone
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const INSERT_PERSON = gql`
|
||||
mutation InsertPerson(
|
||||
$id: String!
|
||||
$firstname: String!
|
||||
$lastname: String!
|
||||
$phone: String!
|
||||
$city: String!
|
||||
$email: String!
|
||||
$createdAt: DateTime
|
||||
) {
|
||||
createOnePerson(
|
||||
data: {
|
||||
id: $id
|
||||
firstname: $firstname
|
||||
lastname: $lastname
|
||||
phone: $phone
|
||||
city: $city
|
||||
email: $email
|
||||
createdAt: $createdAt
|
||||
}
|
||||
) {
|
||||
city
|
||||
company {
|
||||
domainName
|
||||
name
|
||||
id
|
||||
}
|
||||
email
|
||||
firstname
|
||||
id
|
||||
lastname
|
||||
phone
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const DELETE_PEOPLE = gql`
|
||||
mutation DeletePeople($ids: [String!]) {
|
||||
deleteManyPerson(where: { id: { in: $ids } }) {
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export async function updatePerson(
|
||||
person: Person,
|
||||
): Promise<FetchResult<Person>> {
|
||||
const result = await apiClient.mutate({
|
||||
mutation: UPDATE_PERSON,
|
||||
variables: mapToGqlPerson(person),
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function insertPerson(
|
||||
person: Person,
|
||||
): Promise<FetchResult<Person>> {
|
||||
const result = await apiClient.mutate({
|
||||
mutation: INSERT_PERSON,
|
||||
variables: mapToGqlPerson(person),
|
||||
refetchQueries: ['GetPeople'],
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function deletePeople(
|
||||
peopleIds: string[],
|
||||
): Promise<FetchResult<Person>> {
|
||||
const result = await apiClient.mutate({
|
||||
mutation: DELETE_PEOPLE,
|
||||
variables: { ids: peopleIds },
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user