[Refactor] generateDepthOneRecordGqlFieldsFromRecord (#10499)
## Introduction This refactor results from this https://github.com/twentyhq/twenty/pull/10493 review Introduced a new abstraction to the extinsting `generateDepthOneRecordGqlFields` that was accepting an optional record in arg in order to map generated `recordGqlFields` to the keys in the record 1/ Created a dedicated util method `generateDepthOneRecordGqlFieldsFromRecord` to do so 2/ Updated each previous `generateDepthOneRecordGqlFields` passing a record to call new `generateDepthOneRecordGqlFieldsFromRecord`
This commit is contained in:
@ -7,7 +7,7 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
|||||||
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery';
|
||||||
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
||||||
import { getRecordNodeFromRecord } from '@/object-record/cache/utils/getRecordNodeFromRecord';
|
import { getRecordNodeFromRecord } from '@/object-record/cache/utils/getRecordNodeFromRecord';
|
||||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { prefillRecord } from '@/object-record/utils/prefillRecord';
|
import { prefillRecord } from '@/object-record/utils/prefillRecord';
|
||||||
import { capitalize } from 'twenty-shared';
|
import { capitalize } from 'twenty-shared';
|
||||||
@ -28,7 +28,7 @@ export const useCreateOneRecordInCache = <T extends ObjectRecord>({
|
|||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
input: record,
|
input: record,
|
||||||
});
|
});
|
||||||
const recordGqlFields = generateDepthOneRecordGqlFields({
|
const recordGqlFields = computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record: prefilledRecord,
|
record: prefilledRecord,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
|
||||||
|
import {
|
||||||
|
getPersonObjectMetadataItem,
|
||||||
|
getPersonRecord,
|
||||||
|
} from '~/testing/mock-data/people';
|
||||||
|
|
||||||
|
describe('computeDepthOneRecordGqlFieldsFromRecord', () => {
|
||||||
|
const objectMetadataItem = getPersonObjectMetadataItem();
|
||||||
|
it('Should handle basic call', () => {
|
||||||
|
const personRecord = getPersonRecord();
|
||||||
|
const result = computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
|
objectMetadataItem,
|
||||||
|
record: personRecord,
|
||||||
|
});
|
||||||
|
expect(result).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"attachments": false,
|
||||||
|
"avatarUrl": false,
|
||||||
|
"calendarEventParticipants": false,
|
||||||
|
"city": true,
|
||||||
|
"company": true,
|
||||||
|
"companyId": false,
|
||||||
|
"createdAt": true,
|
||||||
|
"createdBy": true,
|
||||||
|
"deletedAt": true,
|
||||||
|
"emails": false,
|
||||||
|
"favorites": false,
|
||||||
|
"id": true,
|
||||||
|
"intro": false,
|
||||||
|
"jobTitle": true,
|
||||||
|
"linkedinLink": true,
|
||||||
|
"messageParticipants": false,
|
||||||
|
"name": true,
|
||||||
|
"noteTargets": true,
|
||||||
|
"performanceRating": false,
|
||||||
|
"phones": true,
|
||||||
|
"pointOfContactForOpportunities": false,
|
||||||
|
"position": true,
|
||||||
|
"searchVector": false,
|
||||||
|
"taskTargets": true,
|
||||||
|
"timelineActivities": false,
|
||||||
|
"updatedAt": false,
|
||||||
|
"whatsapp": false,
|
||||||
|
"workPreference": false,
|
||||||
|
"xLink": true,
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,52 +1,8 @@
|
|||||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
||||||
import {
|
import { getPersonObjectMetadataItem } from '~/testing/mock-data/people';
|
||||||
getPersonObjectMetadataItem,
|
|
||||||
getPersonRecord,
|
|
||||||
} from '~/testing/mock-data/people';
|
|
||||||
|
|
||||||
describe('generateDepthOneRecordGqlFields', () => {
|
describe('generateDepthOneRecordGqlFields', () => {
|
||||||
const objectMetadataItem = getPersonObjectMetadataItem();
|
const objectMetadataItem = getPersonObjectMetadataItem();
|
||||||
it('Should handle basic call with both objectMetadataItem and record', () => {
|
|
||||||
const personRecord = getPersonRecord();
|
|
||||||
const result = generateDepthOneRecordGqlFields({
|
|
||||||
objectMetadataItem,
|
|
||||||
record: personRecord,
|
|
||||||
});
|
|
||||||
expect(result).toMatchInlineSnapshot(`
|
|
||||||
{
|
|
||||||
"attachments": false,
|
|
||||||
"avatarUrl": false,
|
|
||||||
"calendarEventParticipants": false,
|
|
||||||
"city": true,
|
|
||||||
"company": true,
|
|
||||||
"companyId": false,
|
|
||||||
"createdAt": true,
|
|
||||||
"createdBy": true,
|
|
||||||
"deletedAt": true,
|
|
||||||
"emails": false,
|
|
||||||
"favorites": false,
|
|
||||||
"id": true,
|
|
||||||
"intro": false,
|
|
||||||
"jobTitle": true,
|
|
||||||
"linkedinLink": true,
|
|
||||||
"messageParticipants": false,
|
|
||||||
"name": true,
|
|
||||||
"noteTargets": true,
|
|
||||||
"performanceRating": false,
|
|
||||||
"phones": true,
|
|
||||||
"pointOfContactForOpportunities": false,
|
|
||||||
"position": true,
|
|
||||||
"searchVector": false,
|
|
||||||
"taskTargets": true,
|
|
||||||
"timelineActivities": false,
|
|
||||||
"updatedAt": false,
|
|
||||||
"whatsapp": false,
|
|
||||||
"workPreference": false,
|
|
||||||
"xLink": true,
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should handle basic call with standalone objectMetadataItem', () => {
|
it('Should handle basic call with standalone objectMetadataItem', () => {
|
||||||
const result = generateDepthOneRecordGqlFields({
|
const result = generateDepthOneRecordGqlFields({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
import {
|
||||||
|
GenerateDepthOneRecordGqlFields,
|
||||||
|
generateDepthOneRecordGqlFields,
|
||||||
|
} from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
||||||
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
|
||||||
|
type ComputeDepthOneRecordGqlFieldsFromRecordArgs =
|
||||||
|
GenerateDepthOneRecordGqlFields & {
|
||||||
|
record: Partial<ObjectRecord>;
|
||||||
|
};
|
||||||
|
export const computeDepthOneRecordGqlFieldsFromRecord = ({
|
||||||
|
objectMetadataItem,
|
||||||
|
record,
|
||||||
|
}: ComputeDepthOneRecordGqlFieldsFromRecordArgs) => {
|
||||||
|
const depthOneRecordGqlFields = generateDepthOneRecordGqlFields({
|
||||||
|
objectMetadataItem,
|
||||||
|
});
|
||||||
|
const recordKeys = Object.keys(record);
|
||||||
|
|
||||||
|
return Object.keys(depthOneRecordGqlFields).reduce<Record<string, boolean>>(
|
||||||
|
(acc, key) => {
|
||||||
|
return {
|
||||||
|
...acc,
|
||||||
|
[key]: recordKeys.includes(key),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
depthOneRecordGqlFields,
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -1,30 +1,14 @@
|
|||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
|
|
||||||
|
export type GenerateDepthOneRecordGqlFields = {
|
||||||
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
|
};
|
||||||
export const generateDepthOneRecordGqlFields = ({
|
export const generateDepthOneRecordGqlFields = ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record,
|
}: GenerateDepthOneRecordGqlFields) =>
|
||||||
}: {
|
objectMetadataItem.fields.reduce<Record<string, true>>((acc, field) => {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
|
||||||
record?: Record<string, any>;
|
|
||||||
}) => {
|
|
||||||
const gqlFieldsFromObjectMetadataItem = objectMetadataItem.fields.reduce<
|
|
||||||
Record<string, boolean>
|
|
||||||
>((acc, field) => {
|
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[field.name]: true,
|
[field.name]: true,
|
||||||
};
|
};
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
if (isDefined(record)) {
|
|
||||||
return Object.keys(gqlFieldsFromObjectMetadataItem).reduce((acc, key) => {
|
|
||||||
return {
|
|
||||||
...acc,
|
|
||||||
[key]: Object.keys(record).includes(key),
|
|
||||||
};
|
|
||||||
}, gqlFieldsFromObjectMetadataItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return gqlFieldsFromObjectMetadataItem;
|
|
||||||
};
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { renderHook, waitFor } from '@testing-library/react';
|
|||||||
|
|
||||||
import { getRecordFromCache } from '@/object-record/cache/utils/getRecordFromCache';
|
import { getRecordFromCache } from '@/object-record/cache/utils/getRecordFromCache';
|
||||||
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
||||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
|
||||||
import {
|
import {
|
||||||
personIds,
|
personIds,
|
||||||
personRecords,
|
personRecords,
|
||||||
@ -115,7 +115,7 @@ describe('useDeleteManyRecords', () => {
|
|||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
objectMetadataItems,
|
objectMetadataItems,
|
||||||
record,
|
record,
|
||||||
recordGqlFields: generateDepthOneRecordGqlFields({
|
recordGqlFields: computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record,
|
record,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { act } from 'react';
|
|||||||
|
|
||||||
import { getRecordFromCache } from '@/object-record/cache/utils/getRecordFromCache';
|
import { getRecordFromCache } from '@/object-record/cache/utils/getRecordFromCache';
|
||||||
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
||||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
|
||||||
import {
|
import {
|
||||||
query,
|
query,
|
||||||
responseData,
|
responseData,
|
||||||
@ -169,7 +169,7 @@ describe('useDeleteOneRecord', () => {
|
|||||||
|
|
||||||
describe('B. Starting from filled cache', () => {
|
describe('B. Starting from filled cache', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const recordGqlFields = generateDepthOneRecordGqlFields({
|
const recordGqlFields = computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record: personRecord,
|
record: personRecord,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
|||||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||||
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
||||||
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
||||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
|
||||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
@ -85,7 +85,7 @@ export const useAttachRelatedRecordFromRecord = ({
|
|||||||
...cachedRelatedRecord,
|
...cachedRelatedRecord,
|
||||||
[fieldOnRelatedObject]: previousRecord,
|
[fieldOnRelatedObject]: previousRecord,
|
||||||
};
|
};
|
||||||
const gqlFields = generateDepthOneRecordGqlFields({
|
const gqlFields = computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
objectMetadataItem: relatedObjectMetadataItem,
|
objectMetadataItem: relatedObjectMetadataItem,
|
||||||
record: previousRecordWithRelation,
|
record: previousRecordWithRelation,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordF
|
|||||||
import { getObjectTypename } from '@/object-record/cache/utils/getObjectTypename';
|
import { getObjectTypename } from '@/object-record/cache/utils/getObjectTypename';
|
||||||
import { getRecordNodeFromRecord } from '@/object-record/cache/utils/getRecordNodeFromRecord';
|
import { getRecordNodeFromRecord } from '@/object-record/cache/utils/getRecordNodeFromRecord';
|
||||||
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
||||||
|
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
|
||||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
||||||
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
|
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
|
||||||
import { useUpdateOneRecordMutation } from '@/object-record/hooks/useUpdateOneRecordMutation';
|
import { useUpdateOneRecordMutation } from '@/object-record/hooks/useUpdateOneRecordMutation';
|
||||||
@ -105,7 +106,7 @@ export const useUpdateOneRecord = <
|
|||||||
isDefined(cachedRecordWithConnection);
|
isDefined(cachedRecordWithConnection);
|
||||||
|
|
||||||
if (shouldHandleOptimisticCache) {
|
if (shouldHandleOptimisticCache) {
|
||||||
const recordGqlFields = generateDepthOneRecordGqlFields({
|
const recordGqlFields = computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record: optimisticRecordInput,
|
record: optimisticRecordInput,
|
||||||
});
|
});
|
||||||
@ -165,7 +166,7 @@ export const useUpdateOneRecord = <
|
|||||||
).filter((diffKey) => !cachedRecordKeys.has(diffKey));
|
).filter((diffKey) => !cachedRecordKeys.has(diffKey));
|
||||||
|
|
||||||
const recordGqlFields = {
|
const recordGqlFields = {
|
||||||
...generateDepthOneRecordGqlFields({
|
...computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record: cachedRecord,
|
record: cachedRecord,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
||||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
import { computeDepthOneRecordGqlFieldsFromRecord } from '@/object-record/graphql/utils/computeDepthOneRecordGqlFieldsFromRecord';
|
||||||
import { FieldActorForInputValue } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldActorForInputValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput';
|
import { computeOptimisticRecordFromInput } from '@/object-record/utils/computeOptimisticRecordFromInput';
|
||||||
import { InMemoryCache } from '@apollo/client';
|
import { InMemoryCache } from '@apollo/client';
|
||||||
@ -123,7 +123,7 @@ describe('computeOptimisticRecordFromInput', () => {
|
|||||||
(field) => field.name === 'id',
|
(field) => field.name === 'id',
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
const recordGqlFields = generateDepthOneRecordGqlFields({
|
const recordGqlFields = computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record: companyRecord,
|
record: companyRecord,
|
||||||
});
|
});
|
||||||
@ -168,7 +168,7 @@ describe('computeOptimisticRecordFromInput', () => {
|
|||||||
(field) => field.name === 'id',
|
(field) => field.name === 'id',
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
const recordGqlFields = generateDepthOneRecordGqlFields({
|
const recordGqlFields = computeDepthOneRecordGqlFieldsFromRecord({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record: companyRecord,
|
record: companyRecord,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user