diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx index c2f69cb70..3623fd12f 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx @@ -17,6 +17,7 @@ import { FieldContext } from '@/object-record/record-field/contexts/FieldContext import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { mapArrayToObject } from '~/utils/array/mapArrayToObject'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; @@ -102,7 +103,6 @@ export const CalendarEventDetails = ({ value={{ recordId: calendarEvent.id, hotkeyScope: 'calendar-event-details', - recoilScopeId: `${calendarEvent.id}-${fieldName}`, isLabelIdentifier: false, fieldDefinition: formatFieldMetadataItemAsFieldDefinition({ field: fieldsByName[fieldName], @@ -116,7 +116,7 @@ export const CalendarEventDetails = ({ > diff --git a/packages/twenty-front/src/modules/activities/files/components/AttachmentRow.tsx b/packages/twenty-front/src/modules/activities/files/components/AttachmentRow.tsx index 404cb9403..f3a41a905 100644 --- a/packages/twenty-front/src/modules/activities/files/components/AttachmentRow.tsx +++ b/packages/twenty-front/src/modules/activities/files/components/AttachmentRow.tsx @@ -14,7 +14,7 @@ import { import { TextInput } from '@/ui/input/components/TextInput'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { useMemo, useState } from 'react'; +import { useState } from 'react'; import { isDefined } from 'twenty-shared'; import { IconCalendar, @@ -94,11 +94,6 @@ export const AttachmentRow = ({ const [attachmentFileName, setAttachmentFileName] = useState(originalFileName); - const fieldContext = useMemo( - () => ({ recoilScopeId: attachment?.id ?? '' }), - [attachment?.id], - ); - const { destroyOneRecord: destroyOneAttachment } = useDestroyOneRecord({ objectNameSingular: CoreObjectNameSingular.Attachment, }); @@ -161,7 +156,13 @@ export const AttachmentRow = ({ }; return ( - + diff --git a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx index 3447326e8..28568bb64 100644 --- a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx +++ b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx @@ -1,23 +1,21 @@ import { useContext } from 'react'; -import { Key } from 'ts-key-enum'; import { IconArrowUpRight, IconPencil } from 'twenty-ui'; import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips'; import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords'; import { useOpenActivityTargetInlineCellEditMode } from '@/activities/inline-cell/hooks/useOpenActivityTargetInlineCellEditMode'; import { useUpdateActivityTargetFromInlineCell } from '@/activities/inline-cell/hooks/useUpdateActivityTargetFromInlineCell'; -import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useFieldContext } from '@/object-record/hooks/useFieldContext'; 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'; -import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; import { RecordInlineCellContainer } from '@/object-record/record-inline-cell/components/RecordInlineCellContainer'; import { RecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext'; import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell'; import { MultipleRecordPicker } from '@/object-record/record-picker/multiple-record-picker/components/MultipleRecordPicker'; -import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; +import { MultipleRecordPickerHotkeyScope } from '@/object-record/record-picker/multiple-record-picker/types/MultipleRecordPickerHotkeyScope'; type ActivityTargetsInlineCellProps = { activityRecordId: string; @@ -26,6 +24,7 @@ type ActivityTargetsInlineCellProps = { activityObjectNameSingular: | CoreObjectNameSingular.Note | CoreObjectNameSingular.Task; + componentInstanceId: string; }; export const ActivityTargetsInlineCell = ({ @@ -33,26 +32,17 @@ export const ActivityTargetsInlineCell = ({ showLabel = true, maxWidth, activityObjectNameSingular, + componentInstanceId, }: ActivityTargetsInlineCellProps) => { const { activityTargetObjectRecords } = useActivityTargetObjectRecords(activityRecordId); - const multipleRecordPickerInstanceId = `multiple-record-picker-target-${activityRecordId}`; - - const { closeInlineCell } = useInlineCell(); + const { closeInlineCell } = useInlineCell(componentInstanceId); const { fieldDefinition } = useContext(FieldContext); const isFieldReadOnly = useIsFieldValueReadOnly(); - useScopedHotkeys( - Key.Escape, - () => { - closeInlineCell(); - }, - ActivityEditorHotkeyScope.ActivityTargets, - ); - const { FieldContextProvider: ActivityTargetsContextProvider } = useFieldContext({ objectNameSingular: activityObjectNameSingular, @@ -72,7 +62,11 @@ export const ActivityTargetsInlineCell = ({ }); return ( - + {ActivityTargetsContextProvider && ( @@ -80,20 +74,20 @@ export const ActivityTargetsInlineCell = ({ value={{ buttonIcon: IconPencil, customEditHotkeyScope: - ActivityEditorHotkeyScope.ActivityTargets, + MultipleRecordPickerHotkeyScope.MultipleRecordPicker, IconLabel: showLabel ? IconArrowUpRight : undefined, showLabel: showLabel, readonly: isFieldReadOnly, labelWidth: fieldDefinition?.labelWidth, editModeContent: ( { closeInlineCell(); }} onChange={(morphItem) => { updateActivityTargetFromInlineCell({ - recordPickerInstanceId: multipleRecordPickerInstanceId, + recordPickerInstanceId: componentInstanceId, morphItem, activityTargetWithTargetRecords: activityTargetObjectRecords, @@ -113,7 +107,7 @@ export const ActivityTargetsInlineCell = ({ ), onOpenEditMode: () => { openActivityTargetInlineCellEditMode({ - recordPickerInstanceId: multipleRecordPickerInstanceId, + recordPickerInstanceId: componentInstanceId, activityTargetObjectRecords, }); }, @@ -124,6 +118,6 @@ export const ActivityTargetsInlineCell = ({ )} - + ); }; diff --git a/packages/twenty-front/src/modules/activities/notes/components/NoteCard.tsx b/packages/twenty-front/src/modules/activities/notes/components/NoteCard.tsx index 99abf357a..9689a8a11 100644 --- a/packages/twenty-front/src/modules/activities/notes/components/NoteCard.tsx +++ b/packages/twenty-front/src/modules/activities/notes/components/NoteCard.tsx @@ -96,6 +96,7 @@ export const NoteCard = ({ {NoteTargetsContextProvider && ( diff --git a/packages/twenty-front/src/modules/activities/tasks/components/TaskRow.tsx b/packages/twenty-front/src/modules/activities/tasks/components/TaskRow.tsx index 2a62529b1..a4967862c 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/TaskRow.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/TaskRow.tsx @@ -135,6 +135,7 @@ export const TaskRow = ({ task }: { task: Task }) => { activityRecordId={task.id} showLabel={false} maxWidth={200} + componentInstanceId={`task-row-targets-${task.id}`} /> )} diff --git a/packages/twenty-front/src/modules/activities/types/ActivityEditorHotkeyScope.ts b/packages/twenty-front/src/modules/activities/types/ActivityEditorHotkeyScope.ts index 221ee25e1..46aed8941 100644 --- a/packages/twenty-front/src/modules/activities/types/ActivityEditorHotkeyScope.ts +++ b/packages/twenty-front/src/modules/activities/types/ActivityEditorHotkeyScope.ts @@ -1,5 +1,4 @@ export enum ActivityEditorHotkeyScope { ActivityTitle = 'activity-title', ActivityBody = 'activity-body', - ActivityTargets = 'activity-targets', } diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx index 71475f442..8a8a7f734 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx @@ -22,6 +22,8 @@ import { RecordFilterGroupsComponentInstanceContext } from '@/object-record/reco import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext'; import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext'; import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId'; +import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; +import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; @@ -29,7 +31,7 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { AnimatePresence, motion } from 'framer-motion'; import { useRef } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil'; import { useIsMobile } from 'twenty-ui'; import { FeatureFlagKey } from '~/generated-metadata/graphql'; @@ -65,9 +67,23 @@ export const CommandMenuContainer = ({ useCommandMenuHotKeys(); + const handleClickOutside = useRecoilCallback( + ({ snapshot }) => + () => { + const hotkeyScope = snapshot + .getLoadable(currentHotkeyScopeState) + .getValue(); + + if (hotkeyScope.scope === AppHotkeyScope.CommandMenuOpen) { + closeCommandMenu(); + } + }, + [closeCommandMenu], + ); + useListenClickOutside({ refs: [commandMenuRef], - callback: closeCommandMenu, + callback: handleClickOutside, listenerId: 'COMMAND_MENU_LISTENER_ID', excludeClassNames: ['page-header-command-menu-button'], }); diff --git a/packages/twenty-front/src/modules/object-record/components/RecordChip.tsx b/packages/twenty-front/src/modules/object-record/components/RecordChip.tsx index 6646ace6c..f5230116e 100644 --- a/packages/twenty-front/src/modules/object-record/components/RecordChip.tsx +++ b/packages/twenty-front/src/modules/object-record/components/RecordChip.tsx @@ -77,7 +77,12 @@ export const RecordChip = ({ avatarType={recordChipData.avatarType} avatarUrl={recordChipData.avatarUrl ?? ''} className={className} - variant={variant} + variant={ + variant ?? + (!forceDisableClick + ? AvatarChipVariant.Regular + : AvatarChipVariant.Transparent) + } to={to ?? getLinkToShowPage(objectNameSingular, record)} onClick={(clickEvent) => { // TODO refactor wrapper event listener to avoid colliding events diff --git a/packages/twenty-front/src/modules/object-record/hooks/useFieldContext.tsx b/packages/twenty-front/src/modules/object-record/hooks/useFieldContext.tsx index 4c14e9f17..57a863a02 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useFieldContext.tsx +++ b/packages/twenty-front/src/modules/object-record/hooks/useFieldContext.tsx @@ -59,7 +59,6 @@ export const useFieldContext = ({ key={objectRecordId + fieldMetadataItem.id} value={{ recordId: objectRecordId, - recoilScopeId: objectRecordId + fieldMetadataItem.id, isLabelIdentifier, fieldDefinition: formatFieldMetadataItemAsColumnDefinition({ field: fieldMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardBody.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardBody.tsx index 00d73aaef..51fbbd267 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardBody.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardBody.tsx @@ -13,6 +13,7 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata' import { getFieldButtonIcon } from '@/object-record/record-field/utils/getFieldButtonIcon'; import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { useContext } from 'react'; export const RecordBoardCardBody = ({ @@ -43,7 +44,6 @@ export const RecordBoardCardBody = ({ value={{ recordId, maxWidth: 156, - recoilScopeId: `board-card-${recordId}-${fieldDefinition.fieldMetadataId}`, isLabelIdentifier: false, fieldDefinition: { disableTooltip: false, @@ -64,7 +64,11 @@ export const RecordBoardCardBody = ({ > diff --git a/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx index f486a5a68..28f305ff2 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx @@ -10,11 +10,8 @@ import { PhonesFieldInput } from '@/object-record/record-field/meta-types/input/ import { RawJsonFieldInput } from '@/object-record/record-field/meta-types/input/components/RawJsonFieldInput'; import { RelationFromManyFieldInput } from '@/object-record/record-field/meta-types/input/components/RelationFromManyFieldInput'; import { SelectFieldInput } from '@/object-record/record-field/meta-types/input/components/SelectFieldInput'; -import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope'; import { isFieldPhones } from '@/object-record/record-field/types/guards/isFieldPhones'; import { isFieldRelationFromManyObjects } from '@/object-record/record-field/types/guards/isFieldRelationFromManyObjects'; -import { isFieldRelationToOneObject } from '@/object-record/record-field/types/guards/isFieldRelationToOneObject'; -import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; import { ArrayFieldInput } from '@/object-record/record-field/meta-types/input/components/ArrayFieldInput'; import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress'; @@ -30,6 +27,7 @@ import { isFieldMultiSelect } from '@/object-record/record-field/types/guards/is import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber'; import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating'; import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFieldRawJson'; +import { isFieldRelationToOneObject } from '@/object-record/record-field/types/guards/isFieldRelationToOneObject'; import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { FieldContext } from '../contexts/FieldContext'; import { BooleanFieldInput } from '../meta-types/input/components/BooleanFieldInput'; @@ -58,7 +56,6 @@ type FieldInputProps = { }; export const FieldInput = ({ - recordFieldInputdId, onCancel, onSubmit, onEnter, @@ -71,9 +68,7 @@ export const FieldInput = ({ const { fieldDefinition } = useContext(FieldContext); return ( - + <> {isFieldRelationToOneObject(fieldDefinition) ? ( ) : isFieldRelationFromManyObjects(fieldDefinition) ? ( @@ -173,6 +168,6 @@ export const FieldInput = ({ ) : ( <> )} - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/contexts/FieldContext.ts b/packages/twenty-front/src/modules/object-record/record-field/contexts/FieldContext.ts index da3dd5796..a6ec5e4b9 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/contexts/FieldContext.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/contexts/FieldContext.ts @@ -23,7 +23,6 @@ export type GenericFieldContextType = { fieldDefinition: FieldDefinition; useUpdateRecord?: RecordUpdateHook; recordId: string; - recoilScopeId?: string; hotkeyScope: string; isLabelIdentifier: boolean; labelIdentifierLink?: string; diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/internal/useRecordFieldInputStates.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/internal/useRecordFieldInputStates.ts deleted file mode 100644 index 924e838b7..000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/internal/useRecordFieldInputStates.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { RecordFieldInputScopeInternalContext } from '@/object-record/record-field/scopes/scope-internal-context/RecordFieldInputScopeInternalContext'; -import { recordFieldInputDraftValueComponentSelector } from '@/object-record/record-field/states/selectors/recordFieldInputDraftValueComponentSelector'; -import { FieldInputDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue'; -import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; -import { getScopeIdOrUndefinedFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdOrUndefinedFromComponentId'; -import { extractComponentSelector } from '@/ui/utilities/state/component-state/utils/extractComponentSelector'; - -export const useRecordFieldInputStates = ( - recordFieldInputId?: string, -) => { - const scopeId = useAvailableScopeIdOrThrow( - RecordFieldInputScopeInternalContext, - getScopeIdOrUndefinedFromComponentId(recordFieldInputId), - ); - - return { - scopeId, - getDraftValueSelector: extractComponentSelector< - FieldInputDraftValue | undefined - >(recordFieldInputDraftValueComponentSelector, scopeId), - }; -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useInitDraftValueV2.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useInitDraftValueV2.ts index f3847113f..196bd1efb 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useInitDraftValueV2.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useInitDraftValueV2.ts @@ -9,7 +9,6 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata' import { computeDraftValueFromFieldValue } from '@/object-record/record-field/utils/computeDraftValueFromFieldValue'; import { computeDraftValueFromString } from '@/object-record/record-field/utils/computeDraftValueFromString'; import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector'; -import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { extractComponentSelector } from '@/ui/utilities/state/component-state/utils/extractComponentSelector'; export const useInitDraftValueV2 = () => { @@ -19,19 +18,19 @@ export const useInitDraftValueV2 = () => { value, recordId, fieldDefinition, + fieldComponentInstanceId, }: { value?: string; recordId: string; fieldDefinition: FieldDefinition; + fieldComponentInstanceId: string; }) => { - const recordFieldInputScopeId = `${getRecordFieldInputId( - recordId, - fieldDefinition?.metadata?.fieldName, - )}`; - const getDraftValueSelector = extractComponentSelector< FieldInputDraftValue | undefined - >(recordFieldInputDraftValueComponentSelector, recordFieldInputScopeId); + >( + recordFieldInputDraftValueComponentSelector, + fieldComponentInstanceId, + ); const recordFieldValue = snapshot .getLoadable( diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useRecordFieldInput.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useRecordFieldInput.ts index 0fbb69d7d..590ba7ba9 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/hooks/useRecordFieldInput.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useRecordFieldInput.ts @@ -1,13 +1,22 @@ import { useSetRecoilState } from 'recoil'; -import { useRecordFieldInputStates } from '@/object-record/record-field/hooks/internal/useRecordFieldInputStates'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; +import { recordFieldInputDraftValueComponentSelector } from '@/object-record/record-field/states/selectors/recordFieldInputDraftValueComponentSelector'; import { FieldInputDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue'; +import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; +import { extractComponentSelector } from '@/ui/utilities/state/component-state/utils/extractComponentSelector'; -export const useRecordFieldInput = ( - recordFieldInputId?: string, -) => { - const { scopeId, getDraftValueSelector } = - useRecordFieldInputStates(recordFieldInputId); +export const useRecordFieldInput = () => { + const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow( + RecordFieldComponentInstanceContext, + ); + + const getDraftValueSelector = extractComponentSelector< + FieldInputDraftValue | undefined + >( + recordFieldInputDraftValueComponentSelector, + recordFieldComponentInstanceId, + ); const setDraftValue = useSetRecoilState(getDraftValueSelector()); @@ -26,7 +35,6 @@ export const useRecordFieldInput = ( }; return { - scopeId, setDraftValue, getDraftValueSelector, isDraftValueEmpty, diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/components/FieldContextProvider.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/components/FieldContextProvider.tsx index 65e207b3a..17166372c 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/components/FieldContextProvider.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/components/FieldContextProvider.tsx @@ -19,7 +19,6 @@ export const FieldContextProvider = ({ value={{ recordId: recordId ?? '1', isLabelIdentifier: false, - recoilScopeId: '1', hotkeyScope: 'hotkey-scope', fieldDefinition, useUpdateRecord: () => [() => undefined, {}], diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useAddressField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useAddressField.ts index 501285e61..879a28883 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useAddressField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useAddressField.ts @@ -41,7 +41,7 @@ export const useAddressField = () => { }; const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useCurrencyField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useCurrencyField.ts index 89dc171d9..0fe6404c8 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useCurrencyField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useCurrencyField.ts @@ -56,7 +56,7 @@ export const useCurrencyField = () => { }; const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useDateField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useDateField.ts index 959ca7090..d74ccadf2 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useDateField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useDateField.ts @@ -25,9 +25,7 @@ export const useDateField = () => { }), ); - const { setDraftValue } = useRecordFieldInput( - `${recordId}-${fieldName}`, - ); + const { setDraftValue } = useRecordFieldInput(); return { fieldDefinition, diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useDateTimeField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useDateTimeField.ts index 74121c6b3..ab8ba068c 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useDateTimeField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useDateTimeField.ts @@ -29,9 +29,7 @@ export const useDateTimeField = () => { }), ); - const { setDraftValue } = useRecordFieldInput( - `${recordId}-${fieldName}`, - ); + const { setDraftValue } = useRecordFieldInput(); return { fieldDefinition, diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailsField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailsField.ts index 44efe4494..38acd5dbe 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailsField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useEmailsField.ts @@ -27,7 +27,7 @@ export const useEmailsField = () => { ); const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useFullNameField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useFullNameField.ts index 69199b928..c34fab450 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useFullNameField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useFullNameField.ts @@ -41,7 +41,7 @@ export const useFullNameField = () => { }; const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useJsonField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useJsonField.ts index 418aca40b..d0cbd7423 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useJsonField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useJsonField.ts @@ -43,7 +43,7 @@ export const useJsonField = () => { }; const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinksField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinksField.ts index 0a5a3bd79..003c34965 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinksField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useLinksField.ts @@ -27,7 +27,7 @@ export const useLinksField = () => { ); const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useMultiSelectField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useMultiSelectField.ts index 09cf34c55..e8e3b2918 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useMultiSelectField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useMultiSelectField.ts @@ -35,7 +35,7 @@ export const useMultiSelectField = () => { const persistField = usePersistField(); const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); return { diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useNumberField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useNumberField.ts index 6d081e45d..4f4e18ecf 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useNumberField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useNumberField.ts @@ -55,7 +55,7 @@ export const useNumberField = () => { }; const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhonesField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhonesField.ts index 65153947b..fc913f0b5 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhonesField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/usePhonesField.ts @@ -27,7 +27,7 @@ export const usePhonesField = () => { ); const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRelationField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRelationField.ts index 9781fcfac..adf863e5d 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRelationField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRelationField.ts @@ -28,9 +28,8 @@ export const useRelationField = () => { recordStoreFamilySelector({ recordId, fieldName }), ); - const { getDraftValueSelector } = useRecordFieldInput>( - `${recordId}-${fieldName}`, - ); + const { getDraftValueSelector } = + useRecordFieldInput>(); const draftValue = useRecoilValue(getDraftValueSelector()); const initialSearchValue = draftValue; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRichTextField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRichTextField.ts index bd705340c..43dc3c740 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRichTextField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRichTextField.ts @@ -35,7 +35,7 @@ export const useRichTextField = () => { const fieldRichTextValue = isFieldRichTextValue(fieldValue) ? fieldValue : ''; const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRichTextV2Field.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRichTextV2Field.ts index 2c2d395ba..2303329f2 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRichTextV2Field.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useRichTextV2Field.ts @@ -40,7 +40,7 @@ export const useRichTextV2Field = () => { : ({ blocknote: null, markdown: null } as FieldRichTextV2Value); const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useSelectField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useSelectField.ts index 95bd0219e..4c67b3fdd 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useSelectField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useSelectField.ts @@ -30,7 +30,7 @@ export const useSelectField = () => { const persistField = usePersistField(); const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); return { diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useTextField.ts b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useTextField.ts index f193945b2..4236f0403 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useTextField.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/hooks/useTextField.ts @@ -28,7 +28,7 @@ export const useTextField = () => { const fieldTextValue = isFieldTextValue(fieldValue) ? fieldValue : ''; const { setDraftValue, getDraftValueSelector } = - useRecordFieldInput(`${recordId}-${fieldName}`); + useRecordFieldInput(); const draftValue = useRecoilValue(getDraftValueSelector()); diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/AddressFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/AddressFieldInput.stories.tsx index 486e2f436..553e7439e 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/AddressFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/AddressFieldInput.stories.tsx @@ -12,6 +12,8 @@ import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope import { FieldMetadataType } from '~/generated-metadata/graphql'; import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; const AddressValueSetterEffect = ({ value, @@ -49,32 +51,42 @@ const AddressInputWithContext = ({ return (
- - - - -
+ + + + +
+
); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/BooleanFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/BooleanFieldInput.stories.tsx index e60797ee8..18d6430b0 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/BooleanFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/BooleanFieldInput.stories.tsx @@ -7,6 +7,8 @@ import { recordStoreFamilyState } from '@/object-record/record-store/states/reco import { FieldMetadataType } from '~/generated/graphql'; import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { BooleanFieldInput, BooleanFieldInputProps, @@ -39,23 +41,36 @@ const BooleanFieldInputWithContext = ({ onSubmit, }: BooleanFieldInputWithContextProps) => { return ( - - - - + + + + + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/DateTimeFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/DateTimeFieldInput.stories.tsx index c1f5369bc..2eddc4e4e 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/DateTimeFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/DateTimeFieldInput.stories.tsx @@ -6,6 +6,8 @@ import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope import { FieldMetadataType } from '~/generated/graphql'; import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect'; import { useDateTimeField } from '../../../hooks/useDateTimeField'; import { @@ -66,7 +68,15 @@ const DateFieldInputWithContext = ({ }, [setHotkeyScope]); return ( -
+
-
+ ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/NumberFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/NumberFieldInput.stories.tsx index cd4b56e51..3b546f6f5 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/NumberFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/NumberFieldInput.stories.tsx @@ -7,6 +7,8 @@ import { FieldMetadataType } from '~/generated/graphql'; import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect'; import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator'; import { useNumberField } from '../../../hooks/useNumberField'; @@ -43,7 +45,15 @@ const NumberFieldInputWithContext = ({ }, [setHotKeyScope]); return ( -
+
-
+
); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/RatingFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/RatingFieldInput.stories.tsx index f2d1d78b9..d1c617cfb 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/RatingFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/RatingFieldInput.stories.tsx @@ -7,6 +7,8 @@ import { isDefined } from 'twenty-shared'; import { FieldMetadataType } from '~/generated-metadata/graphql'; import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { FieldRatingValue } from '../../../../types/FieldMetadata'; import { useRatingField } from '../../../hooks/useRatingField'; import { RatingFieldInput, RatingFieldInputProps } from '../RatingFieldInput'; @@ -42,22 +44,32 @@ const RatingFieldInputWithContext = ({ }, [setHotKeyScope]); return ( - - - - + + + + + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/TextFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/TextFieldInput.stories.tsx index c8c09f337..ad1a19fe7 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/TextFieldInput.stories.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/__stories__/TextFieldInput.stories.tsx @@ -1,13 +1,14 @@ -import { Decorator, Meta, StoryObj } from '@storybook/react'; import { expect, fn, userEvent, waitFor, within } from '@storybook/test'; import { useEffect } from 'react'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { FieldMetadataType } from '~/generated/graphql'; -import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; +import { Decorator, Meta, StoryObj } from '@storybook/react'; import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect'; import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator'; +import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { FieldContextProvider } from '../../../components/FieldContextProvider'; import { useTextField } from '../../../hooks/useTextField'; import { TextFieldInput, TextFieldInputProps } from '../TextFieldInput'; @@ -43,7 +44,11 @@ const TextFieldInputWithContext = ({ }, [setHotKeyScope]); return ( -
+
-
+
); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/scopes/RecordFieldInputScope.tsx b/packages/twenty-front/src/modules/object-record/record-field/scopes/RecordFieldInputScope.tsx deleted file mode 100644 index bd4f3fce4..000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/scopes/RecordFieldInputScope.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { ReactNode } from 'react'; - -import { RecordFieldInputScopeInternalContext } from '@/object-record/record-field/scopes/scope-internal-context/RecordFieldInputScopeInternalContext'; - -type RecordFieldInputScopeProps = { - children: ReactNode; - recordFieldInputScopeId: string; -}; - -export const RecordFieldInputScope = ({ - children, - recordFieldInputScopeId, -}: RecordFieldInputScopeProps) => { - return ( - - {children} - - ); -}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/scopes/scope-internal-context/RecordFieldInputScopeInternalContext.ts b/packages/twenty-front/src/modules/object-record/record-field/scopes/scope-internal-context/RecordFieldInputScopeInternalContext.ts deleted file mode 100644 index 94769746b..000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/scopes/scope-internal-context/RecordFieldInputScopeInternalContext.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext'; -import { RecoilComponentStateKey } from '@/ui/utilities/state/component-state/types/RecoilComponentStateKey'; - -type RecordFieldInputScopeInternalContextProps = RecoilComponentStateKey; - -export const RecordFieldInputScopeInternalContext = - createScopeInternalContext(); diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCell.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCell.tsx index 0c44c7574..0410485ce 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCell.tsx @@ -12,15 +12,19 @@ import { useIsFieldInputOnly } from '@/object-record/record-field/hooks/useIsFie import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly'; import { useOpenFieldInputEditMode } from '@/object-record/record-field/hooks/useOpenFieldInputEditMode'; import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition'; import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation'; import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell'; +import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope'; import { MultipleRecordPickerHotkeyScope } from '@/object-record/record-picker/multiple-record-picker/types/MultipleRecordPickerHotkeyScope'; import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope'; import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope'; -import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; +import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; +import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; +import { useRecoilCallback } from 'recoil'; import { RelationDefinitionType } from '~/generated-metadata/graphql'; import { RecordInlineCellContainer } from './RecordInlineCellContainer'; import { @@ -42,6 +46,10 @@ export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => { onCloseEditMode, } = useContext(FieldContext); + const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow( + RecordFieldComponentInstanceContext, + ); + const buttonIcon = useGetButtonIcon(); const isFieldInputOnly = useIsFieldInputOnly(); @@ -78,15 +86,22 @@ export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => { closeInlineCell(); }; - const handleClickOutside: FieldInputClickOutsideEvent = ( - persistField, - event, - ) => { - event.stopImmediatePropagation(); + const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback( + ({ snapshot }) => + (persistField, event) => { + const hotkeyScope = snapshot + .getLoadable(currentHotkeyScopeState) + .getValue(); + if (hotkeyScope.scope !== InlineCellHotkeyScope.InlineCell) { + return; + } + event.stopImmediatePropagation(); - persistField(); - closeInlineCell(); - }; + persistField(); + closeInlineCell(); + }, + [closeInlineCell], + ); const { getIcon } = useIcons(); const { openFieldInput, closeFieldInput } = useOpenFieldInputEditMode(); @@ -132,10 +147,7 @@ export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => { isCentered, editModeContent: ( { const { isCentered } = useContext(RecordInlineCellContext); - const { recordId, fieldDefinition } = useContext(FieldContext); - const instanceId = getRecordFieldInputId( - recordId, - fieldDefinition?.metadata?.fieldName, + const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow( + RecordFieldComponentInstanceContext, ); const setFieldInputLayoutDirection = useSetRecoilComponentStateV2( recordFieldInputLayoutDirectionComponentState, - instanceId, + recordFieldComponentInstanceId, ); const setFieldInputLayoutDirectionLoading = useSetRecoilComponentStateV2( recordFieldInputLayoutDirectionLoadingComponentState, - instanceId, + recordFieldComponentInstanceId, ); const setFieldInputLayoutDirectionMiddleware = { diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/hooks/useInlineCell.ts b/packages/twenty-front/src/modules/object-record/record-inline-cell/hooks/useInlineCell.ts index c6df67ec6..68e5f597b 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/hooks/useInlineCell.ts +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/hooks/useInlineCell.ts @@ -6,22 +6,28 @@ import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousH import { isDefined } from 'twenty-shared'; import { useInitDraftValueV2 } from '@/object-record/record-field/hooks/useInitDraftValueV2'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; import { useRecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext'; import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId'; import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious'; +import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { isInlineCellInEditModeScopedState } from '../states/isInlineCellInEditModeScopedState'; import { InlineCellHotkeyScope } from '../types/InlineCellHotkeyScope'; -export const useInlineCell = () => { - const { - recoilScopeId = '', - recordId, - fieldDefinition, - } = useContext(FieldContext); +export const useInlineCell = ( + recordFieldComponentInstanceIdFromProps?: string, +) => { + const { recordId, fieldDefinition } = useContext(FieldContext); + + const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow( + RecordFieldComponentInstanceContext, + recordFieldComponentInstanceIdFromProps, + ); const [isInlineCellInEditMode, setIsInlineCellInEditMode] = useRecoilState( - isInlineCellInEditModeScopedState(recoilScopeId), + isInlineCellInEditModeScopedState(recordFieldComponentInstanceId), ); const { onOpenEditMode, onCloseEditMode } = useRecordInlineCellContext(); @@ -50,7 +56,15 @@ export const useInlineCell = () => { const openInlineCell = (customEditHotkeyScopeForField?: string) => { onOpenEditMode?.(); setIsInlineCellInEditMode(true); - initFieldInputDraftValue({ recordId, fieldDefinition }); + initFieldInputDraftValue({ + recordId, + fieldDefinition, + fieldComponentInstanceId: getRecordFieldInputId( + recordId, + fieldDefinition.metadata.fieldName, + 'inline-cell', + ), + }); if (isDefined(customEditHotkeyScopeForField)) { setHotkeyScopeAndMemorizePreviousScope(customEditHotkeyScopeForField); diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/FieldsCard.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/FieldsCard.tsx index d77ff9af9..af500aab3 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/components/FieldsCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/components/FieldsCard.tsx @@ -15,6 +15,7 @@ import { useRecordShowContainerActions } from '@/object-record/record-show/hooks import { useRecordShowContainerData } from '@/object-record/record-show/hooks/useRecordShowContainerData'; import { RecordDetailDuplicatesSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailDuplicatesSection'; import { RecordDetailRelationSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSection'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { isFieldCellSupported } from '@/object-record/utils/isFieldCellSupported'; import { FieldMetadataType } from '~/generated/graphql'; @@ -97,7 +98,6 @@ export const FieldsCard = ({ value={{ recordId: objectRecordId, maxWidth: 200, - recoilScopeId: objectRecordId + fieldMetadataItem.id, isLabelIdentifier: false, fieldDefinition: formatFieldMetadataItemAsColumnDefinition({ field: fieldMetadataItem, @@ -110,22 +110,21 @@ export const FieldsCard = ({ hotkeyScope: InlineCellHotkeyScope.InlineCell, }} > - - - + ), )} @@ -135,7 +134,6 @@ export const FieldsCard = ({ value={{ recordId: objectRecordId, maxWidth: 200, - recoilScopeId: objectRecordId + fieldMetadataItem.id, isLabelIdentifier: false, fieldDefinition: formatFieldMetadataItemAsColumnDefinition({ field: fieldMetadataItem, @@ -150,7 +148,11 @@ export const FieldsCard = ({ > @@ -169,7 +171,6 @@ export const FieldsCard = ({ key={objectRecordId + fieldMetadataItem.id} value={{ recordId: objectRecordId, - recoilScopeId: objectRecordId + fieldMetadataItem.id, isLabelIdentifier: false, fieldDefinition: formatFieldMetadataItemAsColumnDefinition({ field: fieldMetadataItem, diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/ObjectRecordShowPageBreadcrumb.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/ObjectRecordShowPageBreadcrumb.tsx index a30d1fadd..a5dece76e 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/components/ObjectRecordShowPageBreadcrumb.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/components/ObjectRecordShowPageBreadcrumb.tsx @@ -68,8 +68,6 @@ export const ObjectRecordShowPageBreadcrumb = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-store/hooks/useUpsertRecordsInStore.ts b/packages/twenty-front/src/modules/object-record/record-store/hooks/useUpsertRecordsInStore.ts index 0c7692749..a67048727 100644 --- a/packages/twenty-front/src/modules/object-record/record-store/hooks/useUpsertRecordsInStore.ts +++ b/packages/twenty-front/src/modules/object-record/record-store/hooks/useUpsertRecordsInStore.ts @@ -13,7 +13,10 @@ export const useUpsertRecordsInStore = () => { .getValue(); if (JSON.stringify(currentRecord) !== JSON.stringify(record)) { - set(recordStoreFamilyState(record.id), record); + set(recordStoreFamilyState(record.id), { + ...currentRecord, + ...record, + }); } } }, diff --git a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts index 12573f3dc..f367808f3 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useSetRecordTableData.ts @@ -62,7 +62,10 @@ export const useSetRecordTableData = ({ .getValue(); if (JSON.stringify(currentRecord) !== JSON.stringify(record)) { - set(recordStoreFamilyState(record.id), record); + set(recordStoreFamilyState(record.id), { + ...currentRecord, + ...record, + }); } } diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellEditMode.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellEditMode.tsx index b9468a10f..0ad8d1c67 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellEditMode.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellEditMode.tsx @@ -1,9 +1,9 @@ -import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; import { recordFieldInputIsFieldInErrorComponentState } from '@/object-record/record-field/states/recordFieldInputIsFieldInErrorComponentState'; import { recordFieldInputLayoutDirectionComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionComponentState'; import { recordFieldInputLayoutDirectionLoadingComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionLoadingComponentState'; -import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer'; +import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; import styled from '@emotion/styled'; @@ -14,7 +14,7 @@ import { offset, useFloating, } from '@floating-ui/react'; -import { ReactElement, useContext } from 'react'; +import { ReactElement } from 'react'; const StyledEditableCellEditModeContainer = styled.div` align-items: center; @@ -35,25 +35,21 @@ export type RecordTableCellEditModeProps = { export const RecordTableCellEditMode = ({ children, }: RecordTableCellEditModeProps) => { - const { recordId, fieldDefinition } = useContext(FieldContext); - const isFieldInError = useRecoilComponentValueV2( recordFieldInputIsFieldInErrorComponentState, ); - const instanceId = getRecordFieldInputId( - recordId, - fieldDefinition?.metadata?.fieldName, + const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow( + RecordFieldComponentInstanceContext, ); - const setFieldInputLayoutDirection = useSetRecoilComponentStateV2( recordFieldInputLayoutDirectionComponentState, - instanceId, + recordFieldComponentInstanceId, ); const setFieldInputLayoutDirectionLoading = useSetRecoilComponentStateV2( recordFieldInputLayoutDirectionLoadingComponentState, - instanceId, + recordFieldComponentInstanceId, ); const setFieldInputLayoutDirectionMiddleware = { diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldContextWrapper.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldContextWrapper.tsx index c37638dc3..c53ac4b51 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldContextWrapper.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldContextWrapper.tsx @@ -16,6 +16,7 @@ import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/co import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope'; import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { RelationDefinitionType } from '~/generated-metadata/graphql'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; @@ -72,7 +73,6 @@ export const RecordTableCellFieldContextWrapper = ({ return ( [updateRecord, {}], @@ -89,7 +89,13 @@ export const RecordTableCellFieldContextWrapper = ({ }} > {children} diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldInput.tsx index 7c0e919e2..5dddbd693 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldInput.tsx @@ -3,9 +3,13 @@ import { useContext } from 'react'; import { FieldInput } from '@/object-record/record-field/components/FieldInput'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly'; +import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput'; import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent'; import { useRecordTableBodyContextOrThrow } from '@/object-record/record-table/contexts/RecordTableBodyContext'; +import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope'; import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; +import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; +import { useRecoilCallback } from 'recoil'; export const RecordTableCellFieldInput = () => { const { recordId, fieldDefinition } = useContext(FieldContext); @@ -31,16 +35,22 @@ export const RecordTableCellFieldInput = () => { onCloseTableCell(); }; - const handleClickOutside = ( - persistField: () => void, - event: MouseEvent | TouchEvent, - ) => { - event.stopImmediatePropagation(); + const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback( + ({ snapshot }) => + (persistField, event) => { + const hotkeyScope = snapshot + .getLoadable(currentHotkeyScopeState) + .getValue(); + if (hotkeyScope.scope !== TableHotkeyScope.CellEditMode) { + return; + } + event.stopImmediatePropagation(); - persistField(); - - onCloseTableCell(); - }; + persistField(); + onCloseTableCell(); + }, + [onCloseTableCell], + ); const handleEscape: FieldInputEvent = (persistField) => { persistField(); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2.ts index b17c5d6fd..49a706efd 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellV2.ts @@ -24,6 +24,7 @@ import { recordIndexOpenRecordInState } from '@/object-record/record-index/state import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState'; import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId'; import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField'; +import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId'; import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious'; import { useClickOustideListenerStates } from '@/ui/utilities/pointer-event/hooks/useClickOustideListenerStates'; import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType'; @@ -158,6 +159,11 @@ export const useOpenRecordTableCellV2 = (tableScopeId: string) => { value: initialValue, recordId, fieldDefinition, + fieldComponentInstanceId: getRecordFieldInputId( + recordId, + fieldDefinition.metadata.fieldName, + 'record-table-cell', + ), }); toggleClickOutsideListener(false); diff --git a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCell.tsx b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCell.tsx index 116c59a60..af7cb13ba 100644 --- a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCell.tsx @@ -8,6 +8,7 @@ import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEv import { useInlineCell } from '../../record-inline-cell/hooks/useInlineCell'; import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; import { RecordTitleCellContainer } from '@/object-record/record-title-cell/components/RecordTitleCellContainer'; import { RecordTitleCellContext, @@ -30,7 +31,13 @@ export const RecordTitleCell = ({ const isFieldInputOnly = useIsFieldInputOnly(); - const { closeInlineCell } = useInlineCell(); + const { closeInlineCell } = useInlineCell( + getRecordFieldInputId( + recordId, + fieldDefinition?.metadata?.fieldName, + 'title', + ), + ); const handleEnter: FieldInputEvent = (persistField) => { persistField(); @@ -64,10 +71,6 @@ export const RecordTitleCell = ({ const recordTitleCellContextValue: RecordTitleCellContextProps = { editModeContent: ( - - - - + + + + + + + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellFieldInput.tsx index 19d7ccdec..a33497c39 100644 --- a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellFieldInput.tsx @@ -1,8 +1,5 @@ import { useContext } from 'react'; -import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope'; -import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; - import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent'; import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName'; @@ -11,7 +8,6 @@ import { RecordTitleCellTextFieldInput } from '@/object-record/record-title-cell import { RecordTitleFullNameFieldInput } from '@/object-record/record-title-cell/components/RecordTitleFullNameFieldInput'; type RecordTitleCellFieldInputProps = { - recordFieldInputId: string; onClickOutside?: ( persist: () => void, event: MouseEvent | TouchEvent, @@ -25,7 +21,6 @@ type RecordTitleCellFieldInputProps = { export const RecordTitleCellFieldInput = ({ sizeVariant, - recordFieldInputId, onEnter, onEscape, onShiftTab, @@ -39,9 +34,7 @@ export const RecordTitleCellFieldInput = ({ } return ( - + <> {isFieldText(fieldDefinition) ? ( ) : null} - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/utils/getRecordFieldInputId.ts b/packages/twenty-front/src/modules/object-record/utils/getRecordFieldInputId.ts index 35a563993..aed995eaf 100644 --- a/packages/twenty-front/src/modules/object-record/utils/getRecordFieldInputId.ts +++ b/packages/twenty-front/src/modules/object-record/utils/getRecordFieldInputId.ts @@ -1,6 +1,13 @@ +import { isDefined } from 'twenty-shared'; + export const getRecordFieldInputId = ( recordId: string, fieldName?: string, + prefix?: string, ): string => { + if (isDefined(prefix)) { + return `${prefix}-${recordId}-${fieldName}`; + } + return `${recordId}-${fieldName}`; }; diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/preview/components/SettingsDataModelFieldPreview.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/preview/components/SettingsDataModelFieldPreview.tsx index 40a9fafb4..c5b5afa12 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/preview/components/SettingsDataModelFieldPreview.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/fields/preview/components/SettingsDataModelFieldPreview.tsx @@ -9,6 +9,7 @@ import { FieldDisplay } from '@/object-record/record-field/components/FieldDispl import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { BooleanFieldInput } from '@/object-record/record-field/meta-types/input/components/BooleanFieldInput'; import { RatingFieldInput } from '@/object-record/record-field/meta-types/input/components/RatingFieldInput'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; import { SettingsDataModelSetFieldValueEffect } from '@/settings/data-model/fields/preview/components/SettingsDataModelSetFieldValueEffect'; import { SettingsDataModelSetPreviewRecordEffect } from '@/settings/data-model/fields/preview/components/SettingsDataModelSetRecordEffect'; import { useFieldPreviewValue } from '@/settings/data-model/fields/preview/hooks/useFieldPreviewValue'; @@ -98,59 +99,65 @@ export const SettingsDataModelFieldPreview = ({ return ( <> - {previewRecord ? ( - - ) : ( - - )} - - {!!withFieldLabel && ( - - - {fieldMetadataItem.label}: - + + {previewRecord ? ( + + ) : ( + )} - - {fieldMetadataItem.type === FieldMetadataType.BOOLEAN ? ( - - ) : fieldMetadataItem.type === FieldMetadataType.RATING ? ( - - ) : ( - + + {!!withFieldLabel && ( + + + {fieldMetadataItem.label}: + )} - - + + {fieldMetadataItem.type === FieldMetadataType.BOOLEAN ? ( + + ) : fieldMetadataItem.type === FieldMetadataType.RATING ? ( + + ) : ( + + )} + + + ); }; diff --git a/packages/twenty-front/src/modules/ui/input/components/internal/currency/components/CurrencyPickerDropdownButton.tsx b/packages/twenty-front/src/modules/ui/input/components/internal/currency/components/CurrencyPickerDropdownButton.tsx index 4bbf2766d..feaa9d417 100644 --- a/packages/twenty-front/src/modules/ui/input/components/internal/currency/components/CurrencyPickerDropdownButton.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/internal/currency/components/CurrencyPickerDropdownButton.tsx @@ -8,8 +8,6 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { CurrencyPickerHotkeyScope } from '../types/CurrencyPickerHotkeyScope'; -import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope'; -import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener'; import { CurrencyPickerDropdownSelect } from './CurrencyPickerDropdownSelect'; const StyledDropdownButtonContainer = styled.div` @@ -69,10 +67,6 @@ export const CurrencyPickerDropdownButton = ({ closeDropdown(); }; - const { toggleClickOutsideListener } = useClickOutsideListener( - TableHotkeyScope.CellEditMode, - ); - const currency = currencies.find(({ value }) => value === valueCode); const currencyCode = currency?.value ?? CurrencyCode.USD; @@ -98,8 +92,6 @@ export const CurrencyPickerDropdownButton = ({ } dropdownPlacement="bottom-start" dropdownOffset={{ x: 0, y: 4 }} - onOpen={() => toggleClickOutsideListener(false)} - onClose={() => toggleClickOutsideListener(true)} /> ); }; diff --git a/packages/twenty-front/src/testing/decorators/getFieldDecorator.tsx b/packages/twenty-front/src/testing/decorators/getFieldDecorator.tsx index 36fde3e75..4886ce1a4 100644 --- a/packages/twenty-front/src/testing/decorators/getFieldDecorator.tsx +++ b/packages/twenty-front/src/testing/decorators/getFieldDecorator.tsx @@ -5,6 +5,7 @@ import { useRecoilCallback } from 'recoil'; import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; +import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext'; import { RecordFieldValueSelectorContextProvider, useSetRecordValue, @@ -124,26 +125,32 @@ export const getFieldDecorator = }); return ( - - - - - - + + + + + + + + ); }; diff --git a/packages/twenty-front/src/testing/hooks/useMockFieldContext.tsx b/packages/twenty-front/src/testing/hooks/useMockFieldContext.tsx index dbf606fa5..2b1540339 100644 --- a/packages/twenty-front/src/testing/hooks/useMockFieldContext.tsx +++ b/packages/twenty-front/src/testing/hooks/useMockFieldContext.tsx @@ -46,7 +46,6 @@ export const useMockFieldContext = ({ key={objectRecordId + fieldMetadataItem.id} value={{ recordId: objectRecordId, - recoilScopeId: objectRecordId + fieldMetadataItem.id, isLabelIdentifier, fieldDefinition: formatFieldMetadataItemAsColumnDefinition({ field: fieldMetadataItem, diff --git a/packages/twenty-ui/src/input/button/components/Button/Button.tsx b/packages/twenty-ui/src/input/button/components/Button/Button.tsx index 504940b2f..658813f97 100644 --- a/packages/twenty-ui/src/input/button/components/Button/Button.tsx +++ b/packages/twenty-ui/src/input/button/components/Button/Button.tsx @@ -361,7 +361,7 @@ const StyledButton = styled('button', { const StyledButtonWrapper = styled.div< Pick< ButtonProps, - 'isLoading' | 'variant' | 'accent' | 'inverted' | 'disabled' + 'isLoading' | 'variant' | 'accent' | 'inverted' | 'disabled' | 'fullWidth' > >` ${({ theme, variant, accent, inverted, disabled }) => css` @@ -409,7 +409,9 @@ const StyledButtonWrapper = styled.div< max-width: ${({ isLoading, theme }) => isLoading ? `calc(100% - ${theme.spacing(8)})` : 'none'}; + position: relative; + width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')}; `; export const Button = ({ @@ -445,6 +447,7 @@ export const Button = ({ accent={accent} inverted={inverted} disabled={soon || disabled} + fullWidth={fullWidth} > {(isLoading || Icon) && (