Fix note/task target creation to support morph relations (#17734)

## Overview
Fixes the `unknown fields opportunityId in objectMetadataItem
noteTarget` error when creating notes/tasks from record pages (like the
Notes/Tasks tab on an opportunity).

## Root Cause
The `useOpenCreateActivityDrawer` hook was not handling `MORPH_RELATION`
field types:

1. Code only checked `field.relation` (which is populated for `RELATION`
type fields)
2. When `field.relation` was undefined (because the field is
`MORPH_RELATION`), it fell back to the old naming convention (e.g.,
`opportunityId`)
3. But after the morph migration, the columns are named differently
(e.g., `targetOpportunityId`)

This caused the error on both new workspaces (which are created with
morph relations from the start) and existing workspaces that ran the
migration.

## Solution
Use the existing `findTargetFieldInfo()` utility which properly handles
both `RELATION` and `MORPH_RELATION` field types by:
- Checking `morphRelations` for morph fields and computing the correct
field name
- Checking `relation` for regular relation fields
- Returning the correct `joinColumnName` for each case

This utility is already used elsewhere in the codebase (e.g., in
junction field handling) and is the cleanest solution.
This commit is contained in:
Félix Malfait
2026-02-05 12:52:23 +01:00
committed by GitHub
parent 9604dbe78a
commit 6851085143
@@ -15,7 +15,7 @@ import { type TaskTarget } from '@/activities/types/TaskTarget';
import { useOpenRecordInCommandMenu } from '@/command-menu/hooks/useOpenRecordInCommandMenu';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { isDefined } from 'twenty-shared/utils';
import { findTargetFieldInfo } from '@/object-record/record-field/ui/utils/junction/findTargetFieldInfo';
export const useOpenCreateActivityDrawer = ({
activityObjectNameSingular,
@@ -90,17 +90,15 @@ export const useOpenCreateActivityDrawer = ({
item.nameSingular === targetableObjects[0].targetObjectNameSingular,
);
const targetField = activityTargetObjectMetadata?.fields.find(
(field) =>
field.relation?.targetObjectMetadata.id ===
targetObjectMetadataItem?.id,
const targetFieldInfo = findTargetFieldInfo(
activityTargetObjectMetadata?.fields ?? [],
targetObjectMetadataItem?.id ?? '',
objectMetadataItems,
);
const joinColumnName = targetField?.settings?.joinColumnName;
const targetableObjectRelationIdName = isDefined(joinColumnName)
? joinColumnName
: `${targetableObjects[0].targetObjectNameSingular}Id`;
const targetableObjectRelationIdName =
targetFieldInfo?.joinColumnName ??
`${targetableObjects[0].targetObjectNameSingular}Id`;
await createOneActivityTarget({
...(activityObjectNameSingular === CoreObjectNameSingular.Task