Fix relation from many notes (#11120)

Fixes https://github.com/twentyhq/twenty/issues/3415
This commit is contained in:
Charles Bochet
2025-03-24 15:19:05 +01:00
committed by GitHub
parent e83e7b3b40
commit 6898a40ac3
17 changed files with 269 additions and 279 deletions

View File

@ -6,7 +6,7 @@ import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTa
import { useOpenActivityTargetInlineCellEditMode } from '@/activities/inline-cell/hooks/useOpenActivityTargetInlineCellEditMode';
import { useUpdateActivityTargetFromInlineCell } from '@/activities/inline-cell/hooks/useUpdateActivityTargetFromInlineCell';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
import { FieldContextProvider } from '@/object-record/record-field/components/FieldContextProvider';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { FieldFocusContextProvider } from '@/object-record/record-field/contexts/FieldFocusContextProvider';
import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly';
@ -43,15 +43,6 @@ export const ActivityTargetsInlineCell = ({
const isFieldReadOnly = useIsFieldValueReadOnly();
const { FieldContextProvider: ActivityTargetsContextProvider } =
useFieldContext({
objectNameSingular: activityObjectNameSingular,
objectRecordId: activityRecordId,
fieldMetadataName: fieldDefinition.metadata.fieldName,
fieldPosition: 3,
overridenIsFieldEmpty: activityTargetObjectRecords.length === 0,
});
const { openActivityTargetInlineCellEditMode } =
useOpenActivityTargetInlineCellEditMode();
@ -68,55 +59,59 @@ export const ActivityTargetsInlineCell = ({
}}
>
<FieldFocusContextProvider>
{ActivityTargetsContextProvider && (
<ActivityTargetsContextProvider>
<RecordInlineCellContext.Provider
value={{
buttonIcon: IconPencil,
customEditHotkeyScope:
MultipleRecordPickerHotkeyScope.MultipleRecordPicker,
IconLabel: showLabel ? IconArrowUpRight : undefined,
showLabel: showLabel,
readonly: isFieldReadOnly,
labelWidth: fieldDefinition?.labelWidth,
editModeContent: (
<MultipleRecordPicker
componentInstanceId={componentInstanceId}
onClickOutside={() => {
closeInlineCell();
}}
onChange={(morphItem) => {
updateActivityTargetFromInlineCell({
recordPickerInstanceId: componentInstanceId,
morphItem,
activityTargetWithTargetRecords:
activityTargetObjectRecords,
});
}}
onSubmit={() => {
closeInlineCell();
}}
/>
),
label: 'Relations',
displayModeContent: (
<ActivityTargetChips
activityTargetObjectRecords={activityTargetObjectRecords}
maxWidth={maxWidth}
/>
),
onOpenEditMode: () => {
openActivityTargetInlineCellEditMode({
recordPickerInstanceId: componentInstanceId,
activityTargetObjectRecords,
});
},
}}
>
<RecordInlineCellContainer />
</RecordInlineCellContext.Provider>
</ActivityTargetsContextProvider>
)}
<FieldContextProvider
objectNameSingular={activityObjectNameSingular}
objectRecordId={activityRecordId}
fieldMetadataName={fieldDefinition.metadata.fieldName}
fieldPosition={3}
overridenIsFieldEmpty={activityTargetObjectRecords.length === 0}
>
<RecordInlineCellContext.Provider
value={{
buttonIcon: IconPencil,
customEditHotkeyScope:
MultipleRecordPickerHotkeyScope.MultipleRecordPicker,
IconLabel: showLabel ? IconArrowUpRight : undefined,
showLabel: showLabel,
readonly: isFieldReadOnly,
labelWidth: fieldDefinition?.labelWidth,
editModeContent: (
<MultipleRecordPicker
componentInstanceId={componentInstanceId}
onClickOutside={() => {
closeInlineCell();
}}
onChange={(morphItem) => {
updateActivityTargetFromInlineCell({
recordPickerInstanceId: componentInstanceId,
morphItem,
activityTargetWithTargetRecords:
activityTargetObjectRecords,
});
}}
onSubmit={() => {
closeInlineCell();
}}
/>
),
label: 'Relations',
displayModeContent: (
<ActivityTargetChips
activityTargetObjectRecords={activityTargetObjectRecords}
maxWidth={maxWidth}
/>
),
onOpenEditMode: () => {
openActivityTargetInlineCellEditMode({
recordPickerInstanceId: componentInstanceId,
activityTargetObjectRecords,
});
},
}}
>
<RecordInlineCellContainer />
</RecordInlineCellContext.Provider>
</FieldContextProvider>
</FieldFocusContextProvider>
</RecordFieldComponentInstanceContext.Provider>
);

View File

@ -5,7 +5,7 @@ import { Note } from '@/activities/types/Note';
import { getActivityPreview } from '@/activities/utils/getActivityPreview';
import { useOpenRecordInCommandMenu } from '@/command-menu/hooks/useOpenRecordInCommandMenu';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
import { FieldContextProvider } from '@/object-record/record-field/components/FieldContextProvider';
const StyledCard = styled.div<{ isSingleNote: boolean }>`
align-items: flex-start;
@ -72,13 +72,6 @@ export const NoteCard = ({
const body = getActivityPreview(note?.bodyV2?.blocknote ?? null);
const { FieldContextProvider: NoteTargetsContextProvider } = useFieldContext({
objectNameSingular: CoreObjectNameSingular.Note,
objectRecordId: note.id,
fieldMetadataName: 'noteTargets',
fieldPosition: 0,
});
return (
<StyledCard isSingleNote={isSingleNote}>
<StyledCardDetailsContainer
@ -93,15 +86,18 @@ export const NoteCard = ({
<StyledCardContent>{body}</StyledCardContent>
</StyledCardDetailsContainer>
<StyledFooter>
{NoteTargetsContextProvider && (
<NoteTargetsContextProvider>
<ActivityTargetsInlineCell
componentInstanceId={`note-card-${note.id}-targets`}
activityRecordId={note.id}
activityObjectNameSingular={CoreObjectNameSingular.Note}
/>
</NoteTargetsContextProvider>
)}
<FieldContextProvider
objectNameSingular={CoreObjectNameSingular.Note}
objectRecordId={note.id}
fieldMetadataName={'noteTargets'}
fieldPosition={0}
>
<ActivityTargetsInlineCell
componentInstanceId={`note-card-${note.id}-targets`}
activityRecordId={note.id}
activityObjectNameSingular={CoreObjectNameSingular.Note}
/>
</FieldContextProvider>
</StyledFooter>
</StyledCard>
);

View File

@ -15,7 +15,7 @@ import { ActivityRow } from '@/activities/components/ActivityRow';
import { Task } from '@/activities/types/Task';
import { useOpenRecordInCommandMenu } from '@/command-menu/hooks/useOpenRecordInCommandMenu';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
import { FieldContextProvider } from '@/object-record/record-field/components/FieldContextProvider';
import { useCompleteTask } from '../hooks/useCompleteTask';
const StyledTaskBody = styled.div`
@ -84,13 +84,6 @@ export const TaskRow = ({ task }: { task: Task }) => {
const { completeTask } = useCompleteTask(task);
const { FieldContextProvider: TaskTargetsContextProvider } = useFieldContext({
objectNameSingular: CoreObjectNameSingular.Task,
objectRecordId: task.id,
fieldMetadataName: 'taskTargets',
fieldPosition: 0,
});
return (
<ActivityRow
onClick={() => {
@ -128,8 +121,13 @@ export const TaskRow = ({ task }: { task: Task }) => {
{beautifyExactDate(task.dueAt)}
</StyledDueDate>
)}
{TaskTargetsContextProvider && (
<TaskTargetsContextProvider>
{
<FieldContextProvider
objectNameSingular={CoreObjectNameSingular.Task}
objectRecordId={task.id}
fieldMetadataName={'taskTargets'}
fieldPosition={0}
>
<ActivityTargetsInlineCell
activityObjectNameSingular={CoreObjectNameSingular.Task}
activityRecordId={task.id}
@ -137,8 +135,8 @@ export const TaskRow = ({ task }: { task: Task }) => {
maxWidth={200}
componentInstanceId={`task-row-targets-${task.id}`}
/>
</TaskTargetsContextProvider>
)}
</FieldContextProvider>
}
</StyledRightSideContainer>
</ActivityRow>
);