Files
twenty/packages/twenty-front/src/modules/command-menu/components/CommandMenuContainer.tsx
Lucas Bordeau fe98deef4e Fixed command menu hotkey listener refactor (#11534)
This PR fixes a refactor that was done recently to avoid having
clickoutside listeners on the closed command menu.

The useScopedHotkey hook should have stayed in the command menu
container, because it should always listen.

This has been fixed.
2025-04-11 14:59:48 +02:00

85 lines
4.0 KiB
TypeScript

import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
import { CommandMenuOpenContainer } from '@/command-menu/components/CommandMenuOpenContainer';
import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/CommandMenuComponentInstanceId';
import { useCommandMenuCloseAnimationCompleteCleanup } from '@/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup';
import { useCommandMenuHotKeys } from '@/command-menu/hooks/useCommandMenuHotKeys';
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { RecordFilterGroupsComponentInstanceContext } from '@/object-record/record-filter-group/states/context/RecordFilterGroupsComponentInstanceContext';
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 { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { AnimatePresence } from 'framer-motion';
import { useRecoilValue } from 'recoil';
export const CommandMenuContainer = ({
children,
}: {
children: React.ReactNode;
}) => {
const { commandMenuCloseAnimationCompleteCleanup } =
useCommandMenuCloseAnimationCompleteCleanup();
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
const objectMetadataItemId = useRecoilComponentValueV2(
contextStoreCurrentObjectMetadataItemIdComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const objectMetadataItem = objectMetadataItems.find(
(objectMetadataItem) => objectMetadataItem.id === objectMetadataItemId,
);
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
const recordIndexId = getRecordIndexIdFromObjectNamePluralAndViewId(
objectMetadataItem?.namePlural ?? '',
currentViewId ?? '',
);
useCommandMenuHotKeys();
return (
<RecordFilterGroupsComponentInstanceContext.Provider
value={{ instanceId: recordIndexId }}
>
<RecordFiltersComponentInstanceContext.Provider
value={{ instanceId: recordIndexId }}
>
<RecordSortsComponentInstanceContext.Provider
value={{ instanceId: recordIndexId }}
>
<ContextStoreComponentInstanceContext.Provider
value={{ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID }}
>
<ActionMenuComponentInstanceContext.Provider
value={{ instanceId: COMMAND_MENU_COMPONENT_INSTANCE_ID }}
>
<AnimatePresence
mode="wait"
onExitComplete={commandMenuCloseAnimationCompleteCleanup}
>
{isCommandMenuOpened && (
<CommandMenuOpenContainer>
{children}
</CommandMenuOpenContainer>
)}
</AnimatePresence>
</ActionMenuComponentInstanceContext.Provider>
</ContextStoreComponentInstanceContext.Provider>
</RecordSortsComponentInstanceContext.Provider>
</RecordFiltersComponentInstanceContext.Provider>
</RecordFilterGroupsComponentInstanceContext.Provider>
);
};