Recursively turn relation connection into records (#3334)

* Use new ObjectRecordConnection

* Use new records without connection in GraphQLView

* Added playwright for storybook tests

* Fixed lint

* Fixed test and tsc

* Fixed storybook tests

* wip tests

* Added useMapConnectionToRecords unit test

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Lucas Bordeau
2024-01-11 20:27:59 +01:00
committed by GitHub
parent 299bed511f
commit e2bdf0ce45
24 changed files with 1252 additions and 266 deletions

View File

@ -4,7 +4,7 @@ import { produce } from 'immer';
import { OptimisticEffectDefinition } from '@/apollo/optimistic-effect/types/OptimisticEffectDefinition';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { isRecordMatchingFilter } from '@/object-record/record-filter/utils/isRecordMatchingFilter';
import { PaginatedRecordTypeResults } from '@/object-record/types/PaginatedRecordTypeResults';
import { ObjectRecordConnection } from '@/object-record/types/ObjectRecordConnection';
import { isDefined } from '~/utils/isDefined';
import { capitalize } from '~/utils/string/capitalize';
@ -21,77 +21,39 @@ export const getRecordOptimisticEffectDefinition = ({
deletedRecordIds,
variables,
}) => {
const newRecordPaginatedCacheField = produce<
PaginatedRecordTypeResults<any>
>(currentData as PaginatedRecordTypeResults<any>, (draft) => {
const existingDataIsEmpty = !draft || !draft.edges || !draft.edges[0];
const newRecordPaginatedCacheField = produce<ObjectRecordConnection<any>>(
currentData as ObjectRecordConnection<any>,
(draft) => {
const existingDataIsEmpty = !draft || !draft.edges || !draft.edges[0];
if (isNonEmptyArray(createdRecords)) {
if (existingDataIsEmpty) {
return {
__typename: `${capitalize(objectMetadataItem.nameSingular)}Edge`,
edges: createdRecords.map((createdRecord) => ({
node: createdRecord,
cursor: '',
})),
pageInfo: {
endCursor: '',
hasNextPage: false,
hasPreviousPage: false,
startCursor: '',
},
};
} else {
for (const createdRecord of createdRecords) {
const existingRecord = draft.edges.find(
(edge) => edge.node.id === createdRecord.id,
);
if (existingRecord) {
existingRecord.node = createdRecord;
continue;
}
draft.edges.unshift({
node: createdRecord,
cursor: '',
if (isNonEmptyArray(createdRecords)) {
if (existingDataIsEmpty) {
return {
__typename: `${capitalize(objectMetadataItem.nameSingular)}Edge`,
});
}
}
}
if (isNonEmptyArray(deletedRecordIds)) {
draft.edges = draft.edges.filter(
(edge) => !deletedRecordIds.includes(edge.node.id),
);
}
if (isNonEmptyArray(updatedRecords)) {
for (const updatedRecord of updatedRecords) {
const updatedRecordIsOutOfQueryFilter =
isDefined(variables.filter) &&
!isRecordMatchingFilter({
record: updatedRecord,
filter: variables.filter,
objectMetadataItem,
});
if (updatedRecordIsOutOfQueryFilter) {
draft.edges = draft.edges.filter(
(edge) => edge.node.id !== updatedRecord.id,
);
edges: createdRecords.map((createdRecord) => ({
node: createdRecord,
cursor: '',
})),
pageInfo: {
endCursor: '',
hasNextPage: false,
hasPreviousPage: false,
startCursor: '',
},
};
} else {
const foundUpdatedRecordInCacheQuery = draft.edges.find(
(edge) => edge.node.id === updatedRecord.id,
);
for (const createdRecord of createdRecords) {
const existingRecord = draft.edges.find(
(edge) => edge.node.id === createdRecord.id,
);
if (foundUpdatedRecordInCacheQuery) {
foundUpdatedRecordInCacheQuery.node = updatedRecord;
} else {
// TODO: add order by
draft.edges.push({
node: updatedRecord,
if (existingRecord) {
existingRecord.node = createdRecord;
continue;
}
draft.edges.unshift({
node: createdRecord,
cursor: '',
__typename: `${capitalize(
objectMetadataItem.nameSingular,
@ -100,8 +62,49 @@ export const getRecordOptimisticEffectDefinition = ({
}
}
}
}
});
if (isNonEmptyArray(deletedRecordIds)) {
draft.edges = draft.edges.filter(
(edge) => !deletedRecordIds.includes(edge.node.id),
);
}
if (isNonEmptyArray(updatedRecords)) {
for (const updatedRecord of updatedRecords) {
const updatedRecordIsOutOfQueryFilter =
isDefined(variables.filter) &&
!isRecordMatchingFilter({
record: updatedRecord,
filter: variables.filter,
objectMetadataItem,
});
if (updatedRecordIsOutOfQueryFilter) {
draft.edges = draft.edges.filter(
(edge) => edge.node.id !== updatedRecord.id,
);
} else {
const foundUpdatedRecordInCacheQuery = draft.edges.find(
(edge) => edge.node.id === updatedRecord.id,
);
if (foundUpdatedRecordInCacheQuery) {
foundUpdatedRecordInCacheQuery.node = updatedRecord;
} else {
// TODO: add order by
draft.edges.push({
node: updatedRecord,
cursor: '',
__typename: `${capitalize(
objectMetadataItem.nameSingular,
)}Edge`,
});
}
}
}
}
},
);
return newRecordPaginatedCacheField;
},