diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/RelationToOneFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/RelationToOneFieldDisplay.tsx index ee6d5c7df3..3dd320c683 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/RelationToOneFieldDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/RelationToOneFieldDisplay.tsx @@ -1,16 +1,25 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { RecordChip } from '@/object-record/components/RecordChip'; import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; +import { ForbiddenFieldDisplay } from '@/object-record/record-field/ui/meta-types/display/components/ForbiddenFieldDisplay'; import { useRelationToOneFieldDisplay } from '@/object-record/record-field/ui/meta-types/hooks/useRelationToOneFieldDisplay'; import { useContext } from 'react'; import { isDefined } from 'twenty-shared/utils'; export const RelationToOneFieldDisplay = () => { - const { fieldValue, fieldDefinition, generateRecordChipData } = - useRelationToOneFieldDisplay(); + const { + fieldValue, + fieldDefinition, + generateRecordChipData, + foreignKeyFieldValue, + } = useRelationToOneFieldDisplay(); const { disableChipClick, triggerEvent } = useContext(FieldContext); + if (!isDefined(fieldValue) && isDefined(foreignKeyFieldValue)) { + return ; + } + if ( !isDefined(fieldValue) || !isDefined(fieldDefinition?.metadata.relationObjectMetadataNameSingular) diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRelationToOneFieldDisplay.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRelationToOneFieldDisplay.ts index 257ea7ce07..7956827c0d 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRelationToOneFieldDisplay.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useRelationToOneFieldDisplay.ts @@ -11,6 +11,7 @@ import { generateDefaultRecordChipData } from '@/object-metadata/utils/generateD import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext'; import { assertFieldMetadata } from '@/object-record/record-field/ui/types/guards/assertFieldMetadata'; import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation'; +import { getJoinColumnNameOrThrow } from '@/object-record/record-field/ui/utils/junction/getJoinColumnNameOrThrow'; import { useRecordFieldValue } from '@/object-record/record-store/hooks/useRecordFieldValue'; import { isDefined } from 'twenty-shared/utils'; @@ -41,6 +42,16 @@ export const useRelationToOneFieldDisplay = () => { fieldDefinition, ); + const joinColumnName = getJoinColumnNameOrThrow( + fieldDefinition.metadata.settings, + ); + + const foreignKeyFieldValue = useRecordFieldValue( + recordId, + joinColumnName, + { type: FieldMetadataType.UUID, metadata: { fieldName: joinColumnName } }, + ); + const maxWidthForField = isDefined(button) && isDefined(maxWidth) ? maxWidth - FIELD_EDIT_BUTTON_WIDTH @@ -69,6 +80,7 @@ export const useRelationToOneFieldDisplay = () => { return { fieldDefinition, fieldValue, + foreignKeyFieldValue, maxWidth: maxWidthForField, recordId, generateRecordChipData, diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/utils/junction/getJoinColumnNameOrThrow.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/utils/junction/getJoinColumnNameOrThrow.ts new file mode 100644 index 0000000000..4326a3e4bd --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/utils/junction/getJoinColumnNameOrThrow.ts @@ -0,0 +1,13 @@ +import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; +import { getJoinColumnName } from '@/object-record/record-field/ui/utils/junction/getJoinColumnName'; +import { isDefined } from 'twenty-shared/utils'; + +export const getJoinColumnNameOrThrow = ( + settings: FieldMetadataItem['settings'], +): string => { + const joinColumnName = getJoinColumnName(settings); + if (!isDefined(joinColumnName)) { + throw new Error('Join column name is not defined'); + } + return joinColumnName; +}; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationFormCard.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationFormCard.tsx index a7bff24f2c..15444f68e5 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationFormCard.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/morph-relation/components/SettingsDataModelFieldRelationFormCard.tsx @@ -84,6 +84,7 @@ export const SettingsDataModelFieldRelationFormCard = ({ type: FieldMetadataType.RELATION, settings: { relationType, + joinColumnName: 'previewJoinColumnId', }, }} shrink @@ -107,6 +108,7 @@ export const SettingsDataModelFieldRelationFormCard = ({ type: FieldMetadataType.RELATION, settings: { relationType: oppositeRelationType, + joinColumnName: 'previewJoinColumnId', }, }} shrink diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper.ts index 80601fc367..62a96925cf 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper.ts @@ -417,9 +417,6 @@ export class ProcessNestedRelationsV2Helper { (rel) => rel[joinField] === item.id, ); } else { - if (relationResults.length === 0) { - item[`${sourceFieldName}Id`] = null; - } item[sourceFieldName] = relationResults.find( (rel) => rel.id === item[`${sourceFieldName}Id`],