From 836e2f792c46baad53547f958dff63069160a67e Mon Sep 17 00:00:00 2001 From: Paul Rastoin <45004772+prastoin@users.noreply.github.com> Date: Fri, 13 Jun 2025 16:07:35 +0200 Subject: [PATCH] Remove selected record id on related relation record detach (#12591) # Introduction Verified for multi select record picker and it's already working Also works for both single and multi after record deletion Fixes https://github.com/twentyhq/twenty/issues/12544 --- .../RecordDetailRelationRecordsListItem.tsx | 33 +++++++++++++------ .../RecordDetailRelationSection.tsx | 6 +++- .../RecordDetailRelationSectionDropdown.tsx | 6 +++- ...RecordFieldCardRelationPickerDropdownId.ts | 12 +++++++ 4 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId.ts diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItem.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItem.tsx index da089fae3..504b9bd34 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItem.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListItem.tsx @@ -24,7 +24,9 @@ import { RecordFieldComponentInstanceContext } from '@/object-record/record-fiel import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; +import { singleRecordPickerSelectedIdComponentState } from '@/object-record/record-picker/single-record-picker/states/singleRecordPickerSelectedIdComponentState'; import { RecordDetailRecordsListItem } from '@/object-record/record-show/record-detail-section/components/RecordDetailRecordsListItem'; +import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { getForeignKeyNameFromRelationFieldName } from '@/object-record/utils/getForeignKeyNameFromRelationFieldName'; import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; @@ -36,6 +38,7 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal'; import { useModal } from '@/ui/layout/modal/hooks/useModal'; +import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; import { createPortal } from 'react-dom'; import { IconChevronDown, @@ -103,7 +106,7 @@ export const RecordDetailRelationRecordsListItem = ({ onClick, relationRecord, }: RecordDetailRelationRecordsListItemProps) => { - const { fieldDefinition } = useContext(FieldContext); + const { fieldDefinition, recordId } = useContext(FieldContext); const { openModal } = useModal(); @@ -156,6 +159,15 @@ export const RecordDetailRelationRecordsListItem = ({ const { closeDropdown, isDropdownOpen } = useDropdown(dropdownScopeId); + const dropdownId = getRecordFieldCardRelationPickerDropdownId({ + fieldDefinition, + recordId, + }); + const setSingleRecordPickerSelectedId = useSetRecoilComponentStateV2( + singleRecordPickerSelectedIdComponentState, + dropdownId, + ); + const handleDetach = () => { closeDropdown(); @@ -167,17 +179,18 @@ export const RecordDetailRelationRecordsListItem = ({ if (isToOneObject) { persistField(null); - return; + } else { + updateOneRelationRecord({ + idToUpdate: relationRecord.id, + updateOneRecordInput: { + [getForeignKeyNameFromRelationFieldName( + relationFieldMetadataItem.name, + )]: null, + }, + }); } - updateOneRelationRecord({ - idToUpdate: relationRecord.id, - updateOneRecordInput: { - [getForeignKeyNameFromRelationFieldName( - relationFieldMetadataItem.name, - )]: null, - }, - }); + setSingleRecordPickerSelectedId(undefined); }; const handleDelete = async () => { diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx index a7aa8ed5d..07c345dad 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx @@ -12,6 +12,7 @@ import { RecordDetailRelationRecordsList } from '@/object-record/record-show/rec import { RecordDetailRelationSectionDropdown } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdown'; import { RecordDetailSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailSection'; import { RecordDetailSectionHeader } from '@/object-record/record-show/record-detail-section/components/RecordDetailSectionHeader'; +import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId'; import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector'; import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; @@ -65,7 +66,10 @@ export const RecordDetailRelationSection = ({ ? [fieldValue as ObjectRecord] : ((fieldValue as ObjectRecord[]) ?? []); - const dropdownId = `record-field-card-relation-picker-${fieldDefinition.fieldMetadataId}-${recordId}`; + const dropdownId = getRecordFieldCardRelationPickerDropdownId({ + fieldDefinition, + recordId, + }); const { isDropdownOpen } = useDropdown(dropdownId); diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdown.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdown.tsx index 9f23d7503..3ce2669ff 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdown.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdown.tsx @@ -19,6 +19,7 @@ import { SingleRecordPicker } from '@/object-record/record-picker/single-record- import { singleRecordPickerSearchFilterComponentState } from '@/object-record/record-picker/single-record-picker/states/singleRecordPickerSearchFilterComponentState'; import { singleRecordPickerSelectedIdComponentState } from '@/object-record/record-picker/single-record-picker/states/singleRecordPickerSelectedIdComponentState'; import { SingleRecordPickerRecord } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerRecord'; +import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; @@ -69,7 +70,10 @@ export const RecordDetailRelationSectionDropdown = ({ ? [fieldValue as ObjectRecord] : ((fieldValue as ObjectRecord[]) ?? []); - const dropdownId = `record-field-card-relation-picker-${fieldDefinition.fieldMetadataId}-${recordId}`; + const dropdownId = getRecordFieldCardRelationPickerDropdownId({ + fieldDefinition, + recordId, + }); const { closeDropdown, dropdownPlacement } = useDropdown(dropdownId); diff --git a/packages/twenty-front/src/modules/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId.ts b/packages/twenty-front/src/modules/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId.ts new file mode 100644 index 000000000..e9d14148d --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId.ts @@ -0,0 +1,12 @@ +import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition'; +import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; + +type GetRecordFieldCardRelationPickerDropdownIdArgs = { + fieldDefinition: FieldDefinition; + recordId: string; +}; +export const getRecordFieldCardRelationPickerDropdownId = ({ + fieldDefinition, + recordId, +}: GetRecordFieldCardRelationPickerDropdownIdArgs) => + `record-field-card-relation-picker-${fieldDefinition.fieldMetadataId}-${recordId}`;