diff --git a/packages/twenty-front/src/modules/activities/files/components/AttachmentDropdown.tsx b/packages/twenty-front/src/modules/activities/files/components/AttachmentDropdown.tsx
index 0d7955aa1..ab03f51e4 100644
--- a/packages/twenty-front/src/modules/activities/files/components/AttachmentDropdown.tsx
+++ b/packages/twenty-front/src/modules/activities/files/components/AttachmentDropdown.tsx
@@ -2,7 +2,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import {
IconDotsVertical,
IconDownload,
@@ -27,21 +27,21 @@ export const AttachmentDropdown = ({
}: AttachmentDropdownProps) => {
const dropdownId = `${scopeKey}-settings-field-active-action-dropdown`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const handleDownload = () => {
onDownload();
- closeDropdown();
+ closeDropdown(dropdownId);
};
const handleDelete = () => {
onDelete();
- closeDropdown();
+ closeDropdown(dropdownId);
};
const handleRename = () => {
onRename();
- closeDropdown();
+ closeDropdown(dropdownId);
};
return (
diff --git a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx
index 88cf7b46e..74f26caa0 100644
--- a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx
+++ b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx
@@ -10,7 +10,8 @@ import { openFavoriteFolderIdsState } from '@/favorites/states/openFavoriteFolde
import { isLocationMatchingFavorite } from '@/favorites/utils/isLocationMatchingFavorite';
import { ProcessedFavorite } from '@/favorites/utils/sortFavorites';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { useModal } from '@/ui/layout/modal/hooks/useModal';
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
@@ -28,6 +29,7 @@ import { useRecoilState } from 'recoil';
import { IconFolder, IconFolderOpen, IconHeartOff } from 'twenty-ui/display';
import { LightIconButton } from 'twenty-ui/input';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
+
type CurrentWorkspaceMemberFavoritesProps = {
folder: {
folderId: string;
@@ -68,10 +70,16 @@ export const CurrentWorkspaceMemberFavorites = ({
const { renameFavoriteFolder } = useRenameFavoriteFolder();
const { deleteFavoriteFolder } = useDeleteFavoriteFolder();
- const {
- closeDropdown: closeFavoriteFolderEditDropdown,
- isDropdownOpen: isFavoriteFolderEditDropdownOpen,
- } = useDropdown(`favorite-folder-edit-${folder.folderId}`);
+
+ const dropdownId = `favorite-folder-edit-${folder.folderId}`;
+
+ const isDropdownOpenComponent = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ dropdownId,
+ );
+
+ const { closeDropdown } = useCloseDropdown();
+
const selectedFavoriteIndex = folder.favorites.findIndex((favorite) =>
isLocationMatchingFavorite(currentPath, currentViewPath, favorite),
);
@@ -110,10 +118,10 @@ export const CurrentWorkspaceMemberFavorites = ({
const handleFavoriteFolderDelete = async () => {
if (folder.favorites.length > 0) {
openModal(modalId);
- closeFavoriteFolderEditDropdown();
+ closeDropdown(dropdownId);
} else {
await deleteFavoriteFolder(folder.folderId);
- closeFavoriteFolderEditDropdown();
+ closeDropdown(dropdownId);
}
};
@@ -126,7 +134,9 @@ export const CurrentWorkspaceMemberFavorites = ({
folderId={folder.folderId}
onRename={() => setIsFavoriteFolderRenaming(true)}
onDelete={handleFavoriteFolderDelete}
- closeDropdown={closeFavoriteFolderEditDropdown}
+ closeDropdown={() => {
+ closeDropdown(dropdownId);
+ }}
/>
);
@@ -159,7 +169,7 @@ export const CurrentWorkspaceMemberFavorites = ({
onClick={handleToggle}
rightOptions={rightOptions}
className="navigation-drawer-item"
- isRightOptionsDropdownOpen={isFavoriteFolderEditDropdownOpen}
+ isRightOptionsDropdownOpen={isDropdownOpenComponent}
triggerEvent="CLICK"
/>
diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx
index 2b4020ec4..e5d3bc0ad 100644
--- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx
+++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx
@@ -1,6 +1,6 @@
import { isFavoriteFolderCreatingState } from '@/favorites/states/isFavoriteFolderCreatingState';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useTheme } from '@emotion/react';
@@ -21,7 +21,7 @@ export const FavoriteFolderPickerFooter = ({
);
const { openNavigationSection } = useNavigationSection('Favorites');
const theme = useTheme();
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
return (
@@ -31,7 +31,7 @@ export const FavoriteFolderPickerFooter = ({
setIsNavigationDrawerExpanded(true);
openNavigationSection();
setIsFavoriteFolderCreating(true);
- closeDropdown();
+ closeDropdown(dropdownId);
}}
text="Add folder"
LeftIcon={() => }
diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx
index 4328fa1b7..c803bb617 100644
--- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx
@@ -14,7 +14,7 @@ import { getRecordFilterOperands } from '@/object-record/record-filter/utils/get
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { isDefined } from 'twenty-shared/utils';
import { IconLibraryPlus, IconPlus } from 'twenty-ui/display';
@@ -44,7 +44,7 @@ export const AdvancedFilterAddFilterRuleSelect = ({
const newPositionInRecordFilterGroup = lastChildPosition + 1;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const { defaultFieldMetadataItemForFilter } =
useDefaultFieldMetadataItemForFilter();
@@ -57,7 +57,7 @@ export const AdvancedFilterAddFilterRuleSelect = ({
throw new Error('Missing default field metadata item for filter');
}
- closeDropdown();
+ closeDropdown(dropdownId);
const filterType = getFilterTypeFromFieldType(
defaultFieldMetadataItemForFilter.type,
@@ -87,7 +87,7 @@ export const AdvancedFilterAddFilterRuleSelect = ({
};
const handleAddFilterGroup = () => {
- closeDropdown();
+ closeDropdown(dropdownId);
if (!isDefined(defaultFieldMetadataItemForFilter)) {
throw new Error('Missing default field metadata item for filter');
diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupOptionsDropdown.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupOptionsDropdown.tsx
index 44be3834c..24b848b62 100644
--- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupOptionsDropdown.tsx
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupOptionsDropdown.tsx
@@ -6,7 +6,7 @@ import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRe
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { IconDotsVertical, IconTrash } from 'twenty-ui/display';
import { IconButton } from 'twenty-ui/input';
import { MenuItem } from 'twenty-ui/navigation';
@@ -20,7 +20,7 @@ export const AdvancedFilterRecordFilterGroupOptionsDropdown = ({
}: AdvancedFilterRecordFilterGroupOptionsDropdownProps) => {
const dropdownId = `advanced-filter-record-filter-group-options-${recordFilterGroupId}`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const { removeRecordFilter } = useRemoveRecordFilter();
const { removeRecordFilterGroup } = useRemoveRecordFilterGroup();
@@ -40,7 +40,7 @@ export const AdvancedFilterRecordFilterGroupOptionsDropdown = ({
removeRootRecordFilterGroupIfEmpty();
- closeDropdown();
+ closeDropdown(dropdownId);
};
return (
diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelectContent.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelectContent.tsx
index 2393cecdd..dcdc18da8 100644
--- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelectContent.tsx
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelectContent.tsx
@@ -10,7 +10,7 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
@@ -31,13 +31,13 @@ export const AdvancedFilterRecordFilterOperandSelectContent = ({
}: AdvancedFilterRecordFilterOperandSelectContentProps) => {
const dropdownId = `advanced-filter-view-filter-operand-${recordFilterId}`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const { applyObjectFilterDropdownOperand } =
useApplyObjectFilterDropdownOperand();
const handleOperandChange = (operand: ViewFilterOperand) => {
- closeDropdown();
+ closeDropdown(dropdownId);
applyObjectFilterDropdownOperand(operand);
};
diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOptionsDropdown.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOptionsDropdown.tsx
index cc730fc19..6b1635953 100644
--- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOptionsDropdown.tsx
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOptionsDropdown.tsx
@@ -9,7 +9,7 @@ import { DEFAULT_ADVANCED_FILTER_DROPDOWN_OFFSET } from '@/object-record/advance
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils';
import { IconDotsVertical, IconTrash } from 'twenty-ui/display';
@@ -25,7 +25,7 @@ export const AdvancedFilterRecordFilterOptionsDropdown = ({
}: AdvancedFilterRecordFilterOptionsDropdownProps) => {
const dropdownId = `advanced-filter-record-filter-options-${recordFilterId}`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const { removeRecordFilter } = useRemoveRecordFilter();
const { removeRecordFilterGroup } = useRemoveRecordFilterGroup();
@@ -47,7 +47,7 @@ export const AdvancedFilterRecordFilterOptionsDropdown = ({
useRemoveRootRecordFilterGroupIfEmpty();
const handleRemove = async () => {
- closeDropdown();
+ closeDropdown(dropdownId);
if (isDefined(currentRecordFilter?.recordFilterGroupId)) {
const isOnlyViewFilterInGroup =
diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useAdvancedFilterFieldSelectDropdown.ts b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useAdvancedFilterFieldSelectDropdown.ts
index 11389c948..f5e02727a 100644
--- a/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useAdvancedFilterFieldSelectDropdown.ts
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useAdvancedFilterFieldSelectDropdown.ts
@@ -1,11 +1,13 @@
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
export const useAdvancedFilterFieldSelectDropdown = (viewFilterId?: string) => {
const advancedFilterFieldSelectDropdownId = `advanced-filter-view-filter-field-${viewFilterId}`;
- const { closeDropdown: closeAdvancedFilterFieldSelectDropdown } = useDropdown(
- advancedFilterFieldSelectDropdownId,
- );
+ const { closeDropdown } = useCloseDropdown();
+
+ const closeAdvancedFilterFieldSelectDropdown = () => {
+ closeDropdown(advancedFilterFieldSelectDropdownId);
+ };
return {
closeAdvancedFilterFieldSelectDropdown,
diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect.tsx
index 3c96536da..b579d66a4 100644
--- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect.tsx
+++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect.tsx
@@ -8,7 +8,7 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { IconCheck } from 'twenty-ui/display';
@@ -41,7 +41,7 @@ export const ObjectFilterDropdownBooleanSelect = () => {
const { applyObjectFilterDropdownFilterValue } =
useApplyObjectFilterDropdownFilterValue();
- const { closeDropdown } = useDropdown();
+ const { closeDropdown } = useCloseDropdown();
const handleOptionSelect = (newValue: boolean) => {
applyObjectFilterDropdownFilterValue(
diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandDropdown.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandDropdown.tsx
deleted file mode 100644
index 73040aec7..000000000
--- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandDropdown.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
-
-import { ObjectFilterDropdownOperandSelect } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandSelect';
-import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
-
-import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
-import { ClickOutsideListenerContext } from '@/ui/utilities/pointer-event/contexts/ClickOutsideListenerContext';
-import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
-import { useTheme } from '@emotion/react';
-import styled from '@emotion/styled';
-import { IconChevronDown } from 'twenty-ui/display';
-import { getOperandLabel } from '../utils/getOperandLabel';
-
-const StyledDropdownMenuHeader = styled(DropdownMenuHeader)`
- cursor: pointer;
-`;
-
-export const OPERAND_DROPDOWN_CLICK_OUTSIDE_ID =
- 'object-filter-dropdown-operand-dropdown-click-outside-id';
-
-export const ObjectFilterDropdownOperandDropdown = ({
- filterDropdownId,
-}: {
- filterDropdownId?: string;
-}) => {
- const selectedOperandInDropdown = useRecoilComponentValueV2(
- selectedOperandInDropdownComponentState,
- );
-
- const theme = useTheme();
-
- const dropdownId = `${filterDropdownId}-operand-dropdown`;
-
- return (
-
- }
- >
- {getOperandLabel(selectedOperandInDropdown)}
-
- }
- dropdownComponents={}
- dropdownOffset={{ x: parseInt(theme.spacing(2), 10) }}
- />
-
- );
-};
diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandSelect.tsx
deleted file mode 100644
index 8ff83ff8c..000000000
--- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandSelect.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
-import { useApplyObjectFilterDropdownOperand } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownOperand';
-import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
-import { subFieldNameUsedInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/subFieldNameUsedInDropdownComponentState';
-import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
-import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
-import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
-import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
-import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
-import styled from '@emotion/styled';
-import { isDefined } from 'twenty-shared/utils';
-import { MenuItem } from 'twenty-ui/navigation';
-import { getOperandLabel } from '../utils/getOperandLabel';
-
-const StyledDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)`
- background-color: ${({ theme }) => theme.background.primary};
- border-radius: ${({ theme }) => theme.border.radius.md};
-`;
-
-export const ObjectFilterDropdownOperandSelect = () => {
- const fieldMetadataItemUsedInDropdown = useRecoilComponentValueV2(
- fieldMetadataItemUsedInDropdownComponentSelector,
- );
-
- const subFieldNameUsedInDropdown = useRecoilComponentValueV2(
- subFieldNameUsedInDropdownComponentState,
- );
-
- const { applyObjectFilterDropdownOperand } =
- useApplyObjectFilterDropdownOperand();
-
- const { closeDropdown } = useDropdown();
-
- const operandsForFilterType = isDefined(fieldMetadataItemUsedInDropdown)
- ? getRecordFilterOperands({
- filterType: getFilterTypeFromFieldType(
- fieldMetadataItemUsedInDropdown.type,
- ),
- subFieldName: subFieldNameUsedInDropdown,
- })
- : [];
-
- const handleOperandChange = (newOperand: ViewFilterOperand) => {
- applyObjectFilterDropdownOperand(newOperand);
- };
-
- return (
-
-
- {operandsForFilterType.map((filterOperand, index) => (
-
-
- );
-};
diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx
index 6c1584bb8..2f181563a 100644
--- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx
+++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownOptionSelect.tsx
@@ -4,7 +4,6 @@ import { Key } from 'ts-key-enum';
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
import { useOptionsForSelect } from '@/object-record/object-filter-dropdown/hooks/useOptionsForSelect';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
@@ -15,6 +14,7 @@ import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-recor
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
@@ -64,7 +64,7 @@ export const ObjectFilterDropdownOptionSelect = ({
[objectFilterDropdownCurrentRecordFilter?.value],
);
- const { closeDropdown } = useDropdown();
+ const { closeDropdown } = useCloseDropdown();
const { resetSelectedItem } = useSelectableList(componentInstanceId);
diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdown.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdown.tsx
index 81235ada4..494f67954 100644
--- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdown.tsx
+++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdown.tsx
@@ -9,7 +9,8 @@ import { useRecordGroupReorderConfirmationModal } from '@/object-record/record-g
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
import { DROPDOWN_OFFSET_Y } from '@/ui/layout/dropdown/constants/DropdownOffsetY';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewType } from '@/views/types/ViewType';
import { Trans } from '@lingui/react/macro';
@@ -27,7 +28,11 @@ export const ObjectOptionsDropdown = ({
const { currentContentId, handleContentChange, handleResetContent } =
useDropdownContextCurrentContentId();
- const { isDropdownOpen } = useDropdown(OBJECT_OPTIONS_DROPDOWN_ID);
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ OBJECT_OPTIONS_DROPDOWN_ID,
+ );
+
const {
handleRecordGroupOrderChangeWithModal,
handleRecordGroupReorderConfirmClick,
diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
index 9e1c38733..7dcd4efaf 100644
--- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
+++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownLayoutContent.tsx
@@ -10,7 +10,7 @@ import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
@@ -62,7 +62,7 @@ export const ObjectOptionsDropdownLayoutContent = () => {
const { availableFieldsForKanban, navigateToSelectSettings } =
useGetAvailableFieldsForKanban();
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const handleSelectKanbanViewType = async () => {
if (isDefaultView) {
@@ -70,7 +70,7 @@ export const ObjectOptionsDropdownLayoutContent = () => {
}
if (availableFieldsForKanban.length === 0) {
navigateToSelectSettings();
- closeDropdown();
+ closeDropdown(dropdownId);
}
if (currentView?.type !== ViewType.Kanban) {
await setAndPersistViewType(ViewType.Kanban);
diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx
index aac85f400..9b97918d6 100644
--- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx
+++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/components/ObjectSortDropdownButton.tsx
@@ -26,7 +26,7 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
@@ -194,7 +194,10 @@ export const ObjectSortDropdownButton = () => {
setIsRecordSortDirectionMenuUnfolded(false);
};
- const { isDropdownOpen } = useDropdown(OBJECT_SORT_DROPDOWN_ID);
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ OBJECT_SORT_DROPDOWN_ID,
+ );
const { t } = useLingui();
diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useCloseSortDropdown.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useCloseSortDropdown.ts
index d7ab6e7cd..509b02f77 100644
--- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useCloseSortDropdown.ts
+++ b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useCloseSortDropdown.ts
@@ -1,14 +1,14 @@
import { OBJECT_SORT_DROPDOWN_ID } from '@/object-record/object-sort-dropdown/constants/ObjectSortDropdownId';
import { useResetSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useResetSortDropdown';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
export const useCloseSortDropdown = () => {
const { resetSortDropdown } = useResetSortDropdown();
- const { closeDropdown } = useDropdown(OBJECT_SORT_DROPDOWN_ID);
+ const { closeDropdown } = useCloseDropdown();
const closeSortDropdown = () => {
- closeDropdown();
+ closeDropdown(OBJECT_SORT_DROPDOWN_ID);
resetSortDropdown();
};
diff --git a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useToggleSortDropdown.ts b/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useToggleSortDropdown.ts
deleted file mode 100644
index b0fdfbc98..000000000
--- a/packages/twenty-front/src/modules/object-record/object-sort-dropdown/hooks/useToggleSortDropdown.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { OBJECT_SORT_DROPDOWN_ID } from '@/object-record/object-sort-dropdown/constants/ObjectSortDropdownId';
-import { useResetSortDropdown } from '@/object-record/object-sort-dropdown/hooks/useResetSortDropdown';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
-
-export const useToggleSortDropdown = () => {
- const { toggleDropdown } = useDropdown(OBJECT_SORT_DROPDOWN_ID);
-
- const { resetSortDropdown } = useResetSortDropdown();
-
- const toggleSortDropdown = () => {
- toggleDropdown();
- resetSortDropdown();
- };
-
- return {
- toggleSortDropdown,
- };
-};
diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton.tsx
index 32ad8948a..ce25e7456 100644
--- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton.tsx
@@ -1,8 +1,9 @@
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import styled from '@emotion/styled';
-import { AppTooltip, TooltipDelay } from 'twenty-ui/display';
import { Tag } from 'twenty-ui/components';
+import { AppTooltip, TooltipDelay } from 'twenty-ui/display';
const StyledTag = styled(Tag)`
width: 100%;
@@ -21,7 +22,10 @@ export const RecordBoardColumnHeaderAggregateDropdownButton = ({
value?: string | number;
tooltip?: string;
}) => {
- const { isDropdownOpen } = useDropdown(dropdownId);
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ dropdownId,
+ );
return (
diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateTimeFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateTimeFieldInput.tsx
index dc3315d89..552272b24 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateTimeFieldInput.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateTimeFieldInput.tsx
@@ -12,7 +12,7 @@ import {
import { MAX_DATE } from '@/ui/input/components/internal/date/constants/MaxDate';
import { MIN_DATE } from '@/ui/input/components/internal/date/constants/MinDate';
import { useDateParser } from '@/ui/input/components/internal/hooks/useDateParser';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
@@ -129,12 +129,8 @@ export const FormDateTimeFieldInput = ({
}
};
- const { closeDropdown: closeDropdownMonthSelect } = useDropdown(
- MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID,
- );
- const { closeDropdown: closeDropdownYearSelect } = useDropdown(
- MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID,
- );
+ const { closeDropdown: closeDropdownMonthSelect } = useCloseDropdown();
+ const { closeDropdown: closeDropdownYearSelect } = useCloseDropdown();
const displayDatePicker =
draftValue.type === 'static' && draftValue.mode === 'edit';
@@ -148,8 +144,8 @@ export const FormDateTimeFieldInput = ({
callback: (event) => {
event.stopImmediatePropagation();
- closeDropdownYearSelect();
- closeDropdownMonthSelect();
+ closeDropdownYearSelect(MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID);
+ closeDropdownMonthSelect(MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID);
handlePickerClickOutside();
},
enabled: displayDatePicker,
diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormSingleRecordPicker.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormSingleRecordPicker.tsx
index 3b8bb9a42..da40ee332 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormSingleRecordPicker.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormSingleRecordPicker.tsx
@@ -11,7 +11,7 @@ import { SingleRecordPickerRecord } from '@/object-record/record-picker/single-r
import { InputLabel } from '@/ui/input/components/InputLabel';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { css, useTheme } from '@emotion/react';
@@ -103,7 +103,7 @@ export const FormSingleRecordPicker = ({
const dropdownId = `form-record-picker-${componentId}`;
const variablesDropdownId = `form-record-picker-${componentId}-variables`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const setRecordPickerSearchFilter = useSetRecoilComponentStateV2(
singleRecordPickerSearchFilterComponentState,
@@ -118,7 +118,7 @@ export const FormSingleRecordPicker = ({
selectedEntity: SingleRecordPickerRecord | null | undefined,
) => {
onChange?.(selectedEntity?.record?.id ?? '');
- closeDropdown();
+ closeDropdown(dropdownId);
};
const handleVariableTagInsert = (variable: string) => {
@@ -193,7 +193,7 @@ export const FormSingleRecordPicker = ({
componentInstanceId={dropdownId}
EmptyIcon={IconForbid}
emptyLabel={'No ' + objectNameSingular}
- onCancel={() => closeDropdown()}
+ onCancel={() => closeDropdown(dropdownId)}
onRecordSelected={handleRecordSelected}
objectNameSingular={objectNameSingular}
recordPickerInstanceId={dropdownId}
diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldMenuItem.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldMenuItem.tsx
index 324370988..88971fafe 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldMenuItem.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/MultiItemFieldMenuItem.tsx
@@ -1,7 +1,9 @@
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { MenuItemWithOptionDropdown } from '@/ui/navigation/menu-item/components/MenuItemWithOptionDropdown';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import React, { useState } from 'react';
import {
IconBookmark,
@@ -33,7 +35,11 @@ export const MultiItemFieldMenuItem = ({
showSetAsPrimaryButton,
}: MultiItemFieldMenuItemProps) => {
const [isHovered, setIsHovered] = useState(false);
- const { isDropdownOpen, closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ dropdownId,
+ );
const handleMouseEnter = () => setIsHovered(true);
const handleMouseLeave = () => {
@@ -44,7 +50,7 @@ export const MultiItemFieldMenuItem = ({
event.stopPropagation();
event.preventDefault();
- closeDropdown();
+ closeDropdown(dropdownId);
setIsHovered(false);
onDelete?.();
};
@@ -53,7 +59,7 @@ export const MultiItemFieldMenuItem = ({
event.stopPropagation();
event.preventDefault();
- closeDropdown();
+ closeDropdown(dropdownId);
onSetAsPrimary?.();
};
@@ -61,7 +67,7 @@ export const MultiItemFieldMenuItem = ({
event.stopPropagation();
event.preventDefault();
- closeDropdown();
+ closeDropdown(dropdownId);
onEdit?.();
};
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 38ade134a..33733826e 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
@@ -34,10 +34,12 @@ import { isFieldCellSupported } from '@/object-record/utils/isFieldCellSupported
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { useModal } from '@/ui/layout/modal/hooks/useModal';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { createPortal } from 'react-dom';
import {
@@ -159,7 +161,11 @@ export const RecordDetailRelationRecordsListItem = ({
const dropdownScopeId = `record-field-card-menu-${relationFieldMetadataId}-${relationRecord.id}`;
- const { closeDropdown, isDropdownOpen } = useDropdown(dropdownScopeId);
+ const { closeDropdown } = useCloseDropdown();
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ dropdownScopeId,
+ );
const dropdownId = getRecordFieldCardRelationPickerDropdownId({
fieldDefinition,
@@ -171,7 +177,7 @@ export const RecordDetailRelationRecordsListItem = ({
);
const handleDetach = () => {
- closeDropdown();
+ closeDropdown(dropdownScopeId);
const relationFieldMetadataItem = relationObjectMetadataItem.fields.find(
({ id }) => id === relationFieldMetadataId,
@@ -196,7 +202,7 @@ export const RecordDetailRelationRecordsListItem = ({
};
const handleDelete = async () => {
- closeDropdown();
+ closeDropdown(dropdownScopeId);
openModal(getDeleteRelationModalId(relationRecord.id));
};
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 5c2c31a8b..6261f56b1 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
@@ -16,8 +16,9 @@ import { AggregateOperations } from '@/object-record/record-table/constants/Aggr
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { prefetchIndexViewIdFromObjectMetadataItemFamilySelector } from '@/prefetch/states/selector/prefetchIndexViewIdFromObjectMetadataItemFamilySelector';
import { AppPath } from '@/types/AppPath';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { useLingui } from '@lingui/react/macro';
import { RelationType } from '~/generated-metadata/graphql';
@@ -69,7 +70,10 @@ export const RecordDetailRelationSection = ({
recordId,
});
- const { isDropdownOpen } = useDropdown(dropdownId);
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ dropdownId,
+ );
const indexViewId = useRecoilValue(
prefetchIndexViewIdFromObjectMetadataItemFamilySelector({
diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToMany.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToMany.tsx
index 1b8bc2aa1..fb405e2b7 100644
--- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToMany.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToMany.tsx
@@ -16,7 +16,7 @@ import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/reco
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { dropdownPlacementComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownPlacementComponentStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
@@ -52,7 +52,7 @@ export const RecordDetailRelationSectionDropdownToMany = () => {
recordId,
});
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const dropdownPlacement = useRecoilComponentValueV2(
dropdownPlacementComponentStateV2,
@@ -125,7 +125,7 @@ export const RecordDetailRelationSectionDropdownToMany = () => {
};
const handleCreateNew = (searchString?: string) => {
- closeDropdown();
+ closeDropdown(dropdownId);
createNewRecordAndOpenRightDrawer?.(searchString);
};
@@ -150,8 +150,12 @@ export const RecordDetailRelationSectionDropdownToMany = () => {
componentInstanceId={dropdownId}
onCreate={handleCreateNew}
onChange={updateRelation}
- onSubmit={closeDropdown}
- onClickOutside={closeDropdown}
+ onSubmit={() => {
+ closeDropdown(dropdownId);
+ }}
+ onClickOutside={() => {
+ closeDropdown(dropdownId);
+ }}
layoutDirection={
dropdownPlacement?.includes('end')
? 'search-bar-on-bottom'
diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToOne.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToOne.tsx
index 43865587b..f82c3948d 100644
--- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToOne.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionDropdownToOne.tsx
@@ -16,7 +16,7 @@ import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/reco
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { dropdownPlacementComponentStateV2 } from '@/ui/layout/dropdown/states/dropdownPlacementComponentStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
@@ -54,7 +54,7 @@ export const RecordDetailRelationSectionDropdownToOne = () => {
recordId,
});
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const dropdownPlacement = useRecoilComponentValueV2(
dropdownPlacementComponentStateV2,
@@ -80,7 +80,7 @@ export const RecordDetailRelationSectionDropdownToOne = () => {
const handleRelationPickerEntitySelected = (
selectedRelationEntity?: SingleRecordPickerRecord,
) => {
- closeDropdown();
+ closeDropdown(dropdownId);
if (!selectedRelationEntity?.id || !relationFieldMetadataItem?.name) return;
@@ -107,7 +107,7 @@ export const RecordDetailRelationSectionDropdownToOne = () => {
};
const handleCreateNew = (searchString?: string) => {
- closeDropdown();
+ closeDropdown(dropdownId);
createNewRecordAndOpenRightDrawer?.(searchString);
};
@@ -138,7 +138,7 @@ export const RecordDetailRelationSectionDropdownToOne = () => {
onRecordSelected={handleRelationPickerEntitySelected}
objectNameSingular={relationObjectMetadataNameSingular}
recordPickerInstanceId={dropdownId}
- onCancel={closeDropdown}
+ onCancel={() => closeDropdown(dropdownId)}
onCreate={shouldAllowCreateNew ? handleCreateNew : undefined}
layoutDirection={
dropdownPlacement?.includes('end')
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts
index 2604d1ae2..f29b45fca 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useTriggerActionMenuDropdown.ts
@@ -5,11 +5,12 @@ import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-me
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
+
export const useTriggerActionMenuDropdown = ({
recordTableId,
}: {
@@ -32,7 +33,7 @@ export const useTriggerActionMenuDropdown = ({
actionMenuDropdownId,
);
- const { openDropdown } = useDropdown(actionMenuDropdownId);
+ const { openDropdown } = useOpenDropdown();
const { closeCommandMenu } = useCommandMenu();
@@ -57,13 +58,16 @@ export const useTriggerActionMenuDropdown = ({
closeCommandMenu();
- openDropdown();
+ openDropdown({
+ dropdownComponentInstanceIdFromProps: actionMenuDropdownId,
+ });
},
[
recordIndexActionMenuDropdownPositionState,
isRowSelectedFamilyState,
closeCommandMenu,
openDropdown,
+ actionMenuDropdownId,
],
);
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent.tsx
index 24c930ced..698265910 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateDropdownSubmenuContent.tsx
@@ -6,7 +6,7 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useContext } from 'react';
import { Key } from 'ts-key-enum';
@@ -22,13 +22,13 @@ export const RecordTableColumnAggregateFooterDropdownSubmenuContent = ({
const { dropdownId, resetContent } = useContext(
RecordTableColumnAggregateFooterDropdownContext,
);
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
useScopedHotkeys(
[Key.Escape],
() => {
resetContent();
- closeDropdown();
+ closeDropdown(dropdownId);
},
TableOptionsHotkeyScope.Dropdown,
);
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterAggregateOperationMenuItems.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterAggregateOperationMenuItems.tsx
index d787e216d..4712616df 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterAggregateOperationMenuItems.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterAggregateOperationMenuItems.tsx
@@ -2,7 +2,7 @@ import { getAggregateOperationLabel } from '@/object-record/record-board/record-
import { RecordTableColumnAggregateFooterDropdownContext } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterDropdownContext';
import { useViewFieldAggregateOperation } from '@/object-record/record-table/record-table-footer/hooks/useViewFieldAggregateOperation';
import { ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { ReactNode, useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { IconCheck } from 'twenty-ui/display';
@@ -23,7 +23,8 @@ export const RecordTableColumnAggregateFooterAggregateOperationMenuItems = ({
const { dropdownId, resetContent } = useContext(
RecordTableColumnAggregateFooterDropdownContext,
);
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
+
return (
<>
{aggregateOperations.map((operation) => (
@@ -31,7 +32,7 @@ export const RecordTableColumnAggregateFooterAggregateOperationMenuItems = ({
key={operation}
onClick={() => {
updateViewFieldAggregateOperation(operation);
- closeDropdown();
+ closeDropdown(dropdownId);
}}
text={getAggregateOperationLabel(operation)}
RightIcon={
@@ -48,7 +49,7 @@ export const RecordTableColumnAggregateFooterAggregateOperationMenuItems = ({
onClick={() => {
updateViewFieldAggregateOperation(null);
resetContent();
- closeDropdown();
+ closeDropdown(dropdownId);
}}
text={'None'}
RightIcon={
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
index 0490abfa8..fc3a8dc2a 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterMenuContent.tsx
@@ -7,7 +7,7 @@ import { getAvailableAggregateOperationsForFieldMetadataType } from '@/object-re
import { TableOptionsHotkeyScope } from '@/object-record/record-table/types/TableOptionsHotkeyScope';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { t } from '@lingui/core/macro';
import { useContext, useMemo } from 'react';
@@ -25,13 +25,13 @@ export const RecordTableColumnAggregateFooterMenuContent = () => {
fieldMetadataType,
resetContent,
} = useContext(RecordTableColumnAggregateFooterDropdownContext);
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const { objectMetadataItem } = useRecordTableContextOrThrow();
useScopedHotkeys(
[Key.Escape],
() => {
- closeDropdown();
+ closeDropdown(dropdownId);
},
TableOptionsHotkeyScope.Dropdown,
);
@@ -106,7 +106,7 @@ export const RecordTableColumnAggregateFooterMenuContent = () => {
onClick={() => {
updateViewFieldAggregateOperation(null);
resetContent();
- closeDropdown();
+ closeDropdown(dropdownId);
}}
text={t`None`}
RightIcon={
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValueCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValueCell.tsx
index 3da666ae1..839a88df3 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValueCell.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValueCell.tsx
@@ -3,7 +3,7 @@ import { RECORD_TABLE_TD_WIDTH } from '@/object-record/record-table/record-table
import { RecordTableColumnAggregateFooterCellContext } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterCellContext';
import { RecordTableColumnAggregateFooterValue } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValue';
import { hasAggregateOperationForViewFieldFamilySelector } from '@/object-record/record-table/record-table-footer/states/hasAggregateOperationForViewFieldFamilySelector';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
@@ -60,7 +60,12 @@ export const RecordTableColumnAggregateFooterValueCell = ({
isFirstCell: boolean;
}) => {
const [isHovered, setIsHovered] = useState(false);
- const { isDropdownOpen } = useDropdown(dropdownId);
+
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ dropdownId,
+ );
+
const theme = useTheme();
const { viewFieldId, fieldMetadataId } = useContext(
RecordTableColumnAggregateFooterCellContext,
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
index 3e190adc7..3df082f7c 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx
@@ -1,12 +1,12 @@
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useOpenRecordFilterChipFromTableHeader } from '@/object-record/record-table/record-table-header/hooks/useOpenRecordFilterChipFromTableHeader';
import { onToggleColumnSortComponentState } from '@/object-record/record-table/states/onToggleColumnSortComponentState';
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useToggleScrollWrapper } from '@/ui/utilities/scroll/hooks/useToggleScrollWrapper';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import styled from '@emotion/styled';
@@ -54,10 +54,12 @@ export const RecordTableColumnHeadDropdownMenu = ({
const { handleColumnVisibilityChange, handleMoveTableColumn } =
useTableColumns();
- const { closeDropdown } = useDropdown(column.fieldMetadataId + '-header');
+ const dropdownId = column.fieldMetadataId + '-header';
+
+ const { closeDropdown } = useCloseDropdown();
const closeDropdownAndToggleScroll = () => {
- closeDropdown();
+ closeDropdown(dropdownId);
toggleScrollXWrapper(true);
toggleScrollYWrapper(false);
};
diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderPlusButtonContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderPlusButtonContent.tsx
index 41887b005..af77f80f0 100644
--- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderPlusButtonContent.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderPlusButtonContent.tsx
@@ -11,7 +11,7 @@ import { SettingsPath } from '@/types/SettingsPath';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useLingui } from '@lingui/react/macro';
@@ -23,7 +23,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
const { t } = useLingui();
const { objectMetadataItem } = useRecordTableContextOrThrow();
- const { closeDropdown } = useDropdown();
+ const { closeDropdown } = useCloseDropdown();
const hiddenTableColumns = useRecoilComponentValueV2(
hiddenTableColumnsComponentSelector,
diff --git a/packages/twenty-front/src/modules/object-record/select/components/MultipleSelectDropdown.tsx b/packages/twenty-front/src/modules/object-record/select/components/MultipleSelectDropdown.tsx
index 680eea2af..14221dc04 100644
--- a/packages/twenty-front/src/modules/object-record/select/components/MultipleSelectDropdown.tsx
+++ b/packages/twenty-front/src/modules/object-record/select/components/MultipleSelectDropdown.tsx
@@ -4,7 +4,7 @@ import { SelectableItem } from '@/object-record/select/types/SelectableItem';
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
@@ -35,7 +35,7 @@ export const MultipleSelectDropdown = ({
) => void;
loadingItems: boolean;
}) => {
- const { closeDropdown } = useDropdown();
+ const { closeDropdown } = useCloseDropdown();
const { resetSelectedItem } = useSelectableList(selectableListId);
diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx
index 4b9ac5b46..6f4f584c9 100644
--- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx
+++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx
@@ -6,7 +6,7 @@ import { SettingsPath } from '@/types/SettingsPath';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { useModal } from '@/ui/layout/modal/hooks/useModal';
import { Trans, useLingui } from '@lingui/react/macro';
@@ -35,7 +35,7 @@ export const SettingsAccountsRowDropdownMenu = ({
const { openModal } = useModal();
const navigate = useNavigateSettings();
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const { destroyOneRecord } = useDestroyOneRecord({
objectNameSingular: CoreObjectNameSingular.ConnectedAccount,
@@ -62,7 +62,7 @@ export const SettingsAccountsRowDropdownMenu = ({
text={t`Emails settings`}
onClick={() => {
navigate(SettingsPath.AccountsEmails);
- closeDropdown();
+ closeDropdown(dropdownId);
}}
/>
diff --git a/packages/twenty-front/src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainRowDropdownMenu.tsx b/packages/twenty-front/src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainRowDropdownMenu.tsx
index 32bad7548..19a1ea847 100644
--- a/packages/twenty-front/src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainRowDropdownMenu.tsx
+++ b/packages/twenty-front/src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainRowDropdownMenu.tsx
@@ -4,7 +4,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { UnwrapRecoilValue, useSetRecoilState } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { IconDotsVertical, IconTrash } from 'twenty-ui/display';
@@ -27,7 +27,7 @@ export const SettingsSecurityApprovedAccessDomainRowDropdownMenu = ({
const { enqueueSnackBar } = useSnackBar();
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const [deleteApprovedAccessDomain] = useDeleteApprovedAccessDomainMutation();
@@ -70,7 +70,7 @@ export const SettingsSecurityApprovedAccessDomainRowDropdownMenu = ({
text="Delete"
onClick={() => {
handleDeleteApprovedAccessDomain();
- closeDropdown();
+ closeDropdown(dropdownId);
}}
/>
diff --git a/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTabEnvironmentVariableTableRow.tsx b/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTabEnvironmentVariableTableRow.tsx
index a907c341d..099c1f3c8 100644
--- a/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTabEnvironmentVariableTableRow.tsx
+++ b/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTabEnvironmentVariableTableRow.tsx
@@ -3,7 +3,7 @@ import { TextInputV2 } from '@/ui/input/components/TextInputV2';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import styled from '@emotion/styled';
@@ -41,7 +41,7 @@ export const SettingsServerlessFunctionTabEnvironmentVariableTableRow = ({
const [editedEnvVariable, setEditedEnvVariable] = useState(envVariable);
const [editMode, setEditMode] = useState(initialEditMode);
const dropDownId = `settings-environment-variable-dropdown-${envVariable.id}`;
- const { closeDropdown } = useDropdown(dropDownId);
+ const { closeDropdown } = useCloseDropdown();
return editMode ? (
@@ -117,7 +117,7 @@ export const SettingsServerlessFunctionTabEnvironmentVariableTableRow = ({
LeftIcon={IconPencil}
onClick={() => {
setEditMode(true);
- closeDropdown();
+ closeDropdown(dropDownId);
}}
/>
{
onDelete();
- closeDropdown();
+ closeDropdown(dropDownId);
}}
/>
diff --git a/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnToFieldSelect.tsx b/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnToFieldSelect.tsx
index f460a067f..fa344cce7 100644
--- a/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnToFieldSelect.tsx
+++ b/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnToFieldSelect.tsx
@@ -8,7 +8,7 @@ import { MatchColumnSelectFieldSelectDropdownContent } from '@/spreadsheet-impor
import { MatchColumnSelectSubFieldSelectDropdownContent } from '@/spreadsheet-import/components/MatchColumnSelectSubFieldSelectDropdownContent';
import { DO_NOT_IMPORT_OPTION_KEY } from '@/spreadsheet-import/constants/DoNotImportOptionKey';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import styled from '@emotion/styled';
import { isDefined } from 'twenty-shared/utils';
import { IconChevronDown } from 'twenty-ui/display';
@@ -39,7 +39,7 @@ export const MatchColumnToFieldSelect = ({
}: MatchColumnToFieldSelectProps) => {
const dropdownId = `match-column-select-v2-dropdown-${columnIndex}`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const [selectedFieldMetadataItem, setSelectedFieldMetadataItem] =
useState(null);
@@ -81,7 +81,7 @@ export const MatchColumnToFieldSelect = ({
setSelectedFieldMetadataItem(null);
onChange(correspondingOption);
- closeDropdown();
+ closeDropdown(dropdownId);
}
};
@@ -89,13 +89,13 @@ export const MatchColumnToFieldSelect = ({
selectedSuggestedOption: SelectOption,
) => {
onChange(selectedSuggestedOption);
- closeDropdown();
+ closeDropdown(dropdownId);
};
const handleDoNotImportSelect = () => {
if (isDefined(doNotImportOption)) {
onChange(doNotImportOption);
- closeDropdown();
+ closeDropdown(dropdownId);
}
};
@@ -109,7 +109,7 @@ export const MatchColumnToFieldSelect = ({
const handleCancelSelectClick = () => {
setSelectedFieldMetadataItem(null);
- closeDropdown();
+ closeDropdown(dropdownId);
};
const doNotImportOption = options.find(
diff --git a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/components/SubMatchingSelectDropdownButton.tsx b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/components/SubMatchingSelectDropdownButton.tsx
index cf81bf33d..527ef49a1 100644
--- a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/components/SubMatchingSelectDropdownButton.tsx
+++ b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/components/SubMatchingSelectDropdownButton.tsx
@@ -7,7 +7,6 @@ import {
import { SpreadsheetMatchedOptions } from '@/spreadsheet-import/types/SpreadsheetMatchedOptions';
import { getFieldOptions } from '@/spreadsheet-import/utils/getFieldOptions';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { Tag, TagColor } from 'twenty-ui/components';
@@ -30,8 +29,6 @@ export const SubMatchingSelectDropdownButton = ({
column,
placeholder,
}: SubMatchingSelectDropdownButtonProps) => {
- const { openDropdown } = useDropdown();
-
const { fields } = useSpreadsheetImportInternal();
const options = getFieldOptions(fields, column.value) as SelectOption[];
const value = options.find((opt) => opt.value === option.value);
@@ -39,11 +36,7 @@ export const SubMatchingSelectDropdownButton = ({
const theme = useTheme();
return (
- openDropdown()}
- id="control"
- >
+
({
}: SubMatchingSelectRowRightDropdownProps) => {
const dropdownId = `sub-matching-select-dropdown-${option.entry}`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const { fields } = useSpreadsheetImportInternal();
const options = getFieldOptions(fields, column.value) as SelectOption[];
@@ -46,7 +46,7 @@ export const SubMatchingSelectRowRightDropdown = ({
const handleSelect = (selectedOption: SelectOption) => {
onSubChange(selectedOption.value as T, column.index, option.entry ?? '');
- closeDropdown();
+ closeDropdown(dropdownId);
};
return (
diff --git a/packages/twenty-front/src/modules/support/components/SupportDropdown.tsx b/packages/twenty-front/src/modules/support/components/SupportDropdown.tsx
index 3474a1cae..da1d9f86d 100644
--- a/packages/twenty-front/src/modules/support/components/SupportDropdown.tsx
+++ b/packages/twenty-front/src/modules/support/components/SupportDropdown.tsx
@@ -3,23 +3,23 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { IconHelpCircle, IconMessage } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
export const SupportDropdown = () => {
const dropdownId = `support-field-active-action-dropdown`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const handleTalkToUs = () => {
window.FrontChat?.('show');
- closeDropdown();
+ closeDropdown(dropdownId);
};
const handleUserGuide = () => {
window.open('https://twenty.com/user-guide', '_blank');
- closeDropdown();
+ closeDropdown(dropdownId);
};
return (
diff --git a/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx b/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx
index fffcdbac5..f1e4718ef 100644
--- a/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx
+++ b/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx
@@ -7,7 +7,7 @@ import {
MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID,
MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID,
} from '@/ui/input/components/internal/date/components/InternalDatePicker';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
import { useRecoilCallback } from 'recoil';
import { Nullable } from 'twenty-ui/utilities';
@@ -61,23 +61,19 @@ export const DateInput = ({
onSubmit?.(newDate);
};
- const { closeDropdown: closeDropdownMonthSelect } = useDropdown(
- MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID,
- );
- const { closeDropdown: closeDropdownYearSelect } = useDropdown(
- MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID,
- );
+ const { closeDropdown: closeDropdownMonthSelect } = useCloseDropdown();
+ const { closeDropdown: closeDropdownYearSelect } = useCloseDropdown();
const handleEnter = () => {
- closeDropdownYearSelect();
- closeDropdownMonthSelect();
+ closeDropdownYearSelect(MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID);
+ closeDropdownMonthSelect(MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID);
onEnter(internalValue);
};
const handleEscape = () => {
- closeDropdownYearSelect();
- closeDropdownMonthSelect();
+ closeDropdownYearSelect(MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID);
+ closeDropdownMonthSelect(MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID);
onEscape(internalValue);
};
@@ -90,8 +86,8 @@ export const DateInput = ({
.getValue();
if (hotkeyScope?.scope === TableHotkeyScope.CellEditMode) {
- closeDropdownYearSelect();
- closeDropdownMonthSelect();
+ closeDropdownYearSelect(MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID);
+ closeDropdownMonthSelect(MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID);
onEscape(internalValue);
onClickOutside(event, internalValue);
}
diff --git a/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx b/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx
index 02f4ab381..8c331bfd8 100644
--- a/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx
+++ b/packages/twenty-front/src/modules/ui/input/components/IconPicker.tsx
@@ -5,7 +5,6 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { arrayToChunks } from '~/utils/array/arrayToChunks';
@@ -13,6 +12,8 @@ import { arrayToChunks } from '~/utils/array/arrayToChunks';
import { ICON_PICKER_DROPDOWN_CONTENT_WIDTH } from '@/ui/input/components/constants/IconPickerDropdownContentWidth';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
+import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
import { useSelectableListListenToEnterHotkeyOnItem } from '@/ui/layout/selectable-list/hooks/useSelectableListListenToEnterHotkeyOnItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
@@ -25,7 +26,6 @@ import {
LightIconButton,
} from 'twenty-ui/input';
import { IconPickerHotkeyScope } from '../types/IconPickerHotkeyScope';
-import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
export type IconPickerProps = {
disabled?: boolean;
@@ -137,7 +137,7 @@ export const IconPicker = ({
}
};
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const { getIcons, getIcon } = useIcons();
const icons = getIcons();
@@ -242,7 +242,7 @@ export const IconPicker = ({
iconKey={iconKey}
onClick={() => {
onChange({ iconKey, Icon: getIcon(iconKey) });
- closeDropdown();
+ closeDropdown(dropdownId);
}}
selectedIconKey={selectedIconKey}
Icon={getIcon(iconKey)}
diff --git a/packages/twenty-front/src/modules/ui/input/components/Select.tsx b/packages/twenty-front/src/modules/ui/input/components/Select.tsx
index 340156cf9..5883f9dfd 100644
--- a/packages/twenty-front/src/modules/ui/input/components/Select.tsx
+++ b/packages/twenty-front/src/modules/ui/input/components/Select.tsx
@@ -5,13 +5,13 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { SelectValue } from '@/ui/input/components/internal/select/types';
import { SelectControl } from '@/ui/input/components/SelectControl';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownHotkeyScope } from '@/ui/layout/dropdown/constants/DropdownHotkeyScope';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
@@ -116,7 +116,7 @@ export const Select = ({
!isDefined(callToActionButton) &&
(!isDefined(emptyOption) || selectedOption !== emptyOption));
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const dropDownMenuWidth =
dropdownWidthAuto && selectContainerRef.current?.clientWidth
@@ -195,7 +195,7 @@ export const Select = ({
onEnter={() => {
onChange?.(option.value);
onBlur?.();
- closeDropdown();
+ closeDropdown(dropdownId);
}}
>
({
onClick={() => {
onChange?.(option.value);
onBlur?.();
- closeDropdown();
+ closeDropdown(dropdownId);
}}
/>
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 ae6715624..0adfd5f14 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
@@ -3,12 +3,12 @@ import styled from '@emotion/styled';
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { CurrencyPickerHotkeyScope } from '../types/CurrencyPickerHotkeyScope';
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
import { Currency } from '@/ui/input/components/internal/types/Currency';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { IconChevronDown } from 'twenty-ui/display';
import { CurrencyPickerDropdownSelect } from './CurrencyPickerDropdownSelect';
@@ -52,13 +52,13 @@ export const CurrencyPickerDropdownButton = ({
}) => {
const theme = useTheme();
- const { closeDropdown } = useDropdown(
- CurrencyPickerHotkeyScope.CurrencyPicker,
- );
+ const dropdownId = CurrencyPickerHotkeyScope.CurrencyPicker;
+
+ const { closeDropdown } = useCloseDropdown();
const handleChange = (currency: Currency) => {
onChange(currency);
- closeDropdown();
+ closeDropdown(dropdownId);
};
const currency = CURRENCIES.find(
diff --git a/packages/twenty-front/src/modules/ui/input/components/internal/date/components/InternalDatePicker.tsx b/packages/twenty-front/src/modules/ui/input/components/internal/date/components/InternalDatePicker.tsx
index c4c0f02bf..c2b3bd89f 100644
--- a/packages/twenty-front/src/modules/ui/input/components/internal/date/components/InternalDatePicker.tsx
+++ b/packages/twenty-front/src/modules/ui/input/components/internal/date/components/InternalDatePicker.tsx
@@ -3,13 +3,12 @@ import { DateTime } from 'luxon';
import { lazy, Suspense, useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
-
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
import { AbsoluteDatePickerHeader } from '@/ui/input/components/internal/date/components/AbsoluteDatePickerHeader';
import { DateTimeInput } from '@/ui/input/components/internal/date/components/DateTimeInput';
import { RelativeDatePickerHeader } from '@/ui/input/components/internal/date/components/RelativeDatePickerHeader';
import { getHighlightedDates } from '@/ui/input/components/internal/date/utils/getHighlightedDates';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { UserContext } from '@/users/contexts/UserContext';
import {
VariableDateViewFilterValueDirection,
@@ -342,12 +341,8 @@ export const DateTimePicker = ({
const { timeZone } = useContext(UserContext);
const theme = useTheme();
- const { closeDropdown: closeDropdownMonthSelect } = useDropdown(
- MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID,
- );
- const { closeDropdown: closeDropdownYearSelect } = useDropdown(
- MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID,
- );
+ const { closeDropdown: closeDropdownMonthSelect } = useCloseDropdown();
+ const { closeDropdown: closeDropdownYearSelect } = useCloseDropdown();
const handleClear = () => {
closeDropdowns();
@@ -355,8 +350,8 @@ export const DateTimePicker = ({
};
const closeDropdowns = () => {
- closeDropdownYearSelect();
- closeDropdownMonthSelect();
+ closeDropdownYearSelect(MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID);
+ closeDropdownMonthSelect(MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID);
};
const handleClose = (newDate: Date) => {
diff --git a/packages/twenty-front/src/modules/ui/input/components/internal/phone/components/PhoneCountryPickerDropdownButton.tsx b/packages/twenty-front/src/modules/ui/input/components/internal/phone/components/PhoneCountryPickerDropdownButton.tsx
index 46f6bad3d..9bec7a4f9 100644
--- a/packages/twenty-front/src/modules/ui/input/components/internal/phone/components/PhoneCountryPickerDropdownButton.tsx
+++ b/packages/twenty-front/src/modules/ui/input/components/internal/phone/components/PhoneCountryPickerDropdownButton.tsx
@@ -1,13 +1,15 @@
import { useCountries } from '@/ui/input/components/internal/hooks/useCountries';
import { Country } from '@/ui/input/components/internal/types/Country';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useEffect, useState } from 'react';
import { PhoneCountryPickerDropdownSelect } from './PhoneCountryPickerDropdownSelect';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import 'react-phone-number-input/style.css';
import { isDefined } from 'twenty-shared/utils';
import { IconChevronDown, IconWorld } from 'twenty-ui/display';
@@ -75,12 +77,17 @@ export const PhoneCountryPickerDropdownButton = ({
const [selectedCountry, setSelectedCountry] = useState();
- const { isDropdownOpen, closeDropdown } = useDropdown(
- 'country-picker-dropdown-id',
+ const dropdownId = 'country-picker-dropdown-id';
+
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ dropdownId,
);
+ const { closeDropdown } = useCloseDropdown();
+
const handleChange = (countryCode: string) => {
- closeDropdown();
+ closeDropdown(dropdownId);
onChange(countryCode);
};
diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx
index 3c956392d..6964ae7a1 100644
--- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx
+++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/Dropdown.tsx
@@ -3,11 +3,14 @@ import { DropdownInternalContainer } from '@/ui/layout/dropdown/components/inter
import { DROPDOWN_RESIZE_MIN_HEIGHT } from '@/ui/layout/dropdown/constants/DropdownResizeMinHeight';
import { DROPDOWN_RESIZE_MIN_WIDTH } from '@/ui/layout/dropdown/constants/DropdownResizeMinWidth';
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
+import { useToggleDropdown } from '@/ui/layout/dropdown/hooks/useToggleDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { dropdownMaxHeightComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxHeightComponentState';
import { dropdownMaxWidthComponentState } from '@/ui/layout/dropdown/states/internal/dropdownMaxWidthComponentState';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
import { GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
+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';
import {
@@ -24,7 +27,6 @@ import { Keys } from 'react-hotkeys-hook';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { useIsMobile } from 'twenty-ui/utilities';
-import { useDropdown } from '../hooks/useDropdown';
type Width = `${string}px` | `${number}%` | 'auto' | number;
const StyledDropdownFallbackAnchor = styled.div`
@@ -75,7 +77,12 @@ export const Dropdown = ({
excludedClickOutsideIds,
isDropdownInModal = false,
}: DropdownProps) => {
- const { isDropdownOpen, toggleDropdown } = useDropdown(dropdownId);
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ dropdownId,
+ );
+
+ const { toggleDropdown } = useToggleDropdown();
const isUsingOffset =
isDefined(dropdownOffset?.x) || isDefined(dropdownOffset?.y);
@@ -147,10 +154,12 @@ export const Dropdown = ({
event.stopPropagation();
event.preventDefault();
- toggleDropdown(globalHotkeysConfig);
- onClickOutside?.();
+ toggleDropdown({
+ dropdownComponentInstanceIdFromProps: dropdownId,
+ globalHotkeysConfig,
+ });
},
- [globalHotkeysConfig, onClickOutside, toggleDropdown],
+ [globalHotkeysConfig, toggleDropdown, dropdownId],
);
return (
diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInnerSelect.tsx b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInnerSelect.tsx
index 433e7de5b..ff708c87d 100644
--- a/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInnerSelect.tsx
+++ b/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuInnerSelect.tsx
@@ -1,7 +1,7 @@
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
@@ -43,7 +43,7 @@ export const DropdownMenuInnerSelect = ({
}: DropdownMenuInnerSelectProps) => {
const theme = useTheme();
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
return (
{
onChange(selectOption);
- closeDropdown();
+ closeDropdown(dropdownId);
}}
text={selectOption.label}
disabled={selectOption.disabled}
diff --git a/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useToggleDropdown.ts b/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useToggleDropdown.ts
index dcc832f38..5454d2ec4 100644
--- a/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useToggleDropdown.ts
+++ b/packages/twenty-front/src/modules/ui/layout/dropdown/hooks/useToggleDropdown.ts
@@ -7,6 +7,11 @@ import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
+type ToggleDropdownArgs = {
+ dropdownComponentInstanceIdFromProps?: string;
+ globalHotkeysConfig?: Partial;
+};
+
export const useToggleDropdown = () => {
const dropdownComponentInstanceIdFromContext =
useAvailableComponentInstanceId(DropdownComponentInstanceContext);
@@ -16,15 +21,9 @@ export const useToggleDropdown = () => {
const toggleDropdown = useRecoilCallback(
({ snapshot }) =>
- ({
- dropdownComponentInstanceIdFromProps,
- globalHotkeysConfig,
- }: {
- dropdownComponentInstanceIdFromProps?: string;
- globalHotkeysConfig?: Partial;
- }) => {
+ (args?: ToggleDropdownArgs | null | undefined) => {
const dropdownComponentInstanceId =
- dropdownComponentInstanceIdFromProps ??
+ args?.dropdownComponentInstanceIdFromProps ??
dropdownComponentInstanceIdFromContext;
if (!isDefined(dropdownComponentInstanceId)) {
@@ -44,7 +43,7 @@ export const useToggleDropdown = () => {
} else {
openDropdown({
dropdownComponentInstanceIdFromProps: dropdownComponentInstanceId,
- globalHotkeysConfig,
+ globalHotkeysConfig: args?.globalHotkeysConfig,
});
}
},
diff --git a/packages/twenty-front/src/modules/ui/layout/tab-list/components/TabList.tsx b/packages/twenty-front/src/modules/ui/layout/tab-list/components/TabList.tsx
index c985de3bb..da67b67e1 100644
--- a/packages/twenty-front/src/modules/ui/layout/tab-list/components/TabList.tsx
+++ b/packages/twenty-front/src/modules/ui/layout/tab-list/components/TabList.tsx
@@ -1,4 +1,4 @@
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { TAB_LIST_GAP } from '@/ui/layout/tab-list/constants/TabListGap';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/contexts/TabListComponentInstanceContext';
@@ -87,7 +87,7 @@ export const TabList = ({
const hasHiddenTabs = hiddenTabsCount > 0;
const dropdownId = `tab-overflow-${componentInstanceId}`;
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const isActiveTabHidden = useMemo(() => {
if (!hasHiddenTabs) return false;
@@ -215,7 +215,7 @@ export const TabList = ({
{
- closeDropdown();
+ closeDropdown(dropdownId);
}}
overflow={{
hiddenTabsCount,
diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx
index 64bf94f6c..bc73c7be9 100644
--- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx
+++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx
@@ -16,7 +16,7 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { MULTI_WORKSPACE_DROPDOWN_ID } from '@/ui/navigation/navigation-drawer/constants/MultiWorkspaceDropdownId';
import { multiWorkspaceDropdownState } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownState';
import { useColorScheme } from '@/ui/theme/hooks/useColorScheme';
@@ -57,7 +57,7 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
const availableWorkspacesCount =
countAvailableWorkspaces(availableWorkspaces);
const { buildWorkspaceUrl } = useBuildWorkspaceUrl();
- const { closeDropdown } = useDropdown(MULTI_WORKSPACE_DROPDOWN_ID);
+ const { closeDropdown } = useCloseDropdown();
const { signOut } = useAuth();
const { enqueueSnackBar } = useSnackBar();
const { colorScheme, colorSchemeList } = useColorScheme();
@@ -195,7 +195,9 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
/>
{
+ closeDropdown(MULTI_WORKSPACE_DROPDOWN_ID);
+ }}
>
diff --git a/packages/twenty-front/src/modules/views/components/AdvancedFilterChip.tsx b/packages/twenty-front/src/modules/views/components/AdvancedFilterChip.tsx
index 83aaded8d..b83e6e2d6 100644
--- a/packages/twenty-front/src/modules/views/components/AdvancedFilterChip.tsx
+++ b/packages/twenty-front/src/modules/views/components/AdvancedFilterChip.tsx
@@ -9,7 +9,7 @@ import { SOFT_DELETE_FILTER_FIELD_NAME } from '@/object-record/record-filter/con
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { getAllRecordFilterDescendantsOfRecordFilterGroup } from '@/object-record/record-filter/utils/getAllRecordFilterDescendantsOfRecordFilterGroup';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
@@ -19,7 +19,7 @@ import { isDefined } from 'twenty-shared/utils';
import { IconFilter } from 'twenty-ui/display';
export const AdvancedFilterChip = () => {
- const { closeDropdown } = useDropdown(ADVANCED_FILTER_DROPDOWN_ID);
+ const { closeDropdown } = useCloseDropdown();
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
@@ -49,7 +49,7 @@ export const AdvancedFilterChip = () => {
});
const handleRemoveClick = () => {
- closeDropdown();
+ closeDropdown(ADVANCED_FILTER_DROPDOWN_ID);
const viewFilterGroupIds = currentRecordFilterGroups.map(
(recordFilterGroup) => recordFilterGroup.id,
diff --git a/packages/twenty-front/src/modules/views/components/EditableFilterDropdownButton.tsx b/packages/twenty-front/src/modules/views/components/EditableFilterDropdownButton.tsx
index 468c589b5..4f2279091 100644
--- a/packages/twenty-front/src/modules/views/components/EditableFilterDropdownButton.tsx
+++ b/packages/twenty-front/src/modules/views/components/EditableFilterDropdownButton.tsx
@@ -2,12 +2,12 @@ import { useCallback } from 'react';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { EditableFilterChip } from '@/views/components/EditableFilterChip';
import { ObjectFilterDropdownFilterInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterInput';
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useSetEditableFilterChipDropdownStates } from '@/views/hooks/useSetEditableFilterChipDropdownStates';
type EditableFilterDropdownButtonProps = {
@@ -17,12 +17,14 @@ type EditableFilterDropdownButtonProps = {
export const EditableFilterDropdownButton = ({
recordFilter,
}: EditableFilterDropdownButtonProps) => {
- const { closeDropdown } = useDropdown(recordFilter.id);
+ const dropdownId = recordFilter.id;
+
+ const { closeDropdown } = useCloseDropdown();
const { removeRecordFilter } = useRemoveRecordFilter();
const handleRemove = () => {
- closeDropdown();
+ closeDropdown(dropdownId);
removeRecordFilter({ recordFilterId: recordFilter.id });
};
diff --git a/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx b/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx
index 639e9f933..e0af55c4e 100644
--- a/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx
+++ b/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx
@@ -4,7 +4,8 @@ import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
+import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
@@ -43,12 +44,8 @@ export const UpdateViewButtonGroup = () => {
contextStoreCurrentViewIdComponentState,
);
- const { closeDropdown: closeUpdateViewButtonDropdown } = useDropdown(
- UPDATE_VIEW_BUTTON_DROPDOWN_ID,
- );
- const { openDropdown: openViewPickerDropdown } = useDropdown(
- VIEW_PICKER_DROPDOWN_ID,
- );
+ const { closeDropdown: closeUpdateViewButtonDropdown } = useCloseDropdown();
+ const { openDropdown: openViewPickerDropdown } = useOpenDropdown();
const { currentView } = useGetCurrentViewOnly();
const setViewPickerReferenceViewId = useSetRecoilComponentStateV2(
@@ -60,11 +57,13 @@ export const UpdateViewButtonGroup = () => {
return;
}
- openViewPickerDropdown();
+ openViewPickerDropdown({
+ dropdownComponentInstanceIdFromProps: VIEW_PICKER_DROPDOWN_ID,
+ });
setViewPickerReferenceViewId(currentViewId);
setViewPickerMode('create-from-current');
- closeUpdateViewButtonDropdown();
+ closeUpdateViewButtonDropdown(UPDATE_VIEW_BUTTON_DROPDOWN_ID);
};
const handleCreateViewClick = () => {
diff --git a/packages/twenty-front/src/modules/views/components/ViewBarDetailsAddFilterButton.tsx b/packages/twenty-front/src/modules/views/components/ViewBarDetailsAddFilterButton.tsx
index 26f87ccc2..c3de68375 100644
--- a/packages/twenty-front/src/modules/views/components/ViewBarDetailsAddFilterButton.tsx
+++ b/packages/twenty-front/src/modules/views/components/ViewBarDetailsAddFilterButton.tsx
@@ -1,13 +1,13 @@
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId';
import { useResetFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useResetFilterDropdown';
+import { useToggleDropdown } from '@/ui/layout/dropdown/hooks/useToggleDropdown';
import { t } from '@lingui/core/macro';
import { IconPlus } from 'twenty-ui/display';
import { LightButton } from 'twenty-ui/input';
export const ViewBarDetailsAddFilterButton = () => {
- const { toggleDropdown } = useDropdown(VIEW_BAR_FILTER_DROPDOWN_ID);
+ const { toggleDropdown } = useToggleDropdown();
const { resetFilterDropdown } = useResetFilterDropdown(
VIEW_BAR_FILTER_DROPDOWN_ID,
@@ -15,7 +15,9 @@ export const ViewBarDetailsAddFilterButton = () => {
const handleClick = () => {
resetFilterDropdown();
- toggleDropdown();
+ toggleDropdown({
+ dropdownComponentInstanceIdFromProps: VIEW_BAR_FILTER_DROPDOWN_ID,
+ });
};
return (
diff --git a/packages/twenty-front/src/modules/views/components/ViewBarFilterButton.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterButton.tsx
index 305798f2f..32f43e15d 100644
--- a/packages/twenty-front/src/modules/views/components/ViewBarFilterButton.tsx
+++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterButton.tsx
@@ -1,10 +1,14 @@
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId';
import { Trans } from '@lingui/react/macro';
export const ViewBarFilterButton = () => {
- const { isDropdownOpen } = useDropdown(VIEW_BAR_FILTER_DROPDOWN_ID);
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
+ VIEW_BAR_FILTER_DROPDOWN_ID,
+ );
return (
diff --git a/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdown.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdown.tsx
index d93ca6d7b..8f3101729 100644
--- a/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdown.tsx
+++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdown.tsx
@@ -3,7 +3,6 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId';
import { useVectorSearchFilterActions } from '@/views/hooks/useVectorSearchFilterActions';
-import { OPERAND_DROPDOWN_CLICK_OUTSIDE_ID } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownOperandDropdown';
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty';
@@ -53,7 +52,6 @@ export const ViewBarFilterDropdown = () => {
dropdownComponents={}
dropdownOffset={{ y: 8 }}
onClickOutside={handleDropdownClickOutside}
- excludedClickOutsideIds={[OPERAND_DROPDOWN_CLICK_OUTSIDE_ID]}
/>
);
};
diff --git a/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx
index 596847e39..17e581d11 100644
--- a/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx
+++ b/packages/twenty-front/src/modules/views/components/ViewBarFilterDropdownAdvancedFilterButton.tsx
@@ -12,7 +12,8 @@ import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDrop
import { useSetRecordFilterUsedInAdvancedFilterDropdownRow } from '@/object-record/advanced-filter/hooks/useSetRecordFilterUsedInAdvancedFilterDropdownRow';
import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator';
import { useCreateEmptyRecordFilterFromFieldMetadataItem } from '@/object-record/record-filter/hooks/useCreateEmptyRecordFilterFromFieldMetadataItem';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
+import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
@@ -40,13 +41,9 @@ export const ViewBarFilterDropdownAdvancedFilterButton = () => {
VIEW_BAR_FILTER_BOTTOM_MENU_ITEM_IDS.ADVANCED_FILTER,
);
- const { openDropdown: openAdvancedFilterDropdown } = useDropdown(
- ADVANCED_FILTER_DROPDOWN_ID,
- );
+ const { openDropdown: openAdvancedFilterDropdown } = useOpenDropdown();
- const { closeDropdown: closeObjectFilterDropdown } = useDropdown(
- VIEW_BAR_FILTER_DROPDOWN_ID,
- );
+ const { closeDropdown: closeObjectFilterDropdown } = useCloseDropdown();
const { currentView } = useGetCurrentViewOnly();
@@ -118,8 +115,10 @@ export const ViewBarFilterDropdownAdvancedFilterButton = () => {
setRecordFilterUsedInAdvancedFilterDropdownRow(newRecordFilter);
}
- closeObjectFilterDropdown();
- openAdvancedFilterDropdown();
+ closeObjectFilterDropdown(VIEW_BAR_FILTER_DROPDOWN_ID);
+ openAdvancedFilterDropdown({
+ dropdownComponentInstanceIdFromProps: ADVANCED_FILTER_DROPDOWN_ID,
+ });
};
return (
diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx
index 17bc9e411..afbeadac1 100644
--- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx
+++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerDropdown.tsx
@@ -3,7 +3,8 @@ import styled from '@emotion/styled';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { isDropdownOpenComponentStateV2 } from '@/ui/layout/dropdown/states/isDropdownOpenComponentStateV2';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useGetRecordIndexTotalCount } from '@/views/hooks/internal/useGetRecordIndexTotalCount';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { ViewPickerContentCreateMode } from '@/views/view-picker/components/ViewPickerContentCreateMode';
@@ -51,7 +52,8 @@ export const ViewPickerDropdown = () => {
const { totalCount } = useGetRecordIndexTotalCount();
- const { isDropdownOpen: isViewsListDropdownOpen } = useDropdown(
+ const isDropdownOpen = useRecoilComponentValueV2(
+ isDropdownOpenComponentStateV2,
VIEW_PICKER_DROPDOWN_ID,
);
@@ -61,7 +63,7 @@ export const ViewPickerDropdown = () => {
const CurrentViewIcon = getIcon(currentView?.icon);
const handleClickOutside = async () => {
- if (isViewsListDropdownOpen && viewPickerMode === 'edit') {
+ if (isDropdownOpen && viewPickerMode === 'edit') {
await updateViewFromCurrentState();
}
setViewPickerMode('list');
@@ -74,7 +76,7 @@ export const ViewPickerDropdown = () => {
dropdownPlacement="bottom-start"
onClickOutside={handleClickOutside}
clickableComponent={
-
+
{currentView && CurrentViewIcon ? (
) : (
diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx
index 3090a54a3..4f85a182e 100644
--- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx
+++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx
@@ -9,7 +9,7 @@ import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableLi
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { useChangeView } from '@/views/hooks/useChangeView';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
@@ -51,11 +51,11 @@ export const ViewPickerListContent = () => {
const { updateView } = useUpdateView();
const { changeView } = useChangeView();
- const { closeDropdown } = useDropdown(VIEW_PICKER_DROPDOWN_ID);
+ const { closeDropdown } = useCloseDropdown();
const handleViewSelect = (viewId: string) => {
changeView(viewId);
- closeDropdown();
+ closeDropdown(VIEW_PICKER_DROPDOWN_ID);
};
const handleAddViewButtonClick = () => {
diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
index c7ffe2867..170abb015 100644
--- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
+++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerOptionDropdown.tsx
@@ -2,7 +2,7 @@ import { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite';
import { useFavorites } from '@/favorites/hooks/useFavorites';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { MenuItemWithOptionDropdown } from '@/ui/navigation/menu-item/components/MenuItemWithOptionDropdown';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { View } from '@/views/types/View';
@@ -33,8 +33,10 @@ export const ViewPickerOptionDropdown = ({
view,
handleViewSelect,
}: ViewPickerOptionDropdownProps) => {
+ const dropdownId = `view-picker-options-${view.id}`;
+
const { t } = useLingui();
- const { closeDropdown } = useDropdown(`view-picker-options-${view.id}`);
+ const { closeDropdown } = useCloseDropdown();
const { getIcon } = useIcons();
const [isHovered, setIsHovered] = useState(false);
const { deleteViewFromCurrentState } = useDeleteViewFromCurrentState();
@@ -54,7 +56,7 @@ export const ViewPickerOptionDropdown = ({
const handleDelete = () => {
setViewPickerReferenceViewId(view.id);
deleteViewFromCurrentState();
- closeDropdown();
+ closeDropdown(dropdownId);
};
const handleAddToFavorites = () => {
@@ -64,7 +66,7 @@ export const ViewPickerOptionDropdown = ({
setViewPickerReferenceViewId(view.id);
setViewPickerMode('favorite-folders-picker');
}
- closeDropdown();
+ closeDropdown(dropdownId);
};
return (
@@ -103,7 +105,7 @@ export const ViewPickerOptionDropdown = ({
text={t`Edit`}
onClick={(event) => {
onEdit(event, view.id);
- closeDropdown();
+ closeDropdown(dropdownId);
}}
/>
{
diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems.tsx b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems.tsx
index 4565b0116..d2ebaf949 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems.tsx
@@ -4,12 +4,12 @@ import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
-import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
+import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
import { useState } from 'react';
import { IconX, OverflowingTextWithTooltip, useIcons } from 'twenty-ui/display';
import { MenuItem, MenuItemSelect } from 'twenty-ui/navigation';
-import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
type WorkflowVariablesDropdownWorkflowStepItemsProps = {
dropdownId: string;
@@ -25,7 +25,7 @@ export const WorkflowVariablesDropdownWorkflowStepItems = ({
const { getIcon } = useIcons();
const [searchInputValue, setSearchInputValue] = useState('');
- const { closeDropdown } = useDropdown(dropdownId);
+ const { closeDropdown } = useCloseDropdown();
const availableSteps = steps.filter((step) =>
searchInputValue
@@ -38,7 +38,7 @@ export const WorkflowVariablesDropdownWorkflowStepItems = ({
closeDropdown(dropdownId)}
Icon={IconX}
/>
}