From d5a8cc2085b6bc2ee75b958fd4d4a67a11479891 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Thu, 12 Feb 2026 18:13:31 +0100 Subject: [PATCH] Migrate more to Jotai (#17903) Here we go again --- .../src/modules/activities/hooks/useUpsertActivity.ts | 5 ++++- .../activities/states/isActivityInCreateModeState.ts | 4 ++-- .../src/modules/ai/hooks/useAiModelOptions.ts | 6 +++--- .../src/modules/apollo/hooks/useApolloFactory.ts | 8 +++++--- .../TwoFactorAuthenticationProvisionEffect.tsx | 8 +++++--- .../sign-in-up/components/SignInUpGlobalScopeForm.tsx | 3 ++- .../SignInUpTwoFactorAuthenticationProvision.tsx | 5 +++-- .../src/modules/auth/sign-in-up/hooks/useSignInUp.ts | 3 ++- .../src/modules/auth/states/previousUrlState.ts | 4 ++-- .../twenty-front/src/modules/auth/states/qrCode.ts | 4 ++-- .../src/modules/auth/states/signInUpModeState.ts | 4 ++-- .../components/ChromeExtensionSidecarEffect.tsx | 5 +++-- .../modules/client-config/hooks/useClientConfig.ts | 11 ++++++----- .../src/modules/client-config/states/aiModelsState.ts | 4 ++-- .../modules/client-config/states/appVersionState.ts | 4 ++-- .../client-config/states/authProvidersState.ts | 4 ++-- .../client-config/states/chromeExtensionIdState.ts | 4 ++-- .../client-config/states/isAnalyticsEnabledState.ts | 4 ++-- .../record-merge/hooks/useMergeRecordsActions.ts | 7 ++++--- .../record-merge/hooks/useMergeRecordsSettings.ts | 6 +++--- .../record-merge/hooks/usePerformMergePreview.ts | 6 +++--- .../record-merge/states/mergeInProgressState.ts | 4 ++-- .../record-merge/states/mergeSettingsState.ts | 4 ++-- .../components/SettingsAdminConfigVariables.tsx | 8 ++++---- .../states/configVariableGroupFilterState.ts | 4 ++-- .../states/configVariableSourceFilterState.ts | 4 ++-- .../states/showHiddenGroupVariablesState.ts | 4 ++-- .../domains/hooks/useCheckPublicDomainValidRecords.ts | 4 ++-- .../domains/states/publicDomainRecordsState.ts | 4 ++-- .../SettingsSecurityAuthBypassOptionsList.tsx | 5 +++-- .../SettingsSecurityAuthProvidersOptionsList.tsx | 3 ++- .../TwoFactorAuthenticationSetupForSettingsEffect.tsx | 5 +++-- .../src/modules/ui/input/hooks/useIconPicker.ts | 5 ++--- .../src/modules/ui/input/states/iconPickerState.ts | 4 ++-- .../step-bar/hooks/__tests__/useStepBar.test.tsx | 7 ++++--- .../ui/navigation/step-bar/hooks/useStepBar.ts | 4 ++-- .../step-bar/states/stepBarInternalState.ts | 4 ++-- .../src/modules/users/hooks/useLoadCurrentUser.ts | 5 +++-- .../hooks/useCreateWorkspaceInvitation.ts | 6 ++++-- .../hooks/useDeleteWorkspaceInvitation.ts | 6 ++++-- .../hooks/useResendWorkspaceInvitation.ts | 6 ++++-- .../states/workspaceInvitationsStates.ts | 4 ++-- .../SettingsTwoFactorAuthenticationMethod.tsx | 4 ++-- .../ai/components/SettingsAIRouterSettings.tsx | 5 +++-- .../ai/components/SettingsAgentModelCapabilities.tsx | 4 ++-- .../ai/components/SettingsAgentSettingsTab.tsx | 4 ++-- .../settings/members/SettingsWorkspaceMembers.tsx | 10 +++++++--- .../src/pages/settings/security/SettingsSecurity.tsx | 3 ++- 48 files changed, 134 insertions(+), 105 deletions(-) diff --git a/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts b/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts index dc238a54a3..fc3c3fa1d5 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts @@ -10,6 +10,7 @@ import { type Task } from '@/activities/types/Task'; import { type CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { isDefined } from 'twenty-shared/utils'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; export const useUpsertActivity = ({ activityObjectNameSingular, @@ -18,7 +19,9 @@ export const useUpsertActivity = ({ | CoreObjectNameSingular.Task | CoreObjectNameSingular.Note; }) => { - const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState); + const [isActivityInCreateMode] = useRecoilStateV2( + isActivityInCreateModeState, + ); const { updateOneRecord: updateOneActivity } = useUpdateOneRecord(); diff --git a/packages/twenty-front/src/modules/activities/states/isActivityInCreateModeState.ts b/packages/twenty-front/src/modules/activities/states/isActivityInCreateModeState.ts index 9a6849f31f..13a6172ecb 100644 --- a/packages/twenty-front/src/modules/activities/states/isActivityInCreateModeState.ts +++ b/packages/twenty-front/src/modules/activities/states/isActivityInCreateModeState.ts @@ -1,5 +1,5 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; -export const isActivityInCreateModeState = createState({ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; +export const isActivityInCreateModeState = createStateV2({ key: 'isActivityInCreateModeState', defaultValue: false, }); diff --git a/packages/twenty-front/src/modules/ai/hooks/useAiModelOptions.ts b/packages/twenty-front/src/modules/ai/hooks/useAiModelOptions.ts index 14e67e676c..ceb19d2cf9 100644 --- a/packages/twenty-front/src/modules/ai/hooks/useAiModelOptions.ts +++ b/packages/twenty-front/src/modules/ai/hooks/useAiModelOptions.ts @@ -1,14 +1,14 @@ import { aiModelsState } from '@/client-config/states/aiModelsState'; -import { useRecoilValue } from 'recoil'; import { type SelectOption } from 'twenty-ui/input'; import { DEFAULT_FAST_MODEL } from '@/ai/constants/DefaultFastModel'; import { DEFAULT_SMART_MODEL } from '@/ai/constants/DefaultSmartModel'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const useAiModelOptions = ( includeDeprecated = false, ): SelectOption[] => { - const aiModels = useRecoilValue(aiModelsState); + const aiModels = useRecoilValueV2(aiModelsState); return aiModels .filter((model) => includeDeprecated || !model.deprecated) @@ -24,7 +24,7 @@ export const useAiModelOptions = ( }; export const useAiModelLabel = (modelId: string | undefined): string => { - const aiModels = useRecoilValue(aiModelsState); + const aiModels = useRecoilValueV2(aiModelsState); if (!modelId) { return ''; diff --git a/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts b/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts index 4b16d9e759..b8504c4d42 100644 --- a/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts +++ b/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts @@ -1,7 +1,7 @@ import { InMemoryCache, type NormalizedCacheObject } from '@apollo/client'; import { useMemo, useRef } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilState, useSetRecoilState } from 'recoil'; import { currentUserState } from '@/auth/states/currentUserState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; @@ -18,6 +18,8 @@ import { appVersionState } from '@/client-config/states/appVersionState'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { AppPath } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const useApolloFactory = (options: Partial> = {}) => { // eslint-disable-next-line twenty/no-state-useref @@ -28,14 +30,14 @@ export const useApolloFactory = (options: Partial> = {}) => { const [currentWorkspace, setCurrentWorkspace] = useRecoilState( currentWorkspaceState, ); - const appVersion = useRecoilValue(appVersionState); + const appVersion = useRecoilValueV2(appVersionState); const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState( currentWorkspaceMemberState, ); const setCurrentUser = useSetRecoilState(currentUserState); const setCurrentUserWorkspace = useSetRecoilState(currentUserWorkspaceState); - const setPreviousUrl = useSetRecoilState(previousUrlState); + const setPreviousUrl = useSetRecoilStateV2(previousUrlState); const location = useLocation(); const { enqueueErrorSnackBar } = useSnackBar(); diff --git a/packages/twenty-front/src/modules/auth/components/TwoFactorAuthenticationProvisionEffect.tsx b/packages/twenty-front/src/modules/auth/components/TwoFactorAuthenticationProvisionEffect.tsx index f744d318fe..71dd50b586 100644 --- a/packages/twenty-front/src/modules/auth/components/TwoFactorAuthenticationProvisionEffect.tsx +++ b/packages/twenty-front/src/modules/auth/components/TwoFactorAuthenticationProvisionEffect.tsx @@ -5,10 +5,12 @@ import { useCurrentUserWorkspaceTwoFactorAuthentication } from '@/settings/two-f import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { useLingui } from '@lingui/react/macro'; import { useEffect } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { AppPath } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { useNavigateApp } from '~/hooks/useNavigateApp'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const TwoFactorAuthenticationSetupEffect = () => { const { initiateCurrentUserWorkspaceOtpProvisioning } = @@ -18,8 +20,8 @@ export const TwoFactorAuthenticationSetupEffect = () => { const navigate = useNavigateApp(); const { origin } = useOrigin(); const loginToken = useRecoilValue(loginTokenState); - const qrCode = useRecoilValue(qrCodeState); - const setQrCodeState = useSetRecoilState(qrCodeState); + const qrCode = useRecoilValueV2(qrCodeState); + const setQrCodeState = useSetRecoilStateV2(qrCodeState); const { t } = useLingui(); diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpGlobalScopeForm.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpGlobalScopeForm.tsx index be12892345..8357bce15c 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpGlobalScopeForm.tsx +++ b/packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpGlobalScopeForm.tsx @@ -29,6 +29,7 @@ import { } from 'twenty-ui/display'; import { type AvailableWorkspace } from '~/generated-metadata/graphql'; import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledContentContainer = styled(motion.div)` margin-bottom: ${({ theme }) => theme.spacing(8)}; @@ -124,7 +125,7 @@ const StyledActionLinkContainer = styled.div` `; export const SignInUpGlobalScopeForm = () => { - const authProviders = useRecoilValue(authProvidersState); + const authProviders = useRecoilValueV2(authProvidersState); const signInUpStep = useRecoilValue(signInUpStepState); const { buildWorkspaceUrl } = useBuildWorkspaceUrl(); const { signOut } = useAuth(); diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpTwoFactorAuthenticationProvision.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpTwoFactorAuthenticationProvision.tsx index 002cfdc487..487dd69854 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpTwoFactorAuthenticationProvision.tsx +++ b/packages/twenty-front/src/modules/auth/sign-in-up/components/internal/SignInUpTwoFactorAuthenticationProvision.tsx @@ -10,10 +10,11 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { Trans, useLingui } from '@lingui/react/macro'; import QRCode from 'react-qr-code'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; import { IconCopy } from 'twenty-ui/display'; import { Loader } from 'twenty-ui/feedback'; import { MainButton } from 'twenty-ui/input'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledMainContentContainer = styled.div` margin-bottom: ${({ theme }) => theme.spacing(8)}; @@ -69,7 +70,7 @@ export const SignInUpTwoFactorAuthenticationProvision = () => { const { t } = useLingui(); const theme = useTheme(); const { enqueueSuccessSnackBar } = useSnackBar(); - const qrCode = useRecoilValue(qrCodeState); + const qrCode = useRecoilValueV2(qrCodeState); const setSignInUpStep = useSetRecoilState(signInUpStepState); const handleClick = () => { diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.ts b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.ts index d9e4b853c5..24aefc2c4a 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.ts +++ b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.ts @@ -24,13 +24,14 @@ import { isDefined } from 'twenty-shared/utils'; import { buildAppPathWithQueryParams } from '~/utils/buildAppPathWithQueryParams'; import { isMatchingLocation } from '~/utils/isMatchingLocation'; import { useAuth } from '@/auth/hooks/useAuth'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; export const useSignInUp = (form: UseFormReturn
) => { const { enqueueErrorSnackBar } = useSnackBar(); const { t } = useLingui(); const [signInUpStep, setSignInUpStep] = useRecoilState(signInUpStepState); - const [signInUpMode, setSignInUpMode] = useRecoilState(signInUpModeState); + const [signInUpMode, setSignInUpMode] = useRecoilStateV2(signInUpModeState); const { isOnAWorkspace } = useIsCurrentLocationOnAWorkspace(); const { isCaptchaReady } = useCaptcha(); const setLastAuthenticatedMethod = useSetRecoilState( diff --git a/packages/twenty-front/src/modules/auth/states/previousUrlState.ts b/packages/twenty-front/src/modules/auth/states/previousUrlState.ts index f712dacc28..ff34900116 100644 --- a/packages/twenty-front/src/modules/auth/states/previousUrlState.ts +++ b/packages/twenty-front/src/modules/auth/states/previousUrlState.ts @@ -1,5 +1,5 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; -export const previousUrlState = createState({ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; +export const previousUrlState = createStateV2({ key: 'previousUrlState', defaultValue: '', }); diff --git a/packages/twenty-front/src/modules/auth/states/qrCode.ts b/packages/twenty-front/src/modules/auth/states/qrCode.ts index c59c5ee197..34be7f7eed 100644 --- a/packages/twenty-front/src/modules/auth/states/qrCode.ts +++ b/packages/twenty-front/src/modules/auth/states/qrCode.ts @@ -1,6 +1,6 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const qrCodeState = createState({ +export const qrCodeState = createStateV2({ key: 'qrCodeState', defaultValue: null, }); diff --git a/packages/twenty-front/src/modules/auth/states/signInUpModeState.ts b/packages/twenty-front/src/modules/auth/states/signInUpModeState.ts index 23802d18b4..d77d4e27c8 100644 --- a/packages/twenty-front/src/modules/auth/states/signInUpModeState.ts +++ b/packages/twenty-front/src/modules/auth/states/signInUpModeState.ts @@ -1,7 +1,7 @@ import { SignInUpMode } from '@/auth/types/signInUpMode'; -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const signInUpModeState = createState({ +export const signInUpModeState = createStateV2({ key: 'signInUpModeState', defaultValue: SignInUpMode.SignIn, }); diff --git a/packages/twenty-front/src/modules/chrome-extension-sidecar/components/ChromeExtensionSidecarEffect.tsx b/packages/twenty-front/src/modules/chrome-extension-sidecar/components/ChromeExtensionSidecarEffect.tsx index e00e75a26c..b5b1a67ba2 100644 --- a/packages/twenty-front/src/modules/chrome-extension-sidecar/components/ChromeExtensionSidecarEffect.tsx +++ b/packages/twenty-front/src/modules/chrome-extension-sidecar/components/ChromeExtensionSidecarEffect.tsx @@ -1,17 +1,18 @@ import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; import { tokenPairState } from '@/auth/states/tokenPairState'; import { isLoadingTokensFromExtensionState } from '@/chrome-extension-sidecar/states/isLoadingTokensFromExtensionState'; import { chromeExtensionIdState } from '@/client-config/states/chromeExtensionIdState'; import { isInFrame } from '~/utils/isInIframe'; import { isDefined } from 'twenty-shared/utils'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const ChromeExtensionSidecarEffect = () => { const navigate = useNavigate(); const setTokenPair = useSetRecoilState(tokenPairState); - const chromeExtensionId = useRecoilValue(chromeExtensionIdState); + const chromeExtensionId = useRecoilValueV2(chromeExtensionIdState); const setIsLoadingTokensFromExtension = useSetRecoilState( isLoadingTokensFromExtensionState, ); diff --git a/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts b/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts index d188baebde..497abc50fb 100644 --- a/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts +++ b/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts @@ -33,6 +33,7 @@ import { isAttachmentPreviewEnabledStateV2 } from '@/client-config/states/isAtta import { clientConfigApiStatusState } from '@/client-config/states/clientConfigApiStatusState'; import { getClientConfig } from '@/client-config/utils/getClientConfig'; import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; type UseClientConfigResult = { data: { clientConfig: ClientConfig } | undefined; @@ -43,10 +44,10 @@ type UseClientConfigResult = { }; export const useClientConfig = (): UseClientConfigResult => { - const setIsAnalyticsEnabled = useSetRecoilState(isAnalyticsEnabledState); + const setIsAnalyticsEnabled = useSetRecoilStateV2(isAnalyticsEnabledState); const setDomainConfiguration = useSetRecoilState(domainConfigurationState); - const setAuthProviders = useSetRecoilState(authProvidersState); - const setAiModels = useSetRecoilState(aiModelsState); + const setAuthProviders = useSetRecoilStateV2(authProvidersState); + const setAiModels = useSetRecoilStateV2(aiModelsState); const setIsDeveloperDefaultSignInPrefilled = useSetRecoilState( isDeveloperDefaultSignInPrefilledState, @@ -68,7 +69,7 @@ export const useClientConfig = (): UseClientConfigResult => { const setCaptcha = useSetRecoilState(captchaState); - const setChromeExtensionId = useSetRecoilState(chromeExtensionIdState); + const setChromeExtensionId = useSetRecoilStateV2(chromeExtensionIdState); const setApiConfig = useSetRecoilState(apiConfigState); @@ -127,7 +128,7 @@ export const useClientConfig = (): UseClientConfigResult => { isClickHouseConfiguredState, ); - const setAppVersion = useSetRecoilState(appVersionState); + const setAppVersion = useSetRecoilStateV2(appVersionState); const fetchClientConfig = useCallback(async () => { setClientConfigApiStatus((prev) => ({ diff --git a/packages/twenty-front/src/modules/client-config/states/aiModelsState.ts b/packages/twenty-front/src/modules/client-config/states/aiModelsState.ts index 69e0b38b74..ce86935345 100644 --- a/packages/twenty-front/src/modules/client-config/states/aiModelsState.ts +++ b/packages/twenty-front/src/modules/client-config/states/aiModelsState.ts @@ -1,7 +1,7 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; import { type ClientAiModelConfig } from '~/generated-metadata/graphql'; -export const aiModelsState = createState({ +export const aiModelsState = createStateV2({ key: 'aiModelsState', defaultValue: [], }); diff --git a/packages/twenty-front/src/modules/client-config/states/appVersionState.ts b/packages/twenty-front/src/modules/client-config/states/appVersionState.ts index 2d3d0f4a53..96a0ac6475 100644 --- a/packages/twenty-front/src/modules/client-config/states/appVersionState.ts +++ b/packages/twenty-front/src/modules/client-config/states/appVersionState.ts @@ -1,6 +1,6 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const appVersionState = createState({ +export const appVersionState = createStateV2({ key: 'appVersion', defaultValue: undefined, }); diff --git a/packages/twenty-front/src/modules/client-config/states/authProvidersState.ts b/packages/twenty-front/src/modules/client-config/states/authProvidersState.ts index 23ab4b01b8..b48c932b20 100644 --- a/packages/twenty-front/src/modules/client-config/states/authProvidersState.ts +++ b/packages/twenty-front/src/modules/client-config/states/authProvidersState.ts @@ -1,7 +1,7 @@ import { type AuthProviders } from '~/generated-metadata/graphql'; -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const authProvidersState = createState({ +export const authProvidersState = createStateV2({ key: 'authProvidersState', defaultValue: { google: true, diff --git a/packages/twenty-front/src/modules/client-config/states/chromeExtensionIdState.ts b/packages/twenty-front/src/modules/client-config/states/chromeExtensionIdState.ts index 3f9c0b7abc..6ea14aea4c 100644 --- a/packages/twenty-front/src/modules/client-config/states/chromeExtensionIdState.ts +++ b/packages/twenty-front/src/modules/client-config/states/chromeExtensionIdState.ts @@ -1,5 +1,5 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; -export const chromeExtensionIdState = createState({ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; +export const chromeExtensionIdState = createStateV2({ key: 'chromeExtensionIdState', defaultValue: null, }); diff --git a/packages/twenty-front/src/modules/client-config/states/isAnalyticsEnabledState.ts b/packages/twenty-front/src/modules/client-config/states/isAnalyticsEnabledState.ts index 333140cda3..473abd436b 100644 --- a/packages/twenty-front/src/modules/client-config/states/isAnalyticsEnabledState.ts +++ b/packages/twenty-front/src/modules/client-config/states/isAnalyticsEnabledState.ts @@ -1,5 +1,5 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; -export const isAnalyticsEnabledState = createState({ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; +export const isAnalyticsEnabledState = createStateV2({ key: 'isAnalyticsEnabled', defaultValue: false, }); diff --git a/packages/twenty-front/src/modules/object-record/record-merge/hooks/useMergeRecordsActions.ts b/packages/twenty-front/src/modules/object-record/record-merge/hooks/useMergeRecordsActions.ts index b91caf547e..311178c180 100644 --- a/packages/twenty-front/src/modules/object-record/record-merge/hooks/useMergeRecordsActions.ts +++ b/packages/twenty-front/src/modules/object-record/record-merge/hooks/useMergeRecordsActions.ts @@ -1,5 +1,4 @@ import { useLingui } from '@lingui/react/macro'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { useMergeManyRecords } from '@/object-record/hooks/useMergeManyRecords'; @@ -9,6 +8,8 @@ import { AppPath } from 'twenty-shared/types'; import { useNavigateApp } from '~/hooks/useNavigateApp'; import { isMergeInProgressState } from '@/object-record/record-merge/states/mergeInProgressState'; import { mergeSettingsState } from '@/object-record/record-merge/states/mergeSettingsState'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; type UseMergeRecordsActionsProps = { objectNameSingular: string; @@ -17,7 +18,7 @@ type UseMergeRecordsActionsProps = { export const useMergeRecordsActions = ({ objectNameSingular, }: UseMergeRecordsActionsProps) => { - const mergeSettings = useRecoilValue(mergeSettingsState); + const mergeSettings = useRecoilValueV2(mergeSettingsState); const { selectedRecords } = useMergeRecordsSelectedRecords(); @@ -25,7 +26,7 @@ export const useMergeRecordsActions = ({ objectNameSingular, }); - const setMergeInProgress = useSetRecoilState(isMergeInProgressState); + const setMergeInProgress = useSetRecoilStateV2(isMergeInProgressState); const { t } = useLingui(); const { enqueueSuccessSnackBar, enqueueErrorSnackBar } = useSnackBar(); diff --git a/packages/twenty-front/src/modules/object-record/record-merge/hooks/useMergeRecordsSettings.ts b/packages/twenty-front/src/modules/object-record/record-merge/hooks/useMergeRecordsSettings.ts index 229ab43e47..2d72ea6af7 100644 --- a/packages/twenty-front/src/modules/object-record/record-merge/hooks/useMergeRecordsSettings.ts +++ b/packages/twenty-front/src/modules/object-record/record-merge/hooks/useMergeRecordsSettings.ts @@ -1,10 +1,10 @@ -import { useRecoilState } from 'recoil'; - import { type MergeManySettings } from '@/object-record/hooks/useMergeManyRecords'; import { mergeSettingsState } from '@/object-record/record-merge/states/mergeSettingsState'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; export const useMergeRecordsSettings = () => { - const [mergeSettings, setMergeSettings] = useRecoilState(mergeSettingsState); + const [mergeSettings, setMergeSettings] = + useRecoilStateV2(mergeSettingsState); const updateMergeSettings = (settings: MergeManySettings) => { setMergeSettings(settings); diff --git a/packages/twenty-front/src/modules/object-record/record-merge/hooks/usePerformMergePreview.ts b/packages/twenty-front/src/modules/object-record/record-merge/hooks/usePerformMergePreview.ts index 6d73891536..5c5c34b54b 100644 --- a/packages/twenty-front/src/modules/object-record/record-merge/hooks/usePerformMergePreview.ts +++ b/packages/twenty-front/src/modules/object-record/record-merge/hooks/usePerformMergePreview.ts @@ -4,9 +4,9 @@ import { useMergeRecordsSelectedRecords } from '@/object-record/record-merge/hoo import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; import { useEffect, useState } from 'react'; -import { useRecoilValue } from 'recoil'; import { isMergeInProgressState } from '@/object-record/record-merge/states/mergeInProgressState'; import { mergeSettingsState } from '@/object-record/record-merge/states/mergeSettingsState'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; type UseMergePreviewProps = { objectNameSingular: string; @@ -20,8 +20,8 @@ export const usePerformMergePreview = ({ const [isGeneratingPreview, setIsGeneratingPreview] = useState(false); const [isInitialized, setIsInitialized] = useState(false); - const mergeSettings = useRecoilValue(mergeSettingsState); - const isMergeInProgress = useRecoilValue(isMergeInProgressState); + const mergeSettings = useRecoilValueV2(mergeSettingsState); + const isMergeInProgress = useRecoilValueV2(isMergeInProgressState); const { mergeManyRecords } = useMergeManyRecords({ objectNameSingular, diff --git a/packages/twenty-front/src/modules/object-record/record-merge/states/mergeInProgressState.ts b/packages/twenty-front/src/modules/object-record/record-merge/states/mergeInProgressState.ts index 20c7a84719..8d42272466 100644 --- a/packages/twenty-front/src/modules/object-record/record-merge/states/mergeInProgressState.ts +++ b/packages/twenty-front/src/modules/object-record/record-merge/states/mergeInProgressState.ts @@ -1,6 +1,6 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const isMergeInProgressState = createState({ +export const isMergeInProgressState = createStateV2({ key: 'isMergeInProgress', defaultValue: false, }); diff --git a/packages/twenty-front/src/modules/object-record/record-merge/states/mergeSettingsState.ts b/packages/twenty-front/src/modules/object-record/record-merge/states/mergeSettingsState.ts index 9b59df95e9..7d9d388e41 100644 --- a/packages/twenty-front/src/modules/object-record/record-merge/states/mergeSettingsState.ts +++ b/packages/twenty-front/src/modules/object-record/record-merge/states/mergeSettingsState.ts @@ -1,7 +1,7 @@ import { type MergeManySettings } from '@/object-record/hooks/useMergeManyRecords'; -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const mergeSettingsState = createState({ +export const mergeSettingsState = createStateV2({ key: 'mergeSettingsState', defaultValue: { conflictPriorityIndex: 0, diff --git a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx index 882af53ec4..57628086d1 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx +++ b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/components/SettingsAdminConfigVariables.tsx @@ -9,7 +9,6 @@ import { showHiddenGroupVariablesState } from '@/settings/admin-panel/config-var import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; import { useMemo, useState } from 'react'; -import { useRecoilState } from 'recoil'; import { H2Title } from 'twenty-ui/display'; import { Section } from 'twenty-ui/layout'; import { @@ -18,6 +17,7 @@ import { } from '~/generated-metadata/graphql'; import { normalizeSearchText } from '~/utils/normalizeSearchText'; import { ConfigVariableSearchInput } from './ConfigVariableSearchInput'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; const StyledControlsContainer = styled.div` display: flex; @@ -37,11 +37,11 @@ export const SettingsAdminConfigVariables = () => { const [search, setSearch] = useState(''); const [showHiddenGroupVariables, setShowHiddenGroupVariables] = - useRecoilState(showHiddenGroupVariablesState); + useRecoilStateV2(showHiddenGroupVariablesState); const [configVariableSourceFilter, setConfigVariableSourceFilter] = - useRecoilState(configVariableSourceFilterState); + useRecoilStateV2(configVariableSourceFilterState); const [configVariableGroupFilter, setConfigVariableGroupFilter] = - useRecoilState(configVariableGroupFilterState); + useRecoilStateV2(configVariableGroupFilterState); const allGroups = useMemo( () => configVariables?.getConfigVariablesGrouped.groups ?? [], diff --git a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/configVariableGroupFilterState.ts b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/configVariableGroupFilterState.ts index 53b4083017..b6e1a12072 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/configVariableGroupFilterState.ts +++ b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/configVariableGroupFilterState.ts @@ -1,8 +1,8 @@ import { type ConfigVariableGroupFilter } from '@/settings/admin-panel/config-variables/types/ConfigVariableGroupFilter'; -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; export const configVariableGroupFilterState = - createState({ + createStateV2({ key: 'configVariableGroupFilterState', defaultValue: 'all', }); diff --git a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/configVariableSourceFilterState.ts b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/configVariableSourceFilterState.ts index 998823f6fe..dcca5b0485 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/configVariableSourceFilterState.ts +++ b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/configVariableSourceFilterState.ts @@ -1,8 +1,8 @@ import { type ConfigVariableSourceFilter } from '@/settings/admin-panel/config-variables/types/ConfigVariableSourceFilter'; -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; export const configVariableSourceFilterState = - createState({ + createStateV2({ key: 'configVariableSourceFilterState', defaultValue: 'all', }); diff --git a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/showHiddenGroupVariablesState.ts b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/showHiddenGroupVariablesState.ts index 3b4bd33349..3e30690006 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/showHiddenGroupVariablesState.ts +++ b/packages/twenty-front/src/modules/settings/admin-panel/config-variables/states/showHiddenGroupVariablesState.ts @@ -1,6 +1,6 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const showHiddenGroupVariablesState = createState({ +export const showHiddenGroupVariablesState = createStateV2({ key: 'showHiddenGroupVariablesState', defaultValue: false, }); diff --git a/packages/twenty-front/src/modules/settings/domains/hooks/useCheckPublicDomainValidRecords.ts b/packages/twenty-front/src/modules/settings/domains/hooks/useCheckPublicDomainValidRecords.ts index 1a9d0fbaa6..c31cd982b3 100644 --- a/packages/twenty-front/src/modules/settings/domains/hooks/useCheckPublicDomainValidRecords.ts +++ b/packages/twenty-front/src/modules/settings/domains/hooks/useCheckPublicDomainValidRecords.ts @@ -1,8 +1,8 @@ -import { useRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { publicDomainRecordsState } from '@/settings/domains/states/publicDomainRecordsState'; import { useCheckPublicDomainValidRecordsMutation } from '~/generated-metadata/graphql'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; export const useCheckPublicDomainValidRecords = () => { const [checkPublicDomainValidRecords] = @@ -10,7 +10,7 @@ export const useCheckPublicDomainValidRecords = () => { const { enqueueErrorSnackBar } = useSnackBar(); const [{ isLoading, publicDomainRecords }, setPublicDomainRecords] = - useRecoilState(publicDomainRecordsState); + useRecoilStateV2(publicDomainRecordsState); const checkPublicDomainRecords = (domain: string) => { if (isLoading) { diff --git a/packages/twenty-front/src/modules/settings/domains/states/publicDomainRecordsState.ts b/packages/twenty-front/src/modules/settings/domains/states/publicDomainRecordsState.ts index 70affb357e..22c403bbad 100644 --- a/packages/twenty-front/src/modules/settings/domains/states/publicDomainRecordsState.ts +++ b/packages/twenty-front/src/modules/settings/domains/states/publicDomainRecordsState.ts @@ -1,7 +1,7 @@ import { type DomainValidRecords } from '~/generated-metadata/graphql'; -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const publicDomainRecordsState = createState<{ +export const publicDomainRecordsState = createStateV2<{ publicDomainRecords: DomainValidRecords | null; isLoading: boolean; }>({ diff --git a/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthBypassOptionsList.tsx b/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthBypassOptionsList.tsx index fd7adcc624..80002f8f2f 100644 --- a/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthBypassOptionsList.tsx +++ b/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthBypassOptionsList.tsx @@ -5,7 +5,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { ApolloError } from '@apollo/client'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilState } from 'recoil'; import { capitalize } from 'twenty-shared/utils'; import { IconGoogle, IconMicrosoft, IconPassword } from 'twenty-ui/display'; import { Card } from 'twenty-ui/layout'; @@ -13,6 +13,7 @@ import { type AuthProviders, useUpdateWorkspaceMutation, } from '~/generated-metadata/graphql'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledSettingsSecurityOptionsList = styled.div` display: flex; @@ -24,7 +25,7 @@ export const SettingsSecurityAuthBypassOptionsList = () => { const { t } = useLingui(); const { enqueueErrorSnackBar } = useSnackBar(); - const authProviders = useRecoilValue(authProvidersState); + const authProviders = useRecoilValueV2(authProvidersState); const [currentWorkspace, setCurrentWorkspace] = useRecoilState( currentWorkspaceState, diff --git a/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthProvidersOptionsList.tsx b/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthProvidersOptionsList.tsx index c1c5ddb8d7..5c50391788 100644 --- a/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthProvidersOptionsList.tsx +++ b/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthProvidersOptionsList.tsx @@ -22,6 +22,7 @@ import { } from '~/generated-metadata/graphql'; import { Toggle2FA } from './Toggle2FA'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledSettingsSecurityOptionsList = styled.div` display: flex; @@ -34,7 +35,7 @@ export const SettingsSecurityAuthProvidersOptionsList = () => { const { enqueueErrorSnackBar } = useSnackBar(); const SSOIdentitiesProviders = useRecoilValue(SSOIdentitiesProvidersState); - const authProviders = useRecoilValue(authProvidersState); + const authProviders = useRecoilValueV2(authProvidersState); const [currentWorkspace, setCurrentWorkspace] = useRecoilState( currentWorkspaceState, diff --git a/packages/twenty-front/src/modules/settings/two-factor-authentication/components/TwoFactorAuthenticationSetupForSettingsEffect.tsx b/packages/twenty-front/src/modules/settings/two-factor-authentication/components/TwoFactorAuthenticationSetupForSettingsEffect.tsx index d1024d8ad8..a96ad41d4a 100644 --- a/packages/twenty-front/src/modules/settings/two-factor-authentication/components/TwoFactorAuthenticationSetupForSettingsEffect.tsx +++ b/packages/twenty-front/src/modules/settings/two-factor-authentication/components/TwoFactorAuthenticationSetupForSettingsEffect.tsx @@ -4,8 +4,9 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { gql, useMutation } from '@apollo/client'; import { useLingui } from '@lingui/react/macro'; import { useEffect } from 'react'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; const INITIATE_OTP_PROVISIONING_FOR_AUTHENTICATED_USER = gql` mutation initiateOTPProvisioningForAuthenticatedUser { @@ -17,7 +18,7 @@ const INITIATE_OTP_PROVISIONING_FOR_AUTHENTICATED_USER = gql` export const TwoFactorAuthenticationSetupForSettingsEffect = () => { const { enqueueErrorSnackBar } = useSnackBar(); - const [qrCode, setQrCode] = useRecoilState(qrCodeState); + const [qrCode, setQrCode] = useRecoilStateV2(qrCodeState); const currentUser = useRecoilValue(currentUserState); const { t } = useLingui(); diff --git a/packages/twenty-front/src/modules/ui/input/hooks/useIconPicker.ts b/packages/twenty-front/src/modules/ui/input/hooks/useIconPicker.ts index e363eaac89..4476ad19c4 100644 --- a/packages/twenty-front/src/modules/ui/input/hooks/useIconPicker.ts +++ b/packages/twenty-front/src/modules/ui/input/hooks/useIconPicker.ts @@ -1,9 +1,8 @@ -import { useRecoilState } from 'recoil'; - import { iconPickerState } from '@/ui/input/states/iconPickerState'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; export const useIconPicker = () => { - const [iconPicker, setIconPicker] = useRecoilState(iconPickerState); + const [iconPicker, setIconPicker] = useRecoilStateV2(iconPickerState); return { Icon: iconPicker.Icon, diff --git a/packages/twenty-front/src/modules/ui/input/states/iconPickerState.ts b/packages/twenty-front/src/modules/ui/input/states/iconPickerState.ts index af718574b9..51e0282f89 100644 --- a/packages/twenty-front/src/modules/ui/input/states/iconPickerState.ts +++ b/packages/twenty-front/src/modules/ui/input/states/iconPickerState.ts @@ -1,4 +1,4 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; import { IconApps, type IconComponent } from 'twenty-ui/display'; type IconPickerState = { @@ -6,7 +6,7 @@ type IconPickerState = { iconKey: string; }; -export const iconPickerState = createState({ +export const iconPickerState = createStateV2({ key: 'iconPickerState', defaultValue: { Icon: IconApps, iconKey: 'IconApps' }, }); diff --git a/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/__tests__/useStepBar.test.tsx b/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/__tests__/useStepBar.test.tsx index 9592d736d5..809b8fe4b5 100644 --- a/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/__tests__/useStepBar.test.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/__tests__/useStepBar.test.tsx @@ -1,5 +1,6 @@ import { act, renderHook } from '@testing-library/react'; -import { RecoilRoot, useRecoilValue } from 'recoil'; +import { Provider } from 'jotai'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { stepBarInternalState } from '@/ui/navigation/step-bar/states/stepBarInternalState'; import { useStepBar } from '@/ui/navigation/step-bar/hooks/useStepBar'; @@ -10,7 +11,7 @@ const renderHooks = (initialStep: number) => { const { nextStep, prevStep, reset, setStep } = useStepBar({ initialStep, }); - const stepBarInternal = useRecoilValue(stepBarInternalState); + const stepBarInternal = useRecoilValueV2(stepBarInternalState); return { nextStep, @@ -21,7 +22,7 @@ const renderHooks = (initialStep: number) => { }; }, { - wrapper: RecoilRoot, + wrapper: Provider, }, ); diff --git a/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/useStepBar.ts b/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/useStepBar.ts index fce51408cd..3a82514a89 100644 --- a/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/useStepBar.ts +++ b/packages/twenty-front/src/modules/ui/navigation/step-bar/hooks/useStepBar.ts @@ -1,7 +1,7 @@ import { useCallback, useEffect } from 'react'; -import { useRecoilState } from 'recoil'; import { stepBarInternalState } from '@/ui/navigation/step-bar/states/stepBarInternalState'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; export type StepsOptions = { initialStep: number; @@ -9,7 +9,7 @@ export type StepsOptions = { export const useStepBar = ({ initialStep }: StepsOptions) => { const [stepBarInternal, setStepBarInternal] = - useRecoilState(stepBarInternalState); + useRecoilStateV2(stepBarInternalState); const nextStep = () => { setStepBarInternal((prevState) => ({ diff --git a/packages/twenty-front/src/modules/ui/navigation/step-bar/states/stepBarInternalState.ts b/packages/twenty-front/src/modules/ui/navigation/step-bar/states/stepBarInternalState.ts index c289844d9d..92d70719be 100644 --- a/packages/twenty-front/src/modules/ui/navigation/step-bar/states/stepBarInternalState.ts +++ b/packages/twenty-front/src/modules/ui/navigation/step-bar/states/stepBarInternalState.ts @@ -1,9 +1,9 @@ -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; export type StepsState = { activeStep: number; }; -export const stepBarInternalState = createState({ +export const stepBarInternalState = createStateV2({ key: 'step-bar/internal-state', defaultValue: { activeStep: -1, diff --git a/packages/twenty-front/src/modules/users/hooks/useLoadCurrentUser.ts b/packages/twenty-front/src/modules/users/hooks/useLoadCurrentUser.ts index 3fd0288e9f..404a55066c 100644 --- a/packages/twenty-front/src/modules/users/hooks/useLoadCurrentUser.ts +++ b/packages/twenty-front/src/modules/users/hooks/useLoadCurrentUser.ts @@ -11,7 +11,7 @@ import { useInitializeFormatPreferences } from '@/localization/hooks/useInitiali import { coreViewsState } from '@/views/states/coreViewState'; import { workspaceAuthBypassProvidersState } from '@/workspace/states/workspaceAuthBypassProvidersState'; import { useCallback } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; import { SOURCE_LOCALE, type APP_LOCALES } from 'twenty-shared/translations'; import { type ObjectPermissions } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; @@ -22,6 +22,7 @@ import { } from '~/generated-metadata/graphql'; import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl'; import { dynamicActivate } from '~/utils/i18n/dynamicActivate'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const useLoadCurrentUser = () => { const setCurrentUser = useSetRecoilState(currentUserState); @@ -41,7 +42,7 @@ export const useLoadCurrentUser = () => { const setWorkspaceAuthBypassProviders = useSetRecoilState( workspaceAuthBypassProvidersState, ); - const authProviders = useRecoilValue(authProvidersState); + const authProviders = useRecoilValueV2(authProvidersState); const { isOnAWorkspace } = useIsCurrentLocationOnAWorkspace(); diff --git a/packages/twenty-front/src/modules/workspace-invitation/hooks/useCreateWorkspaceInvitation.ts b/packages/twenty-front/src/modules/workspace-invitation/hooks/useCreateWorkspaceInvitation.ts index e24fb628c6..93d3dae329 100644 --- a/packages/twenty-front/src/modules/workspace-invitation/hooks/useCreateWorkspaceInvitation.ts +++ b/packages/twenty-front/src/modules/workspace-invitation/hooks/useCreateWorkspaceInvitation.ts @@ -1,14 +1,16 @@ -import { useSetRecoilState } from 'recoil'; import { type SendInvitationsMutationVariables, useSendInvitationsMutation, } from '~/generated-metadata/graphql'; import { workspaceInvitationsState } from '@/workspace-invitation/states/workspaceInvitationsStates'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; export const useCreateWorkspaceInvitation = () => { const [sendInvitationsMutation] = useSendInvitationsMutation(); - const setWorkspaceInvitations = useSetRecoilState(workspaceInvitationsState); + const setWorkspaceInvitations = useSetRecoilStateV2( + workspaceInvitationsState, + ); const sendInvitation = async (emails: SendInvitationsMutationVariables) => { return await sendInvitationsMutation({ diff --git a/packages/twenty-front/src/modules/workspace-invitation/hooks/useDeleteWorkspaceInvitation.ts b/packages/twenty-front/src/modules/workspace-invitation/hooks/useDeleteWorkspaceInvitation.ts index 6af85e2dab..526e58ccd1 100644 --- a/packages/twenty-front/src/modules/workspace-invitation/hooks/useDeleteWorkspaceInvitation.ts +++ b/packages/twenty-front/src/modules/workspace-invitation/hooks/useDeleteWorkspaceInvitation.ts @@ -1,15 +1,17 @@ -import { useSetRecoilState } from 'recoil'; import { type DeleteWorkspaceInvitationMutationVariables, useDeleteWorkspaceInvitationMutation, } from '~/generated-metadata/graphql'; import { workspaceInvitationsState } from '@/workspace-invitation/states/workspaceInvitationsStates'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; export const useDeleteWorkspaceInvitation = () => { const [deleteWorkspaceInvitationMutation] = useDeleteWorkspaceInvitationMutation(); - const setWorkspaceInvitations = useSetRecoilState(workspaceInvitationsState); + const setWorkspaceInvitations = useSetRecoilStateV2( + workspaceInvitationsState, + ); const deleteWorkspaceInvitation = async ({ appTokenId, diff --git a/packages/twenty-front/src/modules/workspace-invitation/hooks/useResendWorkspaceInvitation.ts b/packages/twenty-front/src/modules/workspace-invitation/hooks/useResendWorkspaceInvitation.ts index ccfeabad68..309e61c8da 100644 --- a/packages/twenty-front/src/modules/workspace-invitation/hooks/useResendWorkspaceInvitation.ts +++ b/packages/twenty-front/src/modules/workspace-invitation/hooks/useResendWorkspaceInvitation.ts @@ -1,15 +1,17 @@ -import { useSetRecoilState } from 'recoil'; import { type ResendWorkspaceInvitationMutationVariables, useResendWorkspaceInvitationMutation, } from '~/generated-metadata/graphql'; import { workspaceInvitationsState } from '@/workspace-invitation/states/workspaceInvitationsStates'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; export const useResendWorkspaceInvitation = () => { const [resendWorkspaceInvitationMutation] = useResendWorkspaceInvitationMutation(); - const setWorkspaceInvitations = useSetRecoilState(workspaceInvitationsState); + const setWorkspaceInvitations = useSetRecoilStateV2( + workspaceInvitationsState, + ); const resendInvitation = async ({ appTokenId, diff --git a/packages/twenty-front/src/modules/workspace-invitation/states/workspaceInvitationsStates.ts b/packages/twenty-front/src/modules/workspace-invitation/states/workspaceInvitationsStates.ts index 34eb436106..88c54efe14 100644 --- a/packages/twenty-front/src/modules/workspace-invitation/states/workspaceInvitationsStates.ts +++ b/packages/twenty-front/src/modules/workspace-invitation/states/workspaceInvitationsStates.ts @@ -1,7 +1,7 @@ import { type WorkspaceInvitation } from '@/workspace-member/types/WorkspaceMember'; -import { createState } from '@/ui/utilities/state/utils/createState'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; -export const workspaceInvitationsState = createState< +export const workspaceInvitationsState = createStateV2< Omit[] >({ key: 'workspaceInvitationsState', diff --git a/packages/twenty-front/src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx b/packages/twenty-front/src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx index d5bf38ef25..10009f69d4 100644 --- a/packages/twenty-front/src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsTwoFactorAuthenticationMethod.tsx @@ -2,7 +2,6 @@ import styled from '@emotion/styled'; import { Trans, useLingui } from '@lingui/react/macro'; import { FormProvider } from 'react-hook-form'; import QRCode from 'react-qr-code'; -import { useRecoilValue } from 'recoil'; import { qrCodeState } from '@/auth/states/qrCode'; import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons'; @@ -21,6 +20,7 @@ import { getSettingsPath } from 'twenty-shared/utils'; import { H2Title, IconCopy } from 'twenty-ui/display'; import { Loader } from 'twenty-ui/feedback'; import { Section } from 'twenty-ui/layout'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledQRCodeContainer = styled.div` margin: ${({ theme }) => theme.spacing(4)} 0; @@ -81,7 +81,7 @@ export const SettingsTwoFactorAuthenticationMethod = () => { const { t } = useLingui(); const theme = useTheme(); const { enqueueSuccessSnackBar } = useSnackBar(); - const qrCode = useRecoilValue(qrCodeState); + const qrCode = useRecoilValueV2(qrCodeState); const { currentUserWorkspaceTwoFactorAuthenticationMethods } = useCurrentUserWorkspaceTwoFactorAuthentication(); diff --git a/packages/twenty-front/src/pages/settings/ai/components/SettingsAIRouterSettings.tsx b/packages/twenty-front/src/pages/settings/ai/components/SettingsAIRouterSettings.tsx index dd435719cb..1abc2eb1ee 100644 --- a/packages/twenty-front/src/pages/settings/ai/components/SettingsAIRouterSettings.tsx +++ b/packages/twenty-front/src/pages/settings/ai/components/SettingsAIRouterSettings.tsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilState } from 'recoil'; import { DEFAULT_FAST_MODEL } from '@/ai/constants/DefaultFastModel'; import { DEFAULT_SMART_MODEL } from '@/ai/constants/DefaultSmartModel'; @@ -22,6 +22,7 @@ import { t } from '@lingui/core/macro'; import { H2Title, IconBolt, IconBrain } from 'twenty-ui/display'; import { Card, Section } from 'twenty-ui/layout'; import { useUpdateWorkspaceMutation } from '~/generated-metadata/graphql'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledSelectContainer = styled.div` justify-content: flex-end; @@ -42,7 +43,7 @@ export const SettingsAIRouterSettings = () => { ); const [updateWorkspace] = useUpdateWorkspaceMutation(); - const aiModels = useRecoilValue(aiModelsState); + const aiModels = useRecoilValueV2(aiModelsState); const activeModelOptions = useAiModelOptions(); const fastModelLabel = useAiModelLabel(currentWorkspace?.fastModel); const smartModelLabel = useAiModelLabel(currentWorkspace?.smartModel); diff --git a/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentModelCapabilities.tsx b/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentModelCapabilities.tsx index f8faa4ce66..189f62412e 100644 --- a/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentModelCapabilities.tsx +++ b/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentModelCapabilities.tsx @@ -1,6 +1,5 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { useRecoilValue } from 'recoil'; import { aiModelsState } from '@/client-config/states/aiModelsState'; import { InputLabel } from '@/ui/input/components/InputLabel'; @@ -9,6 +8,7 @@ import { isDefined } from 'twenty-shared/utils'; import { IconBrandX, IconWorld } from 'twenty-ui/display'; import { Checkbox } from 'twenty-ui/input'; import { Section } from 'twenty-ui/layout'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledCheckboxContainer = styled.div<{ disabled: boolean }>` display: flex; @@ -57,7 +57,7 @@ export const SettingsAgentModelCapabilities = ({ disabled = false, }: SettingsAgentModelCapabilitiesProps) => { const theme = useTheme(); - const aiModels = useRecoilValue(aiModelsState); + const aiModels = useRecoilValueV2(aiModelsState); const selectedModel = aiModels.find((m) => m.modelId === selectedModelId); const nativeCapabilities = selectedModel?.nativeCapabilities; diff --git a/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx b/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx index 7b3204d576..c8d68cfb84 100644 --- a/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx +++ b/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentSettingsTab.tsx @@ -11,7 +11,6 @@ import { Select } from '@/ui/input/components/Select'; import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput'; import { TextArea } from '@/ui/input/components/TextArea'; import { useModal } from '@/ui/layout/modal/hooks/useModal'; -import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { H2Title, IconTrash } from 'twenty-ui/display'; import { Button } from 'twenty-ui/input'; @@ -22,6 +21,7 @@ import { SettingsAgentResponseFormat } from '~/pages/settings/ai/components/Sett import { computeMetadataNameFromLabel } from '~/pages/settings/data-model/utils/computeMetadataNameFromLabel'; import { SettingsAgentModelCapabilities } from '~/pages/settings/ai/components/SettingsAgentModelCapabilities'; import { type SettingsAIAgentFormValues } from '~/pages/settings/ai/hooks/useSettingsAgentFormState'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledFormContainer = styled.div` display: flex; @@ -66,7 +66,7 @@ export const SettingsAgentSettingsTab = ({ const { t } = useLingui(); const { openModal } = useModal(); - const aiModels = useRecoilValue(aiModelsState); + const aiModels = useRecoilValueV2(aiModelsState); const activeModelOptions = useAiModelOptions(); const currentModelLabel = useAiModelLabel(formValues.modelId); diff --git a/packages/twenty-front/src/pages/settings/members/SettingsWorkspaceMembers.tsx b/packages/twenty-front/src/pages/settings/members/SettingsWorkspaceMembers.tsx index f3fe2edbb7..eb93f39192 100644 --- a/packages/twenty-front/src/pages/settings/members/SettingsWorkspaceMembers.tsx +++ b/packages/twenty-front/src/pages/settings/members/SettingsWorkspaceMembers.tsx @@ -4,7 +4,8 @@ import { Trans, useLingui } from '@lingui/react/macro'; import { isNonEmptyArray } from '@sniptt/guards'; import { useMemo, useState } from 'react'; import { useInView } from 'react-intersection-observer'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { useDebounce } from 'use-debounce'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; @@ -51,6 +52,7 @@ import { TableRow } from '@/ui/layout/table/components/TableRow'; import { useDeleteWorkspaceInvitation } from '@/workspace-invitation/hooks/useDeleteWorkspaceInvitation'; import { useResendWorkspaceInvitation } from '@/workspace-invitation/hooks/useResendWorkspaceInvitation'; import { workspaceInvitationsState } from '@/workspace-invitation/states/workspaceInvitationsStates'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledButtonContainer = styled.div` align-items: center; @@ -152,8 +154,10 @@ export const SettingsWorkspaceMembers = () => { const currentWorkspace = useRecoilValue(currentWorkspaceState); - const workspaceInvitations = useRecoilValue(workspaceInvitationsState); - const setWorkspaceInvitations = useSetRecoilState(workspaceInvitationsState); + const workspaceInvitations = useRecoilValueV2(workspaceInvitationsState); + const setWorkspaceInvitations = useSetRecoilStateV2( + workspaceInvitationsState, + ); const handleSearchChange = (text: string) => { setSearchFilter(text); diff --git a/packages/twenty-front/src/pages/settings/security/SettingsSecurity.tsx b/packages/twenty-front/src/pages/settings/security/SettingsSecurity.tsx index 5abdaf99b9..c41ec88961 100644 --- a/packages/twenty-front/src/pages/settings/security/SettingsSecurity.tsx +++ b/packages/twenty-front/src/pages/settings/security/SettingsSecurity.tsx @@ -34,6 +34,7 @@ import { import { Button } from 'twenty-ui/input'; import { Card, Section } from 'twenty-ui/layout'; import { useUpdateWorkspaceMutation } from '~/generated-metadata/graphql'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledContainer = styled.div` width: 100%; @@ -63,7 +64,7 @@ export const SettingsSecurity = () => { const isMultiWorkspaceEnabled = useRecoilValue(isMultiWorkspaceEnabledState); const isClickHouseConfigured = useRecoilValue(isClickHouseConfiguredState); - const authProviders = useRecoilValue(authProvidersState); + const authProviders = useRecoilValueV2(authProvidersState); const SSOIdentitiesProviders = useRecoilValue(SSOIdentitiesProvidersState); const [currentWorkspace, setCurrentWorkspace] = useRecoilState( currentWorkspaceState,