Migrate more to Jotai (#18087)

Continue jotai migration
This commit is contained in:
Charles Bochet
2026-02-19 13:50:21 +01:00
committed by GitHub
parent 5a46cf7bd3
commit 530f74e28c
63 changed files with 330 additions and 283 deletions
@@ -4,7 +4,7 @@ import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNaviga
import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2';
import { useGoToHotkeys } from '@/ui/utilities/hotkey/hooks/useGoToHotkeys';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { useCallback } from 'react';
import { AppPath, SettingsPath } from 'twenty-shared/types';
import { getAppPath, getSettingsPath } from 'twenty-shared/utils';
@@ -17,14 +17,10 @@ export const GotoHotkeysEffectsProvider = () => {
useGoToHotkeys({
key: 's',
location: getSettingsPath(SettingsPath.ProfilePage),
preNavigateFunction: useRecoilCallback(
({ set }) =>
() => {
set(isNavigationDrawerExpandedState, true);
store.set(navigationDrawerExpandedMemorizedStateV2.atom, true);
},
[store],
),
preNavigateFunction: useCallback(() => {
store.set(isNavigationDrawerExpandedState.atom, true);
store.set(navigationDrawerExpandedMemorizedStateV2.atom, true);
}, [store]),
});
return activeNonSystemObjectMetadataItems.map((objectMetadataItem) => {
@@ -11,6 +11,8 @@ import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigat
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle';
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { isNavigationSectionOpenFamilyState } from '@/ui/navigation/navigation-drawer/states/isNavigationSectionOpenFamilyState';
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
import { useLingui } from '@lingui/react/macro';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
@@ -29,12 +31,12 @@ export const CurrentWorkspaceMemberFavoritesFolders = () => {
const { t } = useLingui();
const {
toggleNavigationSection,
isNavigationSectionOpenState,
openNavigationSection,
} = useNavigationSection('Favorites');
const isNavigationSectionOpen = useRecoilValue(isNavigationSectionOpenState);
const { toggleNavigationSection, openNavigationSection } =
useNavigationSection('Favorites');
const isNavigationSectionOpen = useFamilyRecoilValueV2(
isNavigationSectionOpenFamilyState,
'Favorites',
);
const toggleNewFolder = () => {
openNavigationSection();
@@ -4,9 +4,9 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
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 { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useTheme } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
import { useSetRecoilState } from 'recoil';
import { IconPlus } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
@@ -19,7 +19,7 @@ export const FavoriteFolderPickerFooter = ({
const [, setIsFavoriteFolderCreating] = useRecoilStateV2(
isFavoriteFolderCreatingStateV2,
);
const setIsNavigationDrawerExpanded = useSetRecoilState(
const setIsNavigationDrawerExpanded = useSetRecoilStateV2(
isNavigationDrawerExpandedState,
);
const { openNavigationSection } = useNavigationSection('Favorites');
@@ -17,6 +17,8 @@ import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigat
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle';
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { isNavigationSectionOpenFamilyState } from '@/ui/navigation/navigation-drawer/states/isNavigationSectionOpenFamilyState';
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
export const CurrentWorkspaceMemberNavigationMenuItemFolders = () => {
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
@@ -32,12 +34,12 @@ export const CurrentWorkspaceMemberNavigationMenuItemFolders = () => {
const { t } = useLingui();
const {
toggleNavigationSection,
isNavigationSectionOpenState,
openNavigationSection,
} = useNavigationSection('Favorites');
const isNavigationSectionOpen = useRecoilValue(isNavigationSectionOpenState);
const { toggleNavigationSection, openNavigationSection } =
useNavigationSection('Favorites');
const isNavigationSectionOpen = useFamilyRecoilValueV2(
isNavigationSectionOpenFamilyState,
'Favorites',
);
const toggleNewFolder = () => {
openNavigationSection();
@@ -4,11 +4,11 @@ import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/componen
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { useLingui } from '@lingui/react/macro';
import { useLocation, useNavigate } from 'react-router-dom';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { SettingsPath } from 'twenty-shared/types';
import { getSettingsPath } from 'twenty-shared/utils';
import { IconSearch, IconSettings, IconSparkles } from 'twenty-ui/display';
@@ -18,12 +18,12 @@ import { FeatureFlagKey } from '~/generated-metadata/graphql';
export const MainNavigationDrawerFixedItems = () => {
const isMobile = useIsMobile();
const location = useLocation();
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
const [isNavigationDrawerExpanded, setIsNavigationDrawerExpanded] =
useRecoilState(isNavigationDrawerExpandedState);
useRecoilStateV2(isNavigationDrawerExpandedState);
const setNavigationDrawerExpandedMemorized = useSetRecoilStateV2(
navigationDrawerExpandedMemorizedStateV2,
);
@@ -7,6 +7,7 @@ import { useDefaultHomePagePath } from '@/navigation/hooks/useDefaultHomePagePat
import { useOpenSettingsMenu } from '@/navigation/hooks/useOpenSettings';
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useNavigate } from 'react-router-dom';
@@ -31,7 +32,7 @@ export const MobileNavigationBar = () => {
const { openRecordsSearchPage } = useOpenRecordsSearchPageInCommandMenu();
const isSettingsPage = useIsSettingsPage();
const [isNavigationDrawerExpanded, setIsNavigationDrawerExpanded] =
useRecoilState(isNavigationDrawerExpandedState);
useRecoilStateV2(isNavigationDrawerExpandedState);
const [currentMobileNavigationDrawer, setCurrentMobileNavigationDrawer] =
useRecoilState(currentMobileNavigationDrawerState);
const { openSettingsMenu } = useOpenSettingsMenu();
@@ -3,8 +3,8 @@ import { NavigationDrawer } from '@/ui/navigation/navigation-drawer/components/N
import { NavigationDrawerFixedContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerFixedContent';
import { NavigationDrawerScrollableContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerScrollableContent';
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { useLingui } from '@lingui/react/macro';
import { useRecoilState } from 'recoil';
import { AdvancedSettingsToggle } from 'twenty-ui/navigation';
export const SettingsNavigationDrawer = ({
@@ -13,7 +13,7 @@ export const SettingsNavigationDrawer = ({
className?: string;
}) => {
const { t } = useLingui();
const [isAdvancedModeEnabled, setIsAdvancedModeEnabled] = useRecoilState(
const [isAdvancedModeEnabled, setIsAdvancedModeEnabled] = useRecoilStateV2(
isAdvancedModeEnabledState,
);
@@ -4,6 +4,8 @@ import { MemoryRouter } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { currentMobileNavigationDrawerState } from '@/navigation/states/currentMobileNavigationDrawerState';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
@@ -13,7 +15,6 @@ import {
AppNavigationDrawer,
type AppNavigationDrawerProps,
} from '@/navigation/components/AppNavigationDrawer';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { AppPath } from 'twenty-shared/types';
const MobileNavigationDrawerStateSetterEffect = ({
@@ -22,7 +23,7 @@ const MobileNavigationDrawerStateSetterEffect = ({
mobileNavigationDrawer?: 'main' | 'settings';
}) => {
const isMobile = useIsMobile();
const setIsNavigationDrawerExpanded = useSetRecoilState(
const setIsNavigationDrawerExpanded = useSetRecoilStateV2(
isNavigationDrawerExpandedState,
);
const setCurrentMobileNavigationDrawer = useSetRecoilState(
@@ -1,9 +1,10 @@
import { currentMobileNavigationDrawerState } from '@/navigation/states/currentMobileNavigationDrawerState';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useSetRecoilState } from 'recoil';
export const useOpenSettingsMenu = () => {
const setIsNavigationDrawerExpanded = useSetRecoilState(
const setIsNavigationDrawerExpanded = useSetRecoilStateV2(
isNavigationDrawerExpandedState,
);
const setCurrentMobileNavigationDrawer = useSetRecoilState(
@@ -7,7 +7,8 @@ import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigat
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle';
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { useRecoilValue } from 'recoil';
import { isNavigationSectionOpenFamilyState } from '@/ui/navigation/navigation-drawer/states/isNavigationSectionOpenFamilyState';
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
import { isDefined } from 'twenty-shared/utils';
const ORDERED_FIRST_STANDARD_OBJECTS: string[] = [
@@ -45,9 +46,12 @@ export const NavigationDrawerSectionForObjectMetadataItems = ({
onObjectMetadataItemClick,
onActiveObjectMetadataItemClick,
}: NavigationDrawerSectionForObjectMetadataItemsProps) => {
const { toggleNavigationSection, isNavigationSectionOpenState } =
useNavigationSection('Objects' + (isRemote ? 'Remote' : 'Workspace'));
const isNavigationSectionOpen = useRecoilValue(isNavigationSectionOpenState);
const navigationSectionId = 'Objects' + (isRemote ? 'Remote' : 'Workspace');
const { toggleNavigationSection } = useNavigationSection(navigationSectionId);
const isNavigationSectionOpen = useFamilyRecoilValueV2(
isNavigationSectionOpenFamilyState,
navigationSectionId,
);
const { objectPermissionsByObjectMetadataId } = useObjectPermissions();
@@ -69,9 +69,8 @@ export const NavigationDrawerSectionForWorkspaceItems = ({
const { t } = useLingui();
const theme = useTheme();
const workspaceDropDisabled = useIsDropDisabledForSection(true);
const { toggleNavigationSection, isNavigationSectionOpenState } =
const { toggleNavigationSection, isNavigationSectionOpen } =
useNavigationSection('Workspace');
const isNavigationSectionOpen = useRecoilValue(isNavigationSectionOpenState);
const coreViews = useRecoilValue(coreViewsState);
const views = coreViews.map(convertCoreViewToView);
@@ -1,5 +1,4 @@
import { useLocation } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
@@ -10,6 +9,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 { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { ViewFieldsHiddenDropdownSection } from '@/views/components/ViewFieldsHiddenDropdownSection';
import { useLingui } from '@lingui/react/macro';
import { SettingsPath } from 'twenty-shared/types';
@@ -31,7 +31,7 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => {
});
const location = useLocation();
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
@@ -15,10 +15,10 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useLingui } from '@lingui/react/macro';
import { useLocation } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { VIEW_GROUP_VISIBLE_OPTIONS_MAX } from 'twenty-shared/constants';
import { SettingsPath } from 'twenty-shared/types';
import { getSettingsPath } from 'twenty-shared/utils';
@@ -64,7 +64,7 @@ export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
});
const location = useLocation();
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
@@ -16,10 +16,10 @@ import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/Dropdow
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { ViewType } from '@/views/types/ViewType';
import { useLingui } from '@lingui/react/macro';
import { useLocation } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { SettingsPath } from 'twenty-shared/types';
import { getSettingsPath, isDefined } from 'twenty-shared/utils';
import { IconChevronLeft, IconSettings, useIcons } from 'twenty-ui/display';
@@ -77,7 +77,7 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
);
const location = useLocation();
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
@@ -1,19 +1,19 @@
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { shouldNavigateBackToMemorizedUrlOnSaveState } from '@/ui/navigation/states/shouldNavigateBackToMemorizedUrlOnSaveState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useCallback } from 'react';
import { useParams } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { SettingsPath } from 'twenty-shared/types';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
export const useAddSelectOption = (fieldName: string) => {
const { objectNamePlural } = useParams();
const navigateSettings = useNavigateSettings();
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
const setShouldNavigateBackToMemorizedUrlOnSave = useSetRecoilState(
const setShouldNavigateBackToMemorizedUrlOnSave = useSetRecoilStateV2(
shouldNavigateBackToMemorizedUrlOnSaveState,
);
@@ -11,12 +11,12 @@ import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFla
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { type ViewType } from '@/views/types/ViewType';
import { t } from '@lingui/core/macro';
import { isUndefined } from '@sniptt/guards';
import { useCallback, useContext } from 'react';
import { useLocation } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { SettingsPath } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import {
@@ -56,7 +56,7 @@ export const useRecordGroupActions = ({
const { handleVisibilityChange: handleRecordGroupVisibilityChange } =
useRecordGroupVisibility();
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
@@ -1,6 +1,5 @@
import { useCallback } from 'react';
import { useLocation } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { useActiveFieldMetadataItems } from '@/object-metadata/hooks/useActiveFieldMetadataItems';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
@@ -13,6 +12,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useLingui } from '@lingui/react/macro';
import { SettingsPath } from 'twenty-shared/types';
import { getSettingsPath } from 'twenty-shared/utils';
@@ -42,7 +42,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
);
const location = useLocation();
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
@@ -1,8 +1,8 @@
import { AdvancedSettingsContentWrapperWithDot } from '@/settings/components/AdvancedSettingsContentWrapperWithDot';
import { ADVANCED_SETTINGS_ANIMATION_DURATION } from '@/settings/constants/AdvancedSettingsAnimationDurations';
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
const StyledContent = styled.div`
@@ -24,7 +24,7 @@ export const AdvancedSettingsWrapper = ({
dotPosition = 'centered',
animationDimension = 'height',
}: AdvancedSettingsWrapperProps) => {
const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState);
const isAdvancedModeEnabled = useRecoilValueV2(isAdvancedModeEnabledState);
return (
<AnimatedExpandableContainer
@@ -1,6 +1,5 @@
import { useLingui } from '@lingui/react/macro';
import { useFormContext } from 'react-hook-form';
import { useRecoilValue } from 'recoil';
import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { IconLink } from 'twenty-ui/display';
@@ -11,6 +10,7 @@ import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsO
import { SettingsOptionCardContentToggle } from '@/settings/components/SettingsOptions/SettingsOptionCardContentToggle';
import { Select } from '@/ui/input/components/Select';
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { RelationType } from '~/generated-metadata/graphql';
import { type SettingsDataModelFieldEditFormValues } from '~/pages/settings/data-model/SettingsObjectFieldEdit';
@@ -25,7 +25,7 @@ export const SettingsDataModelFieldRelationJunctionForm = ({
const { watch, setValue } =
useFormContext<SettingsDataModelFieldEditFormValues>();
const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState);
const isAdvancedModeEnabled = useRecoilValueV2(isAdvancedModeEnabledState);
const { objectMetadataItem: sourceObjectMetadataItem } =
useObjectMetadataItem({ objectNameSingular });
@@ -28,11 +28,11 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useTheme } from '@emotion/react';
import { t } from '@lingui/core/macro';
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import {
IconDotsVertical,
@@ -166,7 +166,7 @@ export const SettingsDataModelFieldSelectForm = ({
);
const isNullable = fieldMetadataItem?.isNullable;
const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState);
const isAdvancedModeEnabled = useRecoilValueV2(isAdvancedModeEnabledState);
const [searchParams] = useSearchParams();
@@ -11,11 +11,11 @@ import { TableHeader } from '@/ui/layout/table/components/TableHeader';
import { useSortedArray } from '@/ui/layout/table/hooks/useSortedArray';
import { type TableMetadata } from '@/ui/layout/table/types/TableMetadata';
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import styled from '@emotion/styled';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { FieldMetadataType } from 'twenty-shared/types';
import {
IconArchive,
@@ -83,7 +83,7 @@ export const SettingsObjectRelationsTable = ({
const [showInactive, setShowInactive] = useState(true);
const [showSystemRelations, setShowSystemRelations] = useState(false);
const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState);
const isAdvancedModeEnabled = useRecoilValueV2(isAdvancedModeEnabledState);
const tableMetadata = SETTINGS_OBJECT_RELATION_TABLE_METADATA;
@@ -8,6 +8,7 @@ import {
settingsDataModelObjectAboutFormSchema,
} from '@/settings/data-model/validation-schemas/settingsDataModelObjectAboutFormSchema';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { zodResolver } from '@hookform/resolvers/zod';
import { FormProvider, useForm } from 'react-hook-form';
import { useSetRecoilState } from 'recoil';
@@ -30,7 +31,7 @@ export const SettingsUpdateDataModelObjectAboutForm = ({
const setUpdatedObjectNamePlural = useSetRecoilState(
updatedObjectNamePluralState,
);
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
@@ -1,12 +1,14 @@
import { dialogInternalComponentState } from '@/ui/feedback/dialog-manager/states/dialogInternalComponentState';
import { useDialogManager } from '@/ui/feedback/dialog-manager/hooks/useDialogManager';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { Dialog } from './Dialog';
import { DialogManagerEffect } from './DialogManagerEffect';
export const DialogManager = ({ children }: React.PropsWithChildren) => {
const dialogInternal = useRecoilComponentValue(dialogInternalComponentState);
const dialogInternal = useRecoilComponentValueV2(
dialogInternalComponentState,
);
const { closeDialog } = useDialogManager();
return (
@@ -5,10 +5,12 @@ import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePush
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { dialogInternalComponentState } from '@/ui/feedback/dialog-manager/states/dialogInternalComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
export const DialogManagerEffect = () => {
const dialogInternal = useRecoilComponentValue(dialogInternalComponentState);
const dialogInternal = useRecoilComponentValueV2(
dialogInternalComponentState,
);
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
@@ -1,4 +1,5 @@
import { act, renderHook } from '@testing-library/react';
import { Provider as JotaiProvider } from 'jotai';
import { RecoilRoot } from 'recoil';
import { v4 as uuidv4 } from 'uuid';
@@ -6,7 +7,11 @@ import { DialogComponentInstanceContext } from '@/ui/feedback/dialog-manager/con
import { useDialogManager } from '@/ui/feedback/dialog-manager/hooks/useDialogManager';
import { dialogInternalComponentState } from '@/ui/feedback/dialog-manager/states/dialogInternalComponentState';
import { type DialogOptions } from '@/ui/feedback/dialog-manager/types/DialogOptions';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import {
jotaiStore,
resetJotaiStore,
} from '@/ui/utilities/state/jotai/jotaiStore';
const mockedUuid = 'mocked-uuid';
jest.mock('uuid');
@@ -15,11 +20,13 @@ jest.mock('uuid');
const Wrapper = ({ children }: { children: React.ReactNode }) => (
<RecoilRoot>
<DialogComponentInstanceContext.Provider
value={{ instanceId: 'dialog-manager' }}
>
{children}
</DialogComponentInstanceContext.Provider>
<JotaiProvider store={jotaiStore}>
<DialogComponentInstanceContext.Provider
value={{ instanceId: 'dialog-manager' }}
>
{children}
</DialogComponentInstanceContext.Provider>
</JotaiProvider>
</RecoilRoot>
);
@@ -77,7 +84,7 @@ const renderHooks = () => {
const { result } = renderHook(
() => ({
dialogManager: useDialogManager(),
dialogInternal: useRecoilComponentValue(dialogInternalComponentState),
dialogInternal: useRecoilComponentValueV2(dialogInternalComponentState),
}),
renderHookConfig,
);
@@ -95,6 +102,10 @@ const expectedReturnFromEnqueue = (
};
describe('useDialogManager', () => {
beforeEach(() => {
resetJotaiStore();
});
describe('tests for useDialogManager - enqueueDialog', () => {
it('Should enqueueDialog', () => {
const result = renderHooks();
@@ -1,4 +1,4 @@
import { useRecoilCallback } from 'recoil';
import { useCallback } from 'react';
import { v4 } from 'uuid';
import { DIALOG_FOCUS_ID } from '@/ui/feedback/dialog-manager/constants/DialogFocusId';
@@ -8,55 +8,56 @@ import { DialogComponentInstanceContext } from '@/ui/feedback/dialog-manager/con
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { dialogInternalComponentState } from '@/ui/feedback/dialog-manager/states/dialogInternalComponentState';
import { type DialogOptions } from '@/ui/feedback/dialog-manager/types/DialogOptions';
import { useStore } from 'jotai';
export const useDialogManager = () => {
const componentInstanceId = useAvailableComponentInstanceIdOrThrow(
DialogComponentInstanceContext,
);
const store = useStore();
const { removeFocusItemFromFocusStackById } =
useRemoveFocusItemFromFocusStackById();
const closeDialog = useRecoilCallback(
({ set }) =>
(id: string) => {
set(
dialogInternalComponentState.atomFamily({
instanceId: componentInstanceId,
}),
(prevState) => ({
...prevState,
queue: prevState.queue.filter((dialog) => dialog.id !== id),
}),
);
const closeDialog = useCallback(
(id: string) => {
store.set(
dialogInternalComponentState.atomFamily({
instanceId: componentInstanceId,
}),
(prevState) => ({
...prevState,
queue: prevState.queue.filter((dialog) => dialog.id !== id),
}),
);
removeFocusItemFromFocusStackById({ focusId: DIALOG_FOCUS_ID });
},
[componentInstanceId, removeFocusItemFromFocusStackById],
removeFocusItemFromFocusStackById({ focusId: DIALOG_FOCUS_ID });
},
[componentInstanceId, removeFocusItemFromFocusStackById, store],
);
const setDialogQueue = useRecoilCallback(
({ set }) =>
(newValue) =>
set(
dialogInternalComponentState.atomFamily({
instanceId: componentInstanceId,
}),
(prev) => {
if (prev.queue.length >= prev.maxQueue) {
return {
...prev,
queue: [...prev.queue.slice(1), newValue] as DialogOptions[],
};
}
const setDialogQueue = useCallback(
(newValue: DialogOptions) =>
store.set(
dialogInternalComponentState.atomFamily({
instanceId: componentInstanceId,
}),
(prev) => {
if (prev.queue.length >= prev.maxQueue) {
return {
...prev,
queue: [...prev.queue, newValue] as DialogOptions[],
queue: [...prev.queue.slice(1), newValue],
};
},
),
[componentInstanceId],
}
return {
...prev,
queue: [...prev.queue, newValue],
};
},
),
[componentInstanceId, store],
);
const enqueueDialog = (options?: Omit<DialogOptions, 'id'>) => {
@@ -1,5 +1,5 @@
import { DialogComponentInstanceContext } from '@/ui/feedback/dialog-manager/contexts/DialogComponentInstanceContext';
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { type DialogOptions } from '@/ui/feedback/dialog-manager/types/DialogOptions';
type DialogState = {
@@ -7,11 +7,13 @@ type DialogState = {
queue: DialogOptions[];
};
export const dialogInternalComponentState = createComponentState<DialogState>({
key: 'dialogInternalComponentState',
defaultValue: {
maxQueue: 2,
queue: [],
export const dialogInternalComponentState = createComponentStateV2<DialogState>(
{
key: 'dialogInternalComponentState',
defaultValue: {
maxQueue: 2,
queue: [],
},
componentInstanceContext: DialogComponentInstanceContext,
},
componentInstanceContext: DialogComponentInstanceContext,
});
);
@@ -6,7 +6,7 @@ import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { snackBarInternalComponentState } from '@/ui/feedback/snack-bar-manager/states/snackBarInternalComponentState';
import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { MOBILE_VIEWPORT } from 'twenty-ui/theme';
import { SnackBar } from './SnackBar';
@@ -27,7 +27,7 @@ const StyledSnackBarContainer = styled.div`
`;
export const SnackBarProvider = ({ children }: React.PropsWithChildren) => {
const snackBarInternal = useRecoilComponentValue(
const snackBarInternal = useRecoilComponentValueV2(
snackBarInternalComponentState,
);
@@ -1,5 +1,4 @@
import { useCallback } from 'react';
import { useRecoilCallback } from 'recoil';
import { v4 as uuidv4 } from 'uuid';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
@@ -12,6 +11,7 @@ import { buildErrorAction } from '@/ui/feedback/snack-bar-manager/utils/build-er
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { type ApolloError } from '@apollo/client';
import { t } from '@lingui/core/macro';
import { useStore } from 'jotai';
import { isDefined } from 'twenty-shared/utils';
import { getErrorMessageFromApolloError } from '~/utils/get-error-message-from-apollo-error.util';
@@ -20,53 +20,53 @@ export const useSnackBar = () => {
SnackBarComponentInstanceContext,
);
const handleSnackBarClose = useRecoilCallback(
({ set }) =>
(id: string) => {
set(
snackBarInternalComponentState.atomFamily({
instanceId: componentInstanceId,
}),
(prevState) => ({
...prevState,
queue: prevState.queue.filter((snackBar) => snackBar.id !== id),
}),
);
},
[componentInstanceId],
const store = useStore();
const handleSnackBarClose = useCallback(
(id: string) => {
store.set(
snackBarInternalComponentState.atomFamily({
instanceId: componentInstanceId,
}),
(prevState) => ({
...prevState,
queue: prevState.queue.filter((snackBar) => snackBar.id !== id),
}),
);
},
[componentInstanceId, store],
);
const setSnackBarQueue = useRecoilCallback(
({ set }) =>
(newValue: SnackBarOptions) =>
set(
snackBarInternalComponentState.atomFamily({
instanceId: componentInstanceId,
}),
(prev) => {
if (
isDefined(newValue.dedupeKey) &&
prev.queue.some(
(snackBar) => snackBar.dedupeKey === newValue.dedupeKey,
)
) {
return prev;
}
if (prev.queue.length >= prev.maxQueue) {
return {
...prev,
queue: [...prev.queue.slice(1), newValue] as SnackBarOptions[],
};
}
const setSnackBarQueue = useCallback(
(newValue: SnackBarOptions) =>
store.set(
snackBarInternalComponentState.atomFamily({
instanceId: componentInstanceId,
}),
(prev) => {
if (
isDefined(newValue.dedupeKey) &&
prev.queue.some(
(snackBar) => snackBar.dedupeKey === newValue.dedupeKey,
)
) {
return prev;
}
if (prev.queue.length >= prev.maxQueue) {
return {
...prev,
queue: [...prev.queue, newValue] as SnackBarOptions[],
queue: [...prev.queue.slice(1), newValue] as SnackBarOptions[],
};
},
),
[componentInstanceId],
}
return {
...prev,
queue: [...prev.queue, newValue] as SnackBarOptions[],
};
},
),
[componentInstanceId, store],
);
const enqueueSuccessSnackBar = useCallback(
@@ -1,5 +1,5 @@
import { SnackBarComponentInstanceContext } from '@/ui/feedback/snack-bar-manager/contexts/SnackBarComponentInstanceContext';
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { createComponentStateV2 } from '@/ui/utilities/state/jotai/utils/createComponentStateV2';
import { type SnackBarProps } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
export type SnackBarOptions = SnackBarProps & {
@@ -12,7 +12,7 @@ export type SnackBarState = {
};
export const snackBarInternalComponentState =
createComponentState<SnackBarState>({
createComponentStateV2<SnackBarState>({
key: 'snackBarState',
defaultValue: {
maxQueue: 3,
@@ -1,7 +1,7 @@
import { type FieldFilesValue } from '@/object-record/record-field/ui/types/FieldMetadata';
import { createState } from '@/ui/utilities/state/utils/createState';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const filePreviewState = createState<FieldFilesValue | null>({
export const filePreviewState = createStateV2<FieldFilesValue | null>({
key: 'filePreviewState',
defaultValue: null,
});
@@ -1,5 +1,5 @@
import styled from '@emotion/styled';
import { type ReactNode, useMemo, useState } from 'react';
import { type ReactNode, useCallback, useMemo, useState } from 'react';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@@ -10,16 +10,20 @@ import { arrayToChunks } from '~/utils/array/arrayToChunks';
import { ICON_PICKER_DROPDOWN_CONTENT_WIDTH } from '@/ui/input/components/constants/IconPickerDropdownContentWidth';
import { IconPickerScrollEffect } from '@/ui/input/hooks/IconPickerScrollEffect';
import { iconPickerVisibleCountState } from '@/ui/input/states/iconPickerVisibleCountState';
import {
ICON_PICKER_DEFAULT_VISIBLE_COUNT,
iconPickerVisibleCountState,
} from '@/ui/input/states/iconPickerVisibleCountState';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
import { type DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { useRecoilValue, useResetRecoilState } from 'recoil';
import { useStore } from 'jotai';
import { IconApps, type IconComponent, useIcons } from 'twenty-ui/display';
import {
IconButton,
@@ -156,12 +160,18 @@ export const IconPicker = ({
const { closeDropdown } = useCloseDropdown();
const iconPickerVisibleCount =
useRecoilValue(iconPickerVisibleCountState(dropdownId)) ?? maxIconsVisible;
const store = useStore();
const resetIconPickerVisibleCount = useResetRecoilState(
iconPickerVisibleCountState(dropdownId),
);
const iconPickerVisibleCount =
useFamilyRecoilValueV2(iconPickerVisibleCountState, dropdownId) ??
maxIconsVisible;
const resetIconPickerVisibleCount = useCallback(() => {
store.set(
iconPickerVisibleCountState.atomFamily(dropdownId),
ICON_PICKER_DEFAULT_VISIBLE_COUNT,
);
}, [store, dropdownId]);
const { getIcons, getIcon } = useIcons();
const icons = getIcons();
@@ -1,7 +1,7 @@
import { iconPickerVisibleCountState } from '@/ui/input/states/iconPickerVisibleCountState';
import { useSetFamilyRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetFamilyRecoilStateV2';
import { useScrollWrapperHTMLElement } from '@/ui/utilities/scroll/hooks/useScrollWrapperHTMLElement';
import { useEffect } from 'react';
import { useSetRecoilState } from 'recoil';
import { iconPickerVisibleCountState } from '@/ui/input/states/iconPickerVisibleCountState';
type IconPickerScrollEffectProps = {
sentinelId: string;
@@ -14,8 +14,9 @@ export const IconPickerScrollEffect = ({
}: IconPickerScrollEffectProps) => {
const { scrollWrapperHTMLElement } = useScrollWrapperHTMLElement();
const setIconPickerVisibleCount = useSetRecoilState(
iconPickerVisibleCountState(dropdownId),
const setIconPickerVisibleCount = useSetFamilyRecoilStateV2(
iconPickerVisibleCountState,
dropdownId,
);
useEffect(() => {
@@ -1,6 +1,8 @@
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
export const iconPickerVisibleCountState = createFamilyState<number, string>({
export const ICON_PICKER_DEFAULT_VISIBLE_COUNT = 25;
export const iconPickerVisibleCountState = createFamilyStateV2<number, string>({
key: 'iconPickerVisibleCountState',
defaultValue: 25,
defaultValue: ICON_PICKER_DEFAULT_VISIBLE_COUNT,
});
@@ -1,13 +1,13 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { type ReactNode } from 'react';
import { useRecoilValue } from 'recoil';
import { NavigationDrawerCollapseButton } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerCollapseButton';
import { PAGE_ACTION_CONTAINER_CLICK_OUTSIDE_ID } from '@/ui/layout/page/constants/PageActionContainerClickOutsideId';
import { PAGE_BAR_MIN_HEIGHT } from '@/ui/layout/page/constants/PageBarMinHeight';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { AnimatePresence } from 'framer-motion';
import {
@@ -96,7 +96,7 @@ export const PageHeader = ({
}: PageHeaderProps) => {
const isMobile = useIsMobile();
const theme = useTheme();
const isNavigationDrawerExpanded = useRecoilValue(
const isNavigationDrawerExpanded = useRecoilValueV2(
isNavigationDrawerExpandedState,
);
@@ -1,13 +1,13 @@
import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import {
NAVIGATION_DRAWER_WIDTH_VAR,
navigationDrawerWidthState,
} from '@/ui/navigation/states/navigationDrawerWidthState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
export const NavigationDrawerWidthEffect = () => {
const navigationDrawerWidth = useRecoilValue(navigationDrawerWidthState);
const navigationDrawerWidth = useRecoilValueV2(navigationDrawerWidthState);
useEffect(() => {
document.documentElement.style.setProperty(
@@ -9,13 +9,14 @@ import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useRecoilValue } from 'recoil';
import { useTheme } from '@emotion/react';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { Avatar } from 'twenty-ui/display';
export const MultiWorkspaceDropdownClickableComponent = () => {
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const theme = useTheme();
const isNavigationDrawerExpanded = useRecoilValue(
const isNavigationDrawerExpanded = useRecoilValueV2(
isNavigationDrawerExpandedState,
);
return (
@@ -1,9 +1,10 @@
import styled from '@emotion/styled';
import { type ReactNode, useState } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { useSetRecoilState } from 'recoil';
import { useIsSettingsDrawer } from '@/navigation/hooks/useIsSettingsDrawer';
import { tableWidthResizeIsActiveState } from '@/object-record/record-table/states/tableWidthResizeIsActivedState';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { ResizablePanelEdge } from '@/ui/layout/resizable-panel/components/ResizablePanelEdge';
import { NAVIGATION_DRAWER_COLLAPSED_WIDTH } from '@/ui/layout/resizable-panel/constants/NavigationDrawerCollapsedWidth';
import { NAVIGATION_DRAWER_CONSTRAINTS } from '@/ui/layout/resizable-panel/constants/NavigationDrawerConstraints';
@@ -77,8 +78,8 @@ export const NavigationDrawer = ({
const isSettingsDrawer = useIsSettingsDrawer();
const [isNavigationDrawerExpanded, setIsNavigationDrawerExpanded] =
useRecoilState(isNavigationDrawerExpandedState);
const [navigationDrawerWidth, setNavigationDrawerWidth] = useRecoilState(
useRecoilStateV2(isNavigationDrawerExpandedState);
const [navigationDrawerWidth, setNavigationDrawerWidth] = useRecoilStateV2(
navigationDrawerWidthState,
);
const setTableWidthResizeIsActive = useSetRecoilState(
@@ -1,5 +1,6 @@
import { useIsSettingsPage } from '@/navigation/hooks/useIsSettingsPage';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import {
@@ -7,7 +8,6 @@ import {
motion,
type TargetAndTransition,
} from 'framer-motion';
import { useRecoilValue } from 'recoil';
const StyledAnimatedContainer = styled(motion.span)`
display: block;
@@ -20,7 +20,7 @@ export const NavigationDrawerAnimatedCollapseWrapper = ({
}) => {
const theme = useTheme();
const isSettingsPage = useIsSettingsPage();
const isNavigationDrawerExpanded = useRecoilValue(
const isNavigationDrawerExpanded = useRecoilValueV2(
isNavigationDrawerExpandedState,
);
@@ -1,11 +1,11 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useIsWorkspaceActivationStatusEqualsTo } from '@/workspace/hooks/useIsWorkspaceActivationStatusEqualsTo';
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
import { IconX } from 'twenty-ui/display';
@@ -47,9 +47,9 @@ export const NavigationDrawerBackButton = ({
title,
}: NavigationDrawerBackButtonProps) => {
const theme = useTheme();
const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState);
const navigationMemorizedUrl = useRecoilValueV2(navigationMemorizedUrlState);
const setIsNavigationDrawerExpanded = useSetRecoilState(
const setIsNavigationDrawerExpanded = useSetRecoilStateV2(
isNavigationDrawerExpandedState,
);
const navigationDrawerExpandedMemorized = useRecoilValueV2(
@@ -1,6 +1,6 @@
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import styled from '@emotion/styled';
import { useSetRecoilState } from 'recoil';
import {
IconLayoutSidebarLeftCollapse,
IconLayoutSidebarRightCollapse,
@@ -26,7 +26,7 @@ export const NavigationDrawerCollapseButton = ({
className,
direction = 'left',
}: NavigationDrawerCollapseButtonProps) => {
const setIsNavigationDrawerExpanded = useSetRecoilState(
const setIsNavigationDrawerExpanded = useSetRecoilStateV2(
isNavigationDrawerExpandedState,
);
@@ -1,11 +1,11 @@
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { MultiWorkspaceDropdownButton } from '@/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/MultiWorkspaceDropdownButton';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { PAGE_BAR_MIN_HEIGHT } from '@/ui/layout/page/constants/PageBarMinHeight';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { NavigationDrawerCollapseButton } from './NavigationDrawerCollapseButton';
const StyledContainer = styled.div`
@@ -36,7 +36,7 @@ export const NavigationDrawerHeader = ({
}: NavigationDrawerHeaderProps) => {
const isMobile = useIsMobile();
const isNavigationDrawerExpanded = useRecoilValue(
const isNavigationDrawerExpanded = useRecoilValueV2(
isNavigationDrawerExpandedState,
);
@@ -6,13 +6,13 @@ import { useNavigationDrawerTooltip } from '@/ui/navigation/navigation-drawer/ho
import { type NavigationDrawerSubItemState } from '@/ui/navigation/navigation-drawer/types/NavigationDrawerSubItemState';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import isPropValid from '@emotion/is-prop-valid';
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { type ReactNode } from 'react';
import { Link } from 'react-router-dom';
import { useRecoilState } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { Pill } from 'twenty-ui/components';
import {
@@ -305,7 +305,7 @@ export const NavigationDrawerItem = ({
const isMobile = useIsMobile();
const isSettingsPage = useIsSettingsPage();
const [isNavigationDrawerExpanded, setIsNavigationDrawerExpanded] =
useRecoilState(isNavigationDrawerExpandedState);
useRecoilStateV2(isNavigationDrawerExpandedState);
const { navigationItemId } = useNavigationDrawerTooltip(label, to);
@@ -1,5 +1,6 @@
import { useIsSettingsPage } from '@/navigation/hooks/useIsSettingsPage';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import {
@@ -8,7 +9,6 @@ import {
type TargetAndTransition,
} from 'framer-motion';
import { type ReactNode } from 'react';
import { useRecoilValue } from 'recoil';
const StyledAnimationGroupContainer = styled(motion.div)``;
@@ -23,7 +23,7 @@ export const NavigationDrawerItemsCollapsableContainer = ({
}: NavigationDrawerItemsCollapsableContainerProps) => {
const theme = useTheme();
const isSettingsPage = useIsSettingsPage();
const isNavigationDrawerExpanded = useRecoilValue(
const isNavigationDrawerExpanded = useRecoilValueV2(
isNavigationDrawerExpandedState,
);
const isExpanded = isNavigationDrawerExpanded || isSettingsPage;
@@ -4,6 +4,7 @@ import { useIsPrefetchLoading } from '@/prefetch/hooks/useIsPrefetchLoading';
import { NavigationDrawerSectionTitleSkeletonLoader } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitleSkeletonLoader';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import styled from '@emotion/styled';
import React from 'react';
import { useRecoilValue } from 'recoil';
@@ -60,7 +61,7 @@ export const NavigationDrawerSectionTitle = ({
alwaysShowRightIcon = false,
}: NavigationDrawerSectionTitleProps) => {
const isMobile = useIsMobile();
const isNavigationDrawerExpanded = useRecoilValue(
const isNavigationDrawerExpanded = useRecoilValueV2(
isNavigationDrawerExpandedState,
);
const isSettingsPage = useIsSettingsPage();
@@ -1,45 +1,40 @@
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { isNavigationSectionOpenFamilyState } from '@/ui/navigation/navigation-drawer/states/isNavigationSectionOpenFamilyState';
import { useFamilyRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilyRecoilValueV2';
export const useNavigationSection = (navigationSectionId: string) => {
const closeNavigationSection = useRecoilCallback(
({ set }) =>
() => {
set(isNavigationSectionOpenFamilyState(navigationSectionId), false);
},
[navigationSectionId],
const store = useStore();
const isNavigationSectionOpen = useFamilyRecoilValueV2(
isNavigationSectionOpenFamilyState,
navigationSectionId,
);
const openNavigationSection = useRecoilCallback(
({ set }) =>
() => {
set(isNavigationSectionOpenFamilyState(navigationSectionId), true);
},
[navigationSectionId],
);
const closeNavigationSection = useCallback(() => {
store.set(
isNavigationSectionOpenFamilyState.atomFamily(navigationSectionId),
false,
);
}, [store, navigationSectionId]);
const toggleNavigationSection = useRecoilCallback(
({ snapshot }) =>
() => {
const isNavigationSectionOpen = snapshot
.getLoadable(isNavigationSectionOpenFamilyState(navigationSectionId))
.getValue();
const openNavigationSection = useCallback(() => {
store.set(
isNavigationSectionOpenFamilyState.atomFamily(navigationSectionId),
true,
);
}, [store, navigationSectionId]);
if (isNavigationSectionOpen) {
closeNavigationSection();
} else {
openNavigationSection();
}
},
[closeNavigationSection, openNavigationSection, navigationSectionId],
);
const isNavigationSectionOpenState =
isNavigationSectionOpenFamilyState(navigationSectionId);
const toggleNavigationSection = useCallback(() => {
if (isNavigationSectionOpen) {
closeNavigationSection();
} else {
openNavigationSection();
}
}, [isNavigationSectionOpen, closeNavigationSection, openNavigationSection]);
return {
isNavigationSectionOpenState,
isNavigationSectionOpen,
closeNavigationSection,
openNavigationSection,
toggleNavigationSection,
@@ -1,8 +1,7 @@
import { atom } from 'recoil';
import { localStorageEffect } from '~/utils/recoil/localStorageEffect';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const isAdvancedModeEnabledState = atom<boolean>({
export const isAdvancedModeEnabledState = createStateV2<boolean>({
key: 'isAdvancedModeEnabledAtom',
default: false,
effects: [localStorageEffect()],
defaultValue: false,
useLocalStorage: true,
});
@@ -1,11 +1,10 @@
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
import { localStorageEffect } from '~/utils/recoil/localStorageEffect';
import { createFamilyStateV2 } from '@/ui/utilities/state/jotai/utils/createFamilyStateV2';
export const isNavigationSectionOpenFamilyState = createFamilyState<
export const isNavigationSectionOpenFamilyState = createFamilyStateV2<
boolean,
string
>({
key: 'isNavigationSectionOpenFamilyState',
defaultValue: true,
effects: [localStorageEffect()],
useLocalStorage: true,
});
@@ -1,11 +1,10 @@
import { atom } from 'recoil';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
import { MOBILE_VIEWPORT } from 'twenty-ui/theme';
import { localStorageEffect } from '~/utils/recoil/localStorageEffect';
const isMobile = window.innerWidth <= MOBILE_VIEWPORT;
export const isNavigationDrawerExpandedState = atom({
export const isNavigationDrawerExpandedState = createStateV2<boolean>({
key: 'isNavigationDrawerExpanded',
default: !isMobile,
effects: [localStorageEffect()],
defaultValue: !isMobile,
useLocalStorage: true,
});
@@ -1,12 +1,10 @@
import { atom } from 'recoil';
import { NAVIGATION_DRAWER_CONSTRAINTS } from '@/ui/layout/resizable-panel/constants/NavigationDrawerConstraints';
import { localStorageEffect } from '~/utils/recoil/localStorageEffect';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const NAVIGATION_DRAWER_WIDTH_VAR = '--navigation-drawer-width';
export const navigationDrawerWidthState = atom<number>({
export const navigationDrawerWidthState = createStateV2<number>({
key: 'navigationDrawerWidth',
default: NAVIGATION_DRAWER_CONSTRAINTS.default,
effects: [localStorageEffect()],
defaultValue: NAVIGATION_DRAWER_CONSTRAINTS.default,
useLocalStorage: true,
});
@@ -1,5 +1,5 @@
import { createState } from '@/ui/utilities/state/utils/createState';
export const navigationMemorizedUrlState = createState<string>({
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const navigationMemorizedUrlState = createStateV2<string>({
key: 'navigationMemorizedUrlState',
defaultValue: '/',
});
@@ -1,8 +1,7 @@
import { createState } from '@/ui/utilities/state/utils/createState';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const shouldNavigateBackToMemorizedUrlOnSaveState = createState<boolean>(
{
export const shouldNavigateBackToMemorizedUrlOnSaveState =
createStateV2<boolean>({
key: 'shouldNavigateBackToMemorizedUrlOnSaveState',
defaultValue: false,
},
);
});
@@ -3,7 +3,7 @@ import { createContext } from 'react';
import { useSystemColorScheme } from '@/ui/theme/hooks/useSystemColorScheme';
import { persistedColorSchemeState } from '@/ui/theme/states/persistedColorSchemeState';
import { useRecoilState } from 'recoil';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { type ColorScheme } from 'twenty-ui/input';
import { THEME_DARK, THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
@@ -16,7 +16,7 @@ export const ThemeSchemeContext = createContext<(theme: ColorScheme) => void>(
);
export const BaseThemeProvider = ({ children }: BaseThemeProviderProps) => {
const [persistedColorScheme, setPersistedColorScheme] = useRecoilState(
const [persistedColorScheme, setPersistedColorScheme] = useRecoilStateV2(
persistedColorSchemeState,
);
const systemColorScheme = useSystemColorScheme();
@@ -1,10 +1,11 @@
import { useCallback } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { useRecoilState } from 'recoil';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { persistedColorSchemeState } from '@/ui/theme/states/persistedColorSchemeState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { type ColorScheme } from '@/workspace-member/types/WorkspaceMember';
import {
type IconComponent,
@@ -19,7 +20,9 @@ export const useColorScheme = () => {
);
const { updateOneRecord } = useUpdateOneRecord();
const setPersistedColorScheme = useSetRecoilState(persistedColorSchemeState);
const setPersistedColorScheme = useSetRecoilStateV2(
persistedColorSchemeState,
);
const colorScheme = currentWorkspaceMember?.colorScheme ?? 'System';
@@ -1,10 +1,8 @@
import { atom } from 'recoil';
import { type ColorScheme } from '@/workspace-member/types/WorkspaceMember';
import { localStorageEffect } from '~/utils/recoil/localStorageEffect';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const persistedColorSchemeState = atom<ColorScheme>({
export const persistedColorSchemeState = createStateV2<ColorScheme>({
key: 'persistedColorSchemeState',
default: 'System',
effects: [localStorageEffect()],
defaultValue: 'System',
useLocalStorage: true,
});
@@ -1,13 +1,16 @@
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import { type FamilyStateV2 } from '@/ui/utilities/state/jotai/types/FamilyStateV2';
export const createFamilyStateV2 = <ValueType, FamilyKey>({
key,
defaultValue,
useLocalStorage = false,
}: {
key: string;
defaultValue: ValueType;
useLocalStorage?: boolean;
}): FamilyStateV2<ValueType, FamilyKey> => {
const atomCache = new Map<
string,
@@ -26,8 +29,11 @@ export const createFamilyStateV2 = <ValueType, FamilyKey>({
return existing;
}
const baseAtom = atom(defaultValue);
baseAtom.debugLabel = `${key}__${cacheKey}`;
const atomKey = `${key}__${cacheKey}`;
const baseAtom = useLocalStorage
? atomWithStorage<ValueType>(atomKey, defaultValue)
: atom(defaultValue);
baseAtom.debugLabel = atomKey;
atomCache.set(cacheKey, baseAtom);
return baseAtom;
@@ -1,15 +1,20 @@
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
import { type StateV2 } from '@/ui/utilities/state/jotai/types/StateV2';
export const createStateV2 = <ValueType>({
key,
defaultValue,
useLocalStorage = false,
}: {
key: string;
defaultValue: ValueType;
useLocalStorage?: boolean;
}): StateV2<ValueType> => {
const baseAtom = atom(defaultValue);
const baseAtom = useLocalStorage
? atomWithStorage<ValueType>(key, defaultValue)
: atom(defaultValue);
baseAtom.debugLabel = key;
return {
@@ -1,9 +1,10 @@
import { useCallback } from 'react';
import { useLocation } from 'react-router-dom';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useRecoilValue } from 'recoil';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
import { FieldMetadataType, SettingsPath } from 'twenty-shared/types';
@@ -15,7 +16,7 @@ export const useGetAvailableFieldsForCalendar = () => {
viewObjectMetadataIdComponentState,
);
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
const location = useLocation();
@@ -1,9 +1,10 @@
import { useCallback } from 'react';
import { useLocation } from 'react-router-dom';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useRecoilValue } from 'recoil';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
import { SettingsPath } from 'twenty-shared/types';
@@ -16,7 +17,7 @@ export const useGetAvailableFieldsToGroupRecordsBy = () => {
viewObjectMetadataIdComponentState,
);
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const setNavigationMemorizedUrl = useSetRecoilState(
const setNavigationMemorizedUrl = useSetRecoilStateV2(
navigationMemorizedUrlState,
);
const location = useLocation();
@@ -9,9 +9,10 @@ import { ObjectSettings } from '@/settings/data-model/object-details/components/
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
import { TabList } from '@/ui/layout/tab-list/components/TabList';
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecoilState } from 'recoil';
import { AppPath, SettingsPath } from 'twenty-shared/types';
import { isObjectMetadataReadOnly } from '@/object-record/read-only/utils/isObjectMetadataReadOnly';
@@ -66,7 +67,7 @@ export const SettingsObjectDetailPage = () => {
SETTINGS_OBJECT_DETAIL_TABS.COMPONENT_INSTANCE_ID,
);
const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState);
const isAdvancedModeEnabled = useRecoilValueV2(isAdvancedModeEnabledState);
const isUniqueIndexesEnabled = useIsFeatureEnabled(
FeatureFlagKey.IS_UNIQUE_INDEXES_ENABLED,
);
@@ -27,9 +27,9 @@ import { useModal } from '@/ui/layout/modal/hooks/useModal';
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { shouldNavigateBackToMemorizedUrlOnSaveState } from '@/ui/navigation/states/shouldNavigateBackToMemorizedUrlOnSaveState';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { useRecoilState } from 'recoil';
import { AppPath, SettingsPath } from 'twenty-shared/types';
import { getSettingsPath, isDefined } from 'twenty-shared/utils';
import {
@@ -67,14 +67,14 @@ export const SettingsObjectFieldEdit = () => {
const navigate = useNavigate();
const [navigationMemorizedUrl, setNavigationMemorizedUrl] = useRecoilState(
const [navigationMemorizedUrl, setNavigationMemorizedUrl] = useRecoilStateV2(
navigationMemorizedUrlState,
);
const [
shouldNavigateBackToMemorizedUrlOnSave,
setShouldNavigateBackToMemorizedUrlOnSave,
] = useRecoilState(shouldNavigateBackToMemorizedUrlOnSaveState);
] = useRecoilStateV2(shouldNavigateBackToMemorizedUrlOnSaveState);
const { objectNamePlural = '', fieldName = '' } = useParams();
@@ -15,11 +15,12 @@ import { TableHeader } from '@/ui/layout/table/components/TableHeader';
import { useSortedArray } from '@/ui/layout/table/hooks/useSortedArray';
import { type TableMetadata } from '@/ui/layout/table/types/TableMetadata';
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import styled from '@emotion/styled';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { useEffect, useMemo, useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecoilState } from 'recoil';
import { FieldMetadataType } from 'twenty-shared/types';
import {
IconArchive,
@@ -90,7 +91,7 @@ export const SettingsObjectFieldTable = ({
const [showInactive, setShowInactive] = useState(true);
const [showSystemFields, setShowSystemFields] = useState(false);
const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState);
const isAdvancedModeEnabled = useRecoilValueV2(isAdvancedModeEnabledState);
const tableMetadata = SETTINGS_OBJECT_FIELD_TABLE_METADATA;
@@ -16,6 +16,7 @@ import { Table } from '@/ui/layout/table/components/Table';
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
import { useSortedArray } from '@/ui/layout/table/hooks/useSortedArray';
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
@@ -49,7 +50,7 @@ export const SettingsObjectTable = ({
const theme = useTheme();
const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState);
const isAdvancedModeEnabled = useRecoilValueV2(isAdvancedModeEnabledState);
const [searchTerm, setSearchTerm] = useState('');
const [showDeactivated, setShowDeactivated] = useState(true);