From a86b5fb9b271f81d9acb26307309a4fafbbc5724 Mon Sep 17 00:00:00 2001 From: Naifer <161821705+omarNaifer12@users.noreply.github.com> Date: Thu, 5 Jun 2025 19:32:46 +0100 Subject: [PATCH] fix(frontend): prevent command menu reopening when clicking the same field (#12390) ressolve #12205 This PR fixes the issue where the record in the command menu was reopening when clicking the same field again. https://github.com/user-attachments/assets/52da7b3f-4704-4a9c-8fc4-29534568b0c0 - Added recordId to cells so it can be accessed when useListenClickOutside is triggered, and compared the previous recordId with the new one to prevent closing the command menu for the same record. - When the field is clicked, we compare the lastRecordId with the new recordId inside the openRecordInCommandMenu function to avoid reopening the menu unnecessarily. --------- Co-authored-by: Charles Bochet --- .../components/CommandMenuOpenContainer.tsx | 2 ++ .../command-menu/hooks/useOpenRecordInCommandMenu.ts | 7 +++++++ .../constants/RecordChipClickOutsideId.ts | 1 + .../components/RecordTableCellBaseContainer.tsx | 12 +++++++++++- .../pointer-event/hooks/useListenClickOutside.ts | 1 - 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-table/constants/RecordChipClickOutsideId.ts diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuOpenContainer.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuOpenContainer.tsx index 89edd727c..3cabd0b78 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuOpenContainer.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuOpenContainer.tsx @@ -3,6 +3,7 @@ import { COMMAND_MENU_CLICK_OUTSIDE_ID } from '@/command-menu/constants/CommandM import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { CommandMenuAnimationVariant } from '@/command-menu/types/CommandMenuAnimationVariant'; import { CommandMenuHotkeyScope } from '@/command-menu/types/CommandMenuHotkeyScope'; +import { RECORD_CHIP_CLICK_OUTSIDE_ID } from '@/object-record/record-table/constants/RecordChipClickOutsideId'; import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices'; import { PAGE_HEADER_COMMAND_MENU_BUTTON_CLICK_OUTSIDE_ID } from '@/ui/layout/page-header/constants/PageHeaderCommandMenuButtonClickOutsideId'; import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; @@ -68,6 +69,7 @@ export const CommandMenuOpenContainer = ({ excludedClickOutsideIds: [ PAGE_HEADER_COMMAND_MENU_BUTTON_CLICK_OUTSIDE_ID, LINK_CHIP_CLICK_OUTSIDE_ID, + RECORD_CHIP_CLICK_OUTSIDE_ID, ], }); diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordInCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordInCommandMenu.ts index 00367df94..dadb04cd5 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordInCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordInCommandMenu.ts @@ -41,6 +41,13 @@ export const useOpenRecordInCommandMenu = () => { objectNameSingular: string; isNewRecord?: boolean; }) => { + const lastRecordId = snapshot + .getLoadable(viewableRecordIdState) + .getValue(); + if (lastRecordId === recordId) { + return; + } + const pageComponentInstanceId = v4(); set( diff --git a/packages/twenty-front/src/modules/object-record/record-table/constants/RecordChipClickOutsideId.ts b/packages/twenty-front/src/modules/object-record/record-table/constants/RecordChipClickOutsideId.ts new file mode 100644 index 000000000..3e2f3007f --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-table/constants/RecordChipClickOutsideId.ts @@ -0,0 +1 @@ +export const RECORD_CHIP_CLICK_OUTSIDE_ID = 'record-chip-click-outside-id'; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellBaseContainer.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellBaseContainer.tsx index d125c9a88..99c2905a0 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellBaseContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellBaseContainer.tsx @@ -3,6 +3,8 @@ import { ReactNode, useContext } from 'react'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { useFieldFocus } from '@/object-record/record-field/hooks/useFieldFocus'; +import { isFieldIdentifierDisplay } from '@/object-record/record-field/meta-types/display/utils/isFieldIdentifierDisplay'; +import { RECORD_CHIP_CLICK_OUTSIDE_ID } from '@/object-record/record-table/constants/RecordChipClickOutsideId'; import { useRecordTableBodyContextOrThrow } from '@/object-record/record-table/contexts/RecordTableBodyContext'; import { RecordTableCellContext } from '@/object-record/record-table/contexts/RecordTableCellContext'; import { useOpenRecordTableCellFromCell } from '@/object-record/record-table/record-table-cell/hooks/useOpenRecordTableCellFromCell'; @@ -57,13 +59,18 @@ export const RecordTableCellBaseContainer = ({ }: { children: ReactNode; }) => { - const { isReadOnly } = useContext(FieldContext); + const { isReadOnly, fieldDefinition, isLabelIdentifier } = + useContext(FieldContext); const { setIsFocused } = useFieldFocus(); const { openTableCell } = useOpenRecordTableCellFromCell(); const { theme } = useContext(ThemeContext); const { cellPosition } = useContext(RecordTableCellContext); + const isChipDisplay = isFieldIdentifierDisplay( + fieldDefinition, + isLabelIdentifier, + ); const { onMoveHoverToCurrentCell, onCellMouseEnter } = useRecordTableBodyContextOrThrow(); @@ -98,6 +105,9 @@ export const RecordTableCellBaseContainer = ({ borderColorBlue={theme.adaptiveColors.blue4} isReadOnly={isReadOnly ?? false} id={`record-table-cell-${cellPosition.column}-${cellPosition.row}`} + data-click-outside-id={ + isChipDisplay ? RECORD_CHIP_CLICK_OUTSIDE_ID : undefined + } > {children} diff --git a/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useListenClickOutside.ts b/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useListenClickOutside.ts index 8178ee40a..6b13ab27c 100644 --- a/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useListenClickOutside.ts +++ b/packages/twenty-front/src/modules/ui/utilities/pointer-event/hooks/useListenClickOutside.ts @@ -92,7 +92,6 @@ export const useListenClickOutside = ({ while (currentElement) { const currentDataAttributes = currentElement.dataset; - const isGloballyExcluded = currentDataAttributes?.globallyPreventClickOutside === 'true';