Fixed critical bug with record title cell opening (#13355)

This PR fixes a critical bug on record title cell opening when there was
no view loaded before.

This happened because the hook that opens the record title cell was
relying on a state that stored field definitions that were computed only
when a view was loaded.

Since there is no view on a record page, this wasn't working.

We should refactor field / column definitions so that they are always
derived from either view fields or an object metadata item's field
metadata items.

Fixes https://github.com/twentyhq/twenty/issues/13347
This commit is contained in:
Lucas Bordeau
2025-07-22 17:48:03 +02:00
committed by GitHub
parent 4d2fcf33a3
commit dc617177a9

View File

@ -1,5 +1,6 @@
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
import { useInitDraftValueV2 } from '@/object-record/record-field/hooks/useInitDraftValueV2'; import { useInitDraftValueV2 } from '@/object-record/record-field/hooks/useInitDraftValueV2';
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
import { isInlineCellInEditModeScopedState } from '@/object-record/record-inline-cell/states/isInlineCellInEditModeScopedState'; import { isInlineCellInEditModeScopedState } from '@/object-record/record-inline-cell/states/isInlineCellInEditModeScopedState';
import { RecordTitleCellContainerType } from '@/object-record/record-title-cell/types/RecordTitleCellContainerType'; import { RecordTitleCellContainerType } from '@/object-record/record-title-cell/types/RecordTitleCellContainerType';
import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId'; import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId';
@ -17,6 +18,8 @@ export const useRecordTitleCell = () => {
const { removeFocusItemFromFocusStackById } = const { removeFocusItemFromFocusStackById } =
useRemoveFocusItemFromFocusStackById(); useRemoveFocusItemFromFocusStackById();
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
const closeRecordTitleCell = useRecoilCallback( const closeRecordTitleCell = useRecoilCallback(
({ set }) => ({ set }) =>
({ ({
@ -55,7 +58,7 @@ export const useRecordTitleCell = () => {
const initFieldInputDraftValue = useInitDraftValueV2(); const initFieldInputDraftValue = useInitDraftValueV2();
const openRecordTitleCell = useRecoilCallback( const openRecordTitleCell = useRecoilCallback(
({ set, snapshot }) => ({ set }) =>
({ ({
recordId, recordId,
fieldName, fieldName,
@ -92,16 +95,23 @@ export const useRecordTitleCell = () => {
}); });
set(isInlineCellInEditModeScopedState(recordTitleCellId), true); set(isInlineCellInEditModeScopedState(recordTitleCellId), true);
const recordIndexFieldDefinitions = snapshot const fieldDefinitions = objectMetadataItem.fields.map(
.getLoadable(recordIndexFieldDefinitionsState) (fieldMetadataItem, index) =>
.getValue(); formatFieldMetadataItemAsColumnDefinition({
field: fieldMetadataItem,
objectMetadataItem,
position: index,
}),
);
const fieldDefinition = recordIndexFieldDefinitions.find( const fieldDefinition = fieldDefinitions.find(
(field) => field.metadata.fieldName === fieldName, (field) => field.metadata.fieldName === fieldName,
); );
if (!fieldDefinition) { if (!fieldDefinition) {
return; throw new Error(
`Cannot find field definition for field name ${fieldName}, this should not happen.`,
);
} }
initFieldInputDraftValue({ initFieldInputDraftValue({
@ -110,7 +120,7 @@ export const useRecordTitleCell = () => {
fieldComponentInstanceId: recordTitleCellId, fieldComponentInstanceId: recordTitleCellId,
}); });
}, },
[initFieldInputDraftValue, pushFocusItemToFocusStack], [initFieldInputDraftValue, pushFocusItemToFocusStack, objectMetadataItem],
); );
return { return {