Migrate more to Jotai (#17968)

As per title

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
This commit is contained in:
Charles Bochet
2026-02-17 19:24:36 +01:00
committed by GitHub
parent 98482f3a01
commit d7f025157b
179 changed files with 1219 additions and 988 deletions
@@ -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({
@@ -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 } =
@@ -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(() => {
@@ -1,9 +0,0 @@
import { atom } from 'recoil';
import { type RecordGqlOperationVariables } from 'twenty-shared/types';
export const currentNotesQueryVariablesState =
atom<RecordGqlOperationVariables | null>({
default: null,
key: 'currentNotesQueryVariablesState',
});
@@ -0,0 +1,9 @@
import { type RecordGqlOperationVariables } from 'twenty-shared/types';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const currentNotesQueryVariablesStateV2 =
createStateV2<RecordGqlOperationVariables | null>({
key: 'currentNotesQueryVariablesStateV2',
defaultValue: null,
});
@@ -1,9 +0,0 @@
import { atom } from 'recoil';
import { type ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
export const objectShowPageTargetableObjectState =
atom<ActivityTargetableObject | null>({
key: 'objectShowPageTargetableObjectState',
default: null,
});
@@ -0,0 +1,9 @@
import { type ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const objectShowPageTargetableObjectStateV2 =
createStateV2<ActivityTargetableObject | null>({
key: 'objectShowPageTargetableObjectStateV2',
defaultValue: null,
});
@@ -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) => {
@@ -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 (
@@ -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) => {
@@ -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<HTMLInputElement>(null);
const { uploadFiles } = useAIChatFileUpload();
@@ -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) {
@@ -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);
@@ -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 } =
@@ -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<FileUIPart | null> => {
@@ -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,
@@ -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();
@@ -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();
@@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const agentChatInputState = atom<string>({
default: '',
key: 'agentChatInputState',
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const agentChatInputStateV2 = createStateV2<string>({
key: 'agentChatInputStateV2',
defaultValue: '',
});
@@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const agentChatSelectedFilesState = atom<File[]>({
key: 'ai/agentChatSelectedFilesState',
default: [],
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const agentChatSelectedFilesStateV2 = createStateV2<File[]>({
key: 'ai/agentChatSelectedFilesStateV2',
defaultValue: [],
});
@@ -1,7 +0,0 @@
import { type FileUIPart } from 'ai';
import { atom } from 'recoil';
export const agentChatUploadedFilesState = atom<FileUIPart[]>({
key: 'ai/agentChatUploadedFilesState',
default: [],
});
@@ -0,0 +1,8 @@
import { type FileUIPart } from 'ai';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const agentChatUploadedFilesStateV2 = createStateV2<FileUIPart[]>({
key: 'ai/agentChatUploadedFilesStateV2',
defaultValue: [],
});
@@ -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<AgentChatUsageState | null>({
key: 'agentChatUsageState',
default: null,
export const agentChatUsageStateV2 = createStateV2<AgentChatUsageState | null>({
key: 'agentChatUsageStateV2',
defaultValue: null,
});
@@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const currentAIChatThreadState = atom<string | null>({
key: 'ai/currentAIChatThreadState',
default: null,
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const currentAIChatThreadStateV2 = createStateV2<string | null>({
key: 'ai/currentAIChatThreadStateV2',
defaultValue: null,
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const currentAIChatThreadTitleStateV2 = createStateV2<string | null>({
key: 'ai/currentAIChatThreadTitleStateV2',
defaultValue: null,
});
@@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const isCreatingChatThreadState = atom<boolean>({
key: 'ai/isCreatingChatThreadState',
default: false,
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const isCreatingChatThreadStateV2 = createStateV2<boolean>({
key: 'ai/isCreatingChatThreadStateV2',
defaultValue: false,
});
@@ -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);
},
[],
),
@@ -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(
@@ -1,7 +0,0 @@
import { atom } from 'recoil';
import { type PublicFeatureFlag } from '~/generated-metadata/graphql';
export const labPublicFeatureFlagsState = atom<PublicFeatureFlag[]>({
key: 'labPublicFeatureFlagsState',
default: [],
});
@@ -0,0 +1,8 @@
import { type PublicFeatureFlag } from '~/generated-metadata/graphql';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const labPublicFeatureFlagsStateV2 = createStateV2<PublicFeatureFlag[]>({
key: 'labPublicFeatureFlagsStateV2',
defaultValue: [],
});
@@ -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 (
@@ -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();
@@ -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 (
<AnimatePresence>
@@ -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
@@ -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();
@@ -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<HTMLDivElement>(null);
const setIsSidePanelAnimating = useSetRecoilState(isSidePanelAnimatingState);
const setIsSidePanelAnimating = useSetRecoilStateV2(
isSidePanelAnimatingStateV2,
);
const handleClickOutside = useRecoilCallback(
({ snapshot }) =>
@@ -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();
@@ -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,
@@ -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 }) => (
<RecoilRoot initializeState={initializeState}>{children}</RecoilRoot>
),
});
const Wrapper = ({ children }: { children: ReactNode }) => (
<JotaiProvider store={jotaiStore}>
<RecoilRoot>{children}</RecoilRoot>
</JotaiProvider>
);
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(() => {
@@ -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({
@@ -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, []);
@@ -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);
},
[
@@ -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 {
@@ -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({
@@ -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],
);
@@ -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();
@@ -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);
@@ -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(
@@ -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);
@@ -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)
@@ -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)
@@ -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;
@@ -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();
@@ -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 (
@@ -1,12 +0,0 @@
import { atom, type RecoilState } from 'recoil';
export const viewableRichTextComponentState: RecoilState<{
activityId: string;
activityObjectNameSingular: string;
}> = atom({
key: 'viewableRichTextComponentState',
default: {
activityId: '',
activityObjectNameSingular: '',
},
});
@@ -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: '',
},
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const isCommandMenuOpenedStateV2 = createStateV2<boolean>({
key: 'command-menu/isCommandMenuOpenedStateV2',
defaultValue: false,
});
@@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const isSidePanelAnimatingState = atom({
key: 'command-menu/isSidePanelAnimatingState',
default: false,
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const isSidePanelAnimatingStateV2 = createStateV2<boolean>({
key: 'command-menu/isSidePanelAnimatingStateV2',
defaultValue: false,
});
@@ -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);
@@ -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();
@@ -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();
@@ -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);
@@ -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,
@@ -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,
@@ -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) => {
@@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const isFavoriteFolderCreatingState = atom<boolean>({
key: 'isFavoriteFolderCreatingState',
default: false,
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const isFavoriteFolderCreatingStateV2 = createStateV2<boolean>({
key: 'isFavoriteFolderCreatingStateV2',
defaultValue: false,
});
@@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const openFavoriteFolderIdsState = atom<string[]>({
key: 'openFavoriteFolderIdsState',
default: [],
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const openFavoriteFolderIdsStateV2 = createStateV2<string[]>({
key: 'openFavoriteFolderIdsStateV2',
defaultValue: [],
});
@@ -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();
@@ -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 }) => (
<JotaiProvider store={jotaiStore}>
<RecoilRoot>{children}</RecoilRoot>
</JotaiProvider>
);
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 };
@@ -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,
@@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const isKeyboardShortcutMenuOpenedState = atom({
key: 'keyboard-shortcut-menu/isKeyboardShortcutMenuOpenedState',
default: false,
});
@@ -0,0 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
export const isKeyboardShortcutMenuOpenedStateV2 = createStateV2<boolean>({
key: 'keyboard-shortcut-menu/isKeyboardShortcutMenuOpenedStateV2',
defaultValue: false,
});
@@ -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();
@@ -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);
@@ -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,
@@ -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) => {
@@ -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);
@@ -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 } =
@@ -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);
@@ -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 = (
@@ -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 = (
@@ -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 = (
@@ -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);
@@ -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 = (
@@ -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;
@@ -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<typeof openNavigationMenuItemInCommandMenu>[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<typeof openNavigationMenuItemInCommandMenu>[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,
@@ -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) => {
@@ -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) => {
@@ -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) => {
@@ -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 =
@@ -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) =>
@@ -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();
@@ -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();

Some files were not shown because too many files have changed in this diff Show More