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,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,
});