Optimistic follow up (#15071)

Fixing optimistic rendering for the morph relation
This commit is contained in:
Guillim
2025-10-16 12:17:21 +02:00
committed by GitHub
parent d7e3208262
commit da77cd0cdc
7 changed files with 164 additions and 154 deletions
@@ -1,10 +1,9 @@
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getFieldMetadataItemById } from '@/object-metadata/utils/getFieldMetadataItemById';
import { type FieldMorphRelationMetadata } from '@/object-record/record-field/ui/types/FieldMetadata';
import { computeMorphRelationFieldName } from 'twenty-shared/utils';
export const getFieldMetadataMorphRelationFromGqlField = ({
export const getMorphRelationFromFieldMetadataAndGqlField = ({
objectMetadataItems,
fieldMetadata,
gqlField,
@@ -50,25 +49,10 @@ export const getFieldMetadataMorphRelationFromGqlField = ({
return {
morphRelation: gqlFieldMorphRelation.morphRelation,
sourceFieldMetadata: getFieldMetadataItemById({
fieldMetadataId:
gqlFieldMorphRelation.morphRelation.sourceFieldMetadata.id,
objectMetadataItems,
}),
targetFieldMetadata: getFieldMetadataItemById({
fieldMetadataId:
gqlFieldMorphRelation.morphRelation?.targetFieldMetadata.id,
objectMetadataItems,
}),
targetObjectMetadata: objectMetadataItems.find(
(objectMetadataItem) =>
objectMetadataItem.id ===
gqlFieldMorphRelation.morphRelation?.targetObjectMetadata.id,
),
sourceObjectMetadata: objectMetadataItems.find(
(objectMetadataItem) =>
objectMetadataItem.id ===
gqlFieldMorphRelation.morphRelation?.sourceObjectMetadata.id,
gqlFieldMorphRelation.morphRelation.targetObjectMetadata.id,
),
};
};
@@ -1,7 +1,9 @@
import { isNull, isUndefined } from '@sniptt/guards';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { computePossibleMorphGqlFieldForFieldName } from '@/object-record/cache/utils/computePossibleMorphGqlFieldForFieldName';
import { getFieldMetadataFromGqlField } from '@/object-record/cache/utils/getFieldMetadataFromGqlField';
import { getMorphRelationFromFieldMetadataAndGqlField } from '@/object-record/cache/utils/getMorphRelationFromFieldMetadataAndGqlField';
import { getNodeTypename } from '@/object-record/cache/utils/getNodeTypename';
import { getObjectTypename } from '@/object-record/cache/utils/getObjectTypename';
import { getRecordConnectionFromRecords } from '@/object-record/cache/utils/getRecordConnectionFromRecords';
@@ -44,14 +46,14 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
const nestedRecord = Object.fromEntries(
Object.entries(record)
.map(([fieldName, value]) => {
if (isDefined(recordGqlFields) && !recordGqlFields[fieldName]) {
.map(([gqlField, value]) => {
if (isDefined(recordGqlFields) && !recordGqlFields[gqlField]) {
return undefined;
}
const field = getFieldMetadataFromGqlField({
objectMetadataItem,
gqlField: fieldName,
gqlField: gqlField,
});
if (isUndefined(field)) {
@@ -73,16 +75,56 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
}
return [
fieldName,
gqlField,
getRecordConnectionFromRecords({
objectMetadataItems,
objectMetadataItem: oneToManyObjectMetadataItem,
records: value as ObjectRecord[],
recordGqlFields:
recordGqlFields?.[fieldName] === true ||
isUndefined(recordGqlFields?.[fieldName])
recordGqlFields?.[gqlField] === true ||
isUndefined(recordGqlFields?.[gqlField])
? undefined
: recordGqlFields?.[fieldName],
: recordGqlFields?.[gqlField],
withPageInfo: false,
isRootLevel: false,
computeReferences,
}),
];
}
if (
field.type === FieldMetadataType.MORPH_RELATION &&
field.settings?.relationType === RelationType.ONE_TO_MANY
) {
if (field.morphRelations?.length === 0) {
return undefined;
}
const morphRelation = getMorphRelationFromFieldMetadataAndGqlField({
objectMetadataItems,
fieldMetadata: { morphRelations: field.morphRelations ?? [] },
gqlField: gqlField,
});
if (isUndefined(morphRelation?.targetObjectMetadata?.nameSingular)) {
return undefined;
}
if (!morphRelation?.targetObjectMetadata?.nameSingular) {
return undefined;
}
return [
gqlField,
getRecordConnectionFromRecords({
objectMetadataItems,
objectMetadataItem: morphRelation?.targetObjectMetadata,
records: value as ObjectRecord[],
recordGqlFields:
recordGqlFields?.[gqlField] === true ||
isUndefined(recordGqlFields?.[gqlField])
? undefined
: recordGqlFields?.[gqlField],
withPageInfo: false,
isRootLevel: false,
computeReferences,
@@ -92,10 +134,9 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
switch (field.type) {
case FieldMetadataType.RELATION: {
const isJoinColumn = field.settings?.joinColumnName === fieldName;
const isJoinColumn = field.settings?.joinColumnName === gqlField;
if (isJoinColumn) {
return [fieldName, value];
return [gqlField, value];
}
if (
@@ -105,7 +146,7 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
}
if (isNull(value)) {
return [fieldName, null];
return [gqlField, null];
}
if (isUndefined(value?.id)) {
@@ -118,7 +159,7 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
if (computeReferences) {
return [
fieldName,
gqlField,
{
__ref: `${typeName}:${value.id}`,
},
@@ -126,7 +167,64 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
}
return [
fieldName,
gqlField,
{
__typename: typeName,
...value,
},
];
}
case FieldMetadataType.MORPH_RELATION: {
const possibleMorphRelationsJoinColumnNames =
computePossibleMorphGqlFieldForFieldName({
fieldMetadata: {
morphRelations: field.morphRelations ?? [],
fieldName: field.name,
},
}).map(
(possibleMorphRelationName) => `${possibleMorphRelationName}Id`,
);
const isJoinColumn =
possibleMorphRelationsJoinColumnNames.includes(gqlField);
if (isJoinColumn) {
return [gqlField, value];
}
if (field.morphRelations?.length === 0) {
return undefined;
}
const morphRelation = getMorphRelationFromFieldMetadataAndGqlField({
objectMetadataItems,
fieldMetadata: { morphRelations: field.morphRelations ?? [] },
gqlField: gqlField,
});
if (
isUndefined(morphRelation?.targetObjectMetadata?.nameSingular)
) {
return undefined;
}
const typeName = getObjectTypename(
morphRelation?.targetObjectMetadata?.nameSingular,
);
if (isNull(value)) {
return [gqlField, null];
}
if (isUndefined(value?.id)) {
return undefined;
}
if (computeReferences) {
return [gqlField, { __ref: `${typeName}:${value.id}` }];
}
return [
gqlField,
{
__typename: typeName,
...value,
@@ -138,7 +236,7 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
case FieldMetadataType.FULL_NAME:
case FieldMetadataType.CURRENCY: {
return [
fieldName,
gqlField,
{
...value,
__typename: pascalCase(field.type),
@@ -146,7 +244,7 @@ export const getRecordNodeFromRecord = <T extends ObjectRecord>({
];
}
default: {
return [fieldName, value];
return [gqlField, value];
}
}
})