Refactor Views by cleaning the code, relying on apolloCache and improving performances (#4516)

* Wip refactoring view

* Post merge conflicts

* Fix review

* Add create view capability

* Fix create object missing view

* Fix tests
This commit is contained in:
Charles Bochet
2024-03-20 14:21:58 +01:00
committed by GitHub
parent 20e14cb455
commit cfb0cce9b8
392 changed files with 3474 additions and 4410 deletions

View File

@ -26,127 +26,129 @@ export const triggerUpdateRelationsOptimisticEffect = ({
currentSourceRecord: CachedObjectRecord | null;
updatedSourceRecord: CachedObjectRecord | null;
objectMetadataItems: ObjectMetadataItem[];
}) =>
sourceObjectMetadataItem.fields.forEach((fieldMetadataItemOnSourceRecord) => {
const notARelationField =
fieldMetadataItemOnSourceRecord.type !== FieldMetadataType.Relation;
}) => {
return sourceObjectMetadataItem.fields.forEach(
(fieldMetadataItemOnSourceRecord) => {
const notARelationField =
fieldMetadataItemOnSourceRecord.type !== FieldMetadataType.Relation;
if (notARelationField) {
return;
}
if (notARelationField) {
return;
}
const fieldDoesNotExist =
isDefined(updatedSourceRecord) &&
!(fieldMetadataItemOnSourceRecord.name in updatedSourceRecord);
const fieldDoesNotExist =
isDefined(updatedSourceRecord) &&
!(fieldMetadataItemOnSourceRecord.name in updatedSourceRecord);
if (fieldDoesNotExist) {
return;
}
if (fieldDoesNotExist) {
return;
}
const relationDefinition = getRelationDefinition({
fieldMetadataItemOnSourceRecord,
objectMetadataItems,
});
const relationDefinition = getRelationDefinition({
fieldMetadataItemOnSourceRecord,
objectMetadataItems,
});
if (!relationDefinition) {
return;
}
if (!relationDefinition) {
return;
}
const { targetObjectMetadataItem, fieldMetadataItemOnTargetRecord } =
relationDefinition;
const { targetObjectMetadataItem, fieldMetadataItemOnTargetRecord } =
relationDefinition;
const currentFieldValueOnSourceRecord:
| ObjectRecordConnection
| CachedObjectRecord
| null = currentSourceRecord?.[fieldMetadataItemOnSourceRecord.name];
const currentFieldValueOnSourceRecord:
| ObjectRecordConnection
| CachedObjectRecord
| null = currentSourceRecord?.[fieldMetadataItemOnSourceRecord.name];
const updatedFieldValueOnSourceRecord:
| ObjectRecordConnection
| CachedObjectRecord
| null = updatedSourceRecord?.[fieldMetadataItemOnSourceRecord.name];
const updatedFieldValueOnSourceRecord:
| ObjectRecordConnection
| CachedObjectRecord
| null = updatedSourceRecord?.[fieldMetadataItemOnSourceRecord.name];
if (
isDeeplyEqual(
currentFieldValueOnSourceRecord,
updatedFieldValueOnSourceRecord,
)
) {
return;
}
if (
isDeeplyEqual(
currentFieldValueOnSourceRecord,
updatedFieldValueOnSourceRecord,
)
) {
return;
}
// TODO: replace this by a relation type check, if it's one to many,
// it's an object record connection (we can still check it though as a safeguard)
const currentFieldValueOnSourceRecordIsARecordConnection =
isObjectRecordConnection(
targetObjectMetadataItem.nameSingular,
currentFieldValueOnSourceRecord,
);
const targetRecordsToDetachFrom =
currentFieldValueOnSourceRecordIsARecordConnection
? currentFieldValueOnSourceRecord.edges.map(
({ node }) => node as CachedObjectRecord,
)
: [currentFieldValueOnSourceRecord].filter(isDefined);
const updatedFieldValueOnSourceRecordIsARecordConnection =
isObjectRecordConnection(
targetObjectMetadataItem.nameSingular,
updatedFieldValueOnSourceRecord,
);
const targetRecordsToAttachTo =
updatedFieldValueOnSourceRecordIsARecordConnection
? updatedFieldValueOnSourceRecord.edges.map(
({ node }) => node as CachedObjectRecord,
)
: [updatedFieldValueOnSourceRecord].filter(isDefined);
const shouldDetachSourceFromAllTargets =
isDefined(currentSourceRecord) && targetRecordsToDetachFrom.length > 0;
if (shouldDetachSourceFromAllTargets) {
// TODO: see if we can de-hardcode this, put cascade delete in relation metadata item
// Instead of hardcoding it here
const shouldCascadeDeleteTargetRecords =
CORE_OBJECT_NAMES_TO_DELETE_ON_TRIGGER_RELATION_DETACH.includes(
targetObjectMetadataItem.nameSingular as CoreObjectNameSingular,
// TODO: replace this by a relation type check, if it's one to many,
// it's an object record connection (we can still check it though as a safeguard)
const currentFieldValueOnSourceRecordIsARecordConnection =
isObjectRecordConnection(
targetObjectMetadataItem.nameSingular,
currentFieldValueOnSourceRecord,
);
if (shouldCascadeDeleteTargetRecords) {
triggerDeleteRecordsOptimisticEffect({
cache,
objectMetadataItem: targetObjectMetadataItem,
recordsToDelete: targetRecordsToDetachFrom,
objectMetadataItems,
});
} else {
targetRecordsToDetachFrom.forEach((targetRecordToDetachFrom) => {
triggerDetachRelationOptimisticEffect({
const targetRecordsToDetachFrom =
currentFieldValueOnSourceRecordIsARecordConnection
? currentFieldValueOnSourceRecord.edges.map(
({ node }) => node as CachedObjectRecord,
)
: [currentFieldValueOnSourceRecord].filter(isDefined);
const updatedFieldValueOnSourceRecordIsARecordConnection =
isObjectRecordConnection(
targetObjectMetadataItem.nameSingular,
updatedFieldValueOnSourceRecord,
);
const targetRecordsToAttachTo =
updatedFieldValueOnSourceRecordIsARecordConnection
? updatedFieldValueOnSourceRecord.edges.map(
({ node }) => node as CachedObjectRecord,
)
: [updatedFieldValueOnSourceRecord].filter(isDefined);
const shouldDetachSourceFromAllTargets =
isDefined(currentSourceRecord) && targetRecordsToDetachFrom.length > 0;
if (shouldDetachSourceFromAllTargets) {
// TODO: see if we can de-hardcode this, put cascade delete in relation metadata item
// Instead of hardcoding it here
const shouldCascadeDeleteTargetRecords =
CORE_OBJECT_NAMES_TO_DELETE_ON_TRIGGER_RELATION_DETACH.includes(
targetObjectMetadataItem.nameSingular as CoreObjectNameSingular,
);
if (shouldCascadeDeleteTargetRecords) {
triggerDeleteRecordsOptimisticEffect({
cache,
objectMetadataItem: targetObjectMetadataItem,
recordsToDelete: targetRecordsToDetachFrom,
objectMetadataItems,
});
} else {
targetRecordsToDetachFrom.forEach((targetRecordToDetachFrom) => {
triggerDetachRelationOptimisticEffect({
cache,
sourceObjectNameSingular: sourceObjectMetadataItem.nameSingular,
sourceRecordId: currentSourceRecord.id,
fieldNameOnTargetRecord: fieldMetadataItemOnTargetRecord.name,
targetObjectNameSingular: targetObjectMetadataItem.nameSingular,
targetRecordId: targetRecordToDetachFrom.id,
});
});
}
}
const shouldAttachSourceToAllTargets =
isDefined(updatedSourceRecord) && targetRecordsToAttachTo.length > 0;
if (shouldAttachSourceToAllTargets) {
targetRecordsToAttachTo.forEach((targetRecordToAttachTo) =>
triggerAttachRelationOptimisticEffect({
cache,
sourceObjectNameSingular: sourceObjectMetadataItem.nameSingular,
sourceRecordId: currentSourceRecord.id,
sourceRecordId: updatedSourceRecord.id,
fieldNameOnTargetRecord: fieldMetadataItemOnTargetRecord.name,
targetObjectNameSingular: targetObjectMetadataItem.nameSingular,
targetRecordId: targetRecordToDetachFrom.id,
});
});
targetRecordId: targetRecordToAttachTo.id,
}),
);
}
}
const shouldAttachSourceToAllTargets =
isDefined(updatedSourceRecord) && targetRecordsToAttachTo.length > 0;
if (shouldAttachSourceToAllTargets) {
targetRecordsToAttachTo.forEach((targetRecordToAttachTo) =>
triggerAttachRelationOptimisticEffect({
cache,
sourceObjectNameSingular: sourceObjectMetadataItem.nameSingular,
sourceRecordId: updatedSourceRecord.id,
fieldNameOnTargetRecord: fieldMetadataItemOnTargetRecord.name,
targetObjectNameSingular: targetObjectMetadataItem.nameSingular,
targetRecordId: targetRecordToAttachTo.id,
}),
);
}
});
},
);
};