+5
-9
@@ -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) => {
|
||||
|
||||
+8
-6
@@ -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();
|
||||
|
||||
+2
-2
@@ -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');
|
||||
|
||||
+8
-6
@@ -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();
|
||||
|
||||
+3
-3
@@ -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();
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+3
-2
@@ -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(
|
||||
|
||||
+8
-4
@@ -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();
|
||||
|
||||
|
||||
+1
-2
@@ -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);
|
||||
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+3
-3
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+2
-2
@@ -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 });
|
||||
|
||||
+2
-2
@@ -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();
|
||||
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
|
||||
+2
-1
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+4
-2
@@ -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 (
|
||||
|
||||
+4
-2
@@ -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();
|
||||
|
||||
|
||||
+18
-7
@@ -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();
|
||||
|
||||
+36
-35
@@ -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'>) => {
|
||||
|
||||
+10
-8
@@ -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,
|
||||
});
|
||||
);
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+42
-42
@@ -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(
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -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(
|
||||
|
||||
+2
-1
@@ -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 (
|
||||
|
||||
+4
-3
@@ -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(
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+3
-3
@@ -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(
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+2
-1
@@ -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();
|
||||
|
||||
+27
-32
@@ -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,
|
||||
|
||||
+4
-5
@@ -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,
|
||||
});
|
||||
|
||||
+3
-4
@@ -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,
|
||||
});
|
||||
|
||||
+4
-5
@@ -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,
|
||||
});
|
||||
|
||||
+4
-6
@@ -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,
|
||||
});
|
||||
|
||||
+2
-2
@@ -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: '/',
|
||||
});
|
||||
|
||||
+4
-5
@@ -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,
|
||||
});
|
||||
|
||||
+8
-2
@@ -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 {
|
||||
|
||||
+3
-2
@@ -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();
|
||||
|
||||
+3
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user