@@ -9,6 +9,8 @@ import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { RootDecorator } from '../src/testing/decorators/RootDecorator';
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { resetJotaiStore } from '../src/modules/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
import 'react-loading-skeleton/dist/skeleton.css';
|
||||
import 'twenty-ui/style.css';
|
||||
@@ -84,6 +86,10 @@ const preview: Preview = {
|
||||
RootDecorator,
|
||||
],
|
||||
|
||||
beforeEach: () => {
|
||||
resetJotaiStore();
|
||||
},
|
||||
|
||||
loaders: [mswLoader],
|
||||
|
||||
parameters: {
|
||||
|
||||
+41
-35
@@ -1,4 +1,5 @@
|
||||
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import * as test from 'storybook/test';
|
||||
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
||||
@@ -10,6 +11,7 @@ import { ActionMenuComponentInstanceContext } from '@/action-menu/states/context
|
||||
import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-menu/states/recordIndexActionMenuDropdownPositionComponentState';
|
||||
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { RouterDecorator } from 'twenty-ui/testing';
|
||||
import { ContextStoreDecorator } from '~/testing/decorators/ContextStoreDecorator';
|
||||
|
||||
@@ -21,44 +23,48 @@ const meta: Meta<typeof RecordIndexActionMenuDropdown> = {
|
||||
title: 'Modules/ActionMenu/RecordIndexActionMenuDropdown',
|
||||
component: RecordIndexActionMenuDropdown,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<RecoilRoot
|
||||
initializeState={({ set }) => {
|
||||
set(
|
||||
recordIndexActionMenuDropdownPositionComponentState.atomFamily({
|
||||
instanceId: 'action-menu-dropdown-story',
|
||||
}),
|
||||
{ x: 10, y: 10 },
|
||||
);
|
||||
(Story) => {
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: 'action-menu-dropdown-story-action-menu',
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: 'action-menu-dropdown-story-action-menu',
|
||||
}),
|
||||
true,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ActionMenuComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'story-action-menu' }}
|
||||
>
|
||||
<ActionMenuContext.Provider
|
||||
value={{
|
||||
isInRightDrawer: true,
|
||||
displayType: 'dropdownItem',
|
||||
actionMenuType: 'index-page-action-menu-dropdown',
|
||||
actions: createMockActionMenuActions({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
exportMock,
|
||||
}),
|
||||
return (
|
||||
<JotaiProvider store={jotaiStore}>
|
||||
<RecoilRoot
|
||||
initializeState={({ set }) => {
|
||||
set(
|
||||
recordIndexActionMenuDropdownPositionComponentState.atomFamily({
|
||||
instanceId: 'action-menu-dropdown-story',
|
||||
}),
|
||||
{ x: 10, y: 10 },
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
</ActionMenuContext.Provider>
|
||||
</ActionMenuComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
),
|
||||
<ActionMenuComponentInstanceContext.Provider
|
||||
value={{ instanceId: 'story-action-menu' }}
|
||||
>
|
||||
<ActionMenuContext.Provider
|
||||
value={{
|
||||
isInRightDrawer: true,
|
||||
displayType: 'dropdownItem',
|
||||
actionMenuType: 'index-page-action-menu-dropdown',
|
||||
actions: createMockActionMenuActions({
|
||||
deleteMock,
|
||||
addToFavoritesMock,
|
||||
exportMock,
|
||||
}),
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
</ActionMenuContext.Provider>
|
||||
</ActionMenuComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
</JotaiProvider>
|
||||
);
|
||||
},
|
||||
ContextStoreDecorator,
|
||||
RouterDecorator,
|
||||
],
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import {
|
||||
} from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
export type CommandMenuItemDropdownProps = CommandMenuItemProps &
|
||||
Pick<
|
||||
@@ -31,7 +31,7 @@ export const CommandMenuItemDropdown = ({
|
||||
dropdownId,
|
||||
disabled = false,
|
||||
}: CommandMenuItemDropdownProps) => {
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-1
@@ -26,6 +26,7 @@ import { currentFavoriteFolderIdStateV2 } from '@/ui/navigation/navigation-drawe
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { getNavigationSubItemLeftAdornment } from '@/ui/navigation/navigation-drawer/utils/getNavigationSubItemLeftAdornment';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { Droppable } from '@hello-pangea/dnd';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext, useState } from 'react';
|
||||
@@ -95,7 +96,7 @@ export const CurrentWorkspaceMemberFavorites = ({
|
||||
|
||||
const dropdownId = `favorite-folder-edit-${folder.folderId}`;
|
||||
|
||||
const isDropdownOpenComponent = useRecoilComponentValue(
|
||||
const isDropdownOpenComponent = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-1
@@ -45,6 +45,7 @@ import { currentNavigationMenuItemFolderIdStateV2 } from '@/ui/navigation/naviga
|
||||
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
|
||||
import { getNavigationSubItemLeftAdornment } from '@/ui/navigation/navigation-drawer/utils/getNavigationSubItemLeftAdornment';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@@ -123,7 +124,7 @@ export const CurrentWorkspaceMemberNavigationMenuItems = ({
|
||||
|
||||
const dropdownId = `navigation-menu-item-folder-edit-${folder.id}`;
|
||||
|
||||
const isDropdownOpenComponent = useRecoilComponentValue(
|
||||
const isDropdownOpenComponent = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ 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 { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { type ViewType } from '@/views/types/ViewType';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
|
||||
@@ -28,7 +28,7 @@ export const ObjectOptionsDropdown = ({
|
||||
const { currentContentId, handleContentChange, handleResetContent } =
|
||||
useDropdownContextCurrentContentId<ObjectOptionsContentId>();
|
||||
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
@@ -138,7 +139,7 @@ export const ObjectSortDropdownButton = () => {
|
||||
setIsRecordSortDirectionMenuUnfolded(false);
|
||||
};
|
||||
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
OBJECT_SORT_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { type Nullable } from 'twenty-shared/types';
|
||||
import { Tag } from 'twenty-ui/components';
|
||||
@@ -23,7 +23,7 @@ export const RecordBoardColumnHeaderAggregateDropdownButton = ({
|
||||
value?: Nullable<string | number>;
|
||||
tooltip?: Nullable<string>;
|
||||
}) => {
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ import { type FieldMorphRelationMetadata } from '@/object-record/record-field/ui
|
||||
import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
import { RecordDetailMorphRelationSectionDropdown } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailMorphRelationSectionDropdown';
|
||||
import { RecordDetailRelationRecordsList } from '@/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsList';
|
||||
@@ -49,7 +49,7 @@ export const RecordDetailMorphRelationSection = ({
|
||||
instanceId: scopeInstanceId,
|
||||
});
|
||||
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/reco
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -65,7 +65,7 @@ export const RecordDetailMorphRelationSectionDropdownManyToOne = ({
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const dropdownPlacement = useRecoilComponentValue(
|
||||
const dropdownPlacement = useRecoilComponentValueV2(
|
||||
dropdownPlacementComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { CustomError, isDefined } from 'twenty-shared/utils';
|
||||
@@ -68,7 +68,7 @@ export const RecordDetailMorphRelationSectionDropdownOneToMany = ({
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const dropdownPlacement = useRecoilComponentValue(
|
||||
const dropdownPlacement = useRecoilComponentValueV2(
|
||||
dropdownPlacementComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
@@ -152,7 +152,7 @@ export const RecordDetailRelationRecordsListItem = ({
|
||||
const dropdownInstanceId = `record-field-card-menu:${scopeInstanceId}:${relationFieldMetadataId}:${relationRecord.id}`;
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownInstanceId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import { AggregateOperations } from '@/object-record/record-table/constants/Aggr
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { coreIndexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreIndexViewIdFromObjectMetadataItemFamilySelector';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import {
|
||||
@@ -100,7 +100,7 @@ export const RecordDetailRelationSection = ({
|
||||
instanceId: scopeInstanceId,
|
||||
});
|
||||
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { CustomError, isDefined } from 'twenty-shared/utils';
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
@@ -85,7 +85,7 @@ export const RecordDetailRelationSectionDropdownToMany = ({
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const dropdownPlacement = useRecoilComponentValue(
|
||||
const dropdownPlacement = useRecoilComponentValueV2(
|
||||
dropdownPlacementComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { dropdownPlacementComponentState } from '@/ui/layout/dropdown/states/dropdownPlacementComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
@@ -96,7 +96,7 @@ export const RecordDetailRelationSectionDropdownToOne = ({
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const dropdownPlacement = useRecoilComponentValue(
|
||||
const dropdownPlacement = useRecoilComponentValueV2(
|
||||
dropdownPlacementComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDrop
|
||||
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
@@ -128,7 +128,7 @@ export const FormArrayFieldInput = ({
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const dropdownId = `dropdown-${instanceId}`;
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { MenuItemWithOptionDropdown } from '@/ui/navigation/menu-item/components/MenuItemWithOptionDropdown';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
IconBookmark,
|
||||
@@ -44,7 +44,7 @@ export const MultiItemFieldMenuItem = <T,>({
|
||||
}: MultiItemFieldMenuItemProps<T>) => {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+26
-27
@@ -19,7 +19,7 @@ import { usePersistFieldFromFieldInputContext } from '@/object-record/record-fie
|
||||
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
||||
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { RecordInlineCellContainer } from './RecordInlineCellContainer';
|
||||
import {
|
||||
@@ -133,37 +133,36 @@ export const RecordInlineCell = ({
|
||||
closeInlineCell();
|
||||
};
|
||||
|
||||
const handleClickOutside = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
({
|
||||
event,
|
||||
newValue,
|
||||
skipPersist,
|
||||
}: Parameters<FieldInputClickOutsideEvent>[0]) => {
|
||||
const currentDropdownFocusId = snapshot
|
||||
.getLoadable(activeDropdownFocusIdState)
|
||||
.getValue();
|
||||
const handleClickOutside = useCallback(
|
||||
({
|
||||
event,
|
||||
newValue,
|
||||
skipPersist,
|
||||
}: Parameters<FieldInputClickOutsideEvent>[0]) => {
|
||||
const currentDropdownFocusId = jotaiStore.get(
|
||||
activeDropdownFocusIdState.atom,
|
||||
);
|
||||
|
||||
const expectedDropdownFocusId = getDropdownFocusIdForRecordField({
|
||||
recordId,
|
||||
fieldMetadataId: fieldDefinition.fieldMetadataId,
|
||||
componentType: 'inline-cell',
|
||||
instanceId: scopeInstanceId,
|
||||
});
|
||||
const expectedDropdownFocusId = getDropdownFocusIdForRecordField({
|
||||
recordId,
|
||||
fieldMetadataId: fieldDefinition.fieldMetadataId,
|
||||
componentType: 'inline-cell',
|
||||
instanceId: scopeInstanceId,
|
||||
});
|
||||
|
||||
if (currentDropdownFocusId !== expectedDropdownFocusId) {
|
||||
return;
|
||||
}
|
||||
if (currentDropdownFocusId !== expectedDropdownFocusId) {
|
||||
return;
|
||||
}
|
||||
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
|
||||
closeInlineCell();
|
||||
},
|
||||
closeInlineCell();
|
||||
},
|
||||
[
|
||||
recordId,
|
||||
fieldDefinition.fieldMetadataId,
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@ import { RecordTableColumnAggregateFooterValue } from '@/object-record/record-ta
|
||||
import { hasAggregateOperationForViewFieldFamilySelector } from '@/object-record/record-table/record-table-footer/states/hasAggregateOperationForViewFieldFamilySelector';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext, useState } from 'react';
|
||||
@@ -57,7 +58,7 @@ export const RecordTableColumnAggregateFooterValueCell = ({
|
||||
}) => {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+26
-27
@@ -24,7 +24,7 @@ import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropd
|
||||
import { FieldWidgetInlineCellContainer } from '@/page-layout/widgets/field/components/FieldWidgetInlineCellContainer';
|
||||
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
type FieldWidgetInlineCellProps = {
|
||||
loading?: boolean;
|
||||
@@ -132,37 +132,36 @@ export const FieldWidgetInlineCell = ({
|
||||
closeInlineCell();
|
||||
};
|
||||
|
||||
const handleClickOutside = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
({
|
||||
event,
|
||||
newValue,
|
||||
skipPersist,
|
||||
}: Parameters<FieldInputClickOutsideEvent>[0]) => {
|
||||
const currentDropdownFocusId = snapshot
|
||||
.getLoadable(activeDropdownFocusIdState)
|
||||
.getValue();
|
||||
const handleClickOutside = useCallback(
|
||||
({
|
||||
event,
|
||||
newValue,
|
||||
skipPersist,
|
||||
}: Parameters<FieldInputClickOutsideEvent>[0]) => {
|
||||
const currentDropdownFocusId = jotaiStore.get(
|
||||
activeDropdownFocusIdState.atom,
|
||||
);
|
||||
|
||||
const expectedDropdownFocusId = getDropdownFocusIdForRecordField({
|
||||
recordId,
|
||||
fieldMetadataId: fieldDefinition.fieldMetadataId,
|
||||
componentType: 'inline-cell',
|
||||
instanceId: scopeInstanceId,
|
||||
});
|
||||
const expectedDropdownFocusId = getDropdownFocusIdForRecordField({
|
||||
recordId,
|
||||
fieldMetadataId: fieldDefinition.fieldMetadataId,
|
||||
componentType: 'inline-cell',
|
||||
instanceId: scopeInstanceId,
|
||||
});
|
||||
|
||||
if (currentDropdownFocusId !== expectedDropdownFocusId) {
|
||||
return;
|
||||
}
|
||||
if (currentDropdownFocusId !== expectedDropdownFocusId) {
|
||||
return;
|
||||
}
|
||||
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
|
||||
closeInlineCell();
|
||||
},
|
||||
closeInlineCell();
|
||||
},
|
||||
[
|
||||
closeInlineCell,
|
||||
recordId,
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import { isFieldMorphRelation } from '@/object-record/record-field/ui/types/guar
|
||||
import { getRecordFieldCardRelationPickerDropdownId } from '@/object-record/record-show/utils/getRecordFieldCardRelationPickerDropdownId';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { CustomError } from 'twenty-shared/utils';
|
||||
@@ -99,7 +99,7 @@ export const FieldWidgetRelationEditAction = ({
|
||||
instanceId: scopeInstanceId,
|
||||
});
|
||||
|
||||
const isRelationSelectionDropdownOpen = useRecoilComponentValue(
|
||||
const isRelationSelectionDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
relationSelectionDropdownId,
|
||||
);
|
||||
|
||||
@@ -13,7 +13,7 @@ import { SELECT_COUNTRY_DROPDOWN_ID } from '@/ui/input/components/internal/count
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { MOBILE_VIEWPORT } from 'twenty-ui/theme';
|
||||
import { v4 } from 'uuid';
|
||||
@@ -236,7 +236,7 @@ export const AddressInput = ({
|
||||
onShiftTab: handleShiftTab,
|
||||
});
|
||||
|
||||
const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState);
|
||||
const activeDropdownFocusId = useRecoilValueV2(activeDropdownFocusIdState);
|
||||
|
||||
useListenClickOutside({
|
||||
refs: [wrapperRef],
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ import { PhoneCountryPickerDropdownSelect } from './PhoneCountryPickerDropdownSe
|
||||
import { PHONE_COUNTRY_CODE_PICKER_DROPDOWN_ID } from '@/ui/input/components/internal/phone/constants/PhoneCountryCodePickerDropdownId';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import 'react-phone-number-input/style.css';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconChevronDown, IconWorld } from 'twenty-ui/display';
|
||||
@@ -78,7 +78,7 @@ export const PhoneCountryPickerDropdownButton = ({
|
||||
|
||||
const [selectedCountry, setSelectedCountry] = useState<Country>();
|
||||
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
PHONE_COUNTRY_CODE_PICKER_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
@@ -13,8 +13,8 @@ import { dropdownYPositionComponentState } from '@/ui/layout/dropdown/states/int
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { type DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
|
||||
import { type GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import {
|
||||
type Placement,
|
||||
@@ -24,10 +24,9 @@ import {
|
||||
size,
|
||||
useFloating,
|
||||
} from '@floating-ui/react';
|
||||
import { type MouseEvent, type ReactNode } from 'react';
|
||||
import { type MouseEvent, type ReactNode, useCallback } from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
import { type Keys } from 'react-hotkeys-hook';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIsMobile } from 'twenty-ui/utilities';
|
||||
|
||||
@@ -89,7 +88,7 @@ export const Dropdown = ({
|
||||
disableClickForClickableComponent = false,
|
||||
middlewareBoundaryPadding = {},
|
||||
}: DropdownProps) => {
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
@@ -108,17 +107,17 @@ export const Dropdown = ({
|
||||
]
|
||||
: [];
|
||||
|
||||
const setDropdownMaxHeight = useSetRecoilComponentState(
|
||||
const setDropdownMaxHeight = useSetRecoilComponentStateV2(
|
||||
dropdownMaxHeightComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const setDropdownMaxWidth = useSetRecoilComponentState(
|
||||
const setDropdownMaxWidth = useSetRecoilComponentStateV2(
|
||||
dropdownMaxWidthComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const setDropdownYPosition = useSetRecoilComponentState(
|
||||
const setDropdownYPosition = useSetRecoilComponentStateV2(
|
||||
dropdownYPositionComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
@@ -173,8 +172,8 @@ export const Dropdown = ({
|
||||
strategy: dropdownStrategy,
|
||||
});
|
||||
|
||||
const handleClickableComponentClick = useRecoilCallback(
|
||||
() => async (event: MouseEvent) => {
|
||||
const handleClickableComponentClick = useCallback(
|
||||
async (event: MouseEvent) => {
|
||||
if (disableClickForClickableComponent) return;
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
+4
-2
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
export const DropdownOnToggleEffect = ({
|
||||
onDropdownClose,
|
||||
@@ -10,7 +10,9 @@ export const DropdownOnToggleEffect = ({
|
||||
onDropdownClose?: () => void;
|
||||
onDropdownOpen?: () => void;
|
||||
}) => {
|
||||
const isDropdownOpen = useRecoilComponentValue(isDropdownOpenComponentState);
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
);
|
||||
|
||||
const [currentIsDropdownOpen, setCurrentIsDropdownOpen] =
|
||||
useState(isDropdownOpen);
|
||||
|
||||
+10
-8
@@ -11,8 +11,9 @@ import { HotkeyEffect } from '@/ui/utilities/hotkey/components/HotkeyEffect';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { ClickOutsideListenerContext } from '@/ui/utilities/pointer-event/contexts/ClickOutsideListenerContext';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import {
|
||||
FloatingPortal,
|
||||
@@ -21,7 +22,6 @@ import {
|
||||
} from '@floating-ui/react';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { type Keys } from 'react-hotkeys-hook';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
export const StyledDropdownContentContainer = styled.div<{
|
||||
@@ -70,23 +70,25 @@ export const DropdownInternalContainer = ({
|
||||
excludedClickOutsideIds,
|
||||
isDropdownInModal = false,
|
||||
}: DropdownInternalContainerProps) => {
|
||||
const isDropdownOpen = useRecoilComponentValue(isDropdownOpenComponentState);
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
);
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const activeDropdownFocusId = useRecoilValue(activeDropdownFocusIdState);
|
||||
const activeDropdownFocusId = useRecoilValueV2(activeDropdownFocusIdState);
|
||||
|
||||
const dropdownMaxHeight = useRecoilComponentValue(
|
||||
const dropdownMaxHeight = useRecoilComponentValueV2(
|
||||
dropdownMaxHeightComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const dropdownMaxWidth = useRecoilComponentValue(
|
||||
const dropdownMaxWidth = useRecoilComponentValueV2(
|
||||
dropdownMaxWidthComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const setDropdownPlacement = useSetRecoilComponentState(
|
||||
const setDropdownPlacement = useSetRecoilComponentStateV2(
|
||||
dropdownPlacementComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+20
-9
@@ -1,4 +1,5 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import { act } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
@@ -6,27 +7,37 @@ import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/
|
||||
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
||||
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
const dropdownId = 'test-dropdown-id';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{children}
|
||||
</DropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
<JotaiProvider store={jotaiStore}>
|
||||
<RecoilRoot>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{children}
|
||||
</DropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
</JotaiProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('useCloseAnyOpenDropdown', () => {
|
||||
beforeEach(() => {
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({ instanceId: dropdownId }),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('should open dropdown and then close it with closeAnyOpenDropdown', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+32
-15
@@ -1,4 +1,5 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import { act } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
@@ -6,36 +7,52 @@ import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
const dropdownId = 'test-dropdown-id';
|
||||
const outsideDropdownId = 'test-dropdown-id-outside';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{children}
|
||||
</DropdownComponentInstanceContext.Provider>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: outsideDropdownId }}
|
||||
></DropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
<JotaiProvider store={jotaiStore}>
|
||||
<RecoilRoot>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{children}
|
||||
</DropdownComponentInstanceContext.Provider>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: outsideDropdownId }}
|
||||
></DropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
</JotaiProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('useCloseDropdown', () => {
|
||||
beforeEach(() => {
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({ instanceId: dropdownId }),
|
||||
false,
|
||||
);
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: outsideDropdownId,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('should close dropdown from inside component instance context', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const isOutsideDropdownOpen = useRecoilComponentValue(
|
||||
const isOutsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
outsideDropdownId,
|
||||
);
|
||||
|
||||
const isInsideDropdownOpen = useRecoilComponentValue(
|
||||
const isInsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
);
|
||||
|
||||
@@ -72,12 +89,12 @@ describe('useCloseDropdown', () => {
|
||||
it('should close dropdown from outside component instance context', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const isOutsideDropdownOpen = useRecoilComponentValue(
|
||||
const isOutsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
outsideDropdownId,
|
||||
);
|
||||
|
||||
const isInsideDropdownOpen = useRecoilComponentValue(
|
||||
const isInsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
);
|
||||
|
||||
|
||||
+32
-15
@@ -1,40 +1,57 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import { act } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
const dropdownId = 'test-dropdown-id';
|
||||
const outsideDropdownId = 'test-dropdown-id-outside';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{children}
|
||||
</DropdownComponentInstanceContext.Provider>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: outsideDropdownId }}
|
||||
></DropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
<JotaiProvider store={jotaiStore}>
|
||||
<RecoilRoot>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{children}
|
||||
</DropdownComponentInstanceContext.Provider>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: outsideDropdownId }}
|
||||
></DropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
</JotaiProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('useOpenDropdown', () => {
|
||||
beforeEach(() => {
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({ instanceId: dropdownId }),
|
||||
false,
|
||||
);
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: outsideDropdownId,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('should open dropdown from inside component instance context', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const isOutsideDropdownOpen = useRecoilComponentValue(
|
||||
const isOutsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
outsideDropdownId,
|
||||
);
|
||||
|
||||
const isInsideDropdownOpen = useRecoilComponentValue(
|
||||
const isInsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
);
|
||||
|
||||
@@ -61,12 +78,12 @@ describe('useOpenDropdown', () => {
|
||||
it('should open dropdown from outside component instance context', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const isOutsideDropdownOpen = useRecoilComponentValue(
|
||||
const isOutsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
outsideDropdownId,
|
||||
);
|
||||
|
||||
const isInsideDropdownOpen = useRecoilComponentValue(
|
||||
const isInsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
);
|
||||
|
||||
|
||||
+32
-15
@@ -1,40 +1,57 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import { act } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { useToggleDropdown } from '@/ui/layout/dropdown/hooks/useToggleDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
const dropdownId = 'test-dropdown-id';
|
||||
const outsideDropdownId = 'test-dropdown-id-outside';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{children}
|
||||
</DropdownComponentInstanceContext.Provider>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: outsideDropdownId }}
|
||||
></DropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
<JotaiProvider store={jotaiStore}>
|
||||
<RecoilRoot>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: dropdownId }}
|
||||
>
|
||||
{children}
|
||||
</DropdownComponentInstanceContext.Provider>
|
||||
<DropdownComponentInstanceContext.Provider
|
||||
value={{ instanceId: outsideDropdownId }}
|
||||
></DropdownComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
</JotaiProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('useToggleDropdown', () => {
|
||||
beforeEach(() => {
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({ instanceId: dropdownId }),
|
||||
false,
|
||||
);
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: outsideDropdownId,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('should toggle dropdown from inside component instance context', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const isOutsideDropdownOpen = useRecoilComponentValue(
|
||||
const isOutsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
outsideDropdownId,
|
||||
);
|
||||
|
||||
const isInsideDropdownOpen = useRecoilComponentValue(
|
||||
const isInsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
);
|
||||
const { toggleDropdown } = useToggleDropdown();
|
||||
@@ -74,12 +91,12 @@ describe('useToggleDropdown', () => {
|
||||
it('should toggle dropdown from outside component instance context', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const isOutsideDropdownOpen = useRecoilComponentValue(
|
||||
const isOutsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
outsideDropdownId,
|
||||
);
|
||||
|
||||
const isInsideDropdownOpen = useRecoilComponentValue(
|
||||
const isInsideDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
);
|
||||
const { toggleDropdown } = useToggleDropdown();
|
||||
|
||||
+31
-34
@@ -1,8 +1,10 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
import { previousDropdownFocusIdState } from '@/ui/layout/dropdown/states/previousDropdownFocusIdState';
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCloseAnyOpenDropdown = () => {
|
||||
@@ -11,46 +13,41 @@ export const useCloseAnyOpenDropdown = () => {
|
||||
const { removeFocusItemFromFocusStackById } =
|
||||
useRemoveFocusItemFromFocusStackById();
|
||||
|
||||
const closeAnyOpenDropdown = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
() => {
|
||||
const previousDropdownFocusId = snapshot
|
||||
.getLoadable(previousDropdownFocusIdState)
|
||||
.getValue();
|
||||
const closeAnyOpenDropdown = useCallback(() => {
|
||||
const previousDropdownFocusId = jotaiStore.get(
|
||||
previousDropdownFocusIdState.atom,
|
||||
);
|
||||
|
||||
const activeDropdownFocusId = snapshot
|
||||
.getLoadable(activeDropdownFocusIdState)
|
||||
.getValue();
|
||||
const activeDropdownFocusId = jotaiStore.get(
|
||||
activeDropdownFocusIdState.atom,
|
||||
);
|
||||
|
||||
const thereIsNoDropdownOpen =
|
||||
!isDefined(activeDropdownFocusId) &&
|
||||
!isDefined(previousDropdownFocusId);
|
||||
const thereIsNoDropdownOpen =
|
||||
!isDefined(activeDropdownFocusId) && !isDefined(previousDropdownFocusId);
|
||||
|
||||
if (thereIsNoDropdownOpen) {
|
||||
return;
|
||||
}
|
||||
if (thereIsNoDropdownOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
const thereIsOneNestedDropdownOpen = isDefined(previousDropdownFocusId);
|
||||
const thereIsOneNestedDropdownOpen = isDefined(previousDropdownFocusId);
|
||||
|
||||
if (isDefined(activeDropdownFocusId)) {
|
||||
closeDropdown(activeDropdownFocusId);
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: activeDropdownFocusId,
|
||||
});
|
||||
}
|
||||
if (isDefined(activeDropdownFocusId)) {
|
||||
closeDropdown(activeDropdownFocusId);
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: activeDropdownFocusId,
|
||||
});
|
||||
}
|
||||
|
||||
if (thereIsOneNestedDropdownOpen) {
|
||||
closeDropdown(previousDropdownFocusId);
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: previousDropdownFocusId,
|
||||
});
|
||||
}
|
||||
if (thereIsOneNestedDropdownOpen) {
|
||||
closeDropdown(previousDropdownFocusId);
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: previousDropdownFocusId,
|
||||
});
|
||||
}
|
||||
|
||||
set(previousDropdownFocusIdState, null);
|
||||
set(activeDropdownFocusIdState, null);
|
||||
},
|
||||
[closeDropdown, removeFocusItemFromFocusStackById],
|
||||
);
|
||||
jotaiStore.set(previousDropdownFocusIdState.atom, null);
|
||||
jotaiStore.set(activeDropdownFocusIdState.atom, null);
|
||||
}, [closeDropdown, removeFocusItemFromFocusStackById]);
|
||||
|
||||
return { closeAnyOpenDropdown };
|
||||
};
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useCloseDropdown = () => {
|
||||
@@ -17,40 +19,37 @@ export const useCloseDropdown = () => {
|
||||
const dropdownComponentInstanceIdFromContext =
|
||||
useAvailableComponentInstanceId(DropdownComponentInstanceContext);
|
||||
|
||||
const closeDropdown = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(dropdownComponentInstanceIdFromProps?: string) => {
|
||||
const dropdownComponentInstanceId =
|
||||
dropdownComponentInstanceIdFromProps ??
|
||||
dropdownComponentInstanceIdFromContext;
|
||||
const closeDropdown = useCallback(
|
||||
(dropdownComponentInstanceIdFromProps?: string) => {
|
||||
const dropdownComponentInstanceId =
|
||||
dropdownComponentInstanceIdFromProps ??
|
||||
dropdownComponentInstanceIdFromContext;
|
||||
|
||||
if (!isDefined(dropdownComponentInstanceId)) {
|
||||
throw new Error('Dropdown component instance ID is not defined');
|
||||
}
|
||||
if (!isDefined(dropdownComponentInstanceId)) {
|
||||
throw new Error('Dropdown component instance ID is not defined');
|
||||
}
|
||||
|
||||
const isDropdownOpen = snapshot
|
||||
.getLoadable(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const isDropdownOpen = jotaiStore.get(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (isDropdownOpen) {
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: dropdownComponentInstanceId,
|
||||
});
|
||||
if (isDropdownOpen) {
|
||||
removeFocusItemFromFocusStackById({
|
||||
focusId: dropdownComponentInstanceId,
|
||||
});
|
||||
|
||||
goBackToPreviousDropdownFocusId();
|
||||
goBackToPreviousDropdownFocusId();
|
||||
|
||||
set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
}
|
||||
},
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
}
|
||||
},
|
||||
[
|
||||
removeFocusItemFromFocusStackById,
|
||||
goBackToPreviousDropdownFocusId,
|
||||
|
||||
+12
-12
@@ -1,22 +1,22 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
import { previousDropdownFocusIdState } from '@/ui/layout/dropdown/states/previousDropdownFocusIdState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
// TODO: this won't work for more than 1 nested dropdown
|
||||
export const useGoBackToPreviousDropdownFocusId = () => {
|
||||
const goBackToPreviousDropdownFocusId = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
() => {
|
||||
const previouslyFocusedDropdownId = snapshot
|
||||
.getLoadable(previousDropdownFocusIdState)
|
||||
.getValue();
|
||||
const goBackToPreviousDropdownFocusId = useCallback(() => {
|
||||
const previouslyFocusedDropdownId = jotaiStore.get(
|
||||
previousDropdownFocusIdState.atom,
|
||||
);
|
||||
|
||||
set(activeDropdownFocusIdState, previouslyFocusedDropdownId);
|
||||
set(previousDropdownFocusIdState, null);
|
||||
},
|
||||
[],
|
||||
);
|
||||
jotaiStore.set(
|
||||
activeDropdownFocusIdState.atom,
|
||||
previouslyFocusedDropdownId,
|
||||
);
|
||||
jotaiStore.set(previousDropdownFocusIdState.atom, null);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
goBackToPreviousDropdownFocusId,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
||||
|
||||
@@ -6,7 +8,7 @@ import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePush
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { type GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
|
||||
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
type OpenDropdownArgs = {
|
||||
@@ -22,44 +24,41 @@ export const useOpenDropdown = () => {
|
||||
const dropdownComponentInstanceIdFromContext =
|
||||
useAvailableComponentInstanceId(DropdownComponentInstanceContext);
|
||||
|
||||
const openDropdown = useRecoilCallback(
|
||||
({ set }) =>
|
||||
(args?: OpenDropdownArgs | null | undefined) => {
|
||||
const dropdownComponentInstanceId =
|
||||
args?.dropdownComponentInstanceIdFromProps ??
|
||||
dropdownComponentInstanceIdFromContext;
|
||||
const openDropdown = useCallback(
|
||||
(args?: OpenDropdownArgs | null | undefined) => {
|
||||
const dropdownComponentInstanceId =
|
||||
args?.dropdownComponentInstanceIdFromProps ??
|
||||
dropdownComponentInstanceIdFromContext;
|
||||
|
||||
if (!isDefined(dropdownComponentInstanceId)) {
|
||||
throw new Error('Dropdown component instance ID is not defined');
|
||||
}
|
||||
if (!isDefined(dropdownComponentInstanceId)) {
|
||||
throw new Error('Dropdown component instance ID is not defined');
|
||||
}
|
||||
|
||||
set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
jotaiStore.set(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
setActiveDropdownFocusIdAndMemorizePrevious(
|
||||
dropdownComponentInstanceId,
|
||||
);
|
||||
setActiveDropdownFocusIdAndMemorizePrevious(dropdownComponentInstanceId);
|
||||
|
||||
pushFocusItemToFocusStack({
|
||||
focusId: dropdownComponentInstanceId,
|
||||
component: {
|
||||
type: FocusComponentType.DROPDOWN,
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
},
|
||||
globalHotkeysConfig: {
|
||||
enableGlobalHotkeysConflictingWithKeyboard:
|
||||
args?.globalHotkeysConfig
|
||||
?.enableGlobalHotkeysConflictingWithKeyboard ?? false,
|
||||
enableGlobalHotkeysWithModifiers:
|
||||
args?.globalHotkeysConfig?.enableGlobalHotkeysWithModifiers ??
|
||||
false,
|
||||
},
|
||||
});
|
||||
},
|
||||
pushFocusItemToFocusStack({
|
||||
focusId: dropdownComponentInstanceId,
|
||||
component: {
|
||||
type: FocusComponentType.DROPDOWN,
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
},
|
||||
globalHotkeysConfig: {
|
||||
enableGlobalHotkeysConflictingWithKeyboard:
|
||||
args?.globalHotkeysConfig
|
||||
?.enableGlobalHotkeysConflictingWithKeyboard ?? false,
|
||||
enableGlobalHotkeysWithModifiers:
|
||||
args?.globalHotkeysConfig?.enableGlobalHotkeysWithModifiers ??
|
||||
false,
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
pushFocusItemToFocusStack,
|
||||
setActiveDropdownFocusIdAndMemorizePrevious,
|
||||
|
||||
+13
-13
@@ -1,23 +1,23 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
import { previousDropdownFocusIdState } from '@/ui/layout/dropdown/states/previousDropdownFocusIdState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
export const useSetActiveDropdownFocusIdAndMemorizePrevious = () => {
|
||||
const setActiveDropdownFocusIdAndMemorizePrevious = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(dropdownId: string | null) => {
|
||||
const activeDropdownFocusId = snapshot
|
||||
.getLoadable(activeDropdownFocusIdState)
|
||||
.getValue();
|
||||
const setActiveDropdownFocusIdAndMemorizePrevious = useCallback(
|
||||
(dropdownId: string | null) => {
|
||||
const activeDropdownFocusId = jotaiStore.get(
|
||||
activeDropdownFocusIdState.atom,
|
||||
);
|
||||
|
||||
if (activeDropdownFocusId === dropdownId) {
|
||||
return;
|
||||
}
|
||||
if (activeDropdownFocusId === dropdownId) {
|
||||
return;
|
||||
}
|
||||
|
||||
set(previousDropdownFocusIdState, activeDropdownFocusId);
|
||||
set(activeDropdownFocusIdState, dropdownId);
|
||||
},
|
||||
jotaiStore.set(previousDropdownFocusIdState.atom, activeDropdownFocusId);
|
||||
jotaiStore.set(activeDropdownFocusIdState.atom, dropdownId);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { type GlobalHotkeysConfig } from '@/ui/utilities/hotkey/types/GlobalHotkeysConfig';
|
||||
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
type ToggleDropdownArgs = {
|
||||
@@ -19,34 +21,31 @@ export const useToggleDropdown = () => {
|
||||
const { openDropdown } = useOpenDropdown();
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const toggleDropdown = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
(args?: ToggleDropdownArgs | null | undefined) => {
|
||||
const dropdownComponentInstanceId =
|
||||
args?.dropdownComponentInstanceIdFromProps ??
|
||||
dropdownComponentInstanceIdFromContext;
|
||||
const toggleDropdown = useCallback(
|
||||
(args?: ToggleDropdownArgs | null | undefined) => {
|
||||
const dropdownComponentInstanceId =
|
||||
args?.dropdownComponentInstanceIdFromProps ??
|
||||
dropdownComponentInstanceIdFromContext;
|
||||
|
||||
if (!isDefined(dropdownComponentInstanceId)) {
|
||||
throw new Error('Dropdown component instance ID is not defined');
|
||||
}
|
||||
if (!isDefined(dropdownComponentInstanceId)) {
|
||||
throw new Error('Dropdown component instance ID is not defined');
|
||||
}
|
||||
|
||||
const isDropdownOpen = snapshot
|
||||
.getLoadable(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
const isDropdownOpen = jotaiStore.get(
|
||||
isDropdownOpenComponentState.atomFamily({
|
||||
instanceId: dropdownComponentInstanceId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (isDropdownOpen) {
|
||||
closeDropdown(dropdownComponentInstanceId);
|
||||
} else {
|
||||
openDropdown({
|
||||
dropdownComponentInstanceIdFromProps: dropdownComponentInstanceId,
|
||||
globalHotkeysConfig: args?.globalHotkeysConfig,
|
||||
});
|
||||
}
|
||||
},
|
||||
if (isDropdownOpen) {
|
||||
closeDropdown(dropdownComponentInstanceId);
|
||||
} else {
|
||||
openDropdown({
|
||||
dropdownComponentInstanceIdFromProps: dropdownComponentInstanceId,
|
||||
globalHotkeysConfig: args?.globalHotkeysConfig,
|
||||
});
|
||||
}
|
||||
},
|
||||
[closeDropdown, openDropdown, dropdownComponentInstanceIdFromContext],
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const activeDropdownFocusIdState = createState<string | null>({
|
||||
export const activeDropdownFocusIdState = createStateV2<string | null>({
|
||||
key: 'activeDropdownFocusIdState',
|
||||
defaultValue: null,
|
||||
});
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
import { type Placement } from '@floating-ui/react';
|
||||
|
||||
export const dropdownPlacementComponentState =
|
||||
createComponentState<Placement | null>({
|
||||
createComponentStateV2<Placement | null>({
|
||||
key: 'dropdownPlacementComponentState',
|
||||
componentInstanceContext: DropdownComponentInstanceContext,
|
||||
defaultValue: null,
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const dropdownMaxHeightComponentState = createComponentState<
|
||||
export const dropdownMaxHeightComponentState = createComponentStateV2<
|
||||
number | undefined
|
||||
>({
|
||||
key: 'dropdownMaxHeightComponentState',
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const dropdownMaxWidthComponentState = createComponentState<
|
||||
export const dropdownMaxWidthComponentState = createComponentStateV2<
|
||||
number | undefined
|
||||
>({
|
||||
key: 'dropdownMaxWidthComponentState',
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const dropdownYPositionComponentState = createComponentState<
|
||||
export const dropdownYPositionComponentState = createComponentStateV2<
|
||||
number | undefined
|
||||
>({
|
||||
key: 'dropdownYPositionComponentState',
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
|
||||
|
||||
export const isDropdownOpenComponentState = createComponentState<boolean>({
|
||||
export const isDropdownOpenComponentState = createComponentStateV2<boolean>({
|
||||
key: 'isDropdownOpenComponentState',
|
||||
defaultValue: false,
|
||||
componentInstanceContext: DropdownComponentInstanceContext,
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
|
||||
|
||||
export const previousDropdownFocusIdState = createState<string | null>({
|
||||
export const previousDropdownFocusIdState = createStateV2<string | null>({
|
||||
key: 'previousDropdownFocusIdState',
|
||||
defaultValue: null,
|
||||
});
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import { useAtom } from 'jotai';
|
||||
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { globalComponentInstanceContextMap } from '@/ui/utilities/state/component-state/utils/globalComponentInstanceContextMap';
|
||||
import { type ComponentStateV2 } from '@/ui/utilities/state/jotai/types/ComponentStateV2';
|
||||
|
||||
export const useRecoilComponentStateV2 = <StateType>(
|
||||
componentState: ComponentStateV2<StateType>,
|
||||
instanceIdFromProps?: string,
|
||||
): [
|
||||
StateType,
|
||||
(value: StateType | ((prev: StateType) => StateType)) => void,
|
||||
] => {
|
||||
const componentInstanceContext = globalComponentInstanceContextMap.get(
|
||||
componentState.key,
|
||||
);
|
||||
|
||||
if (!componentInstanceContext) {
|
||||
throw new Error(
|
||||
`Instance context for key "${componentState.key}" is not defined`,
|
||||
);
|
||||
}
|
||||
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
componentInstanceContext,
|
||||
instanceIdFromProps,
|
||||
);
|
||||
|
||||
return useAtom(componentState.atomFamily({ instanceId }));
|
||||
};
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import { useAtomValue } from 'jotai';
|
||||
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { globalComponentInstanceContextMap } from '@/ui/utilities/state/component-state/utils/globalComponentInstanceContextMap';
|
||||
import { type ComponentStateV2 } from '@/ui/utilities/state/jotai/types/ComponentStateV2';
|
||||
|
||||
export const useRecoilComponentValueV2 = <StateType>(
|
||||
componentState: ComponentStateV2<StateType>,
|
||||
instanceIdFromProps?: string,
|
||||
): StateType => {
|
||||
const componentInstanceContext = globalComponentInstanceContextMap.get(
|
||||
componentState.key,
|
||||
);
|
||||
|
||||
if (!componentInstanceContext) {
|
||||
throw new Error(
|
||||
`Instance context for key "${componentState.key}" is not defined`,
|
||||
);
|
||||
}
|
||||
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
componentInstanceContext,
|
||||
instanceIdFromProps,
|
||||
);
|
||||
|
||||
return useAtomValue(componentState.atomFamily({ instanceId }));
|
||||
};
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import { useSetAtom } from 'jotai';
|
||||
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { globalComponentInstanceContextMap } from '@/ui/utilities/state/component-state/utils/globalComponentInstanceContextMap';
|
||||
import { type ComponentStateV2 } from '@/ui/utilities/state/jotai/types/ComponentStateV2';
|
||||
|
||||
export const useSetRecoilComponentStateV2 = <ValueType>(
|
||||
componentState: ComponentStateV2<ValueType>,
|
||||
instanceIdFromProps?: string,
|
||||
): ((value: ValueType | ((prev: ValueType) => ValueType)) => void) => {
|
||||
const componentInstanceContext = globalComponentInstanceContextMap.get(
|
||||
componentState.key,
|
||||
);
|
||||
|
||||
if (!componentInstanceContext) {
|
||||
throw new Error(
|
||||
`Instance context for key "${componentState.key}" is not defined`,
|
||||
);
|
||||
}
|
||||
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
componentInstanceContext,
|
||||
instanceIdFromProps,
|
||||
);
|
||||
|
||||
return useSetAtom(componentState.atomFamily({ instanceId }));
|
||||
};
|
||||
@@ -1,3 +1,8 @@
|
||||
import { createStore } from 'jotai';
|
||||
|
||||
export const jotaiStore = createStore();
|
||||
export let jotaiStore = createStore();
|
||||
|
||||
export const resetJotaiStore = () => {
|
||||
jotaiStore = createStore();
|
||||
return jotaiStore;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { type WritableAtom } from 'jotai';
|
||||
|
||||
import { type ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
type JotaiWritableAtom<ValueType> = WritableAtom<
|
||||
ValueType,
|
||||
[ValueType | ((prev: ValueType) => ValueType)],
|
||||
void
|
||||
>;
|
||||
|
||||
export type ComponentStateV2<ValueType> = {
|
||||
type: 'ComponentStateV2';
|
||||
key: string;
|
||||
atomFamily: (key: ComponentStateKey) => JotaiWritableAtom<ValueType>;
|
||||
};
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import { atom } from 'jotai';
|
||||
|
||||
import { type ComponentInstanceStateContext } from '@/ui/utilities/state/component-state/types/ComponentInstanceStateContext';
|
||||
import { type ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
import { globalComponentInstanceContextMap } from '@/ui/utilities/state/component-state/utils/globalComponentInstanceContextMap';
|
||||
import { type ComponentStateV2 } from '@/ui/utilities/state/jotai/types/ComponentStateV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const createComponentStateV2 = <ValueType>({
|
||||
key,
|
||||
defaultValue,
|
||||
componentInstanceContext,
|
||||
}: {
|
||||
key: string;
|
||||
defaultValue: ValueType;
|
||||
componentInstanceContext: ComponentInstanceStateContext<any> | null;
|
||||
}): ComponentStateV2<ValueType> => {
|
||||
if (isDefined(componentInstanceContext)) {
|
||||
globalComponentInstanceContextMap.set(key, componentInstanceContext);
|
||||
}
|
||||
|
||||
const atomCache = new Map<
|
||||
string,
|
||||
ReturnType<ComponentStateV2<ValueType>['atomFamily']>
|
||||
>();
|
||||
|
||||
const familyFunction = ({
|
||||
instanceId,
|
||||
}: ComponentStateKey): ReturnType<
|
||||
ComponentStateV2<ValueType>['atomFamily']
|
||||
> => {
|
||||
const existing = atomCache.get(instanceId);
|
||||
|
||||
if (existing !== undefined) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
const baseAtom = atom(defaultValue);
|
||||
baseAtom.debugLabel = `${key}__${instanceId}`;
|
||||
atomCache.set(instanceId, baseAtom);
|
||||
|
||||
return baseAtom;
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'ComponentStateV2',
|
||||
key,
|
||||
atomFamily: familyFunction,
|
||||
};
|
||||
};
|
||||
@@ -5,6 +5,7 @@ import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObje
|
||||
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
|
||||
import { useHandleToggleTrashColumnFilter } from '@/object-record/record-index/hooks/useHandleToggleTrashColumnFilter';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { AdvancedFilterDropdownButton } from '@/views/advanced-filter-chip/components/AdvancedFilterDropdownButton';
|
||||
import { ViewBarDetailsAddFilterButton } from '@/views/components/ViewBarDetailsAddFilterButton';
|
||||
import { EditableSortChip } from '@/views/editable-chip/components/EditableSortChip';
|
||||
@@ -185,7 +186,7 @@ export const ViewBarDetails = ({
|
||||
const shouldShowAdvancedFilterDropdownButton =
|
||||
currentRecordFilterGroups.length > 0;
|
||||
|
||||
const isAnyFieldSearchDropdownOpen = useRecoilComponentValue(
|
||||
const isAnyFieldSearchDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
ANY_FIELD_SEARCH_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { ViewBarFilterDropdownIds } from '@/views/constants/ViewBarFilterDropdownIds';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
|
||||
export const ViewBarFilterButton = () => {
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
ViewBarFilterDropdownIds.MAIN,
|
||||
);
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableLi
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { dropdownYPositionComponentState } from '@/ui/layout/dropdown/states/internal/dropdownYPositionComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
import { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -77,7 +78,7 @@ export const ViewFieldsVisibleDropdownSection = () => {
|
||||
)
|
||||
.toSorted(sortByProperty('position'));
|
||||
|
||||
const dropdownYPosition = useRecoilComponentValue(
|
||||
const dropdownYPosition = useRecoilComponentValueV2(
|
||||
dropdownYPositionComponentState,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import { t } from '@lingui/core/macro';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useGetRecordIndexTotalCount } from '@/views/hooks/internal/useGetRecordIndexTotalCount';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { ViewPickerContentCreateMode } from '@/views/view-picker/components/ViewPickerContentCreateMode';
|
||||
@@ -61,7 +61,7 @@ export const ViewPickerDropdown = () => {
|
||||
|
||||
const { totalCount } = useGetRecordIndexTotalCount();
|
||||
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
VIEW_PICKER_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { type InputSchemaPropertyType } from 'twenty-shared/workflow';
|
||||
import { WorkflowVariablesDropdownStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownStepItems';
|
||||
import { WorkflowVariablesDropdownSteps } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownSteps';
|
||||
@@ -53,7 +53,7 @@ export const WorkflowVariablesDropdown = ({
|
||||
const theme = useTheme();
|
||||
|
||||
const dropdownId = `${SEARCH_VARIABLES_DROPDOWN_ID}-${instanceId}`;
|
||||
const isDropdownOpen = useRecoilComponentValue(
|
||||
const isDropdownOpen = useRecoilComponentValueV2(
|
||||
isDropdownOpenComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user