Implement eager load relations on graphqlQueries (#4391)
* Implement eager load relations on graphqlQueries * Fix tests * Fixes * Fixes
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
import { useCachedRootQuery } from '@/apollo/hooks/useCachedRootQuery';
|
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { QueryMethodName } from '@/object-metadata/types/QueryMethodName';
|
import { QueryMethodName } from '@/object-metadata/types/QueryMethodName';
|
||||||
|
import { useCachedRootQuery } from '@/object-record/cache/hooks/useCachedRootQuery';
|
||||||
|
|
||||||
export const useDefaultHomePagePath = () => {
|
export const useDefaultHomePagePath = () => {
|
||||||
const { objectMetadataItem: companyObjectMetadataItem } =
|
const { objectMetadataItem: companyObjectMetadataItem } =
|
||||||
|
|||||||
@ -69,7 +69,7 @@ export const useActivities = ({
|
|||||||
useFindManyRecords<Activity>({
|
useFindManyRecords<Activity>({
|
||||||
skip: skipActivities,
|
skip: skipActivities,
|
||||||
objectNameSingular: CoreObjectNameSingular.Activity,
|
objectNameSingular: CoreObjectNameSingular.Activity,
|
||||||
depth: 3,
|
depth: 1,
|
||||||
filter,
|
filter,
|
||||||
orderBy: activitiesOrderByVariables,
|
orderBy: activitiesOrderByVariables,
|
||||||
onCompleted: useRecoilCallback(
|
onCompleted: useRecoilCallback(
|
||||||
|
|||||||
@ -32,7 +32,7 @@ export const useCreateActivityInCache = () => {
|
|||||||
const { record: currentWorkspaceMemberRecord } = useFindOneRecord({
|
const { record: currentWorkspaceMemberRecord } = useFindOneRecord({
|
||||||
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
|
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
|
||||||
objectRecordId: currentWorkspaceMember?.id,
|
objectRecordId: currentWorkspaceMember?.id,
|
||||||
depth: 3,
|
depth: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { injectIntoActivityTargetInlineCellCache } =
|
const { injectIntoActivityTargetInlineCellCache } =
|
||||||
|
|||||||
@ -17,6 +17,7 @@ export const CurrentUserDueTaskCountEffect = () => {
|
|||||||
|
|
||||||
const { records: tasks } = useFindManyRecords({
|
const { records: tasks } = useFindManyRecords({
|
||||||
objectNameSingular: CoreObjectNameSingular.Activity,
|
objectNameSingular: CoreObjectNameSingular.Activity,
|
||||||
|
depth: 0,
|
||||||
filter: {
|
filter: {
|
||||||
type: { eq: 'Task' },
|
type: { eq: 'Task' },
|
||||||
completedAt: { is: 'NULL' },
|
completedAt: { is: 'NULL' },
|
||||||
|
|||||||
@ -7,10 +7,6 @@ import { RecoilRoot } from 'recoil';
|
|||||||
|
|
||||||
import { useEventTracker } from '../useEventTracker';
|
import { useEventTracker } from '../useEventTracker';
|
||||||
|
|
||||||
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
|
|
||||||
useMapFieldMetadataToGraphQLQuery: () => () => '\n',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const mocks: MockedResponse[] = [
|
const mocks: MockedResponse[] = [
|
||||||
{
|
{
|
||||||
request: {
|
request: {
|
||||||
|
|||||||
@ -84,8 +84,77 @@ export const mocks = [
|
|||||||
query: gql`
|
query: gql`
|
||||||
mutation CreateOneFavorite($input: FavoriteCreateInput!) {
|
mutation CreateOneFavorite($input: FavoriteCreateInput!) {
|
||||||
createFavorite(data: $input) {
|
createFavorite(data: $input) {
|
||||||
id
|
__typename
|
||||||
|
id
|
||||||
|
companyId
|
||||||
|
createdAt
|
||||||
|
personId
|
||||||
|
person {
|
||||||
|
__typename
|
||||||
|
xLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
}
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
city
|
||||||
|
email
|
||||||
|
jobTitle
|
||||||
|
name {
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
phone
|
||||||
|
linkedinLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
avatarUrl
|
||||||
|
companyId
|
||||||
|
}
|
||||||
|
position
|
||||||
|
workspaceMemberId
|
||||||
|
workspaceMember {
|
||||||
|
__typename
|
||||||
|
colorScheme
|
||||||
|
name {
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
locale
|
||||||
|
userId
|
||||||
|
avatarUrl
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
id
|
||||||
|
}
|
||||||
|
company {
|
||||||
|
__typename
|
||||||
|
xLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
linkedinLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
annualRecurringRevenue {
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
|
id
|
||||||
|
idealCustomerProfile
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
@ -132,8 +201,77 @@ export const mocks = [
|
|||||||
$input: FavoriteUpdateInput!
|
$input: FavoriteUpdateInput!
|
||||||
) {
|
) {
|
||||||
updateFavorite(id: $idToUpdate, data: $input) {
|
updateFavorite(id: $idToUpdate, data: $input) {
|
||||||
id
|
__typename
|
||||||
|
id
|
||||||
|
companyId
|
||||||
|
createdAt
|
||||||
|
personId
|
||||||
|
person {
|
||||||
|
__typename
|
||||||
|
xLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
}
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
city
|
||||||
|
email
|
||||||
|
jobTitle
|
||||||
|
name {
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
phone
|
||||||
|
linkedinLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
avatarUrl
|
||||||
|
companyId
|
||||||
|
}
|
||||||
|
position
|
||||||
|
workspaceMemberId
|
||||||
|
workspaceMember {
|
||||||
|
__typename
|
||||||
|
colorScheme
|
||||||
|
name {
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
locale
|
||||||
|
userId
|
||||||
|
avatarUrl
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
id
|
||||||
|
}
|
||||||
|
company {
|
||||||
|
__typename
|
||||||
|
xLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
linkedinLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
annualRecurringRevenue {
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
|
id
|
||||||
|
idealCustomerProfile
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
|
|||||||
@ -25,10 +25,6 @@ jest.mock('uuid', () => ({
|
|||||||
v4: jest.fn(() => mockId),
|
v4: jest.fn(() => mockId),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
|
|
||||||
useMapFieldMetadataToGraphQLQuery: () => () => '\n',
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
|
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
|
||||||
useFindManyRecords: () => ({ records: initialFavorites }),
|
useFindManyRecords: () => ({ records: initialFavorites }),
|
||||||
}));
|
}));
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { useCachedRootQuery } from '@/apollo/hooks/useCachedRootQuery';
|
|
||||||
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
|
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { QueryMethodName } from '@/object-metadata/types/QueryMethodName';
|
import { QueryMethodName } from '@/object-metadata/types/QueryMethodName';
|
||||||
|
import { useCachedRootQuery } from '@/object-record/cache/hooks/useCachedRootQuery';
|
||||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||||
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
|
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
|
||||||
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
||||||
|
|||||||
@ -1,180 +0,0 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
|
||||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
|
||||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
|
||||||
import { RelationMetadataType } from '~/generated/graphql';
|
|
||||||
|
|
||||||
const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
|
||||||
|
|
||||||
const formatGQLString = (inputString: string) =>
|
|
||||||
inputString.replace(/^\s*[\r\n]/gm, '');
|
|
||||||
|
|
||||||
const getOneToManyRelation = () => {
|
|
||||||
const objectMetadataItem = mockObjectMetadataItems.find(
|
|
||||||
(item) => item.nameSingular === 'opportunity',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
return {
|
|
||||||
field: objectMetadataItem.fields.find((field) => field.name === 'company')!,
|
|
||||||
res: `company
|
|
||||||
{
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
xLink
|
|
||||||
{
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
linkedinLink
|
|
||||||
{
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
domainName
|
|
||||||
annualRecurringRevenue
|
|
||||||
{
|
|
||||||
amountMicros
|
|
||||||
currencyCode
|
|
||||||
}
|
|
||||||
createdAt
|
|
||||||
address
|
|
||||||
updatedAt
|
|
||||||
name
|
|
||||||
accountOwnerId
|
|
||||||
employees
|
|
||||||
id
|
|
||||||
idealCustomerProfile
|
|
||||||
}`,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const getOneToOneRelationField = () => {
|
|
||||||
const objectMetadataItem = mockObjectMetadataItems.find(
|
|
||||||
(item) => item.nameSingular === 'opportunity',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
const oneToManyfield = objectMetadataItem.fields.find(
|
|
||||||
(field) => field.name === 'company',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
const field: FieldMetadataItem = {
|
|
||||||
...oneToManyfield,
|
|
||||||
toRelationMetadata: {
|
|
||||||
...oneToManyfield.toRelationMetadata!,
|
|
||||||
relationType: RelationMetadataType.OneToOne,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return field;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getOneToManyFromRelationField = () => {
|
|
||||||
const objectMetadataItem = mockObjectMetadataItems.find(
|
|
||||||
(item) => item.nameSingular === 'person',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
const field = objectMetadataItem.fields.find(
|
|
||||||
(field) => field.name === 'opportunities',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
return {
|
|
||||||
field,
|
|
||||||
res: `opportunities
|
|
||||||
{
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
personId
|
|
||||||
pointOfContactId
|
|
||||||
updatedAt
|
|
||||||
companyId
|
|
||||||
pipelineStepId
|
|
||||||
probability
|
|
||||||
closeDate
|
|
||||||
amount
|
|
||||||
{
|
|
||||||
amountMicros
|
|
||||||
currencyCode
|
|
||||||
}
|
|
||||||
id
|
|
||||||
createdAt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const getFullNameRelation = () => {
|
|
||||||
const objectMetadataItem = mockObjectMetadataItems.find(
|
|
||||||
(item) => item.nameSingular === 'person',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
const field = objectMetadataItem.fields.find(
|
|
||||||
(field) => field.name === 'name',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
return {
|
|
||||||
field,
|
|
||||||
res: `\n name\n {\n firstName\n lastName\n }\n `,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('useMapFieldMetadataToGraphQLQuery', () => {
|
|
||||||
it('should work as expected', async () => {
|
|
||||||
const { result } = renderHook(
|
|
||||||
() => {
|
|
||||||
const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
|
|
||||||
setMetadataItems(mockObjectMetadataItems);
|
|
||||||
|
|
||||||
return {
|
|
||||||
mapFieldMetadataToGraphQLQuery: useMapFieldMetadataToGraphQLQuery(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
wrapper: RecoilRoot,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const oneToManyRelation = getOneToManyRelation();
|
|
||||||
|
|
||||||
const { mapFieldMetadataToGraphQLQuery } = result.current;
|
|
||||||
|
|
||||||
const oneToManyRelationFieldRes = mapFieldMetadataToGraphQLQuery({
|
|
||||||
field: oneToManyRelation.field,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(formatGQLString(oneToManyRelationFieldRes)).toEqual(
|
|
||||||
oneToManyRelation.res,
|
|
||||||
);
|
|
||||||
|
|
||||||
const oneToOneRelation = getOneToOneRelationField();
|
|
||||||
|
|
||||||
const oneToOneRelationFieldRes = mapFieldMetadataToGraphQLQuery({
|
|
||||||
field: oneToOneRelation,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(formatGQLString(oneToOneRelationFieldRes)).toEqual(
|
|
||||||
oneToManyRelation.res,
|
|
||||||
);
|
|
||||||
|
|
||||||
const oneToManyFromRelation = getOneToManyFromRelationField();
|
|
||||||
const oneToManyFromRelationFieldRes = mapFieldMetadataToGraphQLQuery({
|
|
||||||
field: oneToManyFromRelation.field,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(formatGQLString(oneToManyFromRelationFieldRes)).toEqual(
|
|
||||||
oneToManyFromRelation.res,
|
|
||||||
);
|
|
||||||
|
|
||||||
const fullNameRelation = getFullNameRelation();
|
|
||||||
const fullNameFieldRes = mapFieldMetadataToGraphQLQuery({
|
|
||||||
field: fullNameRelation.field,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(fullNameFieldRes).toEqual(fullNameRelation.res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,151 +0,0 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
|
||||||
import { FieldType } from '@/object-record/record-field/types/FieldType';
|
|
||||||
|
|
||||||
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
|
||||||
|
|
||||||
export const useMapFieldMetadataToGraphQLQuery = () => {
|
|
||||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
|
||||||
|
|
||||||
const mapFieldMetadataToGraphQLQuery = ({
|
|
||||||
field,
|
|
||||||
depth = 2,
|
|
||||||
}: {
|
|
||||||
field: FieldMetadataItem;
|
|
||||||
depth?: number;
|
|
||||||
}): any => {
|
|
||||||
// TODO: parse
|
|
||||||
const fieldType = field.type as FieldType;
|
|
||||||
|
|
||||||
const fieldIsSimpleValue = (
|
|
||||||
[
|
|
||||||
'UUID',
|
|
||||||
'TEXT',
|
|
||||||
'PHONE',
|
|
||||||
'DATE_TIME',
|
|
||||||
'EMAIL',
|
|
||||||
'NUMBER',
|
|
||||||
'BOOLEAN',
|
|
||||||
'RATING',
|
|
||||||
'SELECT',
|
|
||||||
'POSITION',
|
|
||||||
] as FieldType[]
|
|
||||||
).includes(fieldType);
|
|
||||||
|
|
||||||
if (fieldIsSimpleValue) {
|
|
||||||
return field.name;
|
|
||||||
} else if (
|
|
||||||
fieldType === 'RELATION' &&
|
|
||||||
field.toRelationMetadata?.relationType === 'ONE_TO_MANY'
|
|
||||||
) {
|
|
||||||
const relationMetadataItem = objectMetadataItems.find(
|
|
||||||
(objectMetadataItem) =>
|
|
||||||
objectMetadataItem.id ===
|
|
||||||
(field.toRelationMetadata as any)?.fromObjectMetadata?.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (depth > 1) {
|
|
||||||
return `${field.name}
|
|
||||||
{
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
${(relationMetadataItem?.fields ?? [])
|
|
||||||
.map((field) =>
|
|
||||||
mapFieldMetadataToGraphQLQuery({
|
|
||||||
field,
|
|
||||||
depth: depth - 1,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}`;
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
fieldType === 'RELATION' &&
|
|
||||||
field.toRelationMetadata?.relationType === 'ONE_TO_ONE'
|
|
||||||
) {
|
|
||||||
const relationMetadataItem = objectMetadataItems.find(
|
|
||||||
(objectMetadataItem) =>
|
|
||||||
objectMetadataItem.id ===
|
|
||||||
(field.toRelationMetadata as any)?.fromObjectMetadata?.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (depth > 1) {
|
|
||||||
return `${field.name}
|
|
||||||
{
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
${(relationMetadataItem?.fields ?? [])
|
|
||||||
.map((field) =>
|
|
||||||
mapFieldMetadataToGraphQLQuery({
|
|
||||||
field,
|
|
||||||
depth: depth - 1,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}`;
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
fieldType === 'RELATION' &&
|
|
||||||
field.fromRelationMetadata?.relationType === 'ONE_TO_MANY'
|
|
||||||
) {
|
|
||||||
const relationMetadataItem = objectMetadataItems.find(
|
|
||||||
(objectMetadataItem) =>
|
|
||||||
objectMetadataItem.id ===
|
|
||||||
(field.fromRelationMetadata as any)?.toObjectMetadata?.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (depth > 1) {
|
|
||||||
return `${field.name}
|
|
||||||
{
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
${(relationMetadataItem?.fields ?? [])
|
|
||||||
.map((field) =>
|
|
||||||
mapFieldMetadataToGraphQLQuery({
|
|
||||||
field,
|
|
||||||
depth: depth - 1,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
} else if (fieldType === 'LINK') {
|
|
||||||
return `
|
|
||||||
${field.name}
|
|
||||||
{
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
} else if (fieldType === 'CURRENCY') {
|
|
||||||
return `
|
|
||||||
${field.name}
|
|
||||||
{
|
|
||||||
amountMicros
|
|
||||||
currencyCode
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
} else if (fieldType === 'FULL_NAME') {
|
|
||||||
return `
|
|
||||||
${field.name}
|
|
||||||
{
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return mapFieldMetadataToGraphQLQuery;
|
|
||||||
};
|
|
||||||
@ -40,6 +40,7 @@ export const EMPTY_MUTATION = gql`
|
|||||||
export const useObjectMetadataItem = (
|
export const useObjectMetadataItem = (
|
||||||
{ objectNameSingular }: ObjectMetadataItemIdentifier,
|
{ objectNameSingular }: ObjectMetadataItemIdentifier,
|
||||||
depth?: number,
|
depth?: number,
|
||||||
|
eagerLoadedRelations?: Record<string, any>,
|
||||||
) => {
|
) => {
|
||||||
const currentWorkspace = useRecoilValue(currentWorkspaceState());
|
const currentWorkspace = useRecoilValue(currentWorkspaceState());
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ export const useObjectMetadataItem = (
|
|||||||
const findManyRecordsQuery = generateFindManyRecordsQuery({
|
const findManyRecordsQuery = generateFindManyRecordsQuery({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
depth,
|
depth,
|
||||||
|
eagerLoadedRelations,
|
||||||
});
|
});
|
||||||
|
|
||||||
const generateFindDuplicateRecordsQuery =
|
const generateFindDuplicateRecordsQuery =
|
||||||
|
|||||||
@ -0,0 +1,329 @@
|
|||||||
|
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||||
|
import { mapFieldMetadataToGraphQLQuery } from '@/object-metadata/utils/mapFieldMetadataToGraphQLQuery';
|
||||||
|
|
||||||
|
const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
||||||
|
|
||||||
|
const formatGQLString = (inputString: string) =>
|
||||||
|
inputString.replace(/^\s*[\r\n]/gm, '');
|
||||||
|
|
||||||
|
const personObjectMetadataItem = mockObjectMetadataItems.find(
|
||||||
|
(item) => item.nameSingular === 'person',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!personObjectMetadataItem) {
|
||||||
|
throw new Error('ObjectMetadataItem not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('mapFieldMetadataToGraphQLQuery', () => {
|
||||||
|
it('should return fieldName if simpleValue', async () => {
|
||||||
|
const res = mapFieldMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
field: personObjectMetadataItem.fields.find(
|
||||||
|
(field) => field.name === 'id',
|
||||||
|
)!,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual('id');
|
||||||
|
});
|
||||||
|
it('should return fieldName if composite', async () => {
|
||||||
|
const res = mapFieldMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
field: personObjectMetadataItem.fields.find(
|
||||||
|
(field) => field.name === 'name',
|
||||||
|
)!,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual(`name
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
it('should not return relation if depth is < 1', async () => {
|
||||||
|
const res = mapFieldMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
relationFieldDepth: 0,
|
||||||
|
field: personObjectMetadataItem.fields.find(
|
||||||
|
(field) => field.name === 'company',
|
||||||
|
)!,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return relation if it matches depth', async () => {
|
||||||
|
const res = mapFieldMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
relationFieldDepth: 1,
|
||||||
|
field: personObjectMetadataItem.fields.find(
|
||||||
|
(field) => field.name === 'company',
|
||||||
|
)!,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual(`company
|
||||||
|
{
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
annualRecurringRevenue
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
|
id
|
||||||
|
idealCustomerProfile
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
it('should return relation with all sub relations if it matches depth', async () => {
|
||||||
|
const res = mapFieldMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
relationFieldDepth: 2,
|
||||||
|
field: personObjectMetadataItem.fields.find(
|
||||||
|
(field) => field.name === 'company',
|
||||||
|
)!,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual(`company
|
||||||
|
{
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
accountOwner
|
||||||
|
{
|
||||||
|
__typename
|
||||||
|
colorScheme
|
||||||
|
name
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
locale
|
||||||
|
userId
|
||||||
|
avatarUrl
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
id
|
||||||
|
}
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
attachments
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
updatedAt
|
||||||
|
createdAt
|
||||||
|
name
|
||||||
|
personId
|
||||||
|
activityId
|
||||||
|
companyId
|
||||||
|
id
|
||||||
|
authorId
|
||||||
|
type
|
||||||
|
fullPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
opportunities
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
personId
|
||||||
|
pointOfContactId
|
||||||
|
updatedAt
|
||||||
|
companyId
|
||||||
|
pipelineStepId
|
||||||
|
probability
|
||||||
|
closeDate
|
||||||
|
amount
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
annualRecurringRevenue
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
activityTargets
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
updatedAt
|
||||||
|
createdAt
|
||||||
|
personId
|
||||||
|
activityId
|
||||||
|
companyId
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
favorites
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
id
|
||||||
|
companyId
|
||||||
|
createdAt
|
||||||
|
personId
|
||||||
|
position
|
||||||
|
workspaceMemberId
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
people
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
city
|
||||||
|
email
|
||||||
|
jobTitle
|
||||||
|
name
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
phone
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
avatarUrl
|
||||||
|
companyId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
|
id
|
||||||
|
idealCustomerProfile
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return eagerLoaded relations', async () => {
|
||||||
|
const res = mapFieldMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
relationFieldDepth: 2,
|
||||||
|
relationFieldEagerLoad: { accountOwner: true, people: true },
|
||||||
|
field: personObjectMetadataItem.fields.find(
|
||||||
|
(field) => field.name === 'company',
|
||||||
|
)!,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual(`company
|
||||||
|
{
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
accountOwner
|
||||||
|
{
|
||||||
|
__typename
|
||||||
|
colorScheme
|
||||||
|
name
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
locale
|
||||||
|
userId
|
||||||
|
avatarUrl
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
id
|
||||||
|
}
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
annualRecurringRevenue
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
people
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
city
|
||||||
|
email
|
||||||
|
jobTitle
|
||||||
|
name
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
phone
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
avatarUrl
|
||||||
|
companyId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
|
id
|
||||||
|
idealCustomerProfile
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,281 @@
|
|||||||
|
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
|
|
||||||
|
const mockObjectMetadataItems = getObjectMetadataItemsMock();
|
||||||
|
|
||||||
|
const formatGQLString = (inputString: string) =>
|
||||||
|
inputString.replace(/^\s*[\r\n]/gm, '');
|
||||||
|
|
||||||
|
const personObjectMetadataItem = mockObjectMetadataItems.find(
|
||||||
|
(item) => item.nameSingular === 'person',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!personObjectMetadataItem) {
|
||||||
|
throw new Error('ObjectMetadataItem not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('mapObjectMetadataToGraphQLQuery', () => {
|
||||||
|
it('should return typename if depth < 0', async () => {
|
||||||
|
const res = mapObjectMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
objectMetadataItem: personObjectMetadataItem,
|
||||||
|
depth: -1,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual(`{
|
||||||
|
__typename
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return depth 0 if depth = 0', async () => {
|
||||||
|
const res = mapObjectMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
objectMetadataItem: personObjectMetadataItem,
|
||||||
|
depth: 0,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual(`{
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
city
|
||||||
|
email
|
||||||
|
jobTitle
|
||||||
|
name
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
phone
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
avatarUrl
|
||||||
|
companyId
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return depth 1 if depth = 1', async () => {
|
||||||
|
const res = mapObjectMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
objectMetadataItem: personObjectMetadataItem,
|
||||||
|
depth: 1,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual(`{
|
||||||
|
__typename
|
||||||
|
opportunities
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
personId
|
||||||
|
pointOfContactId
|
||||||
|
updatedAt
|
||||||
|
companyId
|
||||||
|
pipelineStepId
|
||||||
|
probability
|
||||||
|
closeDate
|
||||||
|
amount
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
id
|
||||||
|
pointOfContactForOpportunities
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
personId
|
||||||
|
pointOfContactId
|
||||||
|
updatedAt
|
||||||
|
companyId
|
||||||
|
pipelineStepId
|
||||||
|
probability
|
||||||
|
closeDate
|
||||||
|
amount
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
company
|
||||||
|
{
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
annualRecurringRevenue
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
|
id
|
||||||
|
idealCustomerProfile
|
||||||
|
}
|
||||||
|
city
|
||||||
|
email
|
||||||
|
activityTargets
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
updatedAt
|
||||||
|
createdAt
|
||||||
|
personId
|
||||||
|
activityId
|
||||||
|
companyId
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jobTitle
|
||||||
|
favorites
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
id
|
||||||
|
companyId
|
||||||
|
createdAt
|
||||||
|
personId
|
||||||
|
position
|
||||||
|
workspaceMemberId
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attachments
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
updatedAt
|
||||||
|
createdAt
|
||||||
|
name
|
||||||
|
personId
|
||||||
|
activityId
|
||||||
|
companyId
|
||||||
|
id
|
||||||
|
authorId
|
||||||
|
type
|
||||||
|
fullPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
phone
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
avatarUrl
|
||||||
|
companyId
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should eager load only specified relations', async () => {
|
||||||
|
const res = mapObjectMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems: mockObjectMetadataItems,
|
||||||
|
objectMetadataItem: personObjectMetadataItem,
|
||||||
|
eagerLoadedRelations: { company: true },
|
||||||
|
depth: 1,
|
||||||
|
});
|
||||||
|
expect(formatGQLString(res)).toEqual(`{
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
company
|
||||||
|
{
|
||||||
|
__typename
|
||||||
|
xLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
annualRecurringRevenue
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
|
id
|
||||||
|
idealCustomerProfile
|
||||||
|
}
|
||||||
|
city
|
||||||
|
email
|
||||||
|
jobTitle
|
||||||
|
name
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
phone
|
||||||
|
linkedinLink
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
avatarUrl
|
||||||
|
companyId
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,117 @@
|
|||||||
|
import { shouldFieldBeQueried } from '@/object-metadata/utils/shouldFieldBeQueried';
|
||||||
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
|
describe('shouldFieldBeQueried', () => {
|
||||||
|
describe('if field is not relation', () => {
|
||||||
|
it('should be queried if depth is undefined', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||||
|
});
|
||||||
|
expect(res).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be queried depth = 0', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 0,
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||||
|
});
|
||||||
|
expect(res).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be queried depth > 0', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 1,
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||||
|
});
|
||||||
|
expect(res).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT be queried depth < 0', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: -1,
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||||
|
});
|
||||||
|
expect(res).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not depends on eagerLoadedRelation', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 0,
|
||||||
|
eagerLoadedRelations: {
|
||||||
|
fieldName: true,
|
||||||
|
},
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Boolean },
|
||||||
|
});
|
||||||
|
expect(res).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if field is relation', () => {
|
||||||
|
it('should be queried if eagerLoadedRelation and depth are undefined', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||||
|
});
|
||||||
|
expect(res).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be queried if eagerLoadedRelation is undefined and depth = 1', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 1,
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||||
|
});
|
||||||
|
expect(res).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be queried if eagerLoadedRelation is undefined and depth > 1', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 2,
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||||
|
});
|
||||||
|
expect(res).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT be queried if eagerLoadedRelation is undefined and depth < 1', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 0,
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||||
|
});
|
||||||
|
expect(res).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be queried if eagerLoadedRelation is matching and depth > 1', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 1,
|
||||||
|
eagerLoadedRelations: { fieldName: true },
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||||
|
});
|
||||||
|
expect(res).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT be queried if eagerLoadedRelation is matching and depth < 1', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 0,
|
||||||
|
eagerLoadedRelations: { fieldName: true },
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||||
|
});
|
||||||
|
expect(res).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT be queried if eagerLoadedRelation is not matching (falsy) and depth < 1', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 1,
|
||||||
|
eagerLoadedRelations: { fieldName: false },
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||||
|
});
|
||||||
|
expect(res).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT be queried if eagerLoadedRelation is not matching and depth < 1', () => {
|
||||||
|
const res = shouldFieldBeQueried({
|
||||||
|
depth: 0,
|
||||||
|
eagerLoadedRelations: { anotherFieldName: true },
|
||||||
|
field: { name: 'fieldName', type: FieldMetadataType.Relation },
|
||||||
|
});
|
||||||
|
expect(res).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
import { isUndefined } from '@sniptt/guards';
|
||||||
|
|
||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
|
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||||
|
|
||||||
|
export const mapFieldMetadataToGraphQLQuery = ({
|
||||||
|
objectMetadataItems,
|
||||||
|
field,
|
||||||
|
relationFieldDepth = 0,
|
||||||
|
relationFieldEagerLoad,
|
||||||
|
}: {
|
||||||
|
objectMetadataItems: ObjectMetadataItem[];
|
||||||
|
field: Pick<
|
||||||
|
FieldMetadataItem,
|
||||||
|
'name' | 'type' | 'toRelationMetadata' | 'fromRelationMetadata'
|
||||||
|
>;
|
||||||
|
relationFieldDepth?: number;
|
||||||
|
relationFieldEagerLoad?: Record<string, any>;
|
||||||
|
}): any => {
|
||||||
|
const fieldType = field.type;
|
||||||
|
|
||||||
|
const fieldIsSimpleValue = (
|
||||||
|
[
|
||||||
|
'UUID',
|
||||||
|
'TEXT',
|
||||||
|
'PHONE',
|
||||||
|
'DATE_TIME',
|
||||||
|
'EMAIL',
|
||||||
|
'NUMBER',
|
||||||
|
'BOOLEAN',
|
||||||
|
'RATING',
|
||||||
|
'SELECT',
|
||||||
|
'POSITION',
|
||||||
|
] as FieldMetadataType[]
|
||||||
|
).includes(fieldType);
|
||||||
|
|
||||||
|
if (fieldIsSimpleValue) {
|
||||||
|
return field.name;
|
||||||
|
} else if (
|
||||||
|
fieldType === 'RELATION' &&
|
||||||
|
field.toRelationMetadata?.relationType === 'ONE_TO_MANY' &&
|
||||||
|
relationFieldDepth > 0
|
||||||
|
) {
|
||||||
|
const relationMetadataItem = objectMetadataItems.find(
|
||||||
|
(objectMetadataItem) =>
|
||||||
|
objectMetadataItem.id ===
|
||||||
|
(field.toRelationMetadata as any)?.fromObjectMetadata?.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isUndefined(relationMetadataItem)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${field.name}
|
||||||
|
${mapObjectMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems,
|
||||||
|
objectMetadataItem: relationMetadataItem,
|
||||||
|
eagerLoadedRelations: relationFieldEagerLoad,
|
||||||
|
depth: relationFieldDepth - 1,
|
||||||
|
})}`;
|
||||||
|
} else if (
|
||||||
|
fieldType === 'RELATION' &&
|
||||||
|
field.fromRelationMetadata?.relationType === 'ONE_TO_MANY' &&
|
||||||
|
relationFieldDepth > 0
|
||||||
|
) {
|
||||||
|
const relationMetadataItem = objectMetadataItems.find(
|
||||||
|
(objectMetadataItem) =>
|
||||||
|
objectMetadataItem.id ===
|
||||||
|
(field.fromRelationMetadata as any)?.toObjectMetadata?.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isUndefined(relationMetadataItem)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${field.name}
|
||||||
|
{
|
||||||
|
edges {
|
||||||
|
node ${mapObjectMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems,
|
||||||
|
objectMetadataItem: relationMetadataItem,
|
||||||
|
eagerLoadedRelations: relationFieldEagerLoad,
|
||||||
|
depth: relationFieldDepth - 1,
|
||||||
|
})}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
} else if (fieldType === 'LINK') {
|
||||||
|
return `${field.name}
|
||||||
|
{
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}`;
|
||||||
|
} else if (fieldType === 'CURRENCY') {
|
||||||
|
return `${field.name}
|
||||||
|
{
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
} else if (fieldType === 'FULL_NAME') {
|
||||||
|
return `${field.name}
|
||||||
|
{
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
};
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
import { isUndefined } from '@sniptt/guards';
|
||||||
|
|
||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapFieldMetadataToGraphQLQuery } from '@/object-metadata/utils/mapFieldMetadataToGraphQLQuery';
|
||||||
|
import { shouldFieldBeQueried } from '@/object-metadata/utils/shouldFieldBeQueried';
|
||||||
|
|
||||||
|
export const mapObjectMetadataToGraphQLQuery = ({
|
||||||
|
objectMetadataItems,
|
||||||
|
objectMetadataItem,
|
||||||
|
depth = 1,
|
||||||
|
eagerLoadedRelations,
|
||||||
|
}: {
|
||||||
|
objectMetadataItems: ObjectMetadataItem[];
|
||||||
|
objectMetadataItem: Pick<ObjectMetadataItem, 'fields'>;
|
||||||
|
depth?: number;
|
||||||
|
eagerLoadedRelations?: Record<string, any>;
|
||||||
|
}): any => {
|
||||||
|
return `{
|
||||||
|
__typename
|
||||||
|
${(objectMetadataItem?.fields ?? [])
|
||||||
|
.filter((field) => field.isActive)
|
||||||
|
.filter((field) =>
|
||||||
|
shouldFieldBeQueried({ field, depth, eagerLoadedRelations }),
|
||||||
|
)
|
||||||
|
.map((field) =>
|
||||||
|
mapFieldMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems,
|
||||||
|
field,
|
||||||
|
relationFieldDepth: depth,
|
||||||
|
relationFieldEagerLoad: isUndefined(eagerLoadedRelations)
|
||||||
|
? undefined
|
||||||
|
: eagerLoadedRelations[field.name] ?? undefined,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.join('\n')}
|
||||||
|
}`;
|
||||||
|
};
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
import { isUndefined } from '@sniptt/guards';
|
||||||
|
|
||||||
|
import { FieldType } from '@/object-record/record-field/types/FieldType';
|
||||||
|
|
||||||
|
import { FieldMetadataItem } from '../types/FieldMetadataItem';
|
||||||
|
|
||||||
|
export const shouldFieldBeQueried = ({
|
||||||
|
field,
|
||||||
|
depth,
|
||||||
|
eagerLoadedRelations,
|
||||||
|
}: {
|
||||||
|
field: Pick<FieldMetadataItem, 'name' | 'type'>;
|
||||||
|
depth?: number;
|
||||||
|
eagerLoadedRelations?: Record<string, boolean>;
|
||||||
|
}): any => {
|
||||||
|
const fieldType = field.type as FieldType;
|
||||||
|
|
||||||
|
if (!isUndefined(depth) && depth < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isUndefined(depth) && depth < 1 && fieldType === 'RELATION') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
fieldType === 'RELATION' &&
|
||||||
|
!isUndefined(eagerLoadedRelations) &&
|
||||||
|
(isUndefined(eagerLoadedRelations[field.name]) ||
|
||||||
|
!eagerLoadedRelations[field.name])
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
@ -1,10 +1,10 @@
|
|||||||
import { useApolloClient } from '@apollo/client';
|
import { useApolloClient } from '@apollo/client';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { MAX_QUERY_DEPTH_FOR_CACHE_INJECTION } from '@/object-record/cache/constants/MaxQueryDepthForCacheInjection';
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { useInjectIntoFindOneRecordQueryCache } from '@/object-record/cache/hooks/useInjectIntoFindOneRecordQueryCache';
|
import { useInjectIntoFindOneRecordQueryCache } from '@/object-record/cache/hooks/useInjectIntoFindOneRecordQueryCache';
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
@ -15,7 +15,7 @@ export const useAddRecordInCache = ({
|
|||||||
}: {
|
}: {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
const apolloClient = useApolloClient();
|
const apolloClient = useApolloClient();
|
||||||
|
|
||||||
const { injectIntoFindOneRecordQueryCache } =
|
const { injectIntoFindOneRecordQueryCache } =
|
||||||
@ -29,18 +29,12 @@ export const useAddRecordInCache = ({
|
|||||||
const fragment = gql`
|
const fragment = gql`
|
||||||
fragment Create${capitalize(
|
fragment Create${capitalize(
|
||||||
objectMetadataItem.nameSingular,
|
objectMetadataItem.nameSingular,
|
||||||
)}InCache on ${capitalize(objectMetadataItem.nameSingular)} {
|
)}InCache on ${capitalize(
|
||||||
__typename
|
objectMetadataItem.nameSingular,
|
||||||
id
|
)} ${mapObjectMetadataToGraphQLQuery({
|
||||||
${objectMetadataItem.fields
|
objectMetadataItems,
|
||||||
.map((field) =>
|
objectMetadataItem,
|
||||||
mapFieldMetadataToGraphQLQuery({
|
})}
|
||||||
field,
|
|
||||||
depth: MAX_QUERY_DEPTH_FOR_CACHE_INJECTION,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const cachedObjectRecord = {
|
const cachedObjectRecord = {
|
||||||
@ -62,8 +56,8 @@ export const useAddRecordInCache = ({
|
|||||||
},
|
},
|
||||||
[
|
[
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
|
objectMetadataItems,
|
||||||
apolloClient,
|
apolloClient,
|
||||||
mapFieldMetadataToGraphQLQuery,
|
|
||||||
injectIntoFindOneRecordQueryCache,
|
injectIntoFindOneRecordQueryCache,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import { useApolloClient } from '@apollo/client/react/hooks/useApolloClient';
|
import { useApolloClient } from '@apollo/client/react/hooks/useApolloClient';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { QueryMethodName } from '@/object-metadata/types/QueryMethodName';
|
import { QueryMethodName } from '@/object-metadata/types/QueryMethodName';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
|
|
||||||
export const useCachedRootQuery = ({
|
export const useCachedRootQuery = ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
@ -12,33 +14,28 @@ export const useCachedRootQuery = ({
|
|||||||
objectMetadataItem: ObjectMetadataItem | undefined;
|
objectMetadataItem: ObjectMetadataItem | undefined;
|
||||||
queryMethodName: QueryMethodName;
|
queryMethodName: QueryMethodName;
|
||||||
}) => {
|
}) => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
|
||||||
const apolloClient = useApolloClient();
|
const apolloClient = useApolloClient();
|
||||||
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
if (!objectMetadataItem) {
|
if (!objectMetadataItem) {
|
||||||
return { cachedRootQuery: null };
|
return { cachedRootQuery: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildRecordFieldsFragment = () => {
|
|
||||||
return objectMetadataItem.fields
|
|
||||||
.filter((field) => field.type !== 'RELATION')
|
|
||||||
.map((field) => mapFieldMetadataToGraphQLQuery({ field }))
|
|
||||||
.join(' \n');
|
|
||||||
};
|
|
||||||
|
|
||||||
const cacheReadFragment = gql`
|
const cacheReadFragment = gql`
|
||||||
fragment RootQuery on Query {
|
fragment RootQuery on Query {
|
||||||
${
|
${
|
||||||
QueryMethodName.FindMany === queryMethodName
|
QueryMethodName.FindMany === queryMethodName
|
||||||
? objectMetadataItem.namePlural
|
? objectMetadataItem.namePlural
|
||||||
: objectMetadataItem.nameSingular
|
: objectMetadataItem.nameSingular
|
||||||
} {
|
|
||||||
${QueryMethodName.FindMany === queryMethodName ? 'edges { node { ' : ''}
|
|
||||||
${buildRecordFieldsFragment()}
|
|
||||||
${QueryMethodName.FindMany === queryMethodName ? '}}' : ''}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
${QueryMethodName.FindMany === queryMethodName ? '{ edges { node ' : ''}
|
||||||
|
${mapObjectMetadataToGraphQLQuery({
|
||||||
|
objectMetadataItems,
|
||||||
|
objectMetadataItem,
|
||||||
|
depth: 0,
|
||||||
|
})}
|
||||||
|
${QueryMethodName.FindMany === queryMethodName ? '}}' : ''}
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const cachedRootQuery = apolloClient.readFragment({
|
const cachedRootQuery = apolloClient.readFragment({
|
||||||
@ -1,7 +1,9 @@
|
|||||||
import { gql, useApolloClient } from '@apollo/client';
|
import { gql, useApolloClient } from '@apollo/client';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { isNullable } from '~/utils/isNullable';
|
import { isNullable } from '~/utils/isNullable';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
@ -11,7 +13,8 @@ export const useGetRecordFromCache = ({
|
|||||||
}: {
|
}: {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
const apolloClient = useApolloClient();
|
const apolloClient = useApolloClient();
|
||||||
|
|
||||||
return <CachedObjectRecord extends ObjectRecord = ObjectRecord>(
|
return <CachedObjectRecord extends ObjectRecord = ObjectRecord>(
|
||||||
@ -25,12 +28,12 @@ export const useGetRecordFromCache = ({
|
|||||||
const capitalizedObjectName = capitalize(objectMetadataItem.nameSingular);
|
const capitalizedObjectName = capitalize(objectMetadataItem.nameSingular);
|
||||||
|
|
||||||
const cacheReadFragment = gql`
|
const cacheReadFragment = gql`
|
||||||
fragment ${capitalizedObjectName}Fragment on ${capitalizedObjectName} {
|
fragment ${capitalizedObjectName}Fragment on ${capitalizedObjectName} ${mapObjectMetadataToGraphQLQuery(
|
||||||
id
|
{
|
||||||
${objectMetadataItem.fields
|
objectMetadataItems,
|
||||||
.map((field) => mapFieldMetadataToGraphQLQuery({ field }))
|
objectMetadataItem,
|
||||||
.join('\n')}
|
},
|
||||||
}
|
)}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const cachedRecordId = cache.identify({
|
const cachedRecordId = cache.identify({
|
||||||
|
|||||||
@ -5,72 +5,28 @@ import { Person } from '@/people/types/Person';
|
|||||||
export const query = gql`
|
export const query = gql`
|
||||||
mutation CreatePeople($data: [PersonCreateInput!]!) {
|
mutation CreatePeople($data: [PersonCreateInput!]!) {
|
||||||
createPeople(data: $data) {
|
createPeople(data: $data) {
|
||||||
id
|
__typename
|
||||||
opportunities {
|
xLink {
|
||||||
edges {
|
label
|
||||||
node {
|
url
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
xLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
id
|
|
||||||
pointOfContactForOpportunities {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
createdAt
|
|
||||||
company {
|
|
||||||
__typename
|
|
||||||
id
|
id
|
||||||
}
|
createdAt
|
||||||
city
|
city
|
||||||
email
|
email
|
||||||
activityTargets {
|
jobTitle
|
||||||
edges {
|
name {
|
||||||
node {
|
firstName
|
||||||
__typename
|
lastName
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
phone
|
||||||
jobTitle
|
linkedinLink {
|
||||||
favorites {
|
label
|
||||||
edges {
|
url
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
updatedAt
|
||||||
attachments {
|
avatarUrl
|
||||||
edges {
|
companyId
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name {
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
phone
|
|
||||||
linkedinLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
updatedAt
|
|
||||||
avatarUrl
|
|
||||||
companyId
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@ -86,32 +42,15 @@ const data = [
|
|||||||
export const variables = { data };
|
export const variables = { data };
|
||||||
|
|
||||||
export const responseData = {
|
export const responseData = {
|
||||||
opportunities: {
|
__typeName: '',
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
xLink: {
|
xLink: {
|
||||||
label: '',
|
label: '',
|
||||||
url: '',
|
url: '',
|
||||||
},
|
},
|
||||||
pointOfContactForOpportunities: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
createdAt: '',
|
createdAt: '',
|
||||||
company: {
|
|
||||||
id: '',
|
|
||||||
},
|
|
||||||
city: '',
|
city: '',
|
||||||
email: '',
|
email: '',
|
||||||
activityTargets: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
jobTitle: '',
|
jobTitle: '',
|
||||||
favorites: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
attachments: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
name: {
|
name: {
|
||||||
firstName: '',
|
firstName: '',
|
||||||
lastName: '',
|
lastName: '',
|
||||||
|
|||||||
@ -3,72 +3,28 @@ import { gql } from '@apollo/client';
|
|||||||
export const query = gql`
|
export const query = gql`
|
||||||
mutation CreateOnePerson($input: PersonCreateInput!) {
|
mutation CreateOnePerson($input: PersonCreateInput!) {
|
||||||
createPerson(data: $input) {
|
createPerson(data: $input) {
|
||||||
id
|
__typename
|
||||||
opportunities {
|
xLink {
|
||||||
edges {
|
label
|
||||||
node {
|
url
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
xLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
id
|
|
||||||
pointOfContactForOpportunities {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
createdAt
|
|
||||||
company {
|
|
||||||
__typename
|
|
||||||
id
|
id
|
||||||
}
|
createdAt
|
||||||
city
|
city
|
||||||
email
|
email
|
||||||
activityTargets {
|
jobTitle
|
||||||
edges {
|
name {
|
||||||
node {
|
firstName
|
||||||
__typename
|
lastName
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
phone
|
||||||
jobTitle
|
linkedinLink {
|
||||||
favorites {
|
label
|
||||||
edges {
|
url
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
updatedAt
|
||||||
attachments {
|
avatarUrl
|
||||||
edges {
|
companyId
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name {
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
phone
|
|
||||||
linkedinLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
updatedAt
|
|
||||||
avatarUrl
|
|
||||||
companyId
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -5,72 +5,28 @@ export { responseData } from './useUpdateOneRecord';
|
|||||||
export const query = gql`
|
export const query = gql`
|
||||||
mutation ExecuteQuickActionOnOnePerson($idToExecuteQuickActionOn: ID!) {
|
mutation ExecuteQuickActionOnOnePerson($idToExecuteQuickActionOn: ID!) {
|
||||||
executeQuickActionOnPerson(id: $idToExecuteQuickActionOn) {
|
executeQuickActionOnPerson(id: $idToExecuteQuickActionOn) {
|
||||||
id
|
__typename
|
||||||
opportunities {
|
xLink {
|
||||||
edges {
|
label
|
||||||
node {
|
url
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
xLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
id
|
|
||||||
pointOfContactForOpportunities {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
createdAt
|
|
||||||
company {
|
|
||||||
__typename
|
|
||||||
id
|
id
|
||||||
}
|
createdAt
|
||||||
city
|
city
|
||||||
email
|
email
|
||||||
activityTargets {
|
jobTitle
|
||||||
edges {
|
name {
|
||||||
node {
|
firstName
|
||||||
__typename
|
lastName
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
phone
|
||||||
jobTitle
|
linkedinLink {
|
||||||
favorites {
|
label
|
||||||
edges {
|
url
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
updatedAt
|
||||||
attachments {
|
avatarUrl
|
||||||
edges {
|
companyId
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name {
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
phone
|
|
||||||
linkedinLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
updatedAt
|
|
||||||
avatarUrl
|
|
||||||
companyId
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -5,72 +5,28 @@ import { responseData as person } from './useUpdateOneRecord';
|
|||||||
export const query = gql`
|
export const query = gql`
|
||||||
query FindOnePerson($objectRecordId: UUID!) {
|
query FindOnePerson($objectRecordId: UUID!) {
|
||||||
person(filter: { id: { eq: $objectRecordId } }) {
|
person(filter: { id: { eq: $objectRecordId } }) {
|
||||||
id
|
__typename
|
||||||
opportunities {
|
xLink {
|
||||||
edges {
|
label
|
||||||
node {
|
url
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
}
|
||||||
}
|
id
|
||||||
}
|
createdAt
|
||||||
xLink {
|
city
|
||||||
label
|
email
|
||||||
url
|
jobTitle
|
||||||
}
|
name {
|
||||||
id
|
firstName
|
||||||
pointOfContactForOpportunities {
|
lastName
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
}
|
||||||
}
|
phone
|
||||||
}
|
linkedinLink {
|
||||||
createdAt
|
label
|
||||||
company {
|
url
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
city
|
|
||||||
email
|
|
||||||
activityTargets {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
}
|
||||||
}
|
updatedAt
|
||||||
}
|
avatarUrl
|
||||||
jobTitle
|
companyId
|
||||||
favorites {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attachments {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name {
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
phone
|
|
||||||
linkedinLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
updatedAt
|
|
||||||
avatarUrl
|
|
||||||
companyId
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -3,72 +3,28 @@ import { gql } from '@apollo/client';
|
|||||||
export const query = gql`
|
export const query = gql`
|
||||||
mutation UpdateOnePerson($idToUpdate: ID!, $input: PersonUpdateInput!) {
|
mutation UpdateOnePerson($idToUpdate: ID!, $input: PersonUpdateInput!) {
|
||||||
updatePerson(id: $idToUpdate, data: $input) {
|
updatePerson(id: $idToUpdate, data: $input) {
|
||||||
id
|
__typename
|
||||||
opportunities {
|
xLink {
|
||||||
edges {
|
label
|
||||||
node {
|
url
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
xLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
id
|
|
||||||
pointOfContactForOpportunities {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
createdAt
|
|
||||||
company {
|
|
||||||
__typename
|
|
||||||
id
|
id
|
||||||
}
|
createdAt
|
||||||
city
|
city
|
||||||
email
|
email
|
||||||
activityTargets {
|
jobTitle
|
||||||
edges {
|
name {
|
||||||
node {
|
firstName
|
||||||
__typename
|
lastName
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
phone
|
||||||
jobTitle
|
linkedinLink {
|
||||||
favorites {
|
label
|
||||||
edges {
|
url
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
updatedAt
|
||||||
attachments {
|
avatarUrl
|
||||||
edges {
|
companyId
|
||||||
node {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name {
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
phone
|
|
||||||
linkedinLink {
|
|
||||||
label
|
|
||||||
url
|
|
||||||
}
|
|
||||||
updatedAt
|
|
||||||
avatarUrl
|
|
||||||
companyId
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@ -127,6 +83,6 @@ export const variables = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const responseData = {
|
export const responseData = {
|
||||||
...basePerson,
|
...{ ...basePerson, __typename: 'Person' },
|
||||||
...connectedObjects,
|
...connectedObjects,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
|
||||||
import { EMPTY_MUTATION } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { EMPTY_MUTATION } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { isNullable } from '~/utils/isNullable';
|
import { isNullable } from '~/utils/isNullable';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ export const useGenerateCreateManyRecordMutation = ({
|
|||||||
}: {
|
}: {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
if (isNullable(objectMetadataItem)) {
|
if (isNullable(objectMetadataItem)) {
|
||||||
return EMPTY_MUTATION;
|
return EMPTY_MUTATION;
|
||||||
@ -29,15 +31,9 @@ export const useGenerateCreateManyRecordMutation = ({
|
|||||||
mutation Create${capitalize(
|
mutation Create${capitalize(
|
||||||
objectMetadataItem.namePlural,
|
objectMetadataItem.namePlural,
|
||||||
)}($data: [${capitalize(objectMetadataItem.nameSingular)}CreateInput!]!) {
|
)}($data: [${capitalize(objectMetadataItem.nameSingular)}CreateInput!]!) {
|
||||||
${mutationResponseField}(data: $data) {
|
${mutationResponseField}(data: $data) ${mapObjectMetadataToGraphQLQuery({
|
||||||
id
|
objectMetadataItems,
|
||||||
${objectMetadataItem.fields
|
objectMetadataItem,
|
||||||
.map((field) =>
|
})}
|
||||||
mapFieldMetadataToGraphQLQuery({
|
|
||||||
field,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
}`;
|
}`;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
|
||||||
import { EMPTY_MUTATION } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { EMPTY_MUTATION } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { isNullable } from '~/utils/isNullable';
|
import { isNullable } from '~/utils/isNullable';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ export const useGenerateCreateOneRecordMutation = ({
|
|||||||
}: {
|
}: {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
if (isNullable(objectMetadataItem)) {
|
if (isNullable(objectMetadataItem)) {
|
||||||
return EMPTY_MUTATION;
|
return EMPTY_MUTATION;
|
||||||
@ -29,16 +31,10 @@ export const useGenerateCreateOneRecordMutation = ({
|
|||||||
|
|
||||||
return gql`
|
return gql`
|
||||||
mutation CreateOne${capitalizedObjectName}($input: ${capitalizedObjectName}CreateInput!) {
|
mutation CreateOne${capitalizedObjectName}($input: ${capitalizedObjectName}CreateInput!) {
|
||||||
${mutationResponseField}(data: $input) {
|
${mutationResponseField}(data: $input) ${mapObjectMetadataToGraphQLQuery({
|
||||||
id
|
objectMetadataItems,
|
||||||
${objectMetadataItem.fields
|
objectMetadataItem,
|
||||||
.map((field) =>
|
})}
|
||||||
mapFieldMetadataToGraphQLQuery({
|
|
||||||
field,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
|
||||||
import { EMPTY_MUTATION } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { EMPTY_MUTATION } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { isNullable } from '~/utils/isNullable';
|
import { isNullable } from '~/utils/isNullable';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
@ -19,7 +21,7 @@ export const useGenerateExecuteQuickActionOnOneRecordMutation = ({
|
|||||||
}: {
|
}: {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
if (isNullable(objectMetadataItem)) {
|
if (isNullable(objectMetadataItem)) {
|
||||||
return EMPTY_MUTATION;
|
return EMPTY_MUTATION;
|
||||||
@ -34,16 +36,12 @@ export const useGenerateExecuteQuickActionOnOneRecordMutation = ({
|
|||||||
|
|
||||||
return gql`
|
return gql`
|
||||||
mutation ExecuteQuickActionOnOne${capitalizedObjectName}($idToExecuteQuickActionOn: ID!) {
|
mutation ExecuteQuickActionOnOne${capitalizedObjectName}($idToExecuteQuickActionOn: ID!) {
|
||||||
${graphQLFieldForExecuteQuickActionOnOneRecordMutation}(id: $idToExecuteQuickActionOn) {
|
${graphQLFieldForExecuteQuickActionOnOneRecordMutation}(id: $idToExecuteQuickActionOn) ${mapObjectMetadataToGraphQLQuery(
|
||||||
id
|
{
|
||||||
${objectMetadataItem.fields
|
objectMetadataItems,
|
||||||
.map((field) =>
|
objectMetadataItem,
|
||||||
mapFieldMetadataToGraphQLQuery({
|
},
|
||||||
field,
|
)}
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
export const getFindDuplicateRecordsQueryResponseField = (
|
export const getFindDuplicateRecordsQueryResponseField = (
|
||||||
@ -9,13 +11,13 @@ export const getFindDuplicateRecordsQueryResponseField = (
|
|||||||
) => `${objectNameSingular}Duplicates`;
|
) => `${objectNameSingular}Duplicates`;
|
||||||
|
|
||||||
export const useGenerateFindDuplicateRecordsQuery = () => {
|
export const useGenerateFindDuplicateRecordsQuery = () => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
depth,
|
depth,
|
||||||
}: {
|
}: {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: Pick<ObjectMetadataItem, 'fields' | 'nameSingular'>;
|
||||||
depth?: number;
|
depth?: number;
|
||||||
}) => gql`
|
}) => gql`
|
||||||
query FindDuplicate${capitalize(objectMetadataItem.nameSingular)}($id: ID) {
|
query FindDuplicate${capitalize(objectMetadataItem.nameSingular)}($id: ID) {
|
||||||
@ -23,17 +25,11 @@ export const useGenerateFindDuplicateRecordsQuery = () => {
|
|||||||
objectMetadataItem.nameSingular,
|
objectMetadataItem.nameSingular,
|
||||||
)}(id: $id) {
|
)}(id: $id) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node ${mapObjectMetadataToGraphQLQuery({
|
||||||
id
|
objectMetadataItems,
|
||||||
${objectMetadataItem.fields
|
objectMetadataItem,
|
||||||
.map((field) =>
|
depth,
|
||||||
mapFieldMetadataToGraphQLQuery({
|
})}
|
||||||
field,
|
|
||||||
depth,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
cursor
|
cursor
|
||||||
}
|
}
|
||||||
pageInfo {
|
pageInfo {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
|
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
@ -12,8 +12,6 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
|
|||||||
objectMetadataItems: ObjectMetadataItem[];
|
objectMetadataItems: ObjectMetadataItem[];
|
||||||
depth?: number;
|
depth?: number;
|
||||||
}) => {
|
}) => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
|
||||||
|
|
||||||
const capitalizedObjectNameSingulars = objectMetadataItems.map(
|
const capitalizedObjectNameSingulars = objectMetadataItems.map(
|
||||||
({ nameSingular }) => capitalize(nameSingular),
|
({ nameSingular }) => capitalize(nameSingular),
|
||||||
);
|
);
|
||||||
@ -59,26 +57,22 @@ export const useGenerateFindManyRecordsForMultipleMetadataItemsQuery = ({
|
|||||||
) {
|
) {
|
||||||
${objectMetadataItems
|
${objectMetadataItems
|
||||||
.map(
|
.map(
|
||||||
({ namePlural, nameSingular, fields }) =>
|
(objectMetadataItem) =>
|
||||||
`${namePlural}(filter: $filter${capitalize(
|
`${objectMetadataItem.namePlural}(filter: $filter${capitalize(
|
||||||
nameSingular,
|
objectMetadataItem.nameSingular,
|
||||||
)}, orderBy: $orderBy${capitalize(
|
)}, orderBy: $orderBy${capitalize(
|
||||||
nameSingular,
|
objectMetadataItem.nameSingular,
|
||||||
)}, first: $limit${capitalize(
|
)}, first: $limit${capitalize(
|
||||||
nameSingular,
|
objectMetadataItem.nameSingular,
|
||||||
)}, after: $lastCursor${capitalize(nameSingular)}){
|
)}, after: $lastCursor${capitalize(
|
||||||
|
objectMetadataItem.nameSingular,
|
||||||
|
)}){
|
||||||
edges {
|
edges {
|
||||||
node {
|
node ${mapObjectMetadataToGraphQLQuery({
|
||||||
id
|
objectMetadataItems,
|
||||||
${fields
|
objectMetadataItem,
|
||||||
.map((field) =>
|
depth,
|
||||||
mapFieldMetadataToGraphQLQuery({
|
})}
|
||||||
field,
|
|
||||||
depth,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
cursor
|
cursor
|
||||||
}
|
}
|
||||||
pageInfo {
|
pageInfo {
|
||||||
|
|||||||
@ -1,18 +1,25 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
export const useGenerateFindManyRecordsQuery = () => {
|
export const useGenerateFindManyRecordsQuery = () => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
depth,
|
depth,
|
||||||
|
eagerLoadedRelations,
|
||||||
}: {
|
}: {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: Pick<
|
||||||
|
ObjectMetadataItem,
|
||||||
|
'fields' | 'nameSingular' | 'namePlural'
|
||||||
|
>;
|
||||||
depth?: number;
|
depth?: number;
|
||||||
|
eagerLoadedRelations?: Record<string, any>;
|
||||||
}) => gql`
|
}) => gql`
|
||||||
query FindMany${capitalize(
|
query FindMany${capitalize(
|
||||||
objectMetadataItem.namePlural,
|
objectMetadataItem.namePlural,
|
||||||
@ -25,17 +32,12 @@ export const useGenerateFindManyRecordsQuery = () => {
|
|||||||
objectMetadataItem.namePlural
|
objectMetadataItem.namePlural
|
||||||
}(filter: $filter, orderBy: $orderBy, first: $limit, after: $lastCursor){
|
}(filter: $filter, orderBy: $orderBy, first: $limit, after: $lastCursor){
|
||||||
edges {
|
edges {
|
||||||
node {
|
node ${mapObjectMetadataToGraphQLQuery({
|
||||||
id
|
objectMetadataItems,
|
||||||
${objectMetadataItem.fields
|
objectMetadataItem,
|
||||||
.map((field) =>
|
depth,
|
||||||
mapFieldMetadataToGraphQLQuery({
|
eagerLoadedRelations,
|
||||||
field,
|
})}
|
||||||
depth,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
cursor
|
cursor
|
||||||
}
|
}
|
||||||
pageInfo {
|
pageInfo {
|
||||||
|
|||||||
@ -1,17 +1,19 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
export const useGenerateFindOneRecordQuery = () => {
|
export const useGenerateFindOneRecordQuery = () => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
depth,
|
depth,
|
||||||
}: {
|
}: {
|
||||||
objectMetadataItem: Pick<ObjectMetadataItem, 'nameSingular' | 'fields'>;
|
objectMetadataItem: Pick<ObjectMetadataItem, 'fields' | 'nameSingular'>;
|
||||||
depth?: number;
|
depth?: number;
|
||||||
}) => {
|
}) => {
|
||||||
return gql`
|
return gql`
|
||||||
@ -22,17 +24,11 @@ export const useGenerateFindOneRecordQuery = () => {
|
|||||||
id: {
|
id: {
|
||||||
eq: $objectRecordId
|
eq: $objectRecordId
|
||||||
}
|
}
|
||||||
}){
|
})${mapObjectMetadataToGraphQLQuery({
|
||||||
id
|
objectMetadataItems,
|
||||||
${objectMetadataItem.fields
|
objectMetadataItem,
|
||||||
.map((field) =>
|
depth,
|
||||||
mapFieldMetadataToGraphQLQuery({
|
})}
|
||||||
field,
|
|
||||||
depth,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useMapFieldMetadataToGraphQLQuery } from '@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery';
|
|
||||||
import { EMPTY_MUTATION } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { EMPTY_MUTATION } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { isNullable } from '~/utils/isNullable';
|
import { isNullable } from '~/utils/isNullable';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ export const useGenerateUpdateOneRecordMutation = ({
|
|||||||
}: {
|
}: {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
const mapFieldMetadataToGraphQLQuery = useMapFieldMetadataToGraphQLQuery();
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
|
||||||
|
|
||||||
if (isNullable(objectMetadataItem)) {
|
if (isNullable(objectMetadataItem)) {
|
||||||
return EMPTY_MUTATION;
|
return EMPTY_MUTATION;
|
||||||
@ -29,12 +31,12 @@ export const useGenerateUpdateOneRecordMutation = ({
|
|||||||
|
|
||||||
return gql`
|
return gql`
|
||||||
mutation UpdateOne${capitalizedObjectName}($idToUpdate: ID!, $input: ${capitalizedObjectName}UpdateInput!) {
|
mutation UpdateOne${capitalizedObjectName}($idToUpdate: ID!, $input: ${capitalizedObjectName}UpdateInput!) {
|
||||||
${mutationResponseField}(id: $idToUpdate, data: $input) {
|
${mutationResponseField}(id: $idToUpdate, data: $input) ${mapObjectMetadataToGraphQLQuery(
|
||||||
id
|
{
|
||||||
${objectMetadataItem.fields
|
objectMetadataItems,
|
||||||
.map((field) => mapFieldMetadataToGraphQLQuery({ field }))
|
objectMetadataItem,
|
||||||
.join('\n')}
|
},
|
||||||
}
|
)}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export const useUpdateOneRecord = <
|
|||||||
const apolloClient = useApolloClient();
|
const apolloClient = useApolloClient();
|
||||||
|
|
||||||
const { objectMetadataItem, updateOneRecordMutation, getRecordFromCache } =
|
const { objectMetadataItem, updateOneRecordMutation, getRecordFromCache } =
|
||||||
useObjectMetadataItem({ objectNameSingular });
|
useObjectMetadataItem({ objectNameSingular }, 1);
|
||||||
|
|
||||||
const { generateObjectRecordOptimisticResponse } =
|
const { generateObjectRecordOptimisticResponse } =
|
||||||
useGenerateObjectRecordOptimisticResponse({
|
useGenerateObjectRecordOptimisticResponse({
|
||||||
|
|||||||
@ -20,14 +20,31 @@ import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinit
|
|||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||||
|
|
||||||
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
|
|
||||||
useMapFieldMetadataToGraphQLQuery: () => () => '\n',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const query = gql`
|
const query = gql`
|
||||||
mutation UpdateOnePerson($idToUpdate: ID!, $input: PersonUpdateInput!) {
|
mutation UpdateOnePerson($idToUpdate: ID!, $input: PersonUpdateInput!) {
|
||||||
updatePerson(id: $idToUpdate, data: $input) {
|
updatePerson(id: $idToUpdate, data: $input) {
|
||||||
|
__typename
|
||||||
|
xLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
id
|
id
|
||||||
|
createdAt
|
||||||
|
city
|
||||||
|
email
|
||||||
|
jobTitle
|
||||||
|
name {
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
phone
|
||||||
|
linkedinLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
avatarUrl
|
||||||
|
companyId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -14,10 +14,6 @@ import {
|
|||||||
} from '@/object-record/record-field/contexts/FieldContext';
|
} from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { useToggleEditOnlyInput } from '@/object-record/record-field/hooks/useToggleEditOnlyInput';
|
import { useToggleEditOnlyInput } from '@/object-record/record-field/hooks/useToggleEditOnlyInput';
|
||||||
|
|
||||||
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
|
|
||||||
useMapFieldMetadataToGraphQLQuery: () => () => '\n',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const entityId = 'entityId';
|
const entityId = 'entityId';
|
||||||
|
|
||||||
const mocks: MockedResponse[] = [
|
const mocks: MockedResponse[] = [
|
||||||
@ -29,7 +25,28 @@ const mocks: MockedResponse[] = [
|
|||||||
$input: CompanyUpdateInput!
|
$input: CompanyUpdateInput!
|
||||||
) {
|
) {
|
||||||
updateCompany(id: $idToUpdate, data: $input) {
|
updateCompany(id: $idToUpdate, data: $input) {
|
||||||
|
__typename
|
||||||
|
xLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
linkedinLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
annualRecurringRevenue {
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
id
|
id
|
||||||
|
idealCustomerProfile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { RecoilRoot, useSetRecoilState } from 'recoil';
|
|||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { useMultiObjectSearch } from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
import { useMultiObjectSearch } from '@/object-record/relation-picker/hooks/useMultiObjectSearch';
|
||||||
|
import { FieldMetadataType } from '~/generated/graphql';
|
||||||
|
|
||||||
const query = gql`
|
const query = gql`
|
||||||
query FindManyRecordsMultipleMetadataItems(
|
query FindManyRecordsMultipleMetadataItems(
|
||||||
@ -22,6 +23,7 @@ const query = gql`
|
|||||||
) {
|
) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
__typename
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
cursor
|
cursor
|
||||||
@ -36,7 +38,7 @@ const query = gql`
|
|||||||
`;
|
`;
|
||||||
const response = {
|
const response = {
|
||||||
namePlural: {
|
namePlural: {
|
||||||
edges: [{ node: { id: 'nodeId' }, cursor: 'cursor' }],
|
edges: [{ node: { __typename: 'Custom', id: 'nodeId' }, cursor: 'cursor' }],
|
||||||
pageInfo: { startCursor: '', hasNextPage: '', endCursor: '' },
|
pageInfo: { startCursor: '', hasNextPage: '', endCursor: '' },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -120,7 +122,17 @@ describe('useMultiObjectSearch', () => {
|
|||||||
namePlural: 'namePlural',
|
namePlural: 'namePlural',
|
||||||
nameSingular: 'nameSingular',
|
nameSingular: 'nameSingular',
|
||||||
updatedAt: 'updatedAt',
|
updatedAt: 'updatedAt',
|
||||||
fields: [],
|
fields: [
|
||||||
|
{
|
||||||
|
id: 'f6a0a73a-5ee6-442e-b764-39b682471240',
|
||||||
|
name: 'id',
|
||||||
|
label: 'id',
|
||||||
|
type: FieldMetadataType.Uuid,
|
||||||
|
createdAt: '2024-01-01T00:00:00.000Z',
|
||||||
|
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
act(() => {
|
act(() => {
|
||||||
@ -144,9 +156,19 @@ describe('useMultiObjectSearch', () => {
|
|||||||
namePlural: 'namePlural',
|
namePlural: 'namePlural',
|
||||||
nameSingular: 'nameSingular',
|
nameSingular: 'nameSingular',
|
||||||
updatedAt: 'updatedAt',
|
updatedAt: 'updatedAt',
|
||||||
fields: [],
|
fields: [
|
||||||
|
{
|
||||||
|
id: 'f6a0a73a-5ee6-442e-b764-39b682471240',
|
||||||
|
name: 'id',
|
||||||
|
label: 'id',
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.Uuid,
|
||||||
|
createdAt: '2024-01-01T00:00:00.000Z',
|
||||||
|
updatedAt: '2024-01-01T00:00:00.000Z',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
record: { id: 'nodeId' },
|
record: { id: 'nodeId', __typename: 'Custom' },
|
||||||
recordIdentifier: {
|
recordIdentifier: {
|
||||||
id: 'nodeId',
|
id: 'nodeId',
|
||||||
name: '',
|
name: '',
|
||||||
|
|||||||
@ -86,6 +86,7 @@ export const useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery = ({
|
|||||||
const multiSelectQueryForSelectedIds =
|
const multiSelectQueryForSelectedIds =
|
||||||
useGenerateFindManyRecordsForMultipleMetadataItemsQuery({
|
useGenerateFindManyRecordsForMultipleMetadataItemsQuery({
|
||||||
objectMetadataItems: objectMetadataItemsUsedInSelectedIdsQuery,
|
objectMetadataItems: objectMetadataItemsUsedInSelectedIdsQuery,
|
||||||
|
depth: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|||||||
@ -87,6 +87,7 @@ export const useMultiObjectSearchMatchesSearchFilterAndToSelectQuery = ({
|
|||||||
const multiSelectQuery =
|
const multiSelectQuery =
|
||||||
useGenerateFindManyRecordsForMultipleMetadataItemsQuery({
|
useGenerateFindManyRecordsForMultipleMetadataItemsQuery({
|
||||||
objectMetadataItems: nonSystemObjectMetadataItems,
|
objectMetadataItems: nonSystemObjectMetadataItems,
|
||||||
|
depth: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|||||||
@ -16,17 +16,34 @@ jest.mock('uuid', () => ({
|
|||||||
v4: jest.fn(() => companyId),
|
v4: jest.fn(() => companyId),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
|
|
||||||
useMapFieldMetadataToGraphQLQuery: () => () => '\n',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const companyMocks = [
|
const companyMocks = [
|
||||||
{
|
{
|
||||||
request: {
|
request: {
|
||||||
query: gql`
|
query: gql`
|
||||||
mutation CreateCompanies($data: [CompanyCreateInput!]!) {
|
mutation CreateCompanies($data: [CompanyCreateInput!]!) {
|
||||||
createCompanies(data: $data) {
|
createCompanies(data: $data) {
|
||||||
|
__typename
|
||||||
|
xLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
linkedinLink {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
}
|
||||||
|
domainName
|
||||||
|
annualRecurringRevenue {
|
||||||
|
amountMicros
|
||||||
|
currencyCode
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
address
|
||||||
|
updatedAt
|
||||||
|
name
|
||||||
|
accountOwnerId
|
||||||
|
employees
|
||||||
id
|
id
|
||||||
|
idealCustomerProfile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|||||||
@ -23,12 +23,6 @@ import { entityCountInCurrentViewScopedState } from '@/views/states/entityCountI
|
|||||||
import { viewEditModeScopedState } from '@/views/states/viewEditModeScopedState';
|
import { viewEditModeScopedState } from '@/views/states/viewEditModeScopedState';
|
||||||
import { viewObjectMetadataIdScopeState } from '@/views/states/viewObjectMetadataIdScopeState';
|
import { viewObjectMetadataIdScopeState } from '@/views/states/viewObjectMetadataIdScopeState';
|
||||||
|
|
||||||
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => {
|
|
||||||
return {
|
|
||||||
useMapFieldMetadataToGraphQLQuery: jest.fn().mockReturnValue(() => '\n'),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const mockedUuid = 'mocked-uuid';
|
const mockedUuid = 'mocked-uuid';
|
||||||
jest.mock('uuid');
|
jest.mock('uuid');
|
||||||
|
|
||||||
|
|||||||
@ -14,12 +14,6 @@ import { ViewScope } from '@/views/scopes/ViewScope';
|
|||||||
import { currentViewFieldsScopedFamilyState } from '@/views/states/currentViewFieldsScopedFamilyState';
|
import { currentViewFieldsScopedFamilyState } from '@/views/states/currentViewFieldsScopedFamilyState';
|
||||||
import { ViewField } from '@/views/types/ViewField';
|
import { ViewField } from '@/views/types/ViewField';
|
||||||
|
|
||||||
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => {
|
|
||||||
return {
|
|
||||||
useMapFieldMetadataToGraphQLQuery: jest.fn().mockReturnValue(() => '\n'),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const fieldMetadataId = '12ecdf87-506f-44a7-98c6-393e5f05b225';
|
const fieldMetadataId = '12ecdf87-506f-44a7-98c6-393e5f05b225';
|
||||||
|
|
||||||
const fieldDefinition: ColumnDefinition<FieldMetadata> = {
|
const fieldDefinition: ColumnDefinition<FieldMetadata> = {
|
||||||
@ -53,7 +47,15 @@ const mocks = [
|
|||||||
query: gql`
|
query: gql`
|
||||||
mutation CreateOneViewField($input: ViewFieldCreateInput!) {
|
mutation CreateOneViewField($input: ViewFieldCreateInput!) {
|
||||||
createViewField(data: $input) {
|
createViewField(data: $input) {
|
||||||
|
__typename
|
||||||
|
position
|
||||||
|
isVisible
|
||||||
|
fieldMetadataId
|
||||||
|
viewId
|
||||||
id
|
id
|
||||||
|
size
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|||||||
Reference in New Issue
Block a user