diff --git a/packages/twenty-front/src/modules/activities/hooks/useRefreshShowPageFindManyActivitiesQueries.ts b/packages/twenty-front/src/modules/activities/hooks/useRefreshShowPageFindManyActivitiesQueries.ts index 65575b8a841..e20559cbe60 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useRefreshShowPageFindManyActivitiesQueries.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useRefreshShowPageFindManyActivitiesQueries.ts @@ -1,8 +1,7 @@ -import { useRecoilValue } from 'recoil'; - import { usePrepareFindManyActivitiesQuery } from '@/activities/hooks/usePrepareFindManyActivitiesQuery'; -import { objectShowPageTargetableObjectState } from '@/activities/timeline-activities/states/objectShowPageTargetableObjectIdState'; +import { objectShowPageTargetableObjectStateV2 } from '@/activities/timeline-activities/states/objectShowPageTargetableObjectStateV2'; import { type CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { isDefined } from 'twenty-shared/utils'; // This hook should only be executed if the normalized cache is up-to-date @@ -13,8 +12,8 @@ export const useRefreshShowPageFindManyActivitiesQueries = ({ }: { activityObjectNameSingular: CoreObjectNameSingular; }) => { - const objectShowPageTargetableObject = useRecoilValue( - objectShowPageTargetableObjectState, + const objectShowPageTargetableObject = useRecoilValueV2( + objectShowPageTargetableObjectStateV2, ); const { prepareFindManyActivitiesQuery } = usePrepareFindManyActivitiesQuery({ diff --git a/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts b/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts index fc3c3fa1d59..0ae4cee7405 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts @@ -1,16 +1,17 @@ -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilState } from 'recoil'; import { useCreateActivityInDB } from '@/activities/hooks/useCreateActivityInDB'; import { useRefreshShowPageFindManyActivitiesQueries } from '@/activities/hooks/useRefreshShowPageFindManyActivitiesQueries'; import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState'; import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState'; -import { objectShowPageTargetableObjectState } from '@/activities/timeline-activities/states/objectShowPageTargetableObjectIdState'; +import { objectShowPageTargetableObjectStateV2 } from '@/activities/timeline-activities/states/objectShowPageTargetableObjectStateV2'; import { type Note } from '@/activities/types/Note'; 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'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const useUpsertActivity = ({ activityObjectNameSingular, @@ -33,8 +34,8 @@ export const useUpsertActivity = ({ isUpsertingActivityInDBState, ); - const objectShowPageTargetableObject = useRecoilValue( - objectShowPageTargetableObjectState, + const objectShowPageTargetableObject = useRecoilValueV2( + objectShowPageTargetableObjectStateV2, ); const { refreshShowPageFindManyActivitiesQueries } = diff --git a/packages/twenty-front/src/modules/activities/notes/hooks/useNotes.ts b/packages/twenty-front/src/modules/activities/notes/hooks/useNotes.ts index 3a0a790d867..683aae9482c 100644 --- a/packages/twenty-front/src/modules/activities/notes/hooks/useNotes.ts +++ b/packages/twenty-front/src/modules/activities/notes/hooks/useNotes.ts @@ -1,8 +1,7 @@ import { useEffect, useMemo } from 'react'; -import { useRecoilState } from 'recoil'; import { useActivities } from '@/activities/hooks/useActivities'; -import { currentNotesQueryVariablesState } from '@/activities/notes/states/currentNotesQueryVariablesState'; +import { currentNotesQueryVariablesStateV2 } from '@/activities/notes/states/currentNotesQueryVariablesStateV2'; import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline-activities/constants/FindManyTimelineActivitiesOrderBy'; import { type Note } from '@/activities/types/Note'; import { type RecordGqlOperationVariables } from 'twenty-shared/types'; @@ -10,6 +9,7 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { type ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; export const useNotes = (targetableObject: ActivityTargetableObject) => { const notesQueryVariables = useMemo( @@ -34,7 +34,7 @@ export const useNotes = (targetableObject: ActivityTargetableObject) => { }); const [currentNotesQueryVariables, setCurrentNotesQueryVariables] = - useRecoilState(currentNotesQueryVariablesState); + useRecoilStateV2(currentNotesQueryVariablesStateV2); // TODO: fix useEffect, remove with better pattern useEffect(() => { diff --git a/packages/twenty-front/src/modules/activities/notes/states/currentNotesQueryVariablesState.ts b/packages/twenty-front/src/modules/activities/notes/states/currentNotesQueryVariablesState.ts deleted file mode 100644 index 1b5bb886962..00000000000 --- a/packages/twenty-front/src/modules/activities/notes/states/currentNotesQueryVariablesState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { atom } from 'recoil'; - -import { type RecordGqlOperationVariables } from 'twenty-shared/types'; - -export const currentNotesQueryVariablesState = - atom({ - default: null, - key: 'currentNotesQueryVariablesState', - }); diff --git a/packages/twenty-front/src/modules/activities/notes/states/currentNotesQueryVariablesStateV2.ts b/packages/twenty-front/src/modules/activities/notes/states/currentNotesQueryVariablesStateV2.ts new file mode 100644 index 00000000000..8e0a76a2bd6 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/notes/states/currentNotesQueryVariablesStateV2.ts @@ -0,0 +1,9 @@ +import { type RecordGqlOperationVariables } from 'twenty-shared/types'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const currentNotesQueryVariablesStateV2 = + createStateV2({ + key: 'currentNotesQueryVariablesStateV2', + defaultValue: null, + }); diff --git a/packages/twenty-front/src/modules/activities/timeline-activities/states/objectShowPageTargetableObjectIdState.ts b/packages/twenty-front/src/modules/activities/timeline-activities/states/objectShowPageTargetableObjectIdState.ts deleted file mode 100644 index 561f9264601..00000000000 --- a/packages/twenty-front/src/modules/activities/timeline-activities/states/objectShowPageTargetableObjectIdState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { atom } from 'recoil'; - -import { type ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; - -export const objectShowPageTargetableObjectState = - atom({ - key: 'objectShowPageTargetableObjectState', - default: null, - }); diff --git a/packages/twenty-front/src/modules/activities/timeline-activities/states/objectShowPageTargetableObjectStateV2.ts b/packages/twenty-front/src/modules/activities/timeline-activities/states/objectShowPageTargetableObjectStateV2.ts new file mode 100644 index 00000000000..87dbf332e5e --- /dev/null +++ b/packages/twenty-front/src/modules/activities/timeline-activities/states/objectShowPageTargetableObjectStateV2.ts @@ -0,0 +1,9 @@ +import { type ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const objectShowPageTargetableObjectStateV2 = + createStateV2({ + key: 'objectShowPageTargetableObjectStateV2', + defaultValue: null, + }); diff --git a/packages/twenty-front/src/modules/ai/components/AIChatThreadGroup.tsx b/packages/twenty-front/src/modules/ai/components/AIChatThreadGroup.tsx index 7febd2a0c28..fdeacc62bc2 100644 --- a/packages/twenty-front/src/modules/ai/components/AIChatThreadGroup.tsx +++ b/packages/twenty-front/src/modules/ai/components/AIChatThreadGroup.tsx @@ -1,11 +1,12 @@ -import { agentChatUsageState } from '@/ai/states/agentChatUsageState'; -import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState'; -import { currentAIChatThreadTitleState } from '@/ai/states/currentAIChatThreadTitleState'; +import { agentChatUsageStateV2 } from '@/ai/states/agentChatUsageStateV2'; +import { currentAIChatThreadStateV2 } from '@/ai/states/currentAIChatThreadStateV2'; +import { currentAIChatThreadTitleStateV2 } from '@/ai/states/currentAIChatThreadTitleStateV2'; import { useOpenAskAIPageInCommandMenu } from '@/command-menu/hooks/useOpenAskAIPageInCommandMenu'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; -import { useRecoilState, useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconSparkles } from 'twenty-ui/display'; import { type AgentChatThread } from '~/generated-metadata/graphql'; @@ -78,11 +79,13 @@ export const AIChatThreadGroup = ({ }) => { const { t } = useLingui(); const theme = useTheme(); - const [, setCurrentAIChatThread] = useRecoilState(currentAIChatThreadState); - const setCurrentAIChatThreadTitle = useSetRecoilState( - currentAIChatThreadTitleState, + const [, setCurrentAIChatThread] = useRecoilStateV2( + currentAIChatThreadStateV2, ); - const setAgentChatUsage = useSetRecoilState(agentChatUsageState); + const setCurrentAIChatThreadTitle = useSetRecoilStateV2( + currentAIChatThreadTitleStateV2, + ); + const setAgentChatUsage = useSetRecoilStateV2(agentChatUsageStateV2); const { openAskAIPage } = useOpenAskAIPageInCommandMenu(); const handleThreadClick = (thread: AgentChatThread) => { diff --git a/packages/twenty-front/src/modules/ai/components/internal/AIChatContextUsageButton.tsx b/packages/twenty-front/src/modules/ai/components/internal/AIChatContextUsageButton.tsx index d1776c63c96..896a04318f3 100644 --- a/packages/twenty-front/src/modules/ai/components/internal/AIChatContextUsageButton.tsx +++ b/packages/twenty-front/src/modules/ai/components/internal/AIChatContextUsageButton.tsx @@ -3,7 +3,6 @@ import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; import { useLingui } from '@lingui/react/macro'; import { useState } from 'react'; -import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { HorizontalSeparator } from 'twenty-ui/display'; import { ProgressBar } from 'twenty-ui/feedback'; @@ -11,9 +10,10 @@ import { ProgressBar } from 'twenty-ui/feedback'; import { ContextUsageProgressRing } from '@/ai/components/internal/ContextUsageProgressRing'; import { SettingsBillingLabelValueItem } from '@/billing/components/internal/SettingsBillingLabelValueItem'; import { - agentChatUsageState, + agentChatUsageStateV2, type AgentChatLastMessageUsage, -} from '@/ai/states/agentChatUsageState'; +} from '@/ai/states/agentChatUsageStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledContainer = styled.div` position: relative; @@ -114,7 +114,7 @@ export const AIChatContextUsageButton = () => { const { t } = useLingui(); const theme = useTheme(); const [isHovered, setIsHovered] = useState(false); - const agentChatUsage = useRecoilValue(agentChatUsageState); + const agentChatUsage = useRecoilValueV2(agentChatUsageStateV2); if (!agentChatUsage) { return ( diff --git a/packages/twenty-front/src/modules/ai/components/internal/AgentChatContextPreview.tsx b/packages/twenty-front/src/modules/ai/components/internal/AgentChatContextPreview.tsx index 4f02525b1ba..41271a65e65 100644 --- a/packages/twenty-front/src/modules/ai/components/internal/AgentChatContextPreview.tsx +++ b/packages/twenty-front/src/modules/ai/components/internal/AgentChatContextPreview.tsx @@ -1,7 +1,7 @@ -import { agentChatSelectedFilesState } from '@/ai/states/agentChatSelectedFilesState'; -import { agentChatUploadedFilesState } from '@/ai/states/agentChatUploadedFilesState'; +import { agentChatSelectedFilesStateV2 } from '@/ai/states/agentChatSelectedFilesStateV2'; +import { agentChatUploadedFilesStateV2 } from '@/ai/states/agentChatUploadedFilesStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import styled from '@emotion/styled'; -import { useRecoilState } from 'recoil'; import { AgentChatFilePreview } from './AgentChatFilePreview'; const StyledContainer = styled.div` @@ -19,11 +19,11 @@ const StyledPreviewsContainer = styled.div` `; export const AgentChatContextPreview = () => { - const [agentChatSelectedFiles, setAgentChatSelectedFiles] = useRecoilState( - agentChatSelectedFilesState, + const [agentChatSelectedFiles, setAgentChatSelectedFiles] = useRecoilStateV2( + agentChatSelectedFilesStateV2, ); - const [agentChatUploadedFiles, setAgentChatUploadedFiles] = useRecoilState( - agentChatUploadedFilesState, + const [agentChatUploadedFiles, setAgentChatUploadedFiles] = useRecoilStateV2( + agentChatUploadedFilesStateV2, ); const handleRemoveUploadedFile = (fileIndex: number) => { diff --git a/packages/twenty-front/src/modules/ai/components/internal/AgentChatFileUploadButton.tsx b/packages/twenty-front/src/modules/ai/components/internal/AgentChatFileUploadButton.tsx index e76858840dd..c2732305ad4 100644 --- a/packages/twenty-front/src/modules/ai/components/internal/AgentChatFileUploadButton.tsx +++ b/packages/twenty-front/src/modules/ai/components/internal/AgentChatFileUploadButton.tsx @@ -1,9 +1,9 @@ import { useAIChatFileUpload } from '@/ai/hooks/useAIChatFileUpload'; -import { agentChatSelectedFilesState } from '@/ai/states/agentChatSelectedFilesState'; +import { agentChatSelectedFilesStateV2 } from '@/ai/states/agentChatSelectedFilesStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; import React, { useRef } from 'react'; -import { useSetRecoilState } from 'recoil'; import { IconPlus } from 'twenty-ui/display'; import { IconButton } from 'twenty-ui/input'; @@ -18,8 +18,8 @@ const StyledFileInput = styled.input` `; export const AgentChatFileUploadButton = () => { - const setAgentChatSelectedFiles = useSetRecoilState( - agentChatSelectedFilesState, + const setAgentChatSelectedFiles = useSetRecoilStateV2( + agentChatSelectedFilesStateV2, ); const fileInputRef = useRef(null); const { uploadFiles } = useAIChatFileUpload(); diff --git a/packages/twenty-front/src/modules/ai/components/internal/SendMessageButton.tsx b/packages/twenty-front/src/modules/ai/components/internal/SendMessageButton.tsx index 930948fafb8..053cceff953 100644 --- a/packages/twenty-front/src/modules/ai/components/internal/SendMessageButton.tsx +++ b/packages/twenty-front/src/modules/ai/components/internal/SendMessageButton.tsx @@ -1,6 +1,6 @@ import { useAgentChatContextOrThrow } from '@/ai/hooks/useAgentChatContextOrThrow'; -import { agentChatInputState } from '@/ai/states/agentChatInputState'; -import { useRecoilValue } from 'recoil'; +import { agentChatInputStateV2 } from '@/ai/states/agentChatInputStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { IconArrowUp, IconPlayerStop } from 'twenty-ui/display'; import { RoundedIconButton } from 'twenty-ui/input'; @@ -9,7 +9,7 @@ type SendMessageButtonProps = { }; export const SendMessageButton = ({ onSend }: SendMessageButtonProps) => { - const agentChatInput = useRecoilValue(agentChatInputState); + const agentChatInput = useRecoilValueV2(agentChatInputStateV2); const { handleStop, isLoading, isStreaming } = useAgentChatContextOrThrow(); if (isStreaming) { diff --git a/packages/twenty-front/src/modules/ai/components/suggested-prompts/AIChatSuggestedPrompts.tsx b/packages/twenty-front/src/modules/ai/components/suggested-prompts/AIChatSuggestedPrompts.tsx index 91ea8178649..65dcb8d4e67 100644 --- a/packages/twenty-front/src/modules/ai/components/suggested-prompts/AIChatSuggestedPrompts.tsx +++ b/packages/twenty-front/src/modules/ai/components/suggested-prompts/AIChatSuggestedPrompts.tsx @@ -2,14 +2,14 @@ import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; import { useLingui } from '@lingui/react/macro'; import { type Editor } from '@tiptap/react'; -import { useSetRecoilState } from 'recoil'; import { LightButton } from 'twenty-ui/input'; import { DEFAULT_SUGGESTED_PROMPTS, type SuggestedPrompt, } from '@/ai/components/suggested-prompts/default-suggested-prompts'; -import { agentChatInputState } from '@/ai/states/agentChatInputState'; +import { agentChatInputStateV2 } from '@/ai/states/agentChatInputStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; const StyledContainer = styled.div` display: flex; @@ -43,7 +43,7 @@ export const AIChatSuggestedPrompts = ({ editor, }: AIChatSuggestedPromptsProps) => { const { t: resolveMessage } = useLingui(); - const setAgentChatInput = useSetRecoilState(agentChatInputState); + const setAgentChatInput = useSetRecoilStateV2(agentChatInputStateV2); const handleClick = (prompt: SuggestedPrompt) => { const picked = pickRandom(prompt.prefillPrompts); diff --git a/packages/twenty-front/src/modules/ai/hooks/useAIChatEditor.ts b/packages/twenty-front/src/modules/ai/hooks/useAIChatEditor.ts index ee31512630d..8c2bd829f1f 100644 --- a/packages/twenty-front/src/modules/ai/hooks/useAIChatEditor.ts +++ b/packages/twenty-front/src/modules/ai/hooks/useAIChatEditor.ts @@ -6,11 +6,11 @@ import { Text } from '@tiptap/extension-text'; import { Placeholder } from '@tiptap/extensions'; import { useEditor } from '@tiptap/react'; import { useCallback, useMemo } from 'react'; -import { useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { AI_CHAT_INPUT_ID } from '@/ai/constants/AiChatInputId'; -import { agentChatInputState } from '@/ai/states/agentChatInputState'; +import { agentChatInputStateV2 } from '@/ai/states/agentChatInputStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { MENTION_SUGGESTION_PLUGIN_KEY } from '@/mention/constants/MentionSuggestionPluginKey'; import { MentionSuggestion } from '@/mention/extensions/MentionSuggestion'; import { MentionTag } from '@/mention/extensions/MentionTag'; @@ -25,7 +25,7 @@ type UseAIChatEditorProps = { }; export const useAIChatEditor = ({ onSendMessage }: UseAIChatEditorProps) => { - const setAgentChatInput = useSetRecoilState(agentChatInputState); + const setAgentChatInput = useSetRecoilStateV2(agentChatInputStateV2); const { searchMentionRecords } = useMentionSearch(); const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack(); const { removeFocusItemFromFocusStackById } = diff --git a/packages/twenty-front/src/modules/ai/hooks/useAIChatFileUpload.ts b/packages/twenty-front/src/modules/ai/hooks/useAIChatFileUpload.ts index 92ea1688708..976e37fc6ec 100644 --- a/packages/twenty-front/src/modules/ai/hooks/useAIChatFileUpload.ts +++ b/packages/twenty-front/src/modules/ai/hooks/useAIChatFileUpload.ts @@ -1,10 +1,10 @@ -import { agentChatSelectedFilesState } from '@/ai/states/agentChatSelectedFilesState'; -import { agentChatUploadedFilesState } from '@/ai/states/agentChatUploadedFilesState'; +import { agentChatSelectedFilesStateV2 } from '@/ai/states/agentChatSelectedFilesStateV2'; +import { agentChatUploadedFilesStateV2 } from '@/ai/states/agentChatUploadedFilesStateV2'; import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { useLingui } from '@lingui/react/macro'; import { type FileUIPart } from 'ai'; -import { useRecoilState } from 'recoil'; import { buildSignedPath, isDefined } from 'twenty-shared/utils'; import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { @@ -17,11 +17,11 @@ export const useAIChatFileUpload = () => { const [uploadFile] = useUploadFileMutation({ client: coreClient }); const { t } = useLingui(); const { enqueueErrorSnackBar } = useSnackBar(); - const [agentChatSelectedFiles, setAgentChatSelectedFiles] = useRecoilState( - agentChatSelectedFilesState, + const [agentChatSelectedFiles, setAgentChatSelectedFiles] = useRecoilStateV2( + agentChatSelectedFilesStateV2, ); - const [agentChatUploadedFiles, setAgentChatUploadedFiles] = useRecoilState( - agentChatUploadedFilesState, + const [agentChatUploadedFiles, setAgentChatUploadedFiles] = useRecoilStateV2( + agentChatUploadedFilesStateV2, ); const sendFile = async (file: File): Promise => { diff --git a/packages/twenty-front/src/modules/ai/hooks/useAgentChat.ts b/packages/twenty-front/src/modules/ai/hooks/useAgentChat.ts index d23bb721e26..773a6c44307 100644 --- a/packages/twenty-front/src/modules/ai/hooks/useAgentChat.ts +++ b/packages/twenty-front/src/modules/ai/hooks/useAgentChat.ts @@ -1,12 +1,16 @@ -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; import { useGetBrowsingContext } from '@/ai/hooks/useBrowsingContext'; -import { agentChatInputState } from '@/ai/states/agentChatInputState'; -import { agentChatSelectedFilesState } from '@/ai/states/agentChatSelectedFilesState'; -import { agentChatUploadedFilesState } from '@/ai/states/agentChatUploadedFilesState'; -import { agentChatUsageState } from '@/ai/states/agentChatUsageState'; -import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState'; -import { currentAIChatThreadTitleState } from '@/ai/states/currentAIChatThreadTitleState'; +import { agentChatSelectedFilesStateV2 } from '@/ai/states/agentChatSelectedFilesStateV2'; +import { agentChatUploadedFilesStateV2 } from '@/ai/states/agentChatUploadedFilesStateV2'; +import { agentChatUsageStateV2 } from '@/ai/states/agentChatUsageStateV2'; +import { currentAIChatThreadStateV2 } from '@/ai/states/currentAIChatThreadStateV2'; +import { currentAIChatThreadTitleStateV2 } from '@/ai/states/currentAIChatThreadTitleStateV2'; + +import { agentChatInputStateV2 } from '@/ai/states/agentChatInputStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { REST_API_BASE_URL } from '@/apollo/constant/rest-api-base-url'; import { getTokenPair } from '@/apollo/utils/getTokenPair'; import { renewToken } from '@/auth/services/AuthService'; @@ -20,23 +24,26 @@ import { cookieStorage } from '~/utils/cookie-storage'; export const useAgentChat = (uiMessages: ExtendedUIMessage[]) => { const setTokenPair = useSetRecoilState(tokenPairState); - const setAgentChatUsage = useSetRecoilState(agentChatUsageState); + const setAgentChatUsage = useSetRecoilStateV2(agentChatUsageStateV2); const { getBrowsingContext } = useGetBrowsingContext(); - const setCurrentAIChatThreadTitle = useSetRecoilState( - currentAIChatThreadTitleState, + const setCurrentAIChatThreadTitle = useSetRecoilStateV2( + currentAIChatThreadTitleStateV2, ); - const agentChatSelectedFiles = useRecoilValue(agentChatSelectedFilesState); - - const currentAIChatThread = useRecoilValue(currentAIChatThreadState); - - const [agentChatUploadedFiles, setAgentChatUploadedFiles] = useRecoilState( - agentChatUploadedFilesState, + const agentChatSelectedFiles = useRecoilValueV2( + agentChatSelectedFilesStateV2, ); - const [agentChatInput, setAgentChatInput] = - useRecoilState(agentChatInputState); + const currentAIChatThread = useRecoilValueV2(currentAIChatThreadStateV2); + + const [agentChatUploadedFiles, setAgentChatUploadedFiles] = useRecoilStateV2( + agentChatUploadedFilesStateV2, + ); + + const [agentChatInput, setAgentChatInput] = useRecoilStateV2( + agentChatInputStateV2, + ); const retryFetchWithRenewedToken = async ( input: RequestInfo | URL, diff --git a/packages/twenty-front/src/modules/ai/hooks/useAgentChatData.ts b/packages/twenty-front/src/modules/ai/hooks/useAgentChatData.ts index efaefdd39d4..1d4e9b31744 100644 --- a/packages/twenty-front/src/modules/ai/hooks/useAgentChatData.ts +++ b/packages/twenty-front/src/modules/ai/hooks/useAgentChatData.ts @@ -1,17 +1,15 @@ import { useAgentChatScrollToBottom } from '@/ai/hooks/useAgentChatScrollToBottom'; import { - agentChatUsageState, + agentChatUsageStateV2, type AgentChatUsageState, -} from '@/ai/states/agentChatUsageState'; -import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState'; -import { currentAIChatThreadTitleState } from '@/ai/states/currentAIChatThreadTitleState'; -import { isCreatingChatThreadState } from '@/ai/states/isCreatingChatThreadState'; +} from '@/ai/states/agentChatUsageStateV2'; +import { currentAIChatThreadStateV2 } from '@/ai/states/currentAIChatThreadStateV2'; +import { currentAIChatThreadTitleStateV2 } from '@/ai/states/currentAIChatThreadTitleStateV2'; +import { isCreatingChatThreadStateV2 } from '@/ai/states/isCreatingChatThreadStateV2'; import { mapDBMessagesToUIMessages } from '@/ai/utils/mapDBMessagesToUIMessages'; -import { - type SetterOrUpdater, - useRecoilState, - useSetRecoilState, -} from 'recoil'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; +import { type SetterOrUpdater } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { type AgentChatThread, @@ -43,15 +41,15 @@ const setUsageFromThread = ( }; export const useAgentChatData = () => { - const [currentAIChatThread, setCurrentAIChatThread] = useRecoilState( - currentAIChatThreadState, + const [currentAIChatThread, setCurrentAIChatThread] = useRecoilStateV2( + currentAIChatThreadStateV2, ); - const setAgentChatUsage = useSetRecoilState(agentChatUsageState); - const setCurrentAIChatThreadTitle = useSetRecoilState( - currentAIChatThreadTitleState, + const setAgentChatUsage = useSetRecoilStateV2(agentChatUsageStateV2); + const setCurrentAIChatThreadTitle = useSetRecoilStateV2( + currentAIChatThreadTitleStateV2, ); - const [isCreatingChatThread, setIsCreatingChatThread] = useRecoilState( - isCreatingChatThreadState, + const [isCreatingChatThread, setIsCreatingChatThread] = useRecoilStateV2( + isCreatingChatThreadStateV2, ); const { scrollToBottom } = useAgentChatScrollToBottom(); diff --git a/packages/twenty-front/src/modules/ai/hooks/useCreateNewAIChatThread.ts b/packages/twenty-front/src/modules/ai/hooks/useCreateNewAIChatThread.ts index 15415c9ebb0..4d6dc7c918e 100644 --- a/packages/twenty-front/src/modules/ai/hooks/useCreateNewAIChatThread.ts +++ b/packages/twenty-front/src/modules/ai/hooks/useCreateNewAIChatThread.ts @@ -1,15 +1,18 @@ -import { agentChatUsageState } from '@/ai/states/agentChatUsageState'; -import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState'; -import { currentAIChatThreadTitleState } from '@/ai/states/currentAIChatThreadTitleState'; +import { agentChatUsageStateV2 } from '@/ai/states/agentChatUsageStateV2'; +import { currentAIChatThreadStateV2 } from '@/ai/states/currentAIChatThreadStateV2'; +import { currentAIChatThreadTitleStateV2 } from '@/ai/states/currentAIChatThreadTitleStateV2'; import { useOpenAskAIPageInCommandMenu } from '@/command-menu/hooks/useOpenAskAIPageInCommandMenu'; -import { useRecoilState, useSetRecoilState } from 'recoil'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { useCreateChatThreadMutation } from '~/generated-metadata/graphql'; export const useCreateNewAIChatThread = () => { - const [, setCurrentAIChatThread] = useRecoilState(currentAIChatThreadState); - const setAgentChatUsage = useSetRecoilState(agentChatUsageState); - const setCurrentAIChatThreadTitle = useSetRecoilState( - currentAIChatThreadTitleState, + const [, setCurrentAIChatThread] = useRecoilStateV2( + currentAIChatThreadStateV2, + ); + const setAgentChatUsage = useSetRecoilStateV2(agentChatUsageStateV2); + const setCurrentAIChatThreadTitle = useSetRecoilStateV2( + currentAIChatThreadTitleStateV2, ); const { openAskAIPage } = useOpenAskAIPageInCommandMenu(); diff --git a/packages/twenty-front/src/modules/ai/states/agentChatInputState.ts b/packages/twenty-front/src/modules/ai/states/agentChatInputState.ts deleted file mode 100644 index 1fe34b0573a..00000000000 --- a/packages/twenty-front/src/modules/ai/states/agentChatInputState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const agentChatInputState = atom({ - default: '', - key: 'agentChatInputState', -}); diff --git a/packages/twenty-front/src/modules/ai/states/agentChatInputStateV2.ts b/packages/twenty-front/src/modules/ai/states/agentChatInputStateV2.ts new file mode 100644 index 00000000000..76be61e5f44 --- /dev/null +++ b/packages/twenty-front/src/modules/ai/states/agentChatInputStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const agentChatInputStateV2 = createStateV2({ + key: 'agentChatInputStateV2', + defaultValue: '', +}); diff --git a/packages/twenty-front/src/modules/ai/states/agentChatSelectedFilesState.ts b/packages/twenty-front/src/modules/ai/states/agentChatSelectedFilesState.ts deleted file mode 100644 index af8fba30e73..00000000000 --- a/packages/twenty-front/src/modules/ai/states/agentChatSelectedFilesState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const agentChatSelectedFilesState = atom({ - key: 'ai/agentChatSelectedFilesState', - default: [], -}); diff --git a/packages/twenty-front/src/modules/ai/states/agentChatSelectedFilesStateV2.ts b/packages/twenty-front/src/modules/ai/states/agentChatSelectedFilesStateV2.ts new file mode 100644 index 00000000000..e805a8fedac --- /dev/null +++ b/packages/twenty-front/src/modules/ai/states/agentChatSelectedFilesStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const agentChatSelectedFilesStateV2 = createStateV2({ + key: 'ai/agentChatSelectedFilesStateV2', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/ai/states/agentChatUploadedFilesState.ts b/packages/twenty-front/src/modules/ai/states/agentChatUploadedFilesState.ts deleted file mode 100644 index 3806c87ede5..00000000000 --- a/packages/twenty-front/src/modules/ai/states/agentChatUploadedFilesState.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { type FileUIPart } from 'ai'; -import { atom } from 'recoil'; - -export const agentChatUploadedFilesState = atom({ - key: 'ai/agentChatUploadedFilesState', - default: [], -}); diff --git a/packages/twenty-front/src/modules/ai/states/agentChatUploadedFilesStateV2.ts b/packages/twenty-front/src/modules/ai/states/agentChatUploadedFilesStateV2.ts new file mode 100644 index 00000000000..b3782ab45b7 --- /dev/null +++ b/packages/twenty-front/src/modules/ai/states/agentChatUploadedFilesStateV2.ts @@ -0,0 +1,8 @@ +import { type FileUIPart } from 'ai'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const agentChatUploadedFilesStateV2 = createStateV2({ + key: 'ai/agentChatUploadedFilesStateV2', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/ai/states/agentChatUsageState.ts b/packages/twenty-front/src/modules/ai/states/agentChatUsageStateV2.ts similarity index 66% rename from packages/twenty-front/src/modules/ai/states/agentChatUsageState.ts rename to packages/twenty-front/src/modules/ai/states/agentChatUsageStateV2.ts index 5c2462659f4..449dc0a744d 100644 --- a/packages/twenty-front/src/modules/ai/states/agentChatUsageState.ts +++ b/packages/twenty-front/src/modules/ai/states/agentChatUsageStateV2.ts @@ -1,4 +1,4 @@ -import { atom } from 'recoil'; +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; export type AgentChatLastMessageUsage = { inputTokens: number; @@ -18,7 +18,7 @@ export type AgentChatUsageState = { outputCredits: number; }; -export const agentChatUsageState = atom({ - key: 'agentChatUsageState', - default: null, +export const agentChatUsageStateV2 = createStateV2({ + key: 'agentChatUsageStateV2', + defaultValue: null, }); diff --git a/packages/twenty-front/src/modules/ai/states/currentAIChatThreadState.ts b/packages/twenty-front/src/modules/ai/states/currentAIChatThreadState.ts deleted file mode 100644 index c0538d50d62..00000000000 --- a/packages/twenty-front/src/modules/ai/states/currentAIChatThreadState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const currentAIChatThreadState = atom({ - key: 'ai/currentAIChatThreadState', - default: null, -}); diff --git a/packages/twenty-front/src/modules/ai/states/currentAIChatThreadStateV2.ts b/packages/twenty-front/src/modules/ai/states/currentAIChatThreadStateV2.ts new file mode 100644 index 00000000000..878067e1cb9 --- /dev/null +++ b/packages/twenty-front/src/modules/ai/states/currentAIChatThreadStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const currentAIChatThreadStateV2 = createStateV2({ + key: 'ai/currentAIChatThreadStateV2', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/ai/states/currentAIChatThreadTitleStateV2.ts b/packages/twenty-front/src/modules/ai/states/currentAIChatThreadTitleStateV2.ts new file mode 100644 index 00000000000..737745fefb7 --- /dev/null +++ b/packages/twenty-front/src/modules/ai/states/currentAIChatThreadTitleStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const currentAIChatThreadTitleStateV2 = createStateV2({ + key: 'ai/currentAIChatThreadTitleStateV2', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/ai/states/isCreatingChatThreadState.ts b/packages/twenty-front/src/modules/ai/states/isCreatingChatThreadState.ts deleted file mode 100644 index 1005e99b04e..00000000000 --- a/packages/twenty-front/src/modules/ai/states/isCreatingChatThreadState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const isCreatingChatThreadState = atom({ - key: 'ai/isCreatingChatThreadState', - default: false, -}); diff --git a/packages/twenty-front/src/modules/ai/states/isCreatingChatThreadStateV2.ts b/packages/twenty-front/src/modules/ai/states/isCreatingChatThreadStateV2.ts new file mode 100644 index 00000000000..cc2253694c9 --- /dev/null +++ b/packages/twenty-front/src/modules/ai/states/isCreatingChatThreadStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const isCreatingChatThreadStateV2 = createStateV2({ + key: 'ai/isCreatingChatThreadStateV2', + defaultValue: false, +}); diff --git a/packages/twenty-front/src/modules/app/effect-components/GotoHotkeysEffectsProvider.tsx b/packages/twenty-front/src/modules/app/effect-components/GotoHotkeysEffectsProvider.tsx index 3b239b70056..48eaf543e47 100644 --- a/packages/twenty-front/src/modules/app/effect-components/GotoHotkeysEffectsProvider.tsx +++ b/packages/twenty-front/src/modules/app/effect-components/GotoHotkeysEffectsProvider.tsx @@ -1,8 +1,9 @@ import { GoToHotkeyItemEffect } from '@/app/effect-components/GoToHotkeyItemEffect'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded'; -import { navigationDrawerExpandedMemorizedState } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedState'; +import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2'; import { useGoToHotkeys } from '@/ui/utilities/hotkey/hooks/useGoToHotkeys'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilCallback } from 'recoil'; import { AppPath, SettingsPath } from 'twenty-shared/types'; import { getAppPath, getSettingsPath } from 'twenty-shared/utils'; @@ -18,7 +19,7 @@ export const GotoHotkeysEffectsProvider = () => { ({ set }) => () => { set(isNavigationDrawerExpandedState, true); - set(navigationDrawerExpandedMemorizedState, true); + jotaiStore.set(navigationDrawerExpandedMemorizedStateV2.atom, true); }, [], ), 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 497abc50fb7..77f99710c7b 100644 --- a/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts +++ b/packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts @@ -21,7 +21,7 @@ import { isImapSmtpCaldavEnabledState } from '@/client-config/states/isImapSmtpC import { isMicrosoftCalendarEnabledState } from '@/client-config/states/isMicrosoftCalendarEnabledState'; import { isMicrosoftMessagingEnabledState } from '@/client-config/states/isMicrosoftMessagingEnabledState'; import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState'; -import { labPublicFeatureFlagsState } from '@/client-config/states/labPublicFeatureFlagsState'; +import { labPublicFeatureFlagsStateV2 } from '@/client-config/states/labPublicFeatureFlagsStateV2'; import { sentryConfigState } from '@/client-config/states/sentryConfigState'; import { supportChatState } from '@/client-config/states/supportChatState'; import { type ClientConfig } from '@/client-config/types/ClientConfig'; @@ -77,8 +77,8 @@ export const useClientConfig = (): UseClientConfigResult => { canManageFeatureFlagsState, ); - const setLabPublicFeatureFlags = useSetRecoilState( - labPublicFeatureFlagsState, + const setLabPublicFeatureFlags = useSetRecoilStateV2( + labPublicFeatureFlagsStateV2, ); const setMicrosoftMessagingEnabled = useSetRecoilState( diff --git a/packages/twenty-front/src/modules/client-config/states/labPublicFeatureFlagsState.ts b/packages/twenty-front/src/modules/client-config/states/labPublicFeatureFlagsState.ts deleted file mode 100644 index 3c130a022eb..00000000000 --- a/packages/twenty-front/src/modules/client-config/states/labPublicFeatureFlagsState.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { atom } from 'recoil'; -import { type PublicFeatureFlag } from '~/generated-metadata/graphql'; - -export const labPublicFeatureFlagsState = atom({ - key: 'labPublicFeatureFlagsState', - default: [], -}); diff --git a/packages/twenty-front/src/modules/client-config/states/labPublicFeatureFlagsStateV2.ts b/packages/twenty-front/src/modules/client-config/states/labPublicFeatureFlagsStateV2.ts new file mode 100644 index 00000000000..94d8c3acd42 --- /dev/null +++ b/packages/twenty-front/src/modules/client-config/states/labPublicFeatureFlagsStateV2.ts @@ -0,0 +1,8 @@ +import { type PublicFeatureFlag } from '~/generated-metadata/graphql'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const labPublicFeatureFlagsStateV2 = createStateV2({ + key: 'labPublicFeatureFlagsStateV2', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuAskAIInfo.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuAskAIInfo.tsx index 43b1d5ef45c..41c04bdf9c2 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuAskAIInfo.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuAskAIInfo.tsx @@ -1,7 +1,7 @@ -import { currentAIChatThreadTitleState } from '@/ai/states/currentAIChatThreadTitleState'; +import { currentAIChatThreadTitleStateV2 } from '@/ai/states/currentAIChatThreadTitleStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; -import { useRecoilValue } from 'recoil'; import { OverflowingTextWithTooltip } from 'twenty-ui/display'; const StyledPageTitle = styled.div` @@ -11,8 +11,8 @@ const StyledPageTitle = styled.div` `; export const CommandMenuAskAIInfo = () => { - const currentAIChatThreadTitle = useRecoilValue( - currentAIChatThreadTitleState, + const currentAIChatThreadTitle = useRecoilValueV2( + currentAIChatThreadTitleStateV2, ); return ( diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuFolderInfo.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuFolderInfo.tsx index 851c4b52a06..ae3a7ac2439 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuFolderInfo.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuFolderInfo.tsx @@ -10,7 +10,8 @@ import { NavigationMenuItemType } from '@/navigation-menu-item/constants/Navigat import { StyledNavigationMenuItemIconContainer } from '@/navigation-menu-item/components/NavigationMenuItemIconContainer'; import { useUpdateFolderNameInDraft } from '@/navigation-menu-item/hooks/useUpdateFolderNameInDraft'; import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors'; import { TitleInput } from '@/ui/input/components/TitleInput'; import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState'; @@ -24,8 +25,8 @@ export const CommandMenuFolderInfo = () => { commandMenuShouldFocusTitleInputComponentState, commandMenuPageInfo.instanceId, ); - const selectedNavigationMenuItemInEditMode = useRecoilValue( - selectedNavigationMenuItemInEditModeState, + const selectedNavigationMenuItemInEditMode = useRecoilValueV2( + selectedNavigationMenuItemInEditModeStateV2, ); const items = useWorkspaceSectionItems(); const { updateFolderNameInDraft } = useUpdateFolderNameInDraft(); diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuForMobile.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuForMobile.tsx index e5abf6cddfc..d3aa02806a4 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuForMobile.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuForMobile.tsx @@ -1,11 +1,11 @@ import { CommandMenuOpenContainer } from '@/command-menu/components/CommandMenuOpenContainer'; import { CommandMenuRouter } from '@/command-menu/components/CommandMenuRouter'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import styled from '@emotion/styled'; import { AnimatePresence } from 'framer-motion'; import { createPortal } from 'react-dom'; -import { useRecoilValue } from 'recoil'; const StyledCommandMenuMobileFullScreenContainer = styled.div` height: 100%; @@ -13,7 +13,7 @@ const StyledCommandMenuMobileFullScreenContainer = styled.div` `; export const CommandMenuForMobile = () => { - const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); + const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); return ( diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuItemWithAddToNavigationDrag.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuItemWithAddToNavigationDrag.tsx index 81d9c61db06..c19c2c2ee4c 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuItemWithAddToNavigationDrag.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuItemWithAddToNavigationDrag.tsx @@ -2,12 +2,12 @@ import styled from '@emotion/styled'; import { Draggable } from '@hello-pangea/dnd'; import { useLingui } from '@lingui/react/macro'; import { type ReactNode, useState } from 'react'; -import { useSetRecoilState } from 'recoil'; import { type IconComponent } from 'twenty-ui/display'; import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem'; import { AddToNavigationDragHandle } from '@/navigation-menu-item/components/AddToNavigationDragHandle'; -import { addToNavPayloadRegistryState } from '@/navigation-menu-item/states/addToNavPayloadRegistryState'; +import { addToNavPayloadRegistryStateV2 } from '@/navigation-menu-item/states/addToNavPayloadRegistryStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import type { AddToNavigationDragPayload } from '@/navigation-menu-item/types/add-to-navigation-drag-payload'; type CommandMenuItemWithAddToNavigationDragProps = { @@ -41,7 +41,7 @@ export const CommandMenuItemWithAddToNavigationDrag = ({ dragIndex, }: CommandMenuItemWithAddToNavigationDragProps) => { const { t } = useLingui(); - const setRegistry = useSetRecoilState(addToNavPayloadRegistryState); + const setRegistry = useSetRecoilStateV2(addToNavPayloadRegistryStateV2); const [isHovered, setIsHovered] = useState(false); const contextualDescription = isHovered diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuLinkInfo.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuLinkInfo.tsx index 611dff7d8f7..142d984f8be 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuLinkInfo.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuLinkInfo.tsx @@ -10,7 +10,8 @@ import { NavigationMenuItemType } from '@/navigation-menu-item/constants/Navigat import { StyledNavigationMenuItemIconContainer } from '@/navigation-menu-item/components/NavigationMenuItemIconContainer'; import { useUpdateLinkInDraft } from '@/navigation-menu-item/hooks/useUpdateLinkInDraft'; import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors'; import { TitleInput } from '@/ui/input/components/TitleInput'; import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState'; @@ -24,8 +25,8 @@ export const CommandMenuLinkInfo = () => { commandMenuShouldFocusTitleInputComponentState, commandMenuPageInfo.instanceId, ); - const selectedNavigationMenuItemInEditMode = useRecoilValue( - selectedNavigationMenuItemInEditModeState, + const selectedNavigationMenuItemInEditMode = useRecoilValueV2( + selectedNavigationMenuItemInEditModeStateV2, ); const items = useWorkspaceSectionItems(); const { updateLinkInDraft } = useUpdateLinkInDraft(); diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuOpenContainer.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuOpenContainer.tsx index 7d6cda2879f..9395c49d96f 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuOpenContainer.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuOpenContainer.tsx @@ -2,7 +2,7 @@ import { COMMAND_MENU_ANIMATION_VARIANTS } from '@/command-menu/constants/Comman import { COMMAND_MENU_CLICK_OUTSIDE_ID } from '@/command-menu/constants/CommandMenuClickOutsideId'; import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; -import { isSidePanelAnimatingState } from '@/command-menu/states/isSidePanelAnimatingState'; +import { isSidePanelAnimatingStateV2 } from '@/command-menu/states/isSidePanelAnimatingStateV2'; import { type CommandMenuAnimationVariant } from '@/command-menu/types/CommandMenuAnimationVariant'; import { RECORD_CHIP_CLICK_OUTSIDE_ID } from '@/object-record/record-table/constants/RecordChipClickOutsideId'; import { MENTION_MENU_DROPDOWN_CLICK_OUTSIDE_ID } from '@/ui/input/constants/MentionMenuDropdownClickOutsideId'; @@ -11,6 +11,7 @@ import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingC import { PAGE_HEADER_COMMAND_MENU_BUTTON_CLICK_OUTSIDE_ID } from '@/ui/layout/page-header/constants/PageHeaderCommandMenuButtonClickOutsideId'; import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { WORKFLOW_DIAGRAM_CREATE_STEP_NODE_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/constants/WorkflowDiagramCreateStepNodeClickOutsideId'; import { WORKFLOW_DIAGRAM_STEP_NODE_BASE_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/constants/WorkflowDiagramStepNodeClickOutsideId'; import { WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/workflow-edges/constants/WorkflowDiagramEdgeOptionsClickOutsideId'; @@ -19,7 +20,7 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { motion } from 'framer-motion'; import { useRef } from 'react'; -import { useRecoilCallback, useSetRecoilState } from 'recoil'; +import { useRecoilCallback } from 'recoil'; import { LINK_CHIP_CLICK_OUTSIDE_ID } from 'twenty-ui/components'; import { useIsMobile } from 'twenty-ui/utilities'; @@ -53,7 +54,9 @@ export const CommandMenuOpenContainer = ({ const { closeCommandMenu } = useCommandMenu(); const commandMenuRef = useRef(null); - const setIsSidePanelAnimating = useSetRecoilState(isSidePanelAnimatingState); + const setIsSidePanelAnimating = useSetRecoilStateV2( + isSidePanelAnimatingStateV2, + ); const handleClickOutside = useRecoilCallback( ({ snapshot }) => diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuPageInfo.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuPageInfo.tsx index 2acf46d6295..ec1ff212514 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuPageInfo.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuPageInfo.tsx @@ -1,5 +1,4 @@ import styled from '@emotion/styled'; -import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { OverflowingTextWithTooltip } from 'twenty-ui/display'; @@ -14,7 +13,8 @@ import { CommandMenuWorkflowStepInfo } from '@/command-menu/components/CommandMe import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType'; import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { type CommandMenuContextChipProps } from './CommandMenuContextChip'; @@ -29,8 +29,8 @@ type CommandMenuPageInfoProps = { }; export const CommandMenuPageInfo = ({ pageChip }: CommandMenuPageInfoProps) => { - const selectedNavigationMenuItemInEditMode = useRecoilValue( - selectedNavigationMenuItemInEditModeState, + const selectedNavigationMenuItemInEditMode = useRecoilValueV2( + selectedNavigationMenuItemInEditModeStateV2, ); const items = useWorkspaceSectionItems(); diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuSidePanelForDesktop.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuSidePanelForDesktop.tsx index e4a94628f97..90ff212b5bc 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuSidePanelForDesktop.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuSidePanelForDesktop.tsx @@ -7,11 +7,12 @@ import { commandMenuWidthState, } from '@/command-menu/states/commandMenuWidthState'; import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { tableWidthResizeIsActiveState } from '@/object-record/record-table/states/tableWidthResizeIsActivedState'; import { ModalContainerContext } from '@/ui/layout/modal/contexts/ModalContainerContext'; import { ResizablePanelGap } from '@/ui/layout/resizable-panel/components/ResizablePanelGap'; import { COMMAND_MENU_CONSTRAINTS } from '@/ui/layout/resizable-panel/constants/CommandMenuConstraints'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import styled from '@emotion/styled'; import { useCallback, useState } from 'react'; import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; @@ -54,7 +55,7 @@ const StyledModalContainer = styled.div` const GAP_WIDTH = 8; export const CommandMenuSidePanelForDesktop = () => { - const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); + const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); const isCommandMenuClosing = useRecoilValue(isCommandMenuClosingState); const [commandMenuWidth, setCommandMenuWidth] = useRecoilState( commandMenuWidthState, diff --git a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useOpenAskAIPageInCommandMenu.test.tsx b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useOpenAskAIPageInCommandMenu.test.tsx index 08633d48ce4..514e110f90b 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useOpenAskAIPageInCommandMenu.test.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/__tests__/useOpenAskAIPageInCommandMenu.test.tsx @@ -1,9 +1,12 @@ import { renderHook, act } from '@testing-library/react'; -import { type MutableSnapshot, RecoilRoot } from 'recoil'; +import { Provider as JotaiProvider } from 'jotai'; +import { type ReactNode } from 'react'; +import { RecoilRoot } from 'recoil'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; import { useOpenAskAIPageInCommandMenu } from '@/command-menu/hooks/useOpenAskAIPageInCommandMenu'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { IconSparkles } from 'twenty-ui/display'; const navigateCommandMenuMock = jest.fn(); @@ -17,22 +20,22 @@ jest.mock('@/command-menu/hooks/useCommandMenu', () => ({ }), })); -const renderWithRecoil = ( - initializeState?: (snapshot: MutableSnapshot) => void, -) => - renderHook(() => useOpenAskAIPageInCommandMenu(), { - wrapper: ({ children }) => ( - {children} - ), - }); +const Wrapper = ({ children }: { children: ReactNode }) => ( + + {children} + +); describe('useOpenAskAIPageInCommandMenu', () => { beforeEach(() => { jest.clearAllMocks(); + jotaiStore.set(isCommandMenuOpenedStateV2.atom, false); }); it('should navigate to AskAI page with correct defaults', () => { - const { result } = renderWithRecoil(); + const { result } = renderHook(() => useOpenAskAIPageInCommandMenu(), { + wrapper: Wrapper, + }); act(() => { result.current.openAskAIPage(); @@ -48,8 +51,10 @@ describe('useOpenAskAIPageInCommandMenu', () => { }); it('should use resetNavigationStack from argument when provided', () => { - const { result } = renderWithRecoil((snapshot) => { - snapshot.set(isCommandMenuOpenedState, true); + jotaiStore.set(isCommandMenuOpenedStateV2.atom, true); + + const { result } = renderHook(() => useOpenAskAIPageInCommandMenu(), { + wrapper: Wrapper, }); act(() => { @@ -64,8 +69,10 @@ describe('useOpenAskAIPageInCommandMenu', () => { }); it('should default resetNavigationStack to isCommandMenuOpened', () => { - const { result } = renderWithRecoil((snapshot) => { - snapshot.set(isCommandMenuOpenedState, true); + jotaiStore.set(isCommandMenuOpenedStateV2.atom, true); + + const { result } = renderHook(() => useOpenAskAIPageInCommandMenu(), { + wrapper: Wrapper, }); act(() => { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts index 509fdd0e974..7ff1f40f209 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts @@ -5,10 +5,12 @@ import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandM import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState'; import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState'; import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; -import { addToNavPayloadRegistryState } from '@/navigation-menu-item/states/addToNavPayloadRegistryState'; +import { addToNavPayloadRegistryStateV2 } from '@/navigation-menu-item/states/addToNavPayloadRegistryStateV2'; import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown'; import { emitSidePanelOpenEvent } from '@/ui/layout/right-drawer/utils/emitSidePanelOpenEvent'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById'; import { t } from '@lingui/core/macro'; import { useCallback } from 'react'; @@ -29,8 +31,9 @@ export const useCommandMenu = () => { .getValue(); if (isCommandMenuOpened) { - set(addToNavPayloadRegistryState, new Map()); + jotaiStore.set(addToNavPayloadRegistryStateV2.atom, new Map()); set(isCommandMenuOpenedState, false); + jotaiStore.set(isCommandMenuOpenedStateV2.atom, false); set(isCommandMenuClosingState, true); closeAnyOpenDropdown(); removeFocusItemFromFocusStackById({ diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup.ts b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup.ts index 534e15c7c6b..ac8a39e0fe4 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuCloseAnimationCompleteCleanup.ts @@ -11,6 +11,7 @@ import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchS import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState'; import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState'; import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; @@ -25,6 +26,7 @@ import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getSh import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { WORKFLOW_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-steps/workflow-actions/code-action/constants/WorkflowLogicFunctionTabListComponentId'; import { WorkflowLogicFunctionTabId } from '@/workflow/workflow-steps/workflow-actions/code-action/types/WorkflowLogicFunctionTabId'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilCallback } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; @@ -104,6 +106,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => { instanceId: '', }); set(isCommandMenuOpenedState, false); + jotaiStore.set(isCommandMenuOpenedStateV2.atom, false); set(commandMenuSearchState, ''); set(commandMenuNavigationMorphItemsByPageState, new Map()); set(commandMenuNavigationStackState, []); diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useNavigateCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useNavigateCommandMenu.ts index 25ae22eb65a..5bbd8115973 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useNavigateCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useNavigateCommandMenu.ts @@ -10,10 +10,12 @@ import { commandMenuShouldFocusTitleInputComponentState } from '@/command-menu/s import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState'; import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState'; import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { type CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId'; import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack'; import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useRecoilCallback } from 'recoil'; import { type IconComponent } from 'twenty-ui/display'; import { v4 } from 'uuid'; @@ -70,6 +72,7 @@ export const useNavigateCommandMenu = () => { }); set(isCommandMenuOpenedState, true); + jotaiStore.set(isCommandMenuOpenedStateV2.atom, true); set(hasUserSelectedCommandState, false); }, [ diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts index de0d653ea7e..1f64488de77 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useOpenAskAIPageInCommandMenu.ts @@ -1,39 +1,36 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { t } from '@lingui/core/macro'; -import { useRecoilCallback } from 'recoil'; +import { useCallback } from 'react'; import { IconSparkles } from 'twenty-ui/display'; import { v4 } from 'uuid'; export const useOpenAskAIPageInCommandMenu = () => { const { navigateCommandMenu } = useCommandMenu(); + const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); - const openAskAIPage = useRecoilCallback( - ({ snapshot }) => - ({ - resetNavigationStack, - }: { - resetNavigationStack?: boolean; - } = {}) => { - const isCommandMenuOpened = snapshot - .getLoadable(isCommandMenuOpenedState) - .getValue(); + const openAskAIPage = useCallback( + ({ + resetNavigationStack, + }: { + resetNavigationStack?: boolean; + } = {}) => { + const shouldReset = + resetNavigationStack !== undefined + ? resetNavigationStack + : isCommandMenuOpened; - const shouldReset = - resetNavigationStack !== undefined - ? resetNavigationStack - : isCommandMenuOpened; - - navigateCommandMenu({ - page: CommandMenuPages.AskAI, - pageTitle: t`Ask AI`, - pageIcon: IconSparkles, - pageId: v4(), - resetNavigationStack: shouldReset, - }); - }, - [navigateCommandMenu], + navigateCommandMenu({ + page: CommandMenuPages.AskAI, + pageTitle: t`Ask AI`, + pageIcon: IconSparkles, + pageId: v4(), + resetNavigationStack: shouldReset, + }); + }, + [navigateCommandMenu, isCommandMenuOpened], ); return { diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu.ts index 6ce936f7146..f0051db1d94 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu.ts @@ -1,14 +1,14 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { t } from '@lingui/core/macro'; -import { useRecoilValue } from 'recoil'; import { v4 } from 'uuid'; import { IconSearch } from 'twenty-ui/display'; export const useOpenRecordsSearchPageInCommandMenu = () => { const { navigateCommandMenu } = useCommandMenu(); - const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); + const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); const openRecordsSearchPage = () => { navigateCommandMenu({ diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useRichTextCommandMenu.ts b/packages/twenty-front/src/modules/command-menu/hooks/useRichTextCommandMenu.ts index 1b0d13a886a..f4b818164f5 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useRichTextCommandMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/hooks/useRichTextCommandMenu.ts @@ -1,35 +1,34 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; -import { viewableRichTextComponentState } from '@/command-menu/pages/rich-text-page/states/viewableRichTextComponentState'; +import { viewableRichTextComponentStateV2 } from '@/command-menu/pages/rich-text-page/states/viewableRichTextComponentStateV2'; import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { t } from '@lingui/core/macro'; import { useCallback } from 'react'; -import { useRecoilCallback } from 'recoil'; import { IconPencil } from 'twenty-ui/display'; export const useRichTextCommandMenu = () => { const { navigateCommandMenu, openCommandMenu } = useCommandMenu(); - const openRichTextInCommandMenu = useRecoilCallback( - ({ set }) => - ({ + const openRichTextInCommandMenu = useCallback( + ({ + activityId, + activityObjectNameSingular, + }: { + activityId: string; + activityObjectNameSingular: string; + }) => { + jotaiStore.set(viewableRichTextComponentStateV2.atom, { activityId, activityObjectNameSingular, - }: { - activityId: string; - activityObjectNameSingular: string; - }) => { - set(viewableRichTextComponentState, { - activityId, - activityObjectNameSingular, - }); + }); - openCommandMenu(); - navigateCommandMenu({ - page: CommandMenuPages.EditRichText, - pageTitle: t`Rich Text`, - pageIcon: IconPencil, - }); - }, + openCommandMenu(); + navigateCommandMenu({ + page: CommandMenuPages.EditRichText, + pageTitle: t`Rich Text`, + pageIcon: IconPencil, + }); + }, [navigateCommandMenu, openCommandMenu], ); diff --git a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNavigationMenuItemEditPage.tsx b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNavigationMenuItemEditPage.tsx index bb5a473bd77..56adb0168e4 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNavigationMenuItemEditPage.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNavigationMenuItemEditPage.tsx @@ -11,12 +11,12 @@ import { useSelectedNavigationMenuItemEditItem } from '@/navigation-menu-item/ho import { useSelectedNavigationMenuItemEditItemLabel } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItemLabel'; import { useSelectedNavigationMenuItemEditItemObjectMetadata } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItemObjectMetadata'; import { useUpdateLinkInDraft } from '@/navigation-menu-item/hooks/useUpdateLinkInDraft'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import { useState } from 'react'; -import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const StyledCommandMenuPlaceholder = styled.p` color: ${({ theme }) => theme.font.color.tertiary}; @@ -30,8 +30,8 @@ const StyledCommandMenuPageContainer = styled.div` export const CommandMenuNavigationMenuItemEditPage = () => { const { t } = useLingui(); - const selectedNavigationMenuItemInEditMode = useRecoilValue( - selectedNavigationMenuItemInEditModeState, + const selectedNavigationMenuItemInEditMode = useRecoilValueV2( + selectedNavigationMenuItemInEditModeStateV2, ); const { selectedItemLabel } = useSelectedNavigationMenuItemEditItemLabel(); const { selectedItem } = useSelectedNavigationMenuItemEditItem(); diff --git a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemObjectFlow.tsx b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemObjectFlow.tsx index 1367047204d..c7d06e79fe4 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemObjectFlow.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemObjectFlow.tsx @@ -1,6 +1,5 @@ import { useLingui } from '@lingui/react/macro'; import { useState } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { CommandMenuObjectPickerSubView } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuObjectPickerSubView'; @@ -9,7 +8,9 @@ import { getAvailableObjectMetadataForNewSidebarItem } from '@/command-menu/page import { useAddObjectToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddObjectToNavigationMenuDraft'; import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems'; import { useNavigationMenuObjectMetadataFromDraft } from '@/navigation-menu-item/hooks/useNavigationMenuObjectMetadataFromDraft'; -import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState'; +import { addMenuItemInsertionContextStateV2 } from '@/navigation-menu-item/states/addMenuItemInsertionContextStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; @@ -33,11 +34,11 @@ export const CommandMenuNewSidebarItemObjectFlow = ({ const { addObjectToDraft } = useAddObjectToNavigationMenuDraft(); const { activeNonSystemObjectMetadataItems } = useFilteredObjectMetadataItems(); - const addMenuItemInsertionContext = useRecoilValue( - addMenuItemInsertionContextState, + const addMenuItemInsertionContext = useRecoilValueV2( + addMenuItemInsertionContextStateV2, ); - const setAddMenuItemInsertionContext = useSetRecoilState( - addMenuItemInsertionContextState, + const setAddMenuItemInsertionContext = useSetRecoilStateV2( + addMenuItemInsertionContextStateV2, ); const { views, objectMetadataIdsWithIndexView } = useNavigationMenuObjectMetadataFromDraft(currentDraft); diff --git a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemRecordItem.tsx b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemRecordItem.tsx index e7d377681b4..a02e841fe8e 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemRecordItem.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemRecordItem.tsx @@ -1,4 +1,3 @@ -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { Avatar } from 'twenty-ui/display'; import { CommandMenuItemWithAddToNavigationDrag } from '@/command-menu/components/CommandMenuItemWithAddToNavigationDrag'; @@ -6,7 +5,9 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType'; import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems'; import { useAddRecordToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddRecordToNavigationMenuDraft'; -import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState'; +import { addMenuItemInsertionContextStateV2 } from '@/navigation-menu-item/states/addMenuItemInsertionContextStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import type { AddToNavigationDragPayload } from '@/navigation-menu-item/types/add-to-navigation-drag-payload'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; @@ -31,11 +32,11 @@ export const CommandMenuNewSidebarItemRecordItem = ({ const { closeCommandMenu } = useCommandMenu(); const { addRecordToDraft } = useAddRecordToNavigationMenuDraft(); const { currentDraft } = useDraftNavigationMenuItems(); - const addMenuItemInsertionContext = useRecoilValue( - addMenuItemInsertionContextState, + const addMenuItemInsertionContext = useRecoilValueV2( + addMenuItemInsertionContextStateV2, ); - const setAddMenuItemInsertionContext = useSetRecoilState( - addMenuItemInsertionContextState, + const setAddMenuItemInsertionContext = useSetRecoilStateV2( + addMenuItemInsertionContextStateV2, ); const { objectMetadataItems } = useObjectMetadataItems(); const objectMetadataItem = objectMetadataItems.find( diff --git a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemViewPickerSubView.tsx b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemViewPickerSubView.tsx index 27fe75c9128..e0a6d0029d7 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemViewPickerSubView.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemViewPickerSubView.tsx @@ -1,6 +1,5 @@ import { useLingui } from '@lingui/react/macro'; import { useState } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { useIcons } from 'twenty-ui/display'; import { CommandGroup } from '@/command-menu/components/CommandGroup'; @@ -14,7 +13,9 @@ import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDra import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType'; import { useAddViewToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddViewToNavigationMenuDraft'; import { useNavigationMenuObjectMetadataFromDraft } from '@/navigation-menu-item/hooks/useNavigationMenuObjectMetadataFromDraft'; -import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState'; +import { addMenuItemInsertionContextStateV2 } from '@/navigation-menu-item/states/addMenuItemInsertionContextStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem'; import { type View } from '@/views/types/View'; @@ -35,11 +36,11 @@ export const CommandMenuNewSidebarItemViewPickerSubView = ({ const { closeCommandMenu } = useCommandMenu(); const { addViewToDraft } = useAddViewToNavigationMenuDraft(); const { currentDraft } = useDraftNavigationMenuItems(); - const addMenuItemInsertionContext = useRecoilValue( - addMenuItemInsertionContextState, + const addMenuItemInsertionContext = useRecoilValueV2( + addMenuItemInsertionContextStateV2, ); - const setAddMenuItemInsertionContext = useSetRecoilState( - addMenuItemInsertionContextState, + const setAddMenuItemInsertionContext = useSetRecoilStateV2( + addMenuItemInsertionContextStateV2, ); const { objectMetadataItems } = useObjectMetadataItems(); const { views } = useNavigationMenuObjectMetadataFromDraft(currentDraft); diff --git a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useAddFolderToNavigationMenu.ts b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useAddFolderToNavigationMenu.ts index 9f495ee6523..6cda906c507 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useAddFolderToNavigationMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useAddFolderToNavigationMenu.ts @@ -1,32 +1,33 @@ import { useLingui } from '@lingui/react/macro'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconFolder } from 'twenty-ui/display'; import { useAddFolderToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddFolderToNavigationMenuDraft'; import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/useNavigationMenuItemsDraftState'; import { useOpenNavigationMenuItemInCommandMenu } from '@/navigation-menu-item/hooks/useOpenNavigationMenuItemInCommandMenu'; -import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { addMenuItemInsertionContextStateV2 } from '@/navigation-menu-item/states/addMenuItemInsertionContextStateV2'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; export const useAddFolderToNavigationMenu = () => { const { t } = useLingui(); const { addFolderToDraft } = useAddFolderToNavigationMenuDraft(); const { workspaceNavigationMenuItems } = useNavigationMenuItemsDraftState(); - const navigationMenuItemsDraft = useRecoilValue( - navigationMenuItemsDraftState, + const navigationMenuItemsDraft = useRecoilValueV2( + navigationMenuItemsDraftStateV2, ); - const setSelectedNavigationMenuItemInEditMode = useSetRecoilState( - selectedNavigationMenuItemInEditModeState, + const setSelectedNavigationMenuItemInEditMode = useSetRecoilStateV2( + selectedNavigationMenuItemInEditModeStateV2, ); const { openNavigationMenuItemInCommandMenu } = useOpenNavigationMenuItemInCommandMenu(); - const addMenuItemInsertionContext = useRecoilValue( - addMenuItemInsertionContextState, + const addMenuItemInsertionContext = useRecoilValueV2( + addMenuItemInsertionContextStateV2, ); - const setAddMenuItemInsertionContext = useSetRecoilState( - addMenuItemInsertionContextState, + const setAddMenuItemInsertionContext = useSetRecoilStateV2( + addMenuItemInsertionContextStateV2, ); const currentDraft = isDefined(navigationMenuItemsDraft) diff --git a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useAddLinkToNavigationMenu.ts b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useAddLinkToNavigationMenu.ts index 69d3683e453..6680fdd40d6 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useAddLinkToNavigationMenu.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useAddLinkToNavigationMenu.ts @@ -1,32 +1,33 @@ import { useLingui } from '@lingui/react/macro'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconLink } from 'twenty-ui/display'; import { useAddLinkToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddLinkToNavigationMenuDraft'; import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/useNavigationMenuItemsDraftState'; import { useOpenNavigationMenuItemInCommandMenu } from '@/navigation-menu-item/hooks/useOpenNavigationMenuItemInCommandMenu'; -import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { addMenuItemInsertionContextStateV2 } from '@/navigation-menu-item/states/addMenuItemInsertionContextStateV2'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; export const useAddLinkToNavigationMenu = () => { const { t } = useLingui(); const { addLinkToDraft } = useAddLinkToNavigationMenuDraft(); const { workspaceNavigationMenuItems } = useNavigationMenuItemsDraftState(); - const navigationMenuItemsDraft = useRecoilValue( - navigationMenuItemsDraftState, + const navigationMenuItemsDraft = useRecoilValueV2( + navigationMenuItemsDraftStateV2, ); - const setSelectedNavigationMenuItemInEditMode = useSetRecoilState( - selectedNavigationMenuItemInEditModeState, + const setSelectedNavigationMenuItemInEditMode = useSetRecoilStateV2( + selectedNavigationMenuItemInEditModeStateV2, ); const { openNavigationMenuItemInCommandMenu } = useOpenNavigationMenuItemInCommandMenu(); - const addMenuItemInsertionContext = useRecoilValue( - addMenuItemInsertionContextState, + const addMenuItemInsertionContext = useRecoilValueV2( + addMenuItemInsertionContextStateV2, ); - const setAddMenuItemInsertionContext = useSetRecoilState( - addMenuItemInsertionContextState, + const setAddMenuItemInsertionContext = useSetRecoilStateV2( + addMenuItemInsertionContextStateV2, ); const currentDraft = isDefined(navigationMenuItemsDraft) diff --git a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useFolderPickerSelectionData.ts b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useFolderPickerSelectionData.ts index 4adde683551..6692fa3a8d3 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useFolderPickerSelectionData.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useFolderPickerSelectionData.ts @@ -1,4 +1,3 @@ -import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; @@ -6,7 +5,8 @@ import { useDraftNavigationMenuItemsAllFolders } from '@/navigation-menu-item/ho import { useDraftNavigationMenuItemsWorkspaceFolders } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItemsWorkspaceFolders'; import { useSelectedNavigationMenuItemEditItem } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItem'; import { useNavigationMenuItemMoveRemove } from '@/navigation-menu-item/hooks/useNavigationMenuItemMoveRemove'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType'; type FolderOption = { @@ -47,8 +47,8 @@ export const useFolderPickerSelectionData = ({ }: UseFolderPickerSelectionDataParams) => { const { closeCommandMenu } = useCommandMenu(); const { moveToFolder } = useNavigationMenuItemMoveRemove(); - const selectedNavigationMenuItemInEditMode = useRecoilValue( - selectedNavigationMenuItemInEditModeState, + const selectedNavigationMenuItemInEditMode = useRecoilValueV2( + selectedNavigationMenuItemInEditModeStateV2, ); const { selectedItem } = useSelectedNavigationMenuItemEditItem(); const selectedItemType = selectedItem?.itemType ?? null; diff --git a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useNavigationMenuItemEditOrganizeActions.ts b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useNavigationMenuItemEditOrganizeActions.ts index 9e929fe50f9..cc8f47c04b7 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useNavigationMenuItemEditOrganizeActions.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/hooks/useNavigationMenuItemEditOrganizeActions.ts @@ -1,5 +1,4 @@ import { useLingui } from '@lingui/react/macro'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconPlus } from 'twenty-ui/display'; @@ -10,8 +9,10 @@ import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages'; import { useNavigationMenuItemMoveRemove } from '@/navigation-menu-item/hooks/useNavigationMenuItemMoveRemove'; import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/useNavigationMenuItemsDraftState'; import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems'; -import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { addMenuItemInsertionContextStateV2 } from '@/navigation-menu-item/states/addMenuItemInsertionContextStateV2'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { type AddMenuItemInsertionContext } from '@/navigation-menu-item/types/AddMenuItemInsertionContext'; const getAddMenuItemInsertionContext = ( @@ -48,14 +49,14 @@ export const useNavigationMenuItemEditOrganizeActions = const { t } = useLingui(); const { closeCommandMenu } = useCommandMenu(); const { navigateCommandMenu } = useNavigateCommandMenu(); - const selectedNavigationMenuItemInEditMode = useRecoilValue( - selectedNavigationMenuItemInEditModeState, + const selectedNavigationMenuItemInEditMode = useRecoilValueV2( + selectedNavigationMenuItemInEditModeStateV2, ); - const setSelectedNavigationMenuItemInEditMode = useSetRecoilState( - selectedNavigationMenuItemInEditModeState, + const setSelectedNavigationMenuItemInEditMode = useSetRecoilStateV2( + selectedNavigationMenuItemInEditModeStateV2, ); - const setAddMenuItemInsertionContext = useSetRecoilState( - addMenuItemInsertionContextState, + const setAddMenuItemInsertionContext = useSetRecoilStateV2( + addMenuItemInsertionContextStateV2, ); const { workspaceNavigationMenuItems } = useNavigationMenuItemsDraftState(); const items = useWorkspaceSectionItems(); diff --git a/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/components/CommandMenuEditRichTextPage.tsx b/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/components/CommandMenuEditRichTextPage.tsx index e0edc99d80c..78b584082aa 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/components/CommandMenuEditRichTextPage.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/components/CommandMenuEditRichTextPage.tsx @@ -4,8 +4,8 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { lazy, Suspense } from 'react'; import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; -import { useRecoilValue } from 'recoil'; -import { viewableRichTextComponentState } from '@/command-menu/pages/rich-text-page/states/viewableRichTextComponentState'; +import { viewableRichTextComponentStateV2 } from '@/command-menu/pages/rich-text-page/states/viewableRichTextComponentStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; const ActivityRichTextEditor = lazy(() => import('@/activities/components/ActivityRichTextEditor').then((module) => ({ @@ -35,8 +35,8 @@ const LoadingSkeleton = () => { }; export const CommandMenuEditRichTextPage = () => { - const { activityId, activityObjectNameSingular } = useRecoilValue( - viewableRichTextComponentState, + const { activityId, activityObjectNameSingular } = useRecoilValueV2( + viewableRichTextComponentStateV2, ); if ( diff --git a/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/states/viewableRichTextComponentState.ts b/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/states/viewableRichTextComponentState.ts deleted file mode 100644 index 2f4b6f27761..00000000000 --- a/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/states/viewableRichTextComponentState.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { atom, type RecoilState } from 'recoil'; - -export const viewableRichTextComponentState: RecoilState<{ - activityId: string; - activityObjectNameSingular: string; -}> = atom({ - key: 'viewableRichTextComponentState', - default: { - activityId: '', - activityObjectNameSingular: '', - }, -}); diff --git a/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/states/viewableRichTextComponentStateV2.ts b/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/states/viewableRichTextComponentStateV2.ts new file mode 100644 index 00000000000..34334d0cea4 --- /dev/null +++ b/packages/twenty-front/src/modules/command-menu/pages/rich-text-page/states/viewableRichTextComponentStateV2.ts @@ -0,0 +1,12 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const viewableRichTextComponentStateV2 = createStateV2<{ + activityId: string; + activityObjectNameSingular: string; +}>({ + key: 'viewableRichTextComponentStateV2', + defaultValue: { + activityId: '', + activityObjectNameSingular: '', + }, +}); diff --git a/packages/twenty-front/src/modules/command-menu/states/isCommandMenuOpenedStateV2.ts b/packages/twenty-front/src/modules/command-menu/states/isCommandMenuOpenedStateV2.ts new file mode 100644 index 00000000000..75bd4a53388 --- /dev/null +++ b/packages/twenty-front/src/modules/command-menu/states/isCommandMenuOpenedStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const isCommandMenuOpenedStateV2 = createStateV2({ + key: 'command-menu/isCommandMenuOpenedStateV2', + defaultValue: false, +}); diff --git a/packages/twenty-front/src/modules/command-menu/states/isSidePanelAnimatingState.ts b/packages/twenty-front/src/modules/command-menu/states/isSidePanelAnimatingState.ts deleted file mode 100644 index 72bebd59cf0..00000000000 --- a/packages/twenty-front/src/modules/command-menu/states/isSidePanelAnimatingState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const isSidePanelAnimatingState = atom({ - key: 'command-menu/isSidePanelAnimatingState', - default: false, -}); diff --git a/packages/twenty-front/src/modules/command-menu/states/isSidePanelAnimatingStateV2.ts b/packages/twenty-front/src/modules/command-menu/states/isSidePanelAnimatingStateV2.ts new file mode 100644 index 00000000000..9d568e5a224 --- /dev/null +++ b/packages/twenty-front/src/modules/command-menu/states/isSidePanelAnimatingStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const isSidePanelAnimatingStateV2 = createStateV2({ + key: 'command-menu/isSidePanelAnimatingStateV2', + defaultValue: false, +}); diff --git a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx index 4d91a46c5fe..34d515cf65d 100644 --- a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx +++ b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx @@ -6,7 +6,8 @@ import { FavoritesDragContext } from '@/favorites/contexts/FavoritesDragContext' import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite'; import { useDeleteFavoriteFolder } from '@/favorites/hooks/useDeleteFavoriteFolder'; import { useRenameFavoriteFolder } from '@/favorites/hooks/useRenameFavoriteFolder'; -import { openFavoriteFolderIdsState } from '@/favorites/states/openFavoriteFolderIdsState'; +import { openFavoriteFolderIdsStateV2 } from '@/favorites/states/openFavoriteFolderIdsStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { getFavoriteSecondaryLabel } from '@/favorites/utils/getFavoriteSecondaryLabel'; import { isLocationMatchingFavorite } from '@/favorites/utils/isLocationMatchingFavorite'; import { type ProcessedFavorite } from '@/favorites/utils/sortFavorites'; @@ -21,7 +22,8 @@ import { NavigationDrawerInput } from '@/ui/navigation/navigation-drawer/compone import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { NavigationDrawerItemsCollapsableContainer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItemsCollapsableContainer'; import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem'; -import { currentFavoriteFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState'; +import { currentFavoriteFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { getNavigationSubItemLeftAdornment } from '@/ui/navigation/navigation-drawer/utils/getNavigationSubItemLeftAdornment'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { Droppable } from '@hello-pangea/dnd'; @@ -29,7 +31,7 @@ import { useLingui } from '@lingui/react/macro'; import { useContext, useState } from 'react'; import { createPortal } from 'react-dom'; import { useLocation } from 'react-router-dom'; -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { IconFolder, IconFolderOpen, IconHeartOff } from 'twenty-ui/display'; import { LightIconButton } from 'twenty-ui/input'; import { AnimatedExpandableContainer } from 'twenty-ui/layout'; @@ -62,11 +64,13 @@ export const CurrentWorkspaceMemberFavorites = ({ const isMobile = useIsMobile(); - const [openFavoriteFolderIds, setOpenFavoriteFolderIds] = useRecoilState( - openFavoriteFolderIdsState, + const [openFavoriteFolderIds, setOpenFavoriteFolderIds] = useRecoilStateV2( + openFavoriteFolderIdsStateV2, ); - const setCurrentFolderId = useSetRecoilState(currentFavoriteFolderIdState); + const setCurrentFolderId = useSetRecoilStateV2( + currentFavoriteFolderIdStateV2, + ); const isOpen = openFavoriteFolderIds.includes(folder.folderId); diff --git a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx index 5a69f05f656..29f1aa21a24 100644 --- a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx +++ b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavoritesFolders.tsx @@ -4,14 +4,15 @@ import { FavoriteFolders } from '@/favorites/components/FavoritesFolders'; import { FavoritesSkeletonLoader } from '@/favorites/components/FavoritesSkeletonLoader'; import { useFavorites } from '@/favorites/hooks/useFavorites'; import { useFavoritesByFolder } from '@/favorites/hooks/useFavoritesByFolder'; -import { isFavoriteFolderCreatingState } from '@/favorites/states/isFavoriteFolderCreatingState'; +import { isFavoriteFolderCreatingStateV2 } from '@/favorites/states/isFavoriteFolderCreatingStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { useIsPrefetchLoading } from '@/prefetch/hooks/useIsPrefetchLoading'; import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper'; 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 { useLingui } from '@lingui/react/macro'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconFolderPlus } from 'twenty-ui/display'; import { LightIconButton } from 'twenty-ui/input'; @@ -22,7 +23,7 @@ export const CurrentWorkspaceMemberFavoritesFolders = () => { const { favoritesByFolder } = useFavoritesByFolder(); const [isFavoriteFolderCreating, setIsFavoriteFolderCreating] = - useRecoilState(isFavoriteFolderCreatingState); + useRecoilStateV2(isFavoriteFolderCreatingStateV2); const loading = useIsPrefetchLoading(); diff --git a/packages/twenty-front/src/modules/favorites/components/FavoritesBackButton.tsx b/packages/twenty-front/src/modules/favorites/components/FavoritesBackButton.tsx index 3c0d6c7c54b..346c0af8ef2 100644 --- a/packages/twenty-front/src/modules/favorites/components/FavoritesBackButton.tsx +++ b/packages/twenty-front/src/modules/favorites/components/FavoritesBackButton.tsx @@ -1,7 +1,7 @@ -import { currentFavoriteFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState'; +import { currentFavoriteFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { useSetRecoilState } from 'recoil'; import { IconX } from 'twenty-ui/display'; const StyledBackButton = styled.button` @@ -35,7 +35,9 @@ export const FavoritesBackButton = ({ folderName, }: FavoritesBackButtonProps) => { const theme = useTheme(); - const setCurrentFolderId = useSetRecoilState(currentFavoriteFolderIdState); + const setCurrentFolderId = useSetRecoilStateV2( + currentFavoriteFolderIdStateV2, + ); const handleClick = (e: React.MouseEvent) => { e.preventDefault(); diff --git a/packages/twenty-front/src/modules/favorites/components/FavoritesFolders.tsx b/packages/twenty-front/src/modules/favorites/components/FavoritesFolders.tsx index 2cb84bdd8bc..4ab1a9554c0 100644 --- a/packages/twenty-front/src/modules/favorites/components/FavoritesFolders.tsx +++ b/packages/twenty-front/src/modules/favorites/components/FavoritesFolders.tsx @@ -1,11 +1,11 @@ import { CurrentWorkspaceMemberFavorites } from '@/favorites/components/CurrentWorkspaceMemberFavorites'; import { useCreateFavoriteFolder } from '@/favorites/hooks/useCreateFavoriteFolder'; import { useFavoritesByFolder } from '@/favorites/hooks/useFavoritesByFolder'; -import { isFavoriteFolderCreatingState } from '@/favorites/states/isFavoriteFolderCreatingState'; +import { isFavoriteFolderCreatingStateV2 } from '@/favorites/states/isFavoriteFolderCreatingStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper'; import { NavigationDrawerInput } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerInput'; import { useState } from 'react'; -import { useRecoilState } from 'recoil'; import { IconFolder } from 'twenty-ui/display'; type FavoriteFoldersProps = { @@ -21,7 +21,7 @@ export const FavoriteFolders = ({ const { createNewFavoriteFolder } = useCreateFavoriteFolder(); const [isFavoriteFolderCreating, setIsFavoriteFolderCreating] = - useRecoilState(isFavoriteFolderCreatingState); + useRecoilStateV2(isFavoriteFolderCreatingStateV2); const handleFavoriteFolderNameChange = (value: string) => { setNewFolderName(value); diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPicker.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPicker.tsx index d5e3456e007..a36bf223a4c 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPicker.tsx +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPicker.tsx @@ -4,7 +4,8 @@ import { FavoriteFolderPickerSearchInput } from '@/favorites/favorite-folder-pic import { useFavoriteFolderPicker } from '@/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker'; import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext'; import { favoriteFolderSearchFilterComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFoldersSearchFilterComponentState'; -import { isFavoriteFolderCreatingState } from '@/favorites/states/isFavoriteFolderCreatingState'; +import { isFavoriteFolderCreatingStateV2 } from '@/favorites/states/isFavoriteFolderCreatingStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; @@ -13,7 +14,6 @@ import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotke import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState'; -import { useRecoilState } from 'recoil'; import { Key } from 'ts-key-enum'; type FavoriteFolderPickerProps = { @@ -32,7 +32,7 @@ export const FavoriteFolderPicker = ({ dropdownId, }: FavoriteFolderPickerProps) => { const [isFavoriteFolderCreating, setIsFavoriteFolderCreating] = - useRecoilState(isFavoriteFolderCreatingState); + useRecoilStateV2(isFavoriteFolderCreatingStateV2); const instanceId = useAvailableComponentInstanceIdOrThrow( FavoriteFolderPickerInstanceContext, diff --git a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx index 55c3adc04e2..56a74bacd4d 100644 --- a/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx +++ b/packages/twenty-front/src/modules/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter.tsx @@ -1,11 +1,12 @@ -import { isFavoriteFolderCreatingState } from '@/favorites/states/isFavoriteFolderCreatingState'; +import { isFavoriteFolderCreatingStateV2 } from '@/favorites/states/isFavoriteFolderCreatingStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection'; import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded'; import { useTheme } from '@emotion/react'; import { useLingui } from '@lingui/react/macro'; -import { useRecoilState, useSetRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; import { IconPlus } from 'twenty-ui/display'; import { MenuItem } from 'twenty-ui/navigation'; @@ -15,8 +16,8 @@ export const FavoriteFolderPickerFooter = ({ dropdownId: string; }) => { const { t } = useLingui(); - const [, setIsFavoriteFolderCreating] = useRecoilState( - isFavoriteFolderCreatingState, + const [, setIsFavoriteFolderCreating] = useRecoilStateV2( + isFavoriteFolderCreatingStateV2, ); const setIsNavigationDrawerExpanded = useSetRecoilState( isNavigationDrawerExpandedState, diff --git a/packages/twenty-front/src/modules/favorites/hooks/useHandleFavoriteDragAndDrop.ts b/packages/twenty-front/src/modules/favorites/hooks/useHandleFavoriteDragAndDrop.ts index c51f2ce2ef6..9578e7fee72 100644 --- a/packages/twenty-front/src/modules/favorites/hooks/useHandleFavoriteDragAndDrop.ts +++ b/packages/twenty-front/src/modules/favorites/hooks/useHandleFavoriteDragAndDrop.ts @@ -1,20 +1,20 @@ import { FAVORITE_DROPPABLE_IDS } from '@/favorites/constants/FavoriteDroppableIds'; import { useSortedFavorites } from '@/favorites/hooks/useSortedFavorites'; -import { openFavoriteFolderIdsState } from '@/favorites/states/openFavoriteFolderIdsState'; +import { openFavoriteFolderIdsStateV2 } from '@/favorites/states/openFavoriteFolderIdsStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { calculateNewPosition } from '@/ui/layout/draggable-list/utils/calculateNewPosition'; import { validateAndExtractFolderId } from '@/ui/layout/draggable-list/utils/validateAndExtractFolderId'; import { type OnDragEndResponder } from '@hello-pangea/dnd'; -import { useSetRecoilState } from 'recoil'; import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData'; export const useHandleFavoriteDragAndDrop = () => { const { favorites } = usePrefetchedFavoritesData(); const { favoritesSorted } = useSortedFavorites(); const { updateOneRecord } = useUpdateOneRecord(); - const setOpenFavoriteFolderIds = useSetRecoilState( - openFavoriteFolderIdsState, + const setOpenFavoriteFolderIds = useSetRecoilStateV2( + openFavoriteFolderIdsStateV2, ); const openDestinationFolder = (folderId: string | null) => { diff --git a/packages/twenty-front/src/modules/favorites/states/isFavoriteFolderCreatingState.ts b/packages/twenty-front/src/modules/favorites/states/isFavoriteFolderCreatingState.ts deleted file mode 100644 index 3847d0478cc..00000000000 --- a/packages/twenty-front/src/modules/favorites/states/isFavoriteFolderCreatingState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const isFavoriteFolderCreatingState = atom({ - key: 'isFavoriteFolderCreatingState', - default: false, -}); diff --git a/packages/twenty-front/src/modules/favorites/states/isFavoriteFolderCreatingStateV2.ts b/packages/twenty-front/src/modules/favorites/states/isFavoriteFolderCreatingStateV2.ts new file mode 100644 index 00000000000..d1d742c1973 --- /dev/null +++ b/packages/twenty-front/src/modules/favorites/states/isFavoriteFolderCreatingStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const isFavoriteFolderCreatingStateV2 = createStateV2({ + key: 'isFavoriteFolderCreatingStateV2', + defaultValue: false, +}); diff --git a/packages/twenty-front/src/modules/favorites/states/openFavoriteFolderIdsState.ts b/packages/twenty-front/src/modules/favorites/states/openFavoriteFolderIdsState.ts deleted file mode 100644 index 05c6deb9379..00000000000 --- a/packages/twenty-front/src/modules/favorites/states/openFavoriteFolderIdsState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const openFavoriteFolderIdsState = atom({ - key: 'openFavoriteFolderIdsState', - default: [], -}); diff --git a/packages/twenty-front/src/modules/favorites/states/openFavoriteFolderIdsStateV2.ts b/packages/twenty-front/src/modules/favorites/states/openFavoriteFolderIdsStateV2.ts new file mode 100644 index 00000000000..0658793a2de --- /dev/null +++ b/packages/twenty-front/src/modules/favorites/states/openFavoriteFolderIdsStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const openFavoriteFolderIdsStateV2 = createStateV2({ + key: 'openFavoriteFolderIdsStateV2', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenu.tsx b/packages/twenty-front/src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenu.tsx index 32bfec5fa70..d17e8c5147b 100644 --- a/packages/twenty-front/src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenu.tsx +++ b/packages/twenty-front/src/modules/keyboard-shortcut-menu/components/KeyboardShortcutMenu.tsx @@ -1,17 +1,16 @@ -import { useRecoilValue } from 'recoil'; - import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu'; -import { isKeyboardShortcutMenuOpenedState } from '@/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedState'; +import { isKeyboardShortcutMenuOpenedStateV2 } from '@/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedStateV2'; import { KeyboardShortcutMenuOpenContent } from '@/keyboard-shortcut-menu/components/KeyboardShortcutMenuOpenContent'; import { useGlobalHotkeys } from '@/ui/utilities/hotkey/hooks/useGlobalHotkeys'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const KeyboardShortcutMenu = () => { const { toggleKeyboardShortcutMenu } = useKeyboardShortcutMenu(); - const isKeyboardShortcutMenuOpened = useRecoilValue( - isKeyboardShortcutMenuOpenedState, + const isKeyboardShortcutMenuOpened = useRecoilValueV2( + isKeyboardShortcutMenuOpenedStateV2, ); const { closeCommandMenu } = useCommandMenu(); diff --git a/packages/twenty-front/src/modules/keyboard-shortcut-menu/hooks/__tests__/useKeyboardShortcutMenu.test.tsx b/packages/twenty-front/src/modules/keyboard-shortcut-menu/hooks/__tests__/useKeyboardShortcutMenu.test.tsx index d16ea997ead..71ad5a23238 100644 --- a/packages/twenty-front/src/modules/keyboard-shortcut-menu/hooks/__tests__/useKeyboardShortcutMenu.test.tsx +++ b/packages/twenty-front/src/modules/keyboard-shortcut-menu/hooks/__tests__/useKeyboardShortcutMenu.test.tsx @@ -1,8 +1,11 @@ import { renderHook } from '@testing-library/react'; -import { act } from 'react'; -import { RecoilRoot, useRecoilValue } from 'recoil'; +import { Provider as JotaiProvider } from 'jotai'; +import { type ReactNode, act } from 'react'; +import { RecoilRoot } from 'recoil'; -import { isKeyboardShortcutMenuOpenedState } from '@/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedState'; +import { isKeyboardShortcutMenuOpenedStateV2 } from '@/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu'; @@ -24,11 +27,17 @@ jest.mock( }), ); +const Wrapper = ({ children }: { children: ReactNode }) => ( + + {children} + +); + const renderHookConfig = () => { const { result } = renderHook( () => { - const isKeyboardShortcutMenuOpened = useRecoilValue( - isKeyboardShortcutMenuOpenedState, + const isKeyboardShortcutMenuOpened = useRecoilValueV2( + isKeyboardShortcutMenuOpenedStateV2, ); return { ...useKeyboardShortcutMenu(), @@ -36,7 +45,7 @@ const renderHookConfig = () => { }; }, { - wrapper: RecoilRoot, + wrapper: Wrapper, }, ); return { result }; diff --git a/packages/twenty-front/src/modules/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu.ts b/packages/twenty-front/src/modules/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu.ts index 5aaca9dfcf5..332a1f28397 100644 --- a/packages/twenty-front/src/modules/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu.ts +++ b/packages/twenty-front/src/modules/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu.ts @@ -1,9 +1,10 @@ -import { useRecoilCallback } from 'recoil'; +import { useCallback } from 'react'; +import { isKeyboardShortcutMenuOpenedStateV2 } from '@/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedStateV2'; import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack'; import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById'; import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; -import { isKeyboardShortcutMenuOpenedState } from '@/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedState'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; export const KEYBOARD_SHORTCUT_MENU_INSTANCE_ID = 'keyboard-shortcut-menu'; @@ -12,57 +13,45 @@ export const useKeyboardShortcutMenu = () => { const { removeFocusItemFromFocusStackById } = useRemoveFocusItemFromFocusStackById(); - const openKeyboardShortcutMenu = useRecoilCallback( - ({ set }) => - () => { - set(isKeyboardShortcutMenuOpenedState, true); - pushFocusItemToFocusStack({ - focusId: KEYBOARD_SHORTCUT_MENU_INSTANCE_ID, - component: { - type: FocusComponentType.KEYBOARD_SHORTCUT_MENU, - instanceId: KEYBOARD_SHORTCUT_MENU_INSTANCE_ID, - }, - globalHotkeysConfig: { - enableGlobalHotkeysConflictingWithKeyboard: false, - enableGlobalHotkeysWithModifiers: false, - }, - }); + const openKeyboardShortcutMenu = useCallback(() => { + jotaiStore.set(isKeyboardShortcutMenuOpenedStateV2.atom, true); + pushFocusItemToFocusStack({ + focusId: KEYBOARD_SHORTCUT_MENU_INSTANCE_ID, + component: { + type: FocusComponentType.KEYBOARD_SHORTCUT_MENU, + instanceId: KEYBOARD_SHORTCUT_MENU_INSTANCE_ID, }, - [pushFocusItemToFocusStack], - ); - - const closeKeyboardShortcutMenu = useRecoilCallback( - ({ set, snapshot }) => - () => { - const isKeyboardShortcutMenuOpened = snapshot - .getLoadable(isKeyboardShortcutMenuOpenedState) - .getValue(); - - if (isKeyboardShortcutMenuOpened) { - set(isKeyboardShortcutMenuOpenedState, false); - removeFocusItemFromFocusStackById({ - focusId: KEYBOARD_SHORTCUT_MENU_INSTANCE_ID, - }); - } + globalHotkeysConfig: { + enableGlobalHotkeysConflictingWithKeyboard: false, + enableGlobalHotkeysWithModifiers: false, }, - [removeFocusItemFromFocusStackById], - ); + }); + }, [pushFocusItemToFocusStack]); - const toggleKeyboardShortcutMenu = useRecoilCallback( - ({ snapshot }) => - () => { - const isKeyboardShortcutMenuOpened = snapshot - .getLoadable(isKeyboardShortcutMenuOpenedState) - .getValue(); + const closeKeyboardShortcutMenu = useCallback(() => { + const isKeyboardShortcutMenuOpened = jotaiStore.get( + isKeyboardShortcutMenuOpenedStateV2.atom, + ); - if (isKeyboardShortcutMenuOpened === false) { - openKeyboardShortcutMenu(); - } else { - closeKeyboardShortcutMenu(); - } - }, - [closeKeyboardShortcutMenu, openKeyboardShortcutMenu], - ); + if (isKeyboardShortcutMenuOpened) { + jotaiStore.set(isKeyboardShortcutMenuOpenedStateV2.atom, false); + removeFocusItemFromFocusStackById({ + focusId: KEYBOARD_SHORTCUT_MENU_INSTANCE_ID, + }); + } + }, [removeFocusItemFromFocusStackById]); + + const toggleKeyboardShortcutMenu = useCallback(() => { + const isKeyboardShortcutMenuOpened = jotaiStore.get( + isKeyboardShortcutMenuOpenedStateV2.atom, + ); + + if (isKeyboardShortcutMenuOpened === false) { + openKeyboardShortcutMenu(); + } else { + closeKeyboardShortcutMenu(); + } + }, [closeKeyboardShortcutMenu, openKeyboardShortcutMenu]); return { toggleKeyboardShortcutMenu, diff --git a/packages/twenty-front/src/modules/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedState.ts b/packages/twenty-front/src/modules/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedState.ts deleted file mode 100644 index 443155fbee3..00000000000 --- a/packages/twenty-front/src/modules/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const isKeyboardShortcutMenuOpenedState = atom({ - key: 'keyboard-shortcut-menu/isKeyboardShortcutMenuOpenedState', - default: false, -}); diff --git a/packages/twenty-front/src/modules/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedStateV2.ts b/packages/twenty-front/src/modules/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedStateV2.ts new file mode 100644 index 00000000000..da8bb7953b8 --- /dev/null +++ b/packages/twenty-front/src/modules/keyboard-shortcut-menu/states/isKeyboardShortcutMenuOpenedStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const isKeyboardShortcutMenuOpenedStateV2 = createStateV2({ + key: 'keyboard-shortcut-menu/isKeyboardShortcutMenuOpenedStateV2', + defaultValue: false, +}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx index ae99e7f48c2..c19093ccabb 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItemFolders.tsx @@ -1,5 +1,5 @@ import { useLingui } from '@lingui/react/macro'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconFolderPlus } from 'twenty-ui/display'; import { LightIconButton } from 'twenty-ui/input'; @@ -10,7 +10,8 @@ import { NavigationMenuItemFolders } from '@/navigation-menu-item/components/Nav import { NavigationMenuItemSkeletonLoader } from '@/navigation-menu-item/components/NavigationMenuItemSkeletonLoader'; import { useNavigationMenuItemsByFolder } from '@/navigation-menu-item/hooks/useNavigationMenuItemsByFolder'; import { useSortedNavigationMenuItems } from '@/navigation-menu-item/hooks/useSortedNavigationMenuItems'; -import { isNavigationMenuItemFolderCreatingState } from '@/navigation-menu-item/states/isNavigationMenuItemFolderCreatingState'; +import { isNavigationMenuItemFolderCreatingStateV2 } from '@/navigation-menu-item/states/isNavigationMenuItemFolderCreatingStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { useIsPrefetchLoading } from '@/prefetch/hooks/useIsPrefetchLoading'; import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper'; import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; @@ -25,7 +26,7 @@ export const CurrentWorkspaceMemberNavigationMenuItemFolders = () => { const [ isNavigationMenuItemFolderCreating, setIsNavigationMenuItemFolderCreating, - ] = useRecoilState(isNavigationMenuItemFolderCreatingState); + ] = useRecoilStateV2(isNavigationMenuItemFolderCreatingStateV2); const loading = useIsPrefetchLoading(); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItems.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItems.tsx index 6dcb62fa2f2..5e9d300b483 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItems.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItems.tsx @@ -7,7 +7,7 @@ import { NavigationSections } from '@/navigation-menu-item/constants/NavigationS import { useIsDropDisabledForSection } from '@/navigation-menu-item/hooks/useIsDropDisabledForSection'; import { createPortal } from 'react-dom'; import { useLocation, useNavigate } from 'react-router-dom'; -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { IconFolder, IconFolderOpen, IconHeartOff } from 'twenty-ui/display'; import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors'; @@ -25,7 +25,8 @@ import { NavigationMenuItemDragContext } from '@/navigation-menu-item/contexts/N import { useDeleteNavigationMenuItem } from '@/navigation-menu-item/hooks/useDeleteNavigationMenuItem'; import { useDeleteNavigationMenuItemFolder } from '@/navigation-menu-item/hooks/useDeleteNavigationMenuItemFolder'; import { useRenameNavigationMenuItemFolder } from '@/navigation-menu-item/hooks/useRenameNavigationMenuItemFolder'; -import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsState'; +import { openNavigationMenuItemFolderIdsStateV2 } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { getNavigationMenuItemSecondaryLabel } from '@/navigation-menu-item/utils/getNavigationMenuItemSecondaryLabel'; import { isLocationMatchingNavigationMenuItem } from '@/navigation-menu-item/utils/isLocationMatchingNavigationMenuItem'; import { type ProcessedNavigationMenuItem } from '@/navigation-menu-item/utils/sortNavigationMenuItems'; @@ -40,7 +41,8 @@ import { NavigationDrawerInput } from '@/ui/navigation/navigation-drawer/compone import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { NavigationDrawerItemsCollapsableContainer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItemsCollapsableContainer'; import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem'; -import { currentNavigationMenuItemFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdState'; +import { currentNavigationMenuItemFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { getNavigationSubItemLeftAdornment } from '@/ui/navigation/navigation-drawer/utils/getNavigationSubItemLeftAdornment'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { isNonEmptyString } from '@sniptt/guards'; @@ -81,10 +83,10 @@ export const CurrentWorkspaceMemberNavigationMenuItems = ({ const isMobile = useIsMobile(); const [openNavigationMenuItemFolderIds, setOpenNavigationMenuItemFolderIds] = - useRecoilState(openNavigationMenuItemFolderIdsState); + useRecoilStateV2(openNavigationMenuItemFolderIdsStateV2); - const setCurrentFolderId = useSetRecoilState( - currentNavigationMenuItemFolderIdState, + const setCurrentFolderId = useSetRecoilStateV2( + currentNavigationMenuItemFolderIdStateV2, ); const isOpen = openNavigationMenuItemFolderIds.includes(folder.id); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuEditModeBar.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuEditModeBar.tsx index 906cbd643ae..3738fb212d9 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuEditModeBar.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuEditModeBar.tsx @@ -2,15 +2,16 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import { useState } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { IconCheck, useIcons } from 'twenty-ui/display'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/useNavigationMenuItemsDraftState'; import { useSaveNavigationMenuItemsDraft } from '@/navigation-menu-item/hooks/useSaveNavigationMenuItemsDraft'; -import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { isNavigationMenuInEditModeStateV2 } from '@/navigation-menu-item/states/isNavigationMenuInEditModeStateV2'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; @@ -40,14 +41,14 @@ export const NavigationMenuEditModeBar = () => { const [isSaving, setIsSaving] = useState(false); const { closeCommandMenu } = useCommandMenu(); const { enqueueErrorSnackBar } = useSnackBar(); - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); - const setSelectedNavigationMenuItemInEditMode = useSetRecoilState( - selectedNavigationMenuItemInEditModeState, + const setSelectedNavigationMenuItemInEditMode = useSetRecoilStateV2( + selectedNavigationMenuItemInEditModeStateV2, ); - const setIsNavigationMenuInEditMode = useSetRecoilState( - isNavigationMenuInEditModeState, + const setIsNavigationMenuInEditMode = useSetRecoilStateV2( + isNavigationMenuInEditModeStateV2, ); const { saveDraft } = useSaveNavigationMenuItemsDraft(); const { isDirty } = useNavigationMenuItemsDraftState(); @@ -58,8 +59,8 @@ export const NavigationMenuEditModeBar = () => { setIsNavigationMenuInEditMode(false); }; - const isNavigationMenuInEditMode = useRecoilValue( - isNavigationMenuInEditModeState, + const isNavigationMenuInEditMode = useRecoilValueV2( + isNavigationMenuInEditModeStateV2, ); const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemBackButton.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemBackButton.tsx index bea21386dd1..ea5f876b936 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemBackButton.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemBackButton.tsx @@ -1,9 +1,9 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { useSetRecoilState } from 'recoil'; import { IconX } from 'twenty-ui/display'; -import { currentNavigationMenuItemFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdState'; +import { currentNavigationMenuItemFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; const StyledBackButton = styled.button` display: flex; @@ -36,8 +36,8 @@ export const NavigationMenuItemBackButton = ({ folderName, }: NavigationMenuItemBackButtonProps) => { const theme = useTheme(); - const setCurrentFolderId = useSetRecoilState( - currentNavigationMenuItemFolderIdState, + const setCurrentFolderId = useSetRecoilStateV2( + currentNavigationMenuItemFolderIdStateV2, ); const handleClick = (e: React.MouseEvent) => { diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemFolders.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemFolders.tsx index 84f09a2afdc..6ba2e5c4d44 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemFolders.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemFolders.tsx @@ -1,11 +1,11 @@ import { useState } from 'react'; -import { useRecoilState } from 'recoil'; import { IconFolder } from 'twenty-ui/display'; import { CurrentWorkspaceMemberNavigationMenuItems } from '@/navigation-menu-item/components/CurrentWorkspaceMemberNavigationMenuItems'; import { useCreateNavigationMenuItemFolder } from '@/navigation-menu-item/hooks/useCreateNavigationMenuItemFolder'; import { useNavigationMenuItemsByFolder } from '@/navigation-menu-item/hooks/useNavigationMenuItemsByFolder'; -import { isNavigationMenuItemFolderCreatingState } from '@/navigation-menu-item/states/isNavigationMenuItemFolderCreatingState'; +import { isNavigationMenuItemFolderCreatingStateV2 } from '@/navigation-menu-item/states/isNavigationMenuItemFolderCreatingStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper'; import { NavigationDrawerInput } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerInput'; @@ -25,7 +25,7 @@ export const NavigationMenuItemFolders = ({ const [ isNavigationMenuItemFolderCreating, setIsNavigationMenuItemFolderCreating, - ] = useRecoilState(isNavigationMenuItemFolderCreatingState); + ] = useRecoilStateV2(isNavigationMenuItemFolderCreatingStateV2); const handleNavigationMenuItemFolderNameChange = (value: string) => { setNewFolderName(value); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItems.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItems.tsx index 044eb62137c..bd6eb530e2a 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItems.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItems.tsx @@ -1,11 +1,5 @@ import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; -import { - useRecoilCallback, - useRecoilState, - useRecoilValue, - useSetRecoilState, -} from 'recoil'; import { IconFolder, IconLink, @@ -23,18 +17,23 @@ import { type NavigationMenuItemClickParams, useWorkspaceSectionItems, } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems'; -import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState'; +import { isNavigationMenuInEditModeStateV2 } from '@/navigation-menu-item/states/isNavigationMenuInEditModeStateV2'; import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; import { filterWorkspaceNavigationMenuItems } from '@/navigation-menu-item/utils/filterWorkspaceNavigationMenuItems'; -import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsState'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { openNavigationMenuItemFolderIdsStateV2 } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader'; import { NavigationDrawerSectionForWorkspaceItems } from '@/object-metadata/components/NavigationDrawerSectionForWorkspaceItems'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { useIsPrefetchLoading } from '@/prefetch/hooks/useIsPrefetchLoading'; import { prefetchNavigationMenuItemsState } from '@/prefetch/states/prefetchNavigationMenuItemsState'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; +import { useRecoilCallback } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; const StyledRightIconsContainer = styled.div` @@ -46,7 +45,7 @@ const StyledRightIconsContainer = styled.div` export const WorkspaceNavigationMenuItems = () => { const items = useWorkspaceSectionItems(); const enterEditMode = useRecoilCallback( - ({ set, snapshot }) => + ({ snapshot }) => () => { const prefetchNavigationMenuItems = snapshot .getLoadable(prefetchNavigationMenuItemsState) @@ -54,23 +53,26 @@ export const WorkspaceNavigationMenuItems = () => { const workspaceNavigationMenuItems = filterWorkspaceNavigationMenuItems( prefetchNavigationMenuItems, ); - set(navigationMenuItemsDraftState, workspaceNavigationMenuItems); - set(isNavigationMenuInEditModeState, true); + jotaiStore.set( + navigationMenuItemsDraftStateV2.atom, + workspaceNavigationMenuItems, + ); + jotaiStore.set(isNavigationMenuInEditModeStateV2.atom, true); }, [], ); const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled( FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED, ); - const isNavigationMenuInEditMode = useRecoilValue( - isNavigationMenuInEditModeState, + const isNavigationMenuInEditMode = useRecoilValueV2( + isNavigationMenuInEditModeStateV2, ); const [ selectedNavigationMenuItemInEditMode, setSelectedNavigationMenuItemInEditMode, - ] = useRecoilState(selectedNavigationMenuItemInEditModeState); - const setOpenNavigationMenuItemFolderIds = useSetRecoilState( - openNavigationMenuItemFolderIdsState, + ] = useRecoilStateV2(selectedNavigationMenuItemInEditModeStateV2); + const setOpenNavigationMenuItemFolderIds = useSetRecoilStateV2( + openNavigationMenuItemFolderIdsStateV2, ); const { navigateCommandMenu } = useNavigateCommandMenu(); const { openNavigationMenuItemInCommandMenu } = diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItemsFolder.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItemsFolder.tsx index 1aa67d0e856..f1f79e35fe1 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItemsFolder.tsx +++ b/packages/twenty-front/src/modules/navigation-menu-item/components/WorkspaceNavigationMenuItemsFolder.tsx @@ -7,7 +7,7 @@ import { isDefined } from 'twenty-shared/utils'; import { useIsDropDisabledForSection } from '@/navigation-menu-item/hooks/useIsDropDisabledForSection'; import { useLocation, useNavigate } from 'react-router-dom'; -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { IconFolder, IconFolderOpen } from 'twenty-ui/display'; import { AnimatedExpandableContainer } from 'twenty-ui/layout'; import { useIsMobile } from 'twenty-ui/utilities'; @@ -19,7 +19,8 @@ import { NavigationMenuItemDroppableIds } from '@/navigation-menu-item/constants import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType'; import { NavigationMenuItemDragContext } from '@/navigation-menu-item/contexts/NavigationMenuItemDragContext'; import { type NavigationMenuItemClickParams } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems'; -import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsState'; +import { openNavigationMenuItemFolderIdsStateV2 } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors'; import { getNavigationMenuItemSecondaryLabel } from '@/navigation-menu-item/utils/getNavigationMenuItemSecondaryLabel'; import { getObjectMetadataForNavigationMenuItem } from '@/navigation-menu-item/utils/getObjectMetadataForNavigationMenuItem'; @@ -30,7 +31,8 @@ import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableIt import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { NavigationDrawerItemsCollapsableContainer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItemsCollapsableContainer'; import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem'; -import { currentNavigationMenuItemFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdState'; +import { currentNavigationMenuItemFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { getNavigationSubItemLeftAdornment } from '@/ui/navigation/navigation-drawer/utils/getNavigationSubItemLeftAdornment'; import { coreViewsState } from '@/views/states/coreViewState'; import { ViewKey } from '@/views/types/ViewKey'; @@ -93,10 +95,10 @@ export const WorkspaceNavigationMenuItemsFolder = ({ const isMobile = useIsMobile(); const [openNavigationMenuItemFolderIds, setOpenNavigationMenuItemFolderIds] = - useRecoilState(openNavigationMenuItemFolderIdsState); + useRecoilStateV2(openNavigationMenuItemFolderIdsStateV2); - const setCurrentFolderId = useSetRecoilState( - currentNavigationMenuItemFolderIdState, + const setCurrentFolderId = useSetRecoilStateV2( + currentNavigationMenuItemFolderIdStateV2, ); const isOpen = openNavigationMenuItemFolderIds.includes(folderId); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddFolderToNavigationMenuDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddFolderToNavigationMenuDraft.ts index 3f13c4147bb..e0a9107dc24 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddFolderToNavigationMenuDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddFolderToNavigationMenuDraft.ts @@ -1,14 +1,14 @@ -import { useSetRecoilState } from 'recoil'; import { v4 } from 'uuid'; import { isDefined } from 'twenty-shared/utils'; import type { NavigationMenuItem } from '~/generated-metadata/graphql'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { computeInsertIndexAndPosition } from '@/navigation-menu-item/utils/computeInsertIndexAndPosition'; export const useAddFolderToNavigationMenuDraft = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const addFolderToDraft = ( diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddLinkToNavigationMenuDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddLinkToNavigationMenuDraft.ts index 87dfdd9951d..e65c814979e 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddLinkToNavigationMenuDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddLinkToNavigationMenuDraft.ts @@ -1,15 +1,15 @@ -import { useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { v4 } from 'uuid'; import type { NavigationMenuItem } from '~/generated-metadata/graphql'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { computeInsertIndexAndPosition } from '@/navigation-menu-item/utils/computeInsertIndexAndPosition'; import { normalizeUrl } from '@/navigation-menu-item/utils/normalizeUrl'; export const useAddLinkToNavigationMenuDraft = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const addLinkToDraft = ( diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddObjectToNavigationMenuDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddObjectToNavigationMenuDraft.ts index 9ab0959177e..b687c9ca6d3 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddObjectToNavigationMenuDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddObjectToNavigationMenuDraft.ts @@ -1,14 +1,14 @@ -import { useSetRecoilState } from 'recoil'; import { v4 } from 'uuid'; import { isDefined } from 'twenty-shared/utils'; import type { NavigationMenuItem } from '~/generated-metadata/graphql'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { computeInsertIndexAndPosition } from '@/navigation-menu-item/utils/computeInsertIndexAndPosition'; export const useAddObjectToNavigationMenuDraft = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const addObjectToDraft = ( diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddRecordToNavigationMenuDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddRecordToNavigationMenuDraft.ts index 2bfd929fd80..35b3ada9d6b 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddRecordToNavigationMenuDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddRecordToNavigationMenuDraft.ts @@ -1,10 +1,11 @@ -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { v4 } from 'uuid'; import { isDefined } from 'twenty-shared/utils'; import type { NavigationMenuItem } from '~/generated-metadata/graphql'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { computeInsertIndexAndPosition } from '@/navigation-menu-item/utils/computeInsertIndexAndPosition'; type SearchRecord = { @@ -19,8 +20,8 @@ type SearchRecordWithOptionalMetadataId = SearchRecord & { }; export const useAddRecordToNavigationMenuDraft = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const objectMetadataItems = useRecoilValue(objectMetadataItemsState); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddViewToNavigationMenuDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddViewToNavigationMenuDraft.ts index 54a45375438..53971936460 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddViewToNavigationMenuDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useAddViewToNavigationMenuDraft.ts @@ -1,14 +1,14 @@ -import { useSetRecoilState } from 'recoil'; import { v4 } from 'uuid'; import { isDefined } from 'twenty-shared/utils'; import type { NavigationMenuItem } from '~/generated-metadata/graphql'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { computeInsertIndexAndPosition } from '@/navigation-menu-item/utils/computeInsertIndexAndPosition'; export const useAddViewToNavigationMenuDraft = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const addViewToDraft = ( diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useDraftNavigationMenuItems.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useDraftNavigationMenuItems.ts index 0897f96e4f5..f87b69b087f 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useDraftNavigationMenuItems.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useDraftNavigationMenuItems.ts @@ -1,12 +1,11 @@ -import { useRecoilValue } from 'recoil'; - import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/useNavigationMenuItemsDraftState'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const useDraftNavigationMenuItems = () => { const { workspaceNavigationMenuItems } = useNavigationMenuItemsDraftState(); - const navigationMenuItemsDraft = useRecoilValue( - navigationMenuItemsDraftState, + const navigationMenuItemsDraft = useRecoilValueV2( + navigationMenuItemsDraftStateV2, ); const currentDraft = navigationMenuItemsDraft ?? workspaceNavigationMenuItems; diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleAddToNavigationDrop.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleAddToNavigationDrop.ts index ae4f7740616..a624e1abc0c 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleAddToNavigationDrop.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleAddToNavigationDrop.ts @@ -1,6 +1,6 @@ import type { DropResult, ResponderProvided } from '@hello-pangea/dnd'; import { t } from '@lingui/core/macro'; -import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilCallback, useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconFolder, IconLink, useIcons } from 'twenty-ui/display'; @@ -13,15 +13,17 @@ import { useAddRecordToNavigationMenuDraft } from '@/navigation-menu-item/hooks/ import { useAddViewToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddViewToNavigationMenuDraft'; import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/useNavigationMenuItemsDraftState'; import { useOpenNavigationMenuItemInCommandMenu } from '@/navigation-menu-item/hooks/useOpenNavigationMenuItemInCommandMenu'; -import { addToNavPayloadRegistryState } from '@/navigation-menu-item/states/addToNavPayloadRegistryState'; -import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; -import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsState'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { addToNavPayloadRegistryStateV2 } from '@/navigation-menu-item/states/addToNavPayloadRegistryStateV2'; +import { isNavigationMenuInEditModeStateV2 } from '@/navigation-menu-item/states/isNavigationMenuInEditModeStateV2'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { openNavigationMenuItemFolderIdsStateV2 } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { isWorkspaceDroppableId } from '@/navigation-menu-item/utils/isWorkspaceDroppableId'; import { validateAndExtractWorkspaceFolderId } from '@/navigation-menu-item/utils/validateAndExtractWorkspaceFolderId'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; -import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue'; import { coreViewsState } from '@/views/states/coreViewState'; import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView'; @@ -32,165 +34,160 @@ export const useHandleAddToNavigationDrop = () => { const { addFolderToDraft } = useAddFolderToNavigationMenuDraft(); const { addLinkToDraft } = useAddLinkToNavigationMenuDraft(); const { workspaceNavigationMenuItems } = useNavigationMenuItemsDraftState(); - const navigationMenuItemsDraft = useRecoilValue( - navigationMenuItemsDraftState, + const navigationMenuItemsDraft = useRecoilValueV2( + navigationMenuItemsDraftStateV2, ); const { openNavigationMenuItemInCommandMenu } = useOpenNavigationMenuItemInCommandMenu(); const { objectMetadataItems } = useObjectMetadataItems(); const coreViews = useRecoilValue(coreViewsState); const { getIcon } = useIcons(); - const setSelectedNavigationMenuItemInEditMode = useSetRecoilState( - selectedNavigationMenuItemInEditModeState, + const setSelectedNavigationMenuItemInEditMode = useSetRecoilStateV2( + selectedNavigationMenuItemInEditModeStateV2, ); - const setIsNavigationMenuInEditMode = useSetRecoilState( - isNavigationMenuInEditModeState, + const setIsNavigationMenuInEditMode = useSetRecoilStateV2( + isNavigationMenuInEditModeStateV2, ); - const setOpenNavigationMenuItemFolderIds = useSetRecoilState( - openNavigationMenuItemFolderIdsState, + const setOpenNavigationMenuItemFolderIds = useSetRecoilStateV2( + openNavigationMenuItemFolderIdsStateV2, ); const handleAddToNavigationDrop = useRecoilCallback( - ({ snapshot }) => - (result: DropResult, _provided: ResponderProvided) => { - const { source, destination, draggableId } = result; - if ( - source.droppableId !== ADD_TO_NAV_SOURCE_DROPPABLE_ID || - !destination || - !isWorkspaceDroppableId(destination.droppableId) - ) { - return; - } + () => (result: DropResult, _provided: ResponderProvided) => { + const { source, destination, draggableId } = result; + if ( + source.droppableId !== ADD_TO_NAV_SOURCE_DROPPABLE_ID || + !destination || + !isWorkspaceDroppableId(destination.droppableId) + ) { + return; + } - const payload = - getSnapshotValue(snapshot, addToNavPayloadRegistryState).get( - draggableId, - ) ?? null; - if (!payload) { - return; - } + const payload = + jotaiStore.get(addToNavPayloadRegistryStateV2.atom).get(draggableId) ?? + null; + if (!payload) { + return; + } - const currentDraft = isDefined(navigationMenuItemsDraft) - ? navigationMenuItemsDraft - : workspaceNavigationMenuItems; - const folderId = validateAndExtractWorkspaceFolderId( - destination.droppableId, + const currentDraft = isDefined(navigationMenuItemsDraft) + ? navigationMenuItemsDraft + : workspaceNavigationMenuItems; + const folderId = validateAndExtractWorkspaceFolderId( + destination.droppableId, + ); + const index = destination.index; + + if (payload.type === NavigationMenuItemType.FOLDER && folderId !== null) { + return; + } + + if (isDefined(folderId)) { + setOpenNavigationMenuItemFolderIds((current) => + current.includes(folderId) ? current : [...current, folderId], ); - const index = destination.index; + } - if ( - payload.type === NavigationMenuItemType.FOLDER && - folderId !== null - ) { + const openEditForNewNavItem = ( + newItemId: string, + options: Parameters[0], + ) => { + setIsNavigationMenuInEditMode(true); + setSelectedNavigationMenuItemInEditMode(newItemId); + openNavigationMenuItemInCommandMenu(options); + }; + + switch (payload.type) { + case NavigationMenuItemType.FOLDER: { + const newFolderId = addFolderToDraft( + payload.name, + currentDraft, + null, + index, + ); + openEditForNewNavItem(newFolderId, { + pageTitle: t`Edit folder`, + pageIcon: IconFolder, + focusTitleInput: true, + }); return; } - - if (isDefined(folderId)) { - setOpenNavigationMenuItemFolderIds((current) => - current.includes(folderId) ? current : [...current, folderId], + case NavigationMenuItemType.LINK: { + const newLinkId = addLinkToDraft( + payload.name || t`Link label`, + payload.link, + currentDraft, + folderId, + index, ); + openEditForNewNavItem(newLinkId, { + pageTitle: t`Edit link`, + pageIcon: IconLink, + focusTitleInput: true, + }); + return; } - - const openEditForNewNavItem = ( - newItemId: string, - options: Parameters[0], - ) => { - setIsNavigationMenuInEditMode(true); - setSelectedNavigationMenuItemInEditMode(newItemId); - openNavigationMenuItemInCommandMenu(options); - }; - - switch (payload.type) { - case NavigationMenuItemType.FOLDER: { - const newFolderId = addFolderToDraft( - payload.name, - currentDraft, - null, - index, - ); - openEditForNewNavItem(newFolderId, { - pageTitle: t`Edit folder`, - pageIcon: IconFolder, - focusTitleInput: true, - }); - return; - } - case NavigationMenuItemType.LINK: { - const newLinkId = addLinkToDraft( - payload.name || t`Link label`, - payload.link, - currentDraft, - folderId, - index, - ); - openEditForNewNavItem(newLinkId, { - pageTitle: t`Edit link`, - pageIcon: IconLink, - focusTitleInput: true, - }); - return; - } - case NavigationMenuItemType.OBJECT: { - const newItemId = addObjectToDraft( - payload.objectMetadataId, - payload.defaultViewId, - currentDraft, - folderId, - index, - ); - const objectMetadataItem = objectMetadataItems.find( - (item) => item.id === payload.objectMetadataId, - ); - openEditForNewNavItem(newItemId, { - pageTitle: objectMetadataItem?.labelPlural ?? payload.label, - pageIcon: objectMetadataItem - ? getIcon(objectMetadataItem.icon) - : IconFolder, - }); - return; - } - case NavigationMenuItemType.VIEW: { - const newItemId = addViewToDraft( - payload.viewId, - currentDraft, - folderId, - index, - ); - const views = coreViews.map(convertCoreViewToView); - const view = views.find((v) => v.id === payload.viewId); - openEditForNewNavItem(newItemId, { - pageTitle: view?.name ?? payload.label, - pageIcon: view ? getIcon(view.icon) : IconFolder, - }); - return; - } - case NavigationMenuItemType.RECORD: { - const newItemId = addRecordToDraft( - { - recordId: payload.recordId, - objectMetadataId: payload.objectMetadataId, - objectNameSingular: payload.objectNameSingular, - label: payload.label, - imageUrl: payload.imageUrl, - }, - currentDraft, - folderId, - index, - ); - if (!isDefined(newItemId)) return; - const objectMetadataItem = objectMetadataItems.find( - (item) => item.id === payload.objectMetadataId, - ); - openEditForNewNavItem(newItemId, { - pageTitle: payload.label, - pageIcon: objectMetadataItem - ? getIcon(objectMetadataItem.icon) - : IconFolder, - }); - return; - } + case NavigationMenuItemType.OBJECT: { + const newItemId = addObjectToDraft( + payload.objectMetadataId, + payload.defaultViewId, + currentDraft, + folderId, + index, + ); + const objectMetadataItem = objectMetadataItems.find( + (item) => item.id === payload.objectMetadataId, + ); + openEditForNewNavItem(newItemId, { + pageTitle: objectMetadataItem?.labelPlural ?? payload.label, + pageIcon: objectMetadataItem + ? getIcon(objectMetadataItem.icon) + : IconFolder, + }); + return; } - }, + case NavigationMenuItemType.VIEW: { + const newItemId = addViewToDraft( + payload.viewId, + currentDraft, + folderId, + index, + ); + const views = coreViews.map(convertCoreViewToView); + const view = views.find((v) => v.id === payload.viewId); + openEditForNewNavItem(newItemId, { + pageTitle: view?.name ?? payload.label, + pageIcon: view ? getIcon(view.icon) : IconFolder, + }); + return; + } + case NavigationMenuItemType.RECORD: { + const newItemId = addRecordToDraft( + { + recordId: payload.recordId, + objectMetadataId: payload.objectMetadataId, + objectNameSingular: payload.objectNameSingular, + label: payload.label, + imageUrl: payload.imageUrl, + }, + currentDraft, + folderId, + index, + ); + if (!isDefined(newItemId)) return; + const objectMetadataItem = objectMetadataItems.find( + (item) => item.id === payload.objectMetadataId, + ); + openEditForNewNavItem(newItemId, { + pageTitle: payload.label, + pageIcon: objectMetadataItem + ? getIcon(objectMetadataItem.icon) + : IconFolder, + }); + return; + } + } + }, [ addFolderToDraft, addLinkToDraft, diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleNavigationMenuItemDragAndDrop.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleNavigationMenuItemDragAndDrop.ts index cd116f3efa4..ca8c07c94d7 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleNavigationMenuItemDragAndDrop.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleNavigationMenuItemDragAndDrop.ts @@ -1,11 +1,11 @@ import { type OnDragEndResponder } from '@hello-pangea/dnd'; -import { useSetRecoilState } from 'recoil'; import { NavigationMenuItemDroppableIds } from '@/navigation-menu-item/constants/NavigationMenuItemDroppableIds'; import { isWorkspaceDroppableId } from '@/navigation-menu-item/utils/isWorkspaceDroppableId'; import { useSortedNavigationMenuItems } from '@/navigation-menu-item/hooks/useSortedNavigationMenuItems'; import { useUpdateNavigationMenuItem } from '@/navigation-menu-item/hooks/useUpdateNavigationMenuItem'; -import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsState'; +import { openNavigationMenuItemFolderIdsStateV2 } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { calculateNewPosition } from '@/ui/layout/draggable-list/utils/calculateNewPosition'; import { FOLDER_DROPPABLE_IDS } from '@/ui/layout/draggable-list/utils/folderDroppableIds'; import { validateAndExtractFolderId } from '@/ui/layout/draggable-list/utils/validateAndExtractFolderId'; @@ -16,8 +16,8 @@ export const useHandleNavigationMenuItemDragAndDrop = () => { const { navigationMenuItems } = usePrefetchedNavigationMenuItemsData(); const { navigationMenuItemsSorted } = useSortedNavigationMenuItems(); const { updateNavigationMenuItem } = useUpdateNavigationMenuItem(); - const setOpenNavigationMenuItemFolderIds = useSetRecoilState( - openNavigationMenuItemFolderIdsState, + const setOpenNavigationMenuItemFolderIds = useSetRecoilStateV2( + openNavigationMenuItemFolderIdsStateV2, ); const openDestinationFolder = (folderId: string | null) => { diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleWorkspaceNavigationMenuItemDragAndDrop.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleWorkspaceNavigationMenuItemDragAndDrop.ts index b1e3e3e5864..1eecb2044bb 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleWorkspaceNavigationMenuItemDragAndDrop.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useHandleWorkspaceNavigationMenuItemDragAndDrop.ts @@ -1,11 +1,12 @@ import { type OnDragEndResponder } from '@hello-pangea/dnd'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; import { type NavigationMenuItem } from '~/generated-metadata/graphql'; import { NavigationMenuItemDroppableIds } from '@/navigation-menu-item/constants/NavigationMenuItemDroppableIds'; -import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; -import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsState'; +import { isNavigationMenuInEditModeStateV2 } from '@/navigation-menu-item/states/isNavigationMenuInEditModeStateV2'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { openNavigationMenuItemFolderIdsStateV2 } from '@/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { matchesWorkspaceFolderId, validateAndExtractWorkspaceFolderId, @@ -17,17 +18,17 @@ import { usePrefetchedNavigationMenuItemsData } from './usePrefetchedNavigationM export const useHandleWorkspaceNavigationMenuItemDragAndDrop = () => { const { workspaceNavigationMenuItems } = usePrefetchedNavigationMenuItemsData(); - const isNavigationMenuInEditMode = useRecoilValue( - isNavigationMenuInEditModeState, + const isNavigationMenuInEditMode = useRecoilValueV2( + isNavigationMenuInEditModeStateV2, ); - const navigationMenuItemsDraft = useRecoilValue( - navigationMenuItemsDraftState, + const navigationMenuItemsDraft = useRecoilValueV2( + navigationMenuItemsDraftStateV2, ); - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); - const setOpenNavigationMenuItemFolderIds = useSetRecoilState( - openNavigationMenuItemFolderIdsState, + const setOpenNavigationMenuItemFolderIds = useSetRecoilStateV2( + openNavigationMenuItemFolderIdsStateV2, ); const openDestinationFolder = (folderId: string | null) => { diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useNavigationMenuItemMoveRemove.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useNavigationMenuItemMoveRemove.ts index da5935db33a..d69d3a04fe2 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useNavigationMenuItemMoveRemove.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useNavigationMenuItemMoveRemove.ts @@ -1,8 +1,8 @@ -import { useSetRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import type { NavigationMenuItem } from '~/generated-metadata/graphql'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { isNavigationMenuItemFolder } from '@/navigation-menu-item/utils/isNavigationMenuItemFolder'; const swapPositionsInDraft = ( @@ -21,8 +21,8 @@ const swapPositionsInDraft = ( }); export const useNavigationMenuItemMoveRemove = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const moveUp = (navigationMenuItemId: string) => { diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useNavigationMenuItemsDraftState.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useNavigationMenuItemsDraftState.ts index ae6fb67d626..cee52625bf8 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useNavigationMenuItemsDraftState.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useNavigationMenuItemsDraftState.ts @@ -2,20 +2,21 @@ import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; -import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState'; +import { isNavigationMenuInEditModeStateV2 } from '@/navigation-menu-item/states/isNavigationMenuInEditModeStateV2'; import { filterWorkspaceNavigationMenuItems } from '@/navigation-menu-item/utils/filterWorkspaceNavigationMenuItems'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; import { prefetchNavigationMenuItemsState } from '@/prefetch/states/prefetchNavigationMenuItemsState'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const useNavigationMenuItemsDraftState = () => { - const isNavigationMenuInEditMode = useRecoilValue( - isNavigationMenuInEditModeState, + const isNavigationMenuInEditMode = useRecoilValueV2( + isNavigationMenuInEditModeStateV2, ); const prefetchNavigationMenuItems = useRecoilValue( prefetchNavigationMenuItemsState, ); - const navigationMenuItemsDraft = useRecoilValue( - navigationMenuItemsDraftState, + const navigationMenuItemsDraft = useRecoilValueV2( + navigationMenuItemsDraftStateV2, ); const workspaceNavigationMenuItemsFromPrefetch = diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData.ts index 167f8f6858f..fdfa0258b28 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData.ts @@ -1,8 +1,9 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { isNavigationMenuInEditModeStateV2 } from '@/navigation-menu-item/states/isNavigationMenuInEditModeStateV2'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; import { filterWorkspaceNavigationMenuItems } from '@/navigation-menu-item/utils/filterWorkspaceNavigationMenuItems'; import { prefetchNavigationMenuItemsState } from '@/prefetch/states/prefetchNavigationMenuItemsState'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { type NavigationMenuItem } from '~/generated-metadata/graphql'; @@ -20,11 +21,11 @@ export const usePrefetchedNavigationMenuItemsData = const prefetchNavigationMenuItems = useRecoilValue( prefetchNavigationMenuItemsState, ); - const isNavigationMenuInEditMode = useRecoilValue( - isNavigationMenuInEditModeState, + const isNavigationMenuInEditMode = useRecoilValueV2( + isNavigationMenuInEditModeStateV2, ); - const navigationMenuItemsDraft = useRecoilValue( - navigationMenuItemsDraftState, + const navigationMenuItemsDraft = useRecoilValueV2( + navigationMenuItemsDraftStateV2, ); const navigationMenuItems = prefetchNavigationMenuItems.filter((item) => diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useSaveNavigationMenuItemsDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useSaveNavigationMenuItemsDraft.ts index 4bde76119a7..529eb105e0c 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useSaveNavigationMenuItemsDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useSaveNavigationMenuItemsDraft.ts @@ -5,10 +5,11 @@ import { useCreateNavigationMenuItemMutation } from '~/generated-metadata/graphq import { useDeleteNavigationMenuItem } from '@/navigation-menu-item/hooks/useDeleteNavigationMenuItem'; import { useUpdateNavigationMenuItem } from '@/navigation-menu-item/hooks/useUpdateNavigationMenuItem'; -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; import { filterWorkspaceNavigationMenuItems } from '@/navigation-menu-item/utils/filterWorkspaceNavigationMenuItems'; import { isNavigationMenuItemFolder } from '@/navigation-menu-item/utils/isNavigationMenuItemFolder'; import { isNavigationMenuItemLink } from '@/navigation-menu-item/utils/isNavigationMenuItemLink'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { prefetchNavigationMenuItemsState } from '@/prefetch/states/prefetchNavigationMenuItemsState'; export const useSaveNavigationMenuItemsDraft = () => { @@ -22,9 +23,7 @@ export const useSaveNavigationMenuItemsDraft = () => { const saveDraft = useRecoilCallback( ({ snapshot }) => async () => { - const draft = snapshot - .getLoadable(navigationMenuItemsDraftState) - .getValue(); + const draft = jotaiStore.get(navigationMenuItemsDraftStateV2.atom); const prefetch = snapshot .getLoadable(prefetchNavigationMenuItemsState) .getValue(); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItem.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItem.ts index 4689de6c29d..c6f705b410a 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItem.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItem.ts @@ -1,11 +1,10 @@ -import { useRecoilValue } from 'recoil'; - import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems'; -import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState'; +import { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; export const useSelectedNavigationMenuItemEditItem = () => { - const selectedNavigationMenuItemInEditMode = useRecoilValue( - selectedNavigationMenuItemInEditModeState, + const selectedNavigationMenuItemInEditMode = useRecoilValueV2( + selectedNavigationMenuItemInEditModeStateV2, ); const items = useWorkspaceSectionItems(); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateFolderNameInDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateFolderNameInDraft.ts index ba379234620..b43517ff710 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateFolderNameInDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateFolderNameInDraft.ts @@ -1,11 +1,10 @@ -import { useSetRecoilState } from 'recoil'; - -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { isNavigationMenuItemFolder } from '@/navigation-menu-item/utils/isNavigationMenuItemFolder'; export const useUpdateFolderNameInDraft = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const updateFolderNameInDraft = (folderId: string, name: string) => { diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateLinkInDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateLinkInDraft.ts index 494dce2677e..b985a098070 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateLinkInDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateLinkInDraft.ts @@ -1,11 +1,10 @@ -import { useSetRecoilState } from 'recoil'; - -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { isNavigationMenuItemLink } from '@/navigation-menu-item/utils/isNavigationMenuItemLink'; export const useUpdateLinkInDraft = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const updateLinkInDraft = ( diff --git a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateViewInDraft.ts b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateViewInDraft.ts index 0328fed7ce8..c4a190d9427 100644 --- a/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateViewInDraft.ts +++ b/packages/twenty-front/src/modules/navigation-menu-item/hooks/useUpdateViewInDraft.ts @@ -1,11 +1,10 @@ -import { useSetRecoilState } from 'recoil'; - -import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState'; +import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/navigationMenuItemsDraftStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { type View } from '@/views/types/View'; export const useUpdateViewInDraft = () => { - const setNavigationMenuItemsDraft = useSetRecoilState( - navigationMenuItemsDraftState, + const setNavigationMenuItemsDraft = useSetRecoilStateV2( + navigationMenuItemsDraftStateV2, ); const updateViewInDraft = (navigationMenuItemId: string, view: View) => { diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/addMenuItemInsertionContextState.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/addMenuItemInsertionContextState.ts deleted file mode 100644 index e844385f191..00000000000 --- a/packages/twenty-front/src/modules/navigation-menu-item/states/addMenuItemInsertionContextState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { atom } from 'recoil'; - -import type { AddMenuItemInsertionContext } from '@/navigation-menu-item/types/AddMenuItemInsertionContext'; - -export const addMenuItemInsertionContextState = - atom({ - key: 'addMenuItemInsertionContextState', - default: null, - }); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/addMenuItemInsertionContextStateV2.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/addMenuItemInsertionContextStateV2.ts new file mode 100644 index 00000000000..60d5303674f --- /dev/null +++ b/packages/twenty-front/src/modules/navigation-menu-item/states/addMenuItemInsertionContextStateV2.ts @@ -0,0 +1,9 @@ +import type { AddMenuItemInsertionContext } from '@/navigation-menu-item/types/AddMenuItemInsertionContext'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const addMenuItemInsertionContextStateV2 = + createStateV2({ + key: 'addMenuItemInsertionContextStateV2', + defaultValue: null, + }); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/addToNavPayloadRegistryState.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/addToNavPayloadRegistryState.ts deleted file mode 100644 index d8d199b0add..00000000000 --- a/packages/twenty-front/src/modules/navigation-menu-item/states/addToNavPayloadRegistryState.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { atom } from 'recoil'; - -import type { AddToNavigationDragPayload } from '@/navigation-menu-item/types/add-to-navigation-drag-payload'; - -export const addToNavPayloadRegistryState = atom< - Map ->({ - key: 'navigation-menu-item/addToNavPayloadRegistryState', - default: new Map(), -}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/addToNavPayloadRegistryStateV2.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/addToNavPayloadRegistryStateV2.ts new file mode 100644 index 00000000000..57b6585e133 --- /dev/null +++ b/packages/twenty-front/src/modules/navigation-menu-item/states/addToNavPayloadRegistryStateV2.ts @@ -0,0 +1,10 @@ +import type { AddToNavigationDragPayload } from '@/navigation-menu-item/types/add-to-navigation-drag-payload'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const addToNavPayloadRegistryStateV2 = createStateV2< + Map +>({ + key: 'navigation-menu-item/addToNavPayloadRegistryStateV2', + defaultValue: new Map(), +}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuInEditModeState.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuInEditModeState.ts deleted file mode 100644 index 1436f18e324..00000000000 --- a/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuInEditModeState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const isNavigationMenuInEditModeState = atom({ - key: 'isNavigationMenuInEditModeState', - default: false, -}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuInEditModeStateV2.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuInEditModeStateV2.ts new file mode 100644 index 00000000000..2dff03a7832 --- /dev/null +++ b/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuInEditModeStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const isNavigationMenuInEditModeStateV2 = createStateV2({ + key: 'isNavigationMenuInEditModeStateV2', + defaultValue: false, +}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuItemFolderCreatingState.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuItemFolderCreatingState.ts deleted file mode 100644 index 36e8c57b58d..00000000000 --- a/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuItemFolderCreatingState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const isNavigationMenuItemFolderCreatingState = atom({ - key: 'isNavigationMenuItemFolderCreatingState', - default: false, -}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuItemFolderCreatingStateV2.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuItemFolderCreatingStateV2.ts new file mode 100644 index 00000000000..7749922767f --- /dev/null +++ b/packages/twenty-front/src/modules/navigation-menu-item/states/isNavigationMenuItemFolderCreatingStateV2.ts @@ -0,0 +1,8 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const isNavigationMenuItemFolderCreatingStateV2 = createStateV2( + { + key: 'isNavigationMenuItemFolderCreatingStateV2', + defaultValue: false, + }, +); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/navigationMenuItemsDraftState.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/navigationMenuItemsDraftState.ts deleted file mode 100644 index 7673331d235..00000000000 --- a/packages/twenty-front/src/modules/navigation-menu-item/states/navigationMenuItemsDraftState.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { atom } from 'recoil'; -import { type NavigationMenuItem } from '~/generated-metadata/graphql'; - -export const navigationMenuItemsDraftState = atom({ - key: 'navigationMenuItemsDraftState', - default: null, -}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/navigationMenuItemsDraftStateV2.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/navigationMenuItemsDraftStateV2.ts new file mode 100644 index 00000000000..de168dfdbb7 --- /dev/null +++ b/packages/twenty-front/src/modules/navigation-menu-item/states/navigationMenuItemsDraftStateV2.ts @@ -0,0 +1,10 @@ +import { type NavigationMenuItem } from '~/generated-metadata/graphql'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const navigationMenuItemsDraftStateV2 = createStateV2< + NavigationMenuItem[] | null +>({ + key: 'navigationMenuItemsDraftStateV2', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/openNavigationMenuItemFolderIdsState.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/openNavigationMenuItemFolderIdsState.ts deleted file mode 100644 index b90fb4d29f1..00000000000 --- a/packages/twenty-front/src/modules/navigation-menu-item/states/openNavigationMenuItemFolderIdsState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const openNavigationMenuItemFolderIdsState = atom({ - key: 'openNavigationMenuItemFolderIdsState', - default: [], -}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2.ts new file mode 100644 index 00000000000..31af63fa0f7 --- /dev/null +++ b/packages/twenty-front/src/modules/navigation-menu-item/states/openNavigationMenuItemFolderIdsStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const openNavigationMenuItemFolderIdsStateV2 = createStateV2({ + key: 'openNavigationMenuItemFolderIdsStateV2', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState.ts deleted file mode 100644 index bb3de30a449..00000000000 --- a/packages/twenty-front/src/modules/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const selectedNavigationMenuItemInEditModeState = atom({ - key: 'selectedNavigationMenuItemInEditModeState', - default: null, -}); diff --git a/packages/twenty-front/src/modules/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2.ts b/packages/twenty-front/src/modules/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2.ts new file mode 100644 index 00000000000..5faac7e7850 --- /dev/null +++ b/packages/twenty-front/src/modules/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2.ts @@ -0,0 +1,8 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const selectedNavigationMenuItemInEditModeStateV2 = createStateV2< + string | null +>({ + key: 'selectedNavigationMenuItemInEditModeStateV2', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx index 867e9839ce0..f83a44c6eea 100644 --- a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx @@ -10,8 +10,9 @@ import { MainNavigationDrawerScrollableItems } from '@/navigation/components/Mai import { NavigationDrawer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawer'; import { NavigationDrawerFixedContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerFixedContent'; import { NavigationDrawerScrollableContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerScrollableContent'; -import { currentFavoriteFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState'; -import { currentNavigationMenuItemFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdState'; +import { currentFavoriteFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdStateV2'; +import { currentNavigationMenuItemFolderIdStateV2 } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { FeatureFlagKey } from '~/generated-metadata/graphql'; @@ -22,9 +23,11 @@ const StyledScrollableContent = styled.div` export const MainNavigationDrawer = ({ className }: { className?: string }) => { const currentWorkspace = useRecoilValue(currentWorkspaceState); - const currentFavoriteFolderId = useRecoilValue(currentFavoriteFolderIdState); - const currentNavigationMenuItemFolderId = useRecoilValue( - currentNavigationMenuItemFolderIdState, + const currentFavoriteFolderId = useRecoilValueV2( + currentFavoriteFolderIdStateV2, + ); + const currentNavigationMenuItemFolderId = useRecoilValueV2( + currentNavigationMenuItemFolderIdStateV2, ); const { favoritesByFolder } = useFavoritesByFolder(); const { navigationMenuItemsByFolder } = useNavigationMenuItemsByFolder(); diff --git a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx index 78abcbd17bd..b6d650da4ff 100644 --- a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerFixedItems.tsx @@ -2,8 +2,9 @@ import { useOpenAskAIPageInCommandMenu } from '@/command-menu/hooks/useOpenAskAI import { useOpenRecordsSearchPageInCommandMenu } from '@/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded'; -import { navigationDrawerExpandedMemorizedState } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedState'; +import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2'; import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; +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'; @@ -23,8 +24,8 @@ export const MainNavigationDrawerFixedItems = () => { const [isNavigationDrawerExpanded, setIsNavigationDrawerExpanded] = useRecoilState(isNavigationDrawerExpandedState); - const setNavigationDrawerExpandedMemorized = useSetRecoilState( - navigationDrawerExpandedMemorizedState, + const setNavigationDrawerExpandedMemorized = useSetRecoilStateV2( + navigationDrawerExpandedMemorizedStateV2, ); const navigate = useNavigate(); diff --git a/packages/twenty-front/src/modules/navigation/components/MobileNavigationBar.tsx b/packages/twenty-front/src/modules/navigation/components/MobileNavigationBar.tsx index 440858002d5..efda877cd9a 100644 --- a/packages/twenty-front/src/modules/navigation/components/MobileNavigationBar.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MobileNavigationBar.tsx @@ -1,12 +1,13 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { useOpenRecordsSearchPageInCommandMenu } from '@/command-menu/hooks/useOpenRecordsSearchPageInCommandMenu'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId'; import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState'; import { useDefaultHomePagePath } from '@/navigation/hooks/useDefaultHomePagePath'; import { useOpenSettingsMenu } from '@/navigation/hooks/useOpenSettings'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded'; +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'; import { useRecoilState } from 'recoil'; @@ -25,7 +26,7 @@ type NavigationBarItemName = 'main' | 'search' | 'tasks' | 'settings'; export const MobileNavigationBar = () => { const navigate = useNavigate(); const { defaultHomePagePath } = useDefaultHomePagePath(); - const [isCommandMenuOpened] = useRecoilState(isCommandMenuOpenedState); + const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); const { closeCommandMenu } = useCommandMenu(); const { openRecordsSearchPage } = useOpenRecordsSearchPageInCommandMenu(); const isSettingsPage = useIsSettingsPage(); diff --git a/packages/twenty-front/src/modules/navigation/components/PageDragDropProvider.tsx b/packages/twenty-front/src/modules/navigation/components/PageDragDropProvider.tsx index b39a2a28631..f6f3095cd06 100644 --- a/packages/twenty-front/src/modules/navigation/components/PageDragDropProvider.tsx +++ b/packages/twenty-front/src/modules/navigation/components/PageDragDropProvider.tsx @@ -18,11 +18,11 @@ import { NavigationMenuItemDragContext } from '@/navigation-menu-item/contexts/N import { useHandleAddToNavigationDrop } from '@/navigation-menu-item/hooks/useHandleAddToNavigationDrop'; import { useHandleNavigationMenuItemDragAndDrop } from '@/navigation-menu-item/hooks/useHandleNavigationMenuItemDragAndDrop'; import { useHandleWorkspaceNavigationMenuItemDragAndDrop } from '@/navigation-menu-item/hooks/useHandleWorkspaceNavigationMenuItemDragAndDrop'; -import { addToNavPayloadRegistryState } from '@/navigation-menu-item/states/addToNavPayloadRegistryState'; +import { addToNavPayloadRegistryStateV2 } from '@/navigation-menu-item/states/addToNavPayloadRegistryStateV2'; import { getDropTargetIdFromDestination } from '@/navigation-menu-item/utils/getDropTargetIdFromDestination'; import { isWorkspaceDroppableId } from '@/navigation-menu-item/utils/isWorkspaceDroppableId'; import { validateAndExtractWorkspaceFolderId } from '@/navigation-menu-item/utils/validateAndExtractWorkspaceFolderId'; -import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; type PageDragDropProviderProps = { @@ -59,7 +59,7 @@ export const PageDragDropProvider = ({ }; const handleDragUpdate = useRecoilCallback( - ({ snapshot }) => + () => ((update: Parameters[0]) => { const { source, destination } = update; if (source.droppableId !== ADD_TO_NAV_SOURCE_DROPPABLE_ID) { @@ -74,9 +74,9 @@ export const PageDragDropProvider = ({ setActiveDropTargetId(dropTargetId); const payload = - getSnapshotValue(snapshot, addToNavPayloadRegistryState).get( - update.draggableId, - ) ?? null; + jotaiStore + .get(addToNavPayloadRegistryStateV2.atom) + .get(update.draggableId) ?? null; const folderId = validateAndExtractWorkspaceFolderId( destination.droppableId, ); diff --git a/packages/twenty-front/src/modules/object-record/record-group/states/recordGroupPendingDragEndReorderState.ts b/packages/twenty-front/src/modules/object-record/record-group/states/recordGroupPendingDragEndReorderState.ts deleted file mode 100644 index ddab0dfb005..00000000000 --- a/packages/twenty-front/src/modules/object-record/record-group/states/recordGroupPendingDragEndReorderState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { type OnDragEndResponder } from '@hello-pangea/dnd'; -import { atom } from 'recoil'; - -export const recordGroupPendingDragEndReorderState = - atom | null>({ - key: 'recordGroupPendingDragEndReorderState', - default: null, - }); diff --git a/packages/twenty-front/src/modules/object-record/record-group/states/recordGroupPendingDragEndReorderStateV2.ts b/packages/twenty-front/src/modules/object-record/record-group/states/recordGroupPendingDragEndReorderStateV2.ts new file mode 100644 index 00000000000..51e8b72dcba --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-group/states/recordGroupPendingDragEndReorderStateV2.ts @@ -0,0 +1,9 @@ +import { type OnDragEndResponder } from '@hello-pangea/dnd'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const recordGroupPendingDragEndReorderStateV2 = + createStateV2 | null>({ + key: 'recordGroupPendingDragEndReorderStateV2', + defaultValue: null, + }); diff --git a/packages/twenty-front/src/modules/object-record/utils/__tests__/canOpenObjectInSidePanel.test.ts b/packages/twenty-front/src/modules/object-record/utils/__tests__/canOpenObjectInSidePanel.test.ts new file mode 100644 index 00000000000..eaa762477bc --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/utils/__tests__/canOpenObjectInSidePanel.test.ts @@ -0,0 +1,15 @@ +import { canOpenObjectInSidePanel } from '@/object-record/utils/canOpenObjectInSidePanel'; + +describe('canOpenObjectInSidePanel', () => { + it('should return false for workflow objects', () => { + expect(canOpenObjectInSidePanel('workflow')).toBe(false); + expect(canOpenObjectInSidePanel('workflowVersion')).toBe(false); + expect(canOpenObjectInSidePanel('dashboard')).toBe(false); + }); + + it('should return true for other objects', () => { + expect(canOpenObjectInSidePanel('person')).toBe(true); + expect(canOpenObjectInSidePanel('company')).toBe(true); + expect(canOpenObjectInSidePanel('task')).toBe(true); + }); +}); diff --git a/packages/twenty-front/src/modules/object-record/utils/__tests__/computeNewEvenlySpacedPositions.test.ts b/packages/twenty-front/src/modules/object-record/utils/__tests__/computeNewEvenlySpacedPositions.test.ts new file mode 100644 index 00000000000..5ea223678c4 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/utils/__tests__/computeNewEvenlySpacedPositions.test.ts @@ -0,0 +1,43 @@ +import { computeNewEvenlySpacedPositions } from '@/object-record/utils/computeNewEvenlySpacedPositions'; + +describe('computeNewEvenlySpacedPositions', () => { + it('should compute evenly spaced positions between two values', () => { + const result = computeNewEvenlySpacedPositions({ + startingPosition: 0, + endingPosition: 10, + numberOfRecordsToInsertBetween: 4, + }); + + expect(result).toEqual([2, 4, 6, 8]); + }); + + it('should return a single midpoint when inserting one record', () => { + const result = computeNewEvenlySpacedPositions({ + startingPosition: 0, + endingPosition: 10, + numberOfRecordsToInsertBetween: 1, + }); + + expect(result).toEqual([5]); + }); + + it('should return all same values when gap is zero', () => { + const result = computeNewEvenlySpacedPositions({ + startingPosition: 5, + endingPosition: 5, + numberOfRecordsToInsertBetween: 3, + }); + + expect(result).toEqual([5, 5, 5]); + }); + + it('should throw when starting position is after ending position', () => { + expect(() => + computeNewEvenlySpacedPositions({ + startingPosition: 10, + endingPosition: 5, + numberOfRecordsToInsertBetween: 1, + }), + ).toThrow(); + }); +}); diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/components/GraphWidgetBarChart.tsx b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/components/GraphWidgetBarChart.tsx index 343932b1b08..4c0f0370918 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/components/GraphWidgetBarChart.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/components/GraphWidgetBarChart.tsx @@ -1,4 +1,4 @@ -import { isSidePanelAnimatingState } from '@/command-menu/states/isSidePanelAnimatingState'; +import { isSidePanelAnimatingStateV2 } from '@/command-menu/states/isSidePanelAnimatingStateV2'; import { pageLayoutDraggingWidgetIdComponentState } from '@/page-layout/states/pageLayoutDraggingWidgetIdComponentState'; import { pageLayoutResizingWidgetIdComponentState } from '@/page-layout/states/pageLayoutResizingWidgetIdComponentState'; import { GraphWidgetChartContainer } from '@/page-layout/widgets/graph/components/GraphWidgetChartContainer'; @@ -21,10 +21,10 @@ import { type GraphValueFormatOptions } from '@/page-layout/widgets/graph/utils/ import { NodeDimensionEffect } from '@/ui/utilities/dimensions/components/NodeDimensionEffect'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useMemo, useRef, useState } from 'react'; -import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { useDebouncedCallback } from 'use-debounce'; import { BarChartLayout } from '~/generated-metadata/graphql'; @@ -111,7 +111,7 @@ export const GraphWidgetBarChart = ({ pageLayoutResizingWidgetIdComponentState, ); - const isSidePanelAnimating = useRecoilValue(isSidePanelAnimatingState); + const isSidePanelAnimating = useRecoilValueV2(isSidePanelAnimatingStateV2); const isLayoutAnimating = isSidePanelAnimating || draggingWidgetId === id || resizingWidgetId === id; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx index 48129b88430..2c3debf3f6e 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { type ConnectedAccount } from '@/accounts/types/ConnectedAccount'; import { @@ -13,7 +13,8 @@ import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { SettingsAccountsMessageChannelDetails } from '@/settings/accounts/components/SettingsAccountsMessageChannelDetails'; import { SettingsNewAccountSection } from '@/settings/accounts/components/SettingsNewAccountSection'; import { SETTINGS_ACCOUNT_MESSAGE_CHANNELS_TAB_LIST_COMPONENT_ID } from '@/settings/accounts/constants/SettingsAccountMessageChannelsTabListComponentId'; -import { settingsAccountsSelectedMessageChannelState } from '@/settings/accounts/states/settingsAccountsSelectedMessageChannelState'; +import { settingsAccountsSelectedMessageChannelStateV2 } from '@/settings/accounts/states/settingsAccountsSelectedMessageChannelStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; @@ -30,8 +31,8 @@ export const SettingsAccountsMessageChannelsContainer = () => { SETTINGS_ACCOUNT_MESSAGE_CHANNELS_TAB_LIST_COMPONENT_ID, ); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); - const setSelectedMessageChannel = useSetRecoilState( - settingsAccountsSelectedMessageChannelState, + const setSelectedMessageChannel = useSetRecoilStateV2( + settingsAccountsSelectedMessageChannelStateV2, ); const { records: accounts } = useFindManyRecords({ diff --git a/packages/twenty-front/src/modules/settings/accounts/components/message-folders/SettingsAccountsMessageFoldersCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/message-folders/SettingsAccountsMessageFoldersCard.tsx index f20c98b5343..ebe950856bd 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/message-folders/SettingsAccountsMessageFoldersCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/message-folders/SettingsAccountsMessageFoldersCard.tsx @@ -9,7 +9,7 @@ import { SettingsMessageFoldersTreeItem } from '@/settings/accounts/components/m import { computeFolderIdsForSyncToggle } from '@/settings/accounts/components/message-folders/utils/computeFolderIdsForSyncToggle'; import { computeMessageFolderTree } from '@/settings/accounts/components/message-folders/utils/computeMessageFolderTree'; import { useUpdateMessageFoldersSyncStatus } from '@/settings/accounts/hooks/useUpdateMessageFoldersSyncStatus'; -import { settingsAccountsSelectedMessageChannelState } from '@/settings/accounts/states/settingsAccountsSelectedMessageChannelState'; +import { settingsAccountsSelectedMessageChannelStateV2 } from '@/settings/accounts/states/settingsAccountsSelectedMessageChannelStateV2'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput'; import { Table } from '@/ui/layout/table/components/Table'; @@ -17,8 +17,8 @@ import { TableCell } from '@/ui/layout/table/components/TableCell'; import { ApolloError } from '@apollo/client'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useMemo, useState } from 'react'; -import { useRecoilValue } from 'recoil'; import { Label } from 'twenty-ui/display'; import { Checkbox, CheckboxSize } from 'twenty-ui/input'; import { Section } from 'twenty-ui/layout'; @@ -72,8 +72,8 @@ export const SettingsAccountsMessageFoldersCard = () => { const { enqueueErrorSnackBar } = useSnackBar(); - const settingsAccountsSelectedMessageChannel = useRecoilValue( - settingsAccountsSelectedMessageChannelState, + const settingsAccountsSelectedMessageChannel = useRecoilValueV2( + settingsAccountsSelectedMessageChannelStateV2, ); const { updateMessageFoldersSyncStatus } = diff --git a/packages/twenty-front/src/modules/settings/accounts/states/settingsAccountsSelectedMessageChannelState.ts b/packages/twenty-front/src/modules/settings/accounts/states/settingsAccountsSelectedMessageChannelState.ts deleted file mode 100644 index 726b2ab864d..00000000000 --- a/packages/twenty-front/src/modules/settings/accounts/states/settingsAccountsSelectedMessageChannelState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { atom } from 'recoil'; - -import { type MessageChannel } from '@/accounts/types/MessageChannel'; - -export const settingsAccountsSelectedMessageChannelState = - atom({ - key: 'settingsAccountsSelectedMessageChannelState', - default: null, - }); diff --git a/packages/twenty-front/src/modules/settings/accounts/states/settingsAccountsSelectedMessageChannelStateV2.ts b/packages/twenty-front/src/modules/settings/accounts/states/settingsAccountsSelectedMessageChannelStateV2.ts new file mode 100644 index 00000000000..05b882119c4 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/accounts/states/settingsAccountsSelectedMessageChannelStateV2.ts @@ -0,0 +1,9 @@ +import { type MessageChannel } from '@/accounts/types/MessageChannel'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const settingsAccountsSelectedMessageChannelStateV2 = + createStateV2({ + key: 'settingsAccountsSelectedMessageChannelStateV2', + defaultValue: null, + }); diff --git a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminGeneral.tsx b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminGeneral.tsx index e593c19ca6a..e3858081902 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminGeneral.tsx +++ b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminGeneral.tsx @@ -1,6 +1,6 @@ import { canManageFeatureFlagsState } from '@/client-config/states/canManageFeatureFlagsState'; import { SettingsAdminWorkspaceContent } from '@/settings/admin-panel/components/SettingsAdminWorkspaceContent'; -import { userLookupResultState } from '@/settings/admin-panel/states/userLookupResultState'; +import { userLookupResultStateV2 } from '@/settings/admin-panel/states/userLookupResultStateV2'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; @@ -8,8 +8,9 @@ import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/consta import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; import { isNonEmptyString } from '@sniptt/guards'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { useState } from 'react'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { useUserLookupAdminPanelMutation } from '~/generated-metadata/graphql'; @@ -45,8 +46,8 @@ export const SettingsAdminGeneral = () => { activeTabIdComponentState, SETTINGS_ADMIN_USER_LOOKUP_WORKSPACE_TABS_ID, ); - const [userLookupResult, setUserLookupResult] = useRecoilState( - userLookupResultState, + const [userLookupResult, setUserLookupResult] = useRecoilStateV2( + userLookupResultStateV2, ); const [isUserLookupLoading, setIsUserLookupLoading] = useState(false); diff --git a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminWorkspaceContent.tsx b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminWorkspaceContent.tsx index 54d95dec707..22c8b4d1b49 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminWorkspaceContent.tsx +++ b/packages/twenty-front/src/modules/settings/admin-panel/components/SettingsAdminWorkspaceContent.tsx @@ -5,7 +5,7 @@ import { SettingsAdminTableCard } from '@/settings/admin-panel/components/Settin import { useFeatureFlagState } from '@/settings/admin-panel/hooks/useFeatureFlagState'; import { useImpersonationAuth } from '@/settings/admin-panel/hooks/useImpersonationAuth'; import { useImpersonationRedirect } from '@/settings/admin-panel/hooks/useImpersonationRedirect'; -import { userLookupResultState } from '@/settings/admin-panel/states/userLookupResultState'; +import { userLookupResultStateV2 } from '@/settings/admin-panel/states/userLookupResultStateV2'; import { type WorkspaceInfo } from '@/settings/admin-panel/types/WorkspaceInfo'; import { getWorkspaceSchemaName } from '@/settings/admin-panel/utils/get-workspace-schema-name.util'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; @@ -18,6 +18,7 @@ import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/consta import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import { isNonEmptyString } from '@sniptt/guards'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useState } from 'react'; import { useRecoilState, useRecoilValue } from 'recoil'; import { getImageAbsoluteURI, isDefined } from 'twenty-shared/utils'; @@ -69,7 +70,7 @@ export const SettingsAdminWorkspaceContent = ({ const [impersonate] = useImpersonateMutation(); const { updateFeatureFlagState } = useFeatureFlagState(); - const userLookupResult = useRecoilValue(userLookupResultState); + const userLookupResult = useRecoilValueV2(userLookupResultStateV2); const { t } = useLingui(); diff --git a/packages/twenty-front/src/modules/settings/admin-panel/hooks/useFeatureFlagState.ts b/packages/twenty-front/src/modules/settings/admin-panel/hooks/useFeatureFlagState.ts index 87ebc3c8532..d38456b4cfe 100644 --- a/packages/twenty-front/src/modules/settings/admin-panel/hooks/useFeatureFlagState.ts +++ b/packages/twenty-front/src/modules/settings/admin-panel/hooks/useFeatureFlagState.ts @@ -1,11 +1,11 @@ -import { userLookupResultState } from '@/settings/admin-panel/states/userLookupResultState'; -import { useRecoilState } from 'recoil'; +import { userLookupResultStateV2 } from '@/settings/admin-panel/states/userLookupResultStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { type FeatureFlagKey } from '~/generated-metadata/graphql'; import { isDefined } from 'twenty-shared/utils'; export const useFeatureFlagState = () => { - const [userLookupResult, setUserLookupResult] = useRecoilState( - userLookupResultState, + const [userLookupResult, setUserLookupResult] = useRecoilStateV2( + userLookupResultStateV2, ); const updateFeatureFlagState = ( diff --git a/packages/twenty-front/src/modules/settings/admin-panel/states/userLookupResultState.ts b/packages/twenty-front/src/modules/settings/admin-panel/states/userLookupResultState.ts deleted file mode 100644 index 273ebb313ed..00000000000 --- a/packages/twenty-front/src/modules/settings/admin-panel/states/userLookupResultState.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { type UserLookup } from '@/settings/admin-panel/types/UserLookup'; -import { atom } from 'recoil'; - -export const userLookupResultState = atom({ - key: 'userLookupResultState', - default: null, -}); diff --git a/packages/twenty-front/src/modules/settings/admin-panel/states/userLookupResultStateV2.ts b/packages/twenty-front/src/modules/settings/admin-panel/states/userLookupResultStateV2.ts new file mode 100644 index 00000000000..b6f325c9bb2 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/admin-panel/states/userLookupResultStateV2.ts @@ -0,0 +1,8 @@ +import { type UserLookup } from '@/settings/admin-panel/types/UserLookup'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const userLookupResultStateV2 = createStateV2({ + key: 'userLookupResultStateV2', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/settings/hooks/__tests__/useSettingsNavigationItems.test.tsx b/packages/twenty-front/src/modules/settings/hooks/__tests__/useSettingsNavigationItems.test.tsx index 795736c02d3..c88e7fb0d86 100644 --- a/packages/twenty-front/src/modules/settings/hooks/__tests__/useSettingsNavigationItems.test.tsx +++ b/packages/twenty-front/src/modules/settings/hooks/__tests__/useSettingsNavigationItems.test.tsx @@ -12,7 +12,6 @@ import { import { currentUserState } from '@/auth/states/currentUserState'; import { billingState } from '@/client-config/states/billingState'; -import { labPublicFeatureFlagsState } from '@/client-config/states/labPublicFeatureFlagsState'; import { usePermissionFlagMap } from '@/settings/roles/hooks/usePermissionFlagMap'; import { SnackBarComponentInstanceContext } from '@/ui/feedback/snack-bar-manager/contexts/SnackBarComponentInstanceContext'; import { i18n } from '@lingui/core'; @@ -48,7 +47,6 @@ const mockBilling: Billing = { const initializeState = ({ set }: MutableSnapshot) => { set(currentUserState, mockCurrentUser); set(billingState, mockBilling); - set(labPublicFeatureFlagsState, []); }; const Wrapper = ({ children }: { children: ReactNode }) => ( diff --git a/packages/twenty-front/src/modules/settings/lab/hooks/useLabPublicFeatureFlags.ts b/packages/twenty-front/src/modules/settings/lab/hooks/useLabPublicFeatureFlags.ts index 73160380081..e6992a07e62 100644 --- a/packages/twenty-front/src/modules/settings/lab/hooks/useLabPublicFeatureFlags.ts +++ b/packages/twenty-front/src/modules/settings/lab/hooks/useLabPublicFeatureFlags.ts @@ -1,8 +1,9 @@ import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; -import { labPublicFeatureFlagsState } from '@/client-config/states/labPublicFeatureFlagsState'; +import { labPublicFeatureFlagsStateV2 } from '@/client-config/states/labPublicFeatureFlagsStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { t } from '@lingui/core/macro'; import { useState } from 'react'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { type FeatureFlagKey, @@ -14,7 +15,7 @@ export const useLabPublicFeatureFlags = () => { const [currentWorkspace, setCurrentWorkspace] = useRecoilState( currentWorkspaceState, ); - const labPublicFeatureFlags = useRecoilValue(labPublicFeatureFlagsState); + const labPublicFeatureFlags = useRecoilValueV2(labPublicFeatureFlagsStateV2); const [updateLabPublicFeatureFlag] = useUpdateLabPublicFeatureFlagMutation({ onCompleted: (data) => { diff --git a/packages/twenty-front/src/modules/settings/members/hooks/useWorkspaceMemberRoles.ts b/packages/twenty-front/src/modules/settings/members/hooks/useWorkspaceMemberRoles.ts index e10ab4136e6..72880c66e83 100644 --- a/packages/twenty-front/src/modules/settings/members/hooks/useWorkspaceMemberRoles.ts +++ b/packages/twenty-front/src/modules/settings/members/hooks/useWorkspaceMemberRoles.ts @@ -1,10 +1,13 @@ import { settingsAllRolesSelector } from '@/settings/roles/states/settingsAllRolesSelector'; -import { settingsRolesIsLoadingState } from '@/settings/roles/states/settingsRolesIsLoadingState'; +import { settingsRolesIsLoadingStateV2 } from '@/settings/roles/states/settingsRolesIsLoadingStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useRecoilValue } from 'recoil'; export const useWorkspaceMemberRoles = (workspaceMemberId: string) => { const settingsAllRoles = useRecoilValue(settingsAllRolesSelector); - const settingsRolesIsLoading = useRecoilValue(settingsRolesIsLoadingState); + const settingsRolesIsLoading = useRecoilValueV2( + settingsRolesIsLoadingStateV2, + ); const roles = workspaceMemberId ? settingsAllRoles.filter((role) => diff --git a/packages/twenty-front/src/modules/settings/roles/components/SettingsRolesContainer.tsx b/packages/twenty-front/src/modules/settings/roles/components/SettingsRolesContainer.tsx index e4765822ed5..a9c3ef39744 100644 --- a/packages/twenty-front/src/modules/settings/roles/components/SettingsRolesContainer.tsx +++ b/packages/twenty-front/src/modules/settings/roles/components/SettingsRolesContainer.tsx @@ -7,8 +7,9 @@ import { SettingsRoleDefaultRole } from '@/settings/roles/components/SettingsRol import { SettingsRolesList } from '@/settings/roles/components/SettingsRolesList'; import { settingsAllRolesSelector } from '@/settings/roles/states/settingsAllRolesSelector'; -import { settingsRolesIsLoadingState } from '@/settings/roles/states/settingsRolesIsLoadingState'; +import { settingsRolesIsLoadingStateV2 } from '@/settings/roles/states/settingsRolesIsLoadingStateV2'; import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { Trans, useLingui } from '@lingui/react/macro'; import { useRecoilValue } from 'recoil'; import { H3Title } from 'twenty-ui/display'; @@ -17,7 +18,9 @@ export const SettingsRolesContainer = () => { const { t } = useLingui(); const settingsAllRoles = useRecoilValue(settingsAllRolesSelector); - const settingsRolesIsLoading = useRecoilValue(settingsRolesIsLoadingState); + const settingsRolesIsLoading = useRecoilValueV2( + settingsRolesIsLoadingStateV2, + ); if (settingsRolesIsLoading && !settingsAllRoles) { return null; diff --git a/packages/twenty-front/src/modules/settings/roles/components/SettingsRolesQueryEffect.tsx b/packages/twenty-front/src/modules/settings/roles/components/SettingsRolesQueryEffect.tsx index cd512db1c34..ef25d6d3084 100644 --- a/packages/twenty-front/src/modules/settings/roles/components/SettingsRolesQueryEffect.tsx +++ b/packages/twenty-front/src/modules/settings/roles/components/SettingsRolesQueryEffect.tsx @@ -1,11 +1,14 @@ import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState'; import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState'; import { settingsRoleIdsState } from '@/settings/roles/states/settingsRoleIdsState'; -import { settingsRolesIsLoadingState } from '@/settings/roles/states/settingsRolesIsLoadingState'; +import { settingsRoleIdsStateV2 } from '@/settings/roles/states/settingsRoleIdsStateV2'; +import { settingsRolesIsLoadingStateV2 } from '@/settings/roles/states/settingsRolesIsLoadingStateV2'; import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers'; import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue'; import { useEffect } from 'react'; -import { useRecoilCallback, useSetRecoilState } from 'recoil'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; +import { useRecoilCallback } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { useGetRolesQuery } from '~/generated-metadata/graphql'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; @@ -15,8 +18,8 @@ export const SettingsRolesQueryEffect = () => { fetchPolicy: 'network-only', }); - const setSettingsRolesIsLoading = useSetRecoilState( - settingsRolesIsLoadingState, + const setSettingsRolesIsLoading = useSetRecoilStateV2( + settingsRolesIsLoadingStateV2, ); const populateRoles = useRecoilCallback( @@ -24,6 +27,7 @@ export const SettingsRolesQueryEffect = () => { (roles: RoleWithPartialMembers[]) => { const roleIds = roles.map((role) => role.id); set(settingsRoleIdsState, roleIds); + jotaiStore.set(settingsRoleIdsStateV2.atom, roleIds); roles.forEach((role) => { const persistedRole = getSnapshotValue( snapshot, diff --git a/packages/twenty-front/src/modules/settings/roles/role/components/SettingsRole.tsx b/packages/twenty-front/src/modules/settings/roles/role/components/SettingsRole.tsx index 394c82d4955..9fcb29fa391 100644 --- a/packages/twenty-front/src/modules/settings/roles/role/components/SettingsRole.tsx +++ b/packages/twenty-front/src/modules/settings/roles/role/components/SettingsRole.tsx @@ -9,7 +9,7 @@ import { SETTINGS_ROLE_DETAIL_TABS } from '@/settings/roles/role/constants/Setti import { useSaveDraftRoleToDB } from '@/settings/roles/role/hooks/useSaveDraftRoleToDB'; import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState'; import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState'; -import { settingsRolesIsLoadingState } from '@/settings/roles/states/settingsRolesIsLoadingState'; +import { settingsRolesIsLoadingStateV2 } from '@/settings/roles/states/settingsRolesIsLoadingStateV2'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; @@ -17,6 +17,7 @@ import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTab import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useLoadCurrentUser } from '@/users/hooks/useLoadCurrentUser'; import { t } from '@lingui/core/macro'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useState } from 'react'; import { useRecoilState, useRecoilValue } from 'recoil'; import { SettingsPath } from 'twenty-shared/types'; @@ -43,7 +44,9 @@ export const SettingsRole = ({ roleId, isCreateMode }: SettingsRoleProps) => { const [isSaving, setIsSaving] = useState(false); - const settingsRolesIsLoading = useRecoilValue(settingsRolesIsLoadingState); + const settingsRolesIsLoading = useRecoilValueV2( + settingsRolesIsLoadingStateV2, + ); const [settingsDraftRole, setSettingsDraftRole] = useRecoilState( settingsDraftRoleFamilyState(roleId), diff --git a/packages/twenty-front/src/modules/settings/roles/states/settingsRoleIdsStateV2.ts b/packages/twenty-front/src/modules/settings/roles/states/settingsRoleIdsStateV2.ts new file mode 100644 index 00000000000..92e23602508 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/roles/states/settingsRoleIdsStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const settingsRoleIdsStateV2 = createStateV2({ + key: 'settingsRoleIdsStateV2', + defaultValue: [], +}); diff --git a/packages/twenty-front/src/modules/settings/roles/states/settingsRolesIsLoadingState.ts b/packages/twenty-front/src/modules/settings/roles/states/settingsRolesIsLoadingState.ts deleted file mode 100644 index 19aa0abb370..00000000000 --- a/packages/twenty-front/src/modules/settings/roles/states/settingsRolesIsLoadingState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const settingsRolesIsLoadingState = atom({ - key: 'settingsRolesIsLoadingState', - default: true, -}); diff --git a/packages/twenty-front/src/modules/settings/roles/states/settingsRolesIsLoadingStateV2.ts b/packages/twenty-front/src/modules/settings/roles/states/settingsRolesIsLoadingStateV2.ts new file mode 100644 index 00000000000..bc41773175b --- /dev/null +++ b/packages/twenty-front/src/modules/settings/roles/states/settingsRolesIsLoadingStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const settingsRolesIsLoadingStateV2 = createStateV2({ + key: 'settingsRolesIsLoadingStateV2', + defaultValue: true, +}); diff --git a/packages/twenty-front/src/modules/ui/layout/page-header/components/PageHeaderToggleCommandMenuButton.tsx b/packages/twenty-front/src/modules/ui/layout/page-header/components/PageHeaderToggleCommandMenuButton.tsx index 5e0e9d6ad1c..35fcfa2a54d 100644 --- a/packages/twenty-front/src/modules/ui/layout/page-header/components/PageHeaderToggleCommandMenuButton.tsx +++ b/packages/twenty-front/src/modules/ui/layout/page-header/components/PageHeaderToggleCommandMenuButton.tsx @@ -1,13 +1,13 @@ import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { RootStackingContextZIndices } from '@/ui/layout/constants/RootStackingContextZIndices'; import { PAGE_HEADER_COMMAND_MENU_BUTTON_CLICK_OUTSIDE_ID } from '@/ui/layout/page-header/constants/PageHeaderCommandMenuButtonClickOutsideId'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { i18n } from '@lingui/core'; import { t } from '@lingui/core/macro'; import { motion } from 'framer-motion'; -import { useRecoilValue } from 'recoil'; import { AppTooltip, TooltipDelay, TooltipPosition } from 'twenty-ui/display'; import { AnimatedButton } from 'twenty-ui/input'; import { getOsControlSymbol, useIsMobile } from 'twenty-ui/utilities'; @@ -108,7 +108,7 @@ const AnimatedIcon = ({ export const PageHeaderToggleCommandMenuButton = () => { const { toggleCommandMenu } = useCommandMenu(); - const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); + const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); const isMobile = useIsMobile(); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/MultiWorkspaceDropdownButton.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/MultiWorkspaceDropdownButton.tsx index 41be4e0030b..a267d89348d 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/MultiWorkspaceDropdownButton.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/MultiWorkspaceDropdownButton.tsx @@ -4,13 +4,13 @@ import { MultiWorkspaceDropdownDefaultComponents } from '@/ui/navigation/navigat import { MultiWorkspaceDropdownThemesComponents } from '@/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownThemesComponents'; import { MultiWorkspaceDropdownWorkspacesListComponents } from '@/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents'; import { MULTI_WORKSPACE_DROPDOWN_ID } from '@/ui/navigation/navigation-drawer/constants/MultiWorkspaceDropdownId'; -import { multiWorkspaceDropdownState } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownState'; +import { multiWorkspaceDropdownStateV2 } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownStateV2'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; import { useMemo } from 'react'; -import { useRecoilState } from 'recoil'; export const MultiWorkspaceDropdownButton = () => { - const [multiWorkspaceDropdown, setMultiWorkspaceDropdown] = useRecoilState( - multiWorkspaceDropdownState, + const [multiWorkspaceDropdown, setMultiWorkspaceDropdown] = useRecoilStateV2( + multiWorkspaceDropdownStateV2, ); const DropdownComponents = useMemo(() => { diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx index 5236709f251..724b47fca93 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownDefaultComponents.tsx @@ -18,13 +18,14 @@ 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 { MULTI_WORKSPACE_DROPDOWN_ID } from '@/ui/navigation/navigation-drawer/constants/MultiWorkspaceDropdownId'; -import { multiWorkspaceDropdownState } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownState'; +import { multiWorkspaceDropdownStateV2 } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownStateV2'; import { useColorScheme } from '@/ui/theme/hooks/useColorScheme'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { type ApolloError } from '@apollo/client'; import styled from '@emotion/styled'; import { isNonEmptyString } from '@sniptt/guards'; import { useLingui } from '@lingui/react/macro'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { AppPath, SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; import { @@ -74,8 +75,8 @@ export const MultiWorkspaceDropdownDefaultComponents = () => { const [signUpInNewWorkspaceMutation] = useSignUpInNewWorkspaceMutation(); - const setMultiWorkspaceDropdownState = useSetRecoilState( - multiWorkspaceDropdownState, + const setMultiWorkspaceDropdownState = useSetRecoilStateV2( + multiWorkspaceDropdownStateV2, ); const handleSupport = () => { diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownThemesComponents.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownThemesComponents.tsx index dc7b5acf7e5..1d29f87e419 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownThemesComponents.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownThemesComponents.tsx @@ -2,10 +2,10 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader'; import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; -import { multiWorkspaceDropdownState } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownState'; +import { multiWorkspaceDropdownStateV2 } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownStateV2'; import { useColorScheme } from '@/ui/theme/hooks/useColorScheme'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { useLingui } from '@lingui/react/macro'; -import { useSetRecoilState } from 'recoil'; import { IconCheck, IconChevronLeft } from 'twenty-ui/display'; import { MenuItem } from 'twenty-ui/navigation'; @@ -14,8 +14,8 @@ export const MultiWorkspaceDropdownThemesComponents = () => { const { setColorScheme, colorScheme, colorSchemeList } = useColorScheme(); - const setMultiWorkspaceDropdownState = useSetRecoilState( - multiWorkspaceDropdownState, + const setMultiWorkspaceDropdownState = useSetRecoilStateV2( + multiWorkspaceDropdownStateV2, ); return ( diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents.tsx index 7848e9bc235..fbbda3ce816 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/MultiWorkspaceDropdown/internal/MultiWorkspaceDropdownWorkspacesListComponents.tsx @@ -3,10 +3,11 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator'; -import { multiWorkspaceDropdownState } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownState'; +import { multiWorkspaceDropdownStateV2 } from '@/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownStateV2'; import { useLingui } from '@lingui/react/macro'; import { useState } from 'react'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilValue } from 'recoil'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { IconChevronLeft } from 'twenty-ui/display'; import { WorkspacesForSignIn } from './components/WorkspacesForSignIn'; @@ -18,8 +19,8 @@ export const MultiWorkspaceDropdownWorkspacesListComponents = () => { const availableWorkspaces = useRecoilValue(availableWorkspacesState); - const setMultiWorkspaceDropdownState = useSetRecoilState( - multiWorkspaceDropdownState, + const setMultiWorkspaceDropdownState = useSetRecoilStateV2( + multiWorkspaceDropdownStateV2, ); const [searchValue, setSearchValue] = useState(''); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx index a6090e52881..836d4d6cf8e 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx @@ -3,8 +3,9 @@ import styled from '@emotion/styled'; import { useRecoilValue, useSetRecoilState } from 'recoil'; import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded'; -import { navigationDrawerExpandedMemorizedState } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedState'; +import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2'; import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useIsWorkspaceActivationStatusEqualsTo } from '@/workspace/hooks/useIsWorkspaceActivationStatusEqualsTo'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; import { IconX } from 'twenty-ui/display'; @@ -51,8 +52,8 @@ export const NavigationDrawerBackButton = ({ const setIsNavigationDrawerExpanded = useSetRecoilState( isNavigationDrawerExpandedState, ); - const navigationDrawerExpandedMemorized = useRecoilValue( - navigationDrawerExpandedMemorizedState, + const navigationDrawerExpandedMemorized = useRecoilValueV2( + navigationDrawerExpandedMemorizedStateV2, ); const isWorkspaceSuspended = useIsWorkspaceActivationStatusEqualsTo( diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState.ts deleted file mode 100644 index 79c5a59b787..00000000000 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const currentFavoriteFolderIdState = atom({ - key: 'currentFavoriteFolderIdState', - default: null, -}); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdStateV2.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdStateV2.ts new file mode 100644 index 00000000000..baa4386b0f3 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const currentFavoriteFolderIdStateV2 = createStateV2({ + key: 'currentFavoriteFolderIdStateV2', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdState.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdState.ts deleted file mode 100644 index fd8e09aba03..00000000000 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const currentNavigationMenuItemFolderIdState = atom({ - key: 'currentNavigationMenuItemFolderIdState', - default: null, -}); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdStateV2.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdStateV2.ts new file mode 100644 index 00000000000..675d62e63c7 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdStateV2.ts @@ -0,0 +1,8 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const currentNavigationMenuItemFolderIdStateV2 = createStateV2< + string | null +>({ + key: 'currentNavigationMenuItemFolderIdStateV2', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownState.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownState.ts deleted file mode 100644 index 7804de3fb98..00000000000 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { atom } from 'recoil'; - -export const multiWorkspaceDropdownState = atom< - 'default' | 'workspaces-list' | 'themes' ->({ - key: 'multiWorkspaceDropdownState', - default: 'default', -}); diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownStateV2.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownStateV2.ts new file mode 100644 index 00000000000..42f024370f5 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/multiWorkspaceDropdownStateV2.ts @@ -0,0 +1,8 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const multiWorkspaceDropdownStateV2 = createStateV2< + 'default' | 'workspaces-list' | 'themes' +>({ + key: 'multiWorkspaceDropdownStateV2', + defaultValue: 'default', +}); diff --git a/packages/twenty-front/src/modules/ui/navigation/states/navigationDrawerExpandedMemorizedState.ts b/packages/twenty-front/src/modules/ui/navigation/states/navigationDrawerExpandedMemorizedState.ts deleted file mode 100644 index 09394812b81..00000000000 --- a/packages/twenty-front/src/modules/ui/navigation/states/navigationDrawerExpandedMemorizedState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { atom } from 'recoil'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; - -const isMobile = window.innerWidth <= MOBILE_VIEWPORT; - -export const navigationDrawerExpandedMemorizedState = atom({ - key: 'navigationDrawerExpandedMemorized', - default: !isMobile, -}); diff --git a/packages/twenty-front/src/modules/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2.ts b/packages/twenty-front/src/modules/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2.ts new file mode 100644 index 00000000000..423768192aa --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2.ts @@ -0,0 +1,10 @@ +import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +const isMobile = window.innerWidth <= MOBILE_VIEWPORT; + +export const navigationDrawerExpandedMemorizedStateV2 = createStateV2({ + key: 'navigationDrawerExpandedMemorizedStateV2', + defaultValue: !isMobile, +}); diff --git a/packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/__tests__/useDragSelect.test.tsx b/packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/__tests__/useDragSelect.test.tsx index c75fe128b19..5baca9bf0f6 100644 --- a/packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/__tests__/useDragSelect.test.tsx +++ b/packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/__tests__/useDragSelect.test.tsx @@ -1,13 +1,21 @@ import { renderHook } from '@testing-library/react'; -import { act } from 'react'; +import { Provider as JotaiProvider } from 'jotai'; +import { type ReactNode, act } from 'react'; import { RecoilRoot } from 'recoil'; import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; + +const Wrapper = ({ children }: { children: ReactNode }) => ( + + {children} + +); describe('useDragSelect', () => { it('Should set drag selection start state', () => { const { result } = renderHook(() => useDragSelect(), { - wrapper: RecoilRoot, + wrapper: Wrapper, }); expect(result.current.isDragSelectionStartEnabled()).toBe(true); diff --git a/packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/useDragSelect.ts b/packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/useDragSelect.ts index 49b39662d94..05141d67161 100644 --- a/packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/useDragSelect.ts +++ b/packages/twenty-front/src/modules/ui/utilities/drag-select/hooks/useDragSelect.ts @@ -1,23 +1,20 @@ -import { useRecoilCallback, useSetRecoilState } from 'recoil'; +import { useCallback } from 'react'; -import { isDragSelectionStartEnabledState } from '@/ui/utilities/drag-select/states/internal/isDragSelectionStartEnabledState'; +import { isDragSelectionStartEnabledStateV2 } from '@/ui/utilities/drag-select/states/internal/isDragSelectionStartEnabledStateV2'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; +import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore'; export const useDragSelect = () => { - const setIsDragSelectionStartEnabled = useSetRecoilState( - isDragSelectionStartEnabledState, + const setIsDragSelectionStartEnabled = useSetRecoilStateV2( + isDragSelectionStartEnabledStateV2, ); const setDragSelectionStartEnabled = (isEnabled: boolean) => { setIsDragSelectionStartEnabled(isEnabled); }; - const isDragSelectionStartEnabled = useRecoilCallback( - ({ snapshot }) => - () => { - return snapshot - .getLoadable(isDragSelectionStartEnabledState) - .getValue(); - }, + const isDragSelectionStartEnabled = useCallback( + () => jotaiStore.get(isDragSelectionStartEnabledStateV2.atom), [], ); diff --git a/packages/twenty-front/src/modules/ui/utilities/drag-select/states/internal/isDragSelectionStartEnabledState.ts b/packages/twenty-front/src/modules/ui/utilities/drag-select/states/internal/isDragSelectionStartEnabledState.ts deleted file mode 100644 index a8fb73232ea..00000000000 --- a/packages/twenty-front/src/modules/ui/utilities/drag-select/states/internal/isDragSelectionStartEnabledState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const isDragSelectionStartEnabledState = atom({ - key: 'drag-select/isDragSelectionStartEnabledState', - default: true, -}); diff --git a/packages/twenty-front/src/modules/ui/utilities/drag-select/states/internal/isDragSelectionStartEnabledStateV2.ts b/packages/twenty-front/src/modules/ui/utilities/drag-select/states/internal/isDragSelectionStartEnabledStateV2.ts new file mode 100644 index 00000000000..cca33ccd52b --- /dev/null +++ b/packages/twenty-front/src/modules/ui/utilities/drag-select/states/internal/isDragSelectionStartEnabledStateV2.ts @@ -0,0 +1,6 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const isDragSelectionStartEnabledStateV2 = createStateV2({ + key: 'drag-select/isDragSelectionStartEnabledStateV2', + defaultValue: true, +}); diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/shouldReplaceFilter.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/shouldReplaceFilter.test.ts new file mode 100644 index 00000000000..32e886c11b4 --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/__tests__/shouldReplaceFilter.test.ts @@ -0,0 +1,39 @@ +import { shouldReplaceFilter } from '@/views/utils/shouldReplaceFilter'; + +describe('shouldReplaceFilter', () => { + it('should match advanced filters by id', () => { + const result = shouldReplaceFilter( + { id: 'f1', fieldMetadataId: 'field-a', recordFilterGroupId: 'g1' }, + { id: 'f1', fieldMetadataId: 'field-b', recordFilterGroupId: 'g1' }, + ); + + expect(result).toBe(true); + }); + + it('should not match advanced filters with different ids', () => { + const result = shouldReplaceFilter( + { id: 'f1', fieldMetadataId: 'field-a', recordFilterGroupId: 'g1' }, + { id: 'f2', fieldMetadataId: 'field-a', recordFilterGroupId: 'g1' }, + ); + + expect(result).toBe(false); + }); + + it('should match simple filters by fieldMetadataId when old filter has no group', () => { + const result = shouldReplaceFilter( + { id: 'f1', fieldMetadataId: 'field-a', recordFilterGroupId: undefined }, + { id: 'f2', fieldMetadataId: 'field-a', recordFilterGroupId: undefined }, + ); + + expect(result).toBe(true); + }); + + it('should not replace when old filter belongs to a group but new filter does not', () => { + const result = shouldReplaceFilter( + { id: 'f1', fieldMetadataId: 'field-a', recordFilterGroupId: 'g1' }, + { id: 'f2', fieldMetadataId: 'field-a', recordFilterGroupId: undefined }, + ); + + expect(result).toBe(false); + }); +}); diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/splitFieldNameIntoBaseAndSubField.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/splitFieldNameIntoBaseAndSubField.test.ts new file mode 100644 index 00000000000..a77ba362d5a --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/__tests__/splitFieldNameIntoBaseAndSubField.test.ts @@ -0,0 +1,24 @@ +import { splitFieldNameIntoBaseAndSubField } from '@/views/utils/splitFieldNameIntoBaseAndSubField'; + +describe('splitFieldNameIntoBaseAndSubField', () => { + it('should return the base field name when there is no sub-field', () => { + expect(splitFieldNameIntoBaseAndSubField('name')).toEqual({ + baseFieldName: 'name', + subFieldName: undefined, + }); + }); + + it('should split a dotted field name into base and sub-field', () => { + expect(splitFieldNameIntoBaseAndSubField('address.city')).toEqual({ + baseFieldName: 'address', + subFieldName: 'city', + }); + }); + + it('should preserve nested sub-fields joined with dots', () => { + expect(splitFieldNameIntoBaseAndSubField('address.street.number')).toEqual({ + baseFieldName: 'address', + subFieldName: 'street.number', + }); + }); +}); diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx index 0645af0dbfa..e9a1e5e9be0 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx @@ -1,6 +1,6 @@ import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; import { commandMenuWidthState } from '@/command-menu/states/commandMenuWidthState'; -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { useListenToSidePanelClosing } from '@/ui/layout/right-drawer/hooks/useListenToSidePanelClosing'; import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; @@ -61,7 +61,8 @@ import React, { useRef, useState, } from 'react'; -import { useRecoilCallback, useRecoilValue } from 'recoil'; +import { useRecoilCallback } from 'recoil'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { isDefined } from 'twenty-shared/utils'; import { Tag, type TagColor } from 'twenty-ui/components'; @@ -256,7 +257,7 @@ export const WorkflowDiagramCanvasBase = ({ return { nodes, edges }; }, [workflowDiagram, workflowInsertStepIds]); - const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); + const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); const { isInRightDrawer } = useContext(ActionMenuContext); const handleEdgesChange = ( diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/hooks/useRightDrawerState.ts b/packages/twenty-front/src/modules/workflow/workflow-diagram/hooks/useRightDrawerState.ts index 91227a4c940..73cc44719e6 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/hooks/useRightDrawerState.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/hooks/useRightDrawerState.ts @@ -1,13 +1,13 @@ -import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2'; import { type CommandMenuAnimationVariant } from '@/command-menu/types/CommandMenuAnimationVariant'; -import { useRecoilValue } from 'recoil'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; import { useIsMobile } from 'twenty-ui/utilities'; export const useRightDrawerState = (): { rightDrawerState: CommandMenuAnimationVariant; } => { const isMobile = useIsMobile(); - const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); + const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2); if (isMobile) { return { diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowStepFooter.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowStepFooter.tsx index b63007e15c9..6de66453f17 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowStepFooter.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/WorkflowStepFooter.tsx @@ -8,10 +8,10 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { useDeleteStep } from '@/workflow/workflow-steps/hooks/useDeleteStep'; import { useDuplicateStep } from '@/workflow/workflow-steps/hooks/useDuplicateStep'; -import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { workflowAiAgentActionAgentStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2'; import { useLingui } from '@lingui/react/macro'; import { useId } from 'react'; -import { useRecoilValue } from 'recoil'; import { SettingsPath } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { TRIGGER_STEP_ID } from 'twenty-shared/workflow'; @@ -44,8 +44,8 @@ export const WorkflowStepFooter = ({ } = useWorkflowCommandMenu(); const { deleteStep } = useDeleteStep(); const navigateSettings = useNavigateSettings(); - const workflowAiAgentActionAgent = useRecoilValue( - workflowAiAgentActionAgentState, + const workflowAiAgentActionAgent = useRecoilValueV2( + workflowAiAgentActionAgentStateV2, ); const shouldPinDeleteButton = !isDefined(additionalActions) || additionalActions.length === 0; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx index f79f025acb7..df20c08770c 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab.tsx @@ -3,13 +3,14 @@ import { useActionRolePermissionFlagConfig } from '@/settings/roles/role-permiss import { TextInput } from '@/ui/input/components/TextInput'; import { type WorkflowAiAgentAction } from '@/workflow/types/Workflow'; import { useWorkflowAiAgentPermissionActions } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useWorkflowAiAgentPermissionActions'; -import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState'; -import { workflowAiAgentPermissionsIsAddingPermissionState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState'; -import { workflowAiAgentPermissionsSelectedObjectIdState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdState'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { workflowAiAgentActionAgentStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2'; +import { workflowAiAgentPermissionsIsAddingPermissionStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionStateV2'; +import { workflowAiAgentPermissionsSelectedObjectIdStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdStateV2'; import styled from '@emotion/styled'; import { t } from '@lingui/core/macro'; import { useState } from 'react'; -import { useRecoilState, useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconChevronLeft } from 'twenty-ui/display'; import { IconButton } from 'twenty-ui/input'; @@ -74,18 +75,18 @@ export const WorkflowAiAgentPermissionsTab = ({ isAgentLoading, refetchAgent, }: WorkflowAiAgentPermissionsTabProps) => { - const workflowAiAgentActionAgent = useRecoilValue( - workflowAiAgentActionAgentState, + const workflowAiAgentActionAgent = useRecoilValueV2( + workflowAiAgentActionAgentStateV2, ); const [ workflowAiAgentPermissionsSelectedObjectId, setWorkflowAiAgentPermissionsSelectedObjectId, - ] = useRecoilState(workflowAiAgentPermissionsSelectedObjectIdState); + ] = useRecoilStateV2(workflowAiAgentPermissionsSelectedObjectIdStateV2); const [ workflowAiAgentPermissionsIsAddingPermission, setWorkflowAiAgentPermissionsIsAddingPermission, - ] = useRecoilState(workflowAiAgentPermissionsIsAddingPermissionState); + ] = useRecoilStateV2(workflowAiAgentPermissionsIsAddingPermissionStateV2); const { alphaSortedActiveNonSystemObjectMetadataItems: objectMetadataItems } = useFilteredObjectMetadataItems(); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPromptTab.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPromptTab.tsx index 6f724a68455..8af742b4a4b 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPromptTab.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPromptTab.tsx @@ -1,9 +1,9 @@ import { FormTextFieldInput } from '@/object-record/record-field/ui/form-types/components/FormTextFieldInput'; import { Select } from '@/ui/input/components/Select'; -import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState'; +import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2'; +import { workflowAiAgentActionAgentStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2'; import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker'; import { t } from '@lingui/core/macro'; -import { useRecoilValue } from 'recoil'; import { type AgentResponseSchema, type ModelConfiguration, @@ -32,8 +32,8 @@ export const WorkflowAiAgentPromptTab = ({ onModelConfigurationChange, onResponseFormatChange, }: WorkflowAiAgentPromptTabProps) => { - const workflowAiAgentActionAgent = useRecoilValue( - workflowAiAgentActionAgentState, + const workflowAiAgentActionAgent = useRecoilValueV2( + workflowAiAgentActionAgentStateV2, ); return ( <> diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx index ba08ae22807..3773c0186fc 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowEditActionAiAgent.tsx @@ -12,11 +12,11 @@ import { useUpdateWorkflowVersionStep } from '@/workflow/workflow-steps/hooks/us import { WorkflowAiAgentPermissionsTab } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/components/WorkflowAiAgentPermissionsTab'; import { WORKFLOW_AI_AGENT_TABS } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/constants/WorkflowAiAgentTabs'; import { useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose'; -import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState'; -import { workflowAiAgentPermissionsIsAddingPermissionState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; +import { workflowAiAgentActionAgentStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2'; +import { workflowAiAgentPermissionsIsAddingPermissionStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionStateV2'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; -import { useRecoilState } from 'recoil'; import { type AgentResponseSchema, type ModelConfiguration, @@ -66,7 +66,7 @@ export const WorkflowEditActionAiAgent = ({ const componentInstanceId = `${WORKFLOW_AI_AGENT_TAB_LIST_COMPONENT_ID}-${action.id}`; const agentId = action.settings.input.agentId; const [workflowAiAgentActionAgent, setWorkflowAiAgentActionAgent] = - useRecoilState(workflowAiAgentActionAgentState); + useRecoilStateV2(workflowAiAgentActionAgentStateV2); const { loading: agentLoading, refetch: refetchAgent } = useFindOneAgentQuery( { variables: { id: agentId || '' }, @@ -217,7 +217,7 @@ export const WorkflowEditActionAiAgent = ({ const [ workflowAiAgentPermissionsIsAddingPermission, setWorkflowAiAgentPermissionsIsAddingPermission, - ] = useRecoilState(workflowAiAgentPermissionsIsAddingPermissionState); + ] = useRecoilStateV2(workflowAiAgentPermissionsIsAddingPermissionStateV2); const role = rolesData?.getRoles.find( (item) => item.id === workflowAiAgentActionAgent?.roleId, diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose.ts index 40b06137bf3..17a0c25dc44 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose.ts @@ -1,22 +1,22 @@ import { useListenToSidePanelClosing } from '@/ui/layout/right-drawer/hooks/useListenToSidePanelClosing'; -import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState'; -import { workflowAiAgentPermissionsIsAddingPermissionState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState'; -import { workflowAiAgentPermissionsSelectedObjectIdState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdState'; -import { useResetRecoilState, useSetRecoilState } from 'recoil'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; +import { workflowAiAgentActionAgentStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2'; +import { workflowAiAgentPermissionsIsAddingPermissionStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionStateV2'; +import { workflowAiAgentPermissionsSelectedObjectIdStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdStateV2'; export const useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose = () => { - const resetSelectedObjectId = useResetRecoilState( - workflowAiAgentPermissionsSelectedObjectIdState, + const setSelectedObjectId = useSetRecoilStateV2( + workflowAiAgentPermissionsSelectedObjectIdStateV2, ); - const setIsAddingPermission = useSetRecoilState( - workflowAiAgentPermissionsIsAddingPermissionState, + const setIsAddingPermission = useSetRecoilStateV2( + workflowAiAgentPermissionsIsAddingPermissionStateV2, ); - const resetAgentState = useResetRecoilState(workflowAiAgentActionAgentState); + const setAgentState = useSetRecoilStateV2(workflowAiAgentActionAgentStateV2); const resetPermissionState = () => { - resetSelectedObjectId(); + setSelectedObjectId(undefined); setIsAddingPermission(false); - resetAgentState(); + setAgentState(undefined); }; useListenToSidePanelClosing(resetPermissionState); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useWorkflowAiAgentPermissionActions.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useWorkflowAiAgentPermissionActions.ts index e951a0a5896..b8da0145863 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useWorkflowAiAgentPermissionActions.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useWorkflowAiAgentPermissionActions.ts @@ -4,12 +4,12 @@ import { useActionRolePermissionFlagConfig } from '@/settings/roles/role-permiss import { useSettingsRolePermissionFlagConfig } from '@/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { CRUD_PERMISSIONS } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/constants/WorkflowAiAgentCrudPermissions'; -import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState'; -import { workflowAiAgentPermissionsIsAddingPermissionState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState'; -import { workflowAiAgentPermissionsSelectedObjectIdState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdState'; +import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2'; +import { workflowAiAgentActionAgentStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2'; +import { workflowAiAgentPermissionsIsAddingPermissionStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionStateV2'; +import { workflowAiAgentPermissionsSelectedObjectIdStateV2 } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdStateV2'; import { t } from '@lingui/core/macro'; import { useMemo } from 'react'; -import { useRecoilState } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { v4 } from 'uuid'; import { @@ -37,7 +37,7 @@ export const useWorkflowAiAgentPermissionActions = ({ }: UseWorkflowAiAgentPermissionActionsParams) => { const { enqueueSuccessSnackBar } = useSnackBar(); const [workflowAiAgentActionAgent, setWorkflowAiAgentActionAgent] = - useRecoilState(workflowAiAgentActionAgentState); + useRecoilStateV2(workflowAiAgentActionAgentStateV2); const { alphaSortedActiveNonSystemObjectMetadataItems: objectMetadataItems } = useFilteredObjectMetadataItems(); const settingsPermissionsConfig = useSettingsRolePermissionFlagConfig({ @@ -47,11 +47,11 @@ export const useWorkflowAiAgentPermissionActions = ({ assignmentCapabilities: { canBeAssignedToAgents: true }, }); - const [, setWorkflowAiAgentPermissionsSelectedObjectId] = useRecoilState( - workflowAiAgentPermissionsSelectedObjectIdState, + const [, setWorkflowAiAgentPermissionsSelectedObjectId] = useRecoilStateV2( + workflowAiAgentPermissionsSelectedObjectIdStateV2, ); - const [, setWorkflowAiAgentPermissionsIsAddingPermission] = useRecoilState( - workflowAiAgentPermissionsIsAddingPermissionState, + const [, setWorkflowAiAgentPermissionsIsAddingPermission] = useRecoilStateV2( + workflowAiAgentPermissionsIsAddingPermissionStateV2, ); const [createRole] = useCreateOneRoleMutation(); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState.ts deleted file mode 100644 index 7cf6f45f018..00000000000 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { atom } from 'recoil'; -import { type Agent } from '~/generated-metadata/graphql'; - -export const workflowAiAgentActionAgentState = atom({ - key: 'workflowAiAgentActionAgentState', - default: undefined, -}); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2.ts new file mode 100644 index 00000000000..477d4a392bc --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentStateV2.ts @@ -0,0 +1,10 @@ +import { type Agent } from '~/generated-metadata/graphql'; + +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const workflowAiAgentActionAgentStateV2 = createStateV2< + Agent | undefined +>({ + key: 'workflowAiAgentActionAgentStateV2', + defaultValue: undefined, +}); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState.ts deleted file mode 100644 index f961c278d83..00000000000 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from 'recoil'; - -export const workflowAiAgentPermissionsIsAddingPermissionState = atom({ - key: 'workflowAiAgentPermissionsIsAddingPermissionState', - default: false, -}); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionStateV2.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionStateV2.ts new file mode 100644 index 00000000000..d0a8fa6bab8 --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionStateV2.ts @@ -0,0 +1,7 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const workflowAiAgentPermissionsIsAddingPermissionStateV2 = + createStateV2({ + key: 'workflowAiAgentPermissionsIsAddingPermissionStateV2', + defaultValue: false, + }); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdState.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdState.ts deleted file mode 100644 index 4c2a70ca37c..00000000000 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { atom } from 'recoil'; - -export const workflowAiAgentPermissionsSelectedObjectIdState = atom< - string | undefined ->({ - key: 'workflowAiAgentPermissionsSelectedObjectIdState', - default: undefined, -}); diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdStateV2.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdStateV2.ts new file mode 100644 index 00000000000..552d7940d9d --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdStateV2.ts @@ -0,0 +1,8 @@ +import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2'; + +export const workflowAiAgentPermissionsSelectedObjectIdStateV2 = createStateV2< + string | undefined +>({ + key: 'workflowAiAgentPermissionsSelectedObjectIdStateV2', + defaultValue: undefined, +}); diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfiguration.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfiguration.tsx index e6126b87029..907c1dcfb49 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfiguration.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsConfiguration.tsx @@ -1,14 +1,14 @@ import { useLingui } from '@lingui/react/macro'; import { useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; -import { useSetRecoilState } from 'recoil'; +import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2'; import { type CalendarChannel } from '@/accounts/types/CalendarChannel'; import { type MessageChannel } from '@/accounts/types/MessageChannel'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useGenerateDepthRecordGqlFieldsFromObject } from '@/object-record/graphql/record-gql-fields/hooks/useGenerateDepthRecordGqlFieldsFromObject'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; -import { settingsAccountsSelectedMessageChannelState } from '@/settings/accounts/states/settingsAccountsSelectedMessageChannelState'; +import { settingsAccountsSelectedMessageChannelStateV2 } from '@/settings/accounts/states/settingsAccountsSelectedMessageChannelStateV2'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath, isDefined } from 'twenty-shared/utils'; @@ -30,8 +30,8 @@ export const SettingsAccountsConfiguration = () => { const { enqueueSuccessSnackBar, enqueueErrorSnackBar } = useSnackBar(); const [startChannelSyncMutation, { loading: isSubmitting }] = useStartChannelSyncMutation(); - const setSelectedMessageChannel = useSetRecoilState( - settingsAccountsSelectedMessageChannelState, + const setSelectedMessageChannel = useSetRecoilStateV2( + settingsAccountsSelectedMessageChannelStateV2, ); const [currentStep, setCurrentStep] =