Keep migrating to jotai (#18064)

And we continue!
This commit is contained in:
Charles Bochet
2026-02-19 12:10:02 +01:00
committed by GitHub
parent c0ea049ad7
commit 1a13258302
216 changed files with 2366 additions and 1594 deletions
@@ -8,7 +8,7 @@ import { useCloseActionMenu } from '@/action-menu/hooks/useCloseActionMenu';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { useModal } from '@/ui/layout/modal/hooks/useModal';
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { type ButtonAccent } from 'twenty-ui/input';
export type ActionModalProps = {
@@ -49,7 +49,7 @@ export const ActionModal = ({
const modalId = `${actionConfig?.key}-action-modal-${actionMenuType}`;
const isModalOpened = useRecoilComponentValue(
const isModalOpened = useRecoilComponentValueV2(
isModalOpenedComponentState,
modalId,
);
@@ -2,9 +2,9 @@ import { type ActionDisplayProps } from '@/action-menu/actions/display/component
import { getActionLabel } from '@/action-menu/utils/getActionLabel';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { SelectableListComponentInstanceContext } from '@/ui/layout/selectable-list/states/contexts/SelectableListComponentInstanceContext';
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
import { useNavigate } from 'react-router-dom';
import { isDefined } from 'twenty-shared/utils';
import { MenuItem } from 'twenty-ui/navigation';
@@ -31,8 +31,8 @@ export const ActionDropdownItem = ({
SelectableListComponentInstanceContext,
);
const isSelected = useRecoilComponentFamilyValue(
isSelectedItemIdComponentFamilySelector,
const isSelected = useRecoilComponentFamilyValueV2(
isSelectedItemIdComponentFamilyState,
action.key,
selectableListInstanceId,
);
@@ -16,6 +16,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
@@ -61,7 +62,7 @@ export const RecordIndexActionMenuDropdown = () => {
'more-actions',
];
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -15,8 +15,8 @@ import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotke
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useComponentInstanceStateContext } from '@/ui/utilities/state/component-state/hooks/useComponentInstanceStateContext';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { t } from '@lingui/core/macro';
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { AppPath } from 'twenty-shared/types';
@@ -49,7 +49,7 @@ export const RecordShowRightDrawerOpenRecordButton = ({
targetObjectId: recordId,
});
const activeTabIdInRightDrawer = useRecoilComponentValue(
const activeTabIdInRightDrawer = useRecoilComponentValueV2(
activeTabIdComponentState,
tabListComponentId,
);
@@ -58,7 +58,7 @@ export const RecordShowRightDrawerOpenRecordButton = ({
targetObjectId: recordId,
});
const setActiveTabIdInRecordPage = useSetRecoilComponentState(
const setActiveTabIdInRecordPage = useSetRecoilComponentStateV2(
activeTabIdComponentState,
tabListComponentIdInRecordPage,
);
@@ -9,7 +9,7 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useObjectPermissionsForObject } from '@/object-record/hooks/useObjectPermissionsForObject';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import groupBy from 'lodash.groupby';
import { IconPlus } from 'twenty-ui/display';
@@ -55,7 +55,7 @@ export const TaskGroups = ({ targetableObject }: TaskGroupsProps) => {
activityObjectNameSingular: CoreObjectNameSingular.Task,
});
const activeTabId = useRecoilComponentValue(activeTabIdComponentState);
const activeTabId = useRecoilComponentValueV2(activeTabIdComponentState);
const isLoading =
(activeTabId !== 'done' && tasksLoading) ||
@@ -26,7 +26,7 @@ import { isThinkingStepPartActive } from '@/ai/utils/isThinkingStepPartActive';
import { type ThinkingStepPart } from '@/ai/utils/thinkingStepPart';
import { TabList } from '@/ui/layout/tab-list/components/TabList';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
const StyledContainer = styled.div`
@@ -277,7 +277,7 @@ const ThinkingToolStepRow = ({
? unwrappedResult.data.result
: unwrappedOutput;
const toolTabListComponentInstanceId = `ai-thinking-tool-tabs-${part.toolCallId ?? rawToolName}-${rowIndex}`;
const activeToolTabId = useRecoilComponentValue(
const activeToolTabId = useRecoilComponentValueV2(
activeTabIdComponentState,
toolTabListComponentInstanceId,
);
@@ -1,7 +1,7 @@
import { AI_CHAT_SCROLL_WRAPPER_ID } from '@/ai/constants/AiChatScrollWrapperId';
import { useScrollWrapperHTMLElement } from '@/ui/utilities/scroll/hooks/useScrollWrapperHTMLElement';
import { scrollWrapperScrollBottomComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollBottomComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils';
const SCROLL_BOTTOM_THRESHOLD_PX = 10;
@@ -11,7 +11,7 @@ export const useAgentChatScrollToBottom = () => {
AI_CHAT_SCROLL_WRAPPER_ID,
);
const scrollBottom = useRecoilComponentValue(
const scrollBottom = useRecoilComponentValueV2(
scrollWrapperScrollBottomComponentState,
AI_CHAT_SCROLL_WRAPPER_ID,
);
@@ -14,9 +14,12 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutId';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useStore } from 'jotai';
import { coreViewFromViewIdFamilySelector } from '@/views/states/selectors/coreViewFromViewIdFamilySelector';
export const useGetBrowsingContext = () => {
const store = useStore();
const getBrowsingContext = useRecoilCallback(
({ snapshot }) =>
(): BrowsingContext | null => {
@@ -84,13 +87,11 @@ export const useGetBrowsingContext = () => {
if (isDefined(pageLayoutId)) {
const tabListInstanceId =
getTabListInstanceIdFromPageLayoutId(pageLayoutId);
const activeTabId = snapshot
.getLoadable(
activeTabIdComponentState.atomFamily({
instanceId: tabListInstanceId,
}),
)
.getValue();
const activeTabId = store.get(
activeTabIdComponentState.atomFamily({
instanceId: tabListInstanceId,
}),
);
return {
...recordContext,
@@ -154,7 +155,7 @@ export const useGetBrowsingContext = () => {
return null;
},
[],
[store],
);
return { getBrowsingContext };
@@ -3,7 +3,7 @@ import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilte
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { navigationDrawerExpandedMemorizedStateV2 } from '@/ui/navigation/states/navigationDrawerExpandedMemorizedStateV2';
import { useGoToHotkeys } from '@/ui/utilities/hotkey/hooks/useGoToHotkeys';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { AppPath, SettingsPath } from 'twenty-shared/types';
import { getAppPath, getSettingsPath } from 'twenty-shared/utils';
@@ -12,6 +12,8 @@ export const GotoHotkeysEffectsProvider = () => {
const { activeNonSystemObjectMetadataItems } =
useFilteredObjectMetadataItems();
const store = useStore();
useGoToHotkeys({
key: 's',
location: getSettingsPath(SettingsPath.ProfilePage),
@@ -19,9 +21,9 @@ export const GotoHotkeysEffectsProvider = () => {
({ set }) =>
() => {
set(isNavigationDrawerExpandedState, true);
jotaiStore.set(navigationDrawerExpandedMemorizedStateV2.atom, true);
store.set(navigationDrawerExpandedMemorizedStateV2.atom, true);
},
[],
[store],
),
});
@@ -2,8 +2,8 @@ import { SLASH_MENU_LIST_ID } from '@/ui/input/constants/SlashMenuListId';
import { type SuggestionItem } from '@/blocknote-editor/types/types';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
import { MenuItemSuggestion } from 'twenty-ui/navigation';
export type CustomSlashMenuListItemProps = {
@@ -15,8 +15,8 @@ export const CustomSlashMenuListItem = ({
}: CustomSlashMenuListItemProps) => {
const { resetSelectedItem } = useSelectableList(SLASH_MENU_LIST_ID);
const isSelectedItem = useRecoilComponentFamilyValue(
isSelectedItemIdComponentFamilySelector,
const isSelectedItem = useRecoilComponentFamilyValueV2(
isSelectedItemIdComponentFamilyState,
item.title,
);
@@ -26,7 +26,7 @@ import { sentryConfigState } from '@/client-config/states/sentryConfigState';
import { supportChatState } from '@/client-config/states/supportChatState';
import { type ClientConfig } from '@/client-config/types/ClientConfig';
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { isAttachmentPreviewEnabledStateV2 } from '@/client-config/states/isAttachmentPreviewEnabledStateV2';
@@ -130,6 +130,8 @@ export const useClientConfig = (): UseClientConfigResult => {
const setAppVersion = useSetRecoilStateV2(appVersionState);
const store = useStore();
const fetchClientConfig = useCallback(async () => {
setClientConfigApiStatus((prev) => ({
...prev,
@@ -191,7 +193,7 @@ export const useClientConfig = (): UseClientConfigResult => {
setGoogleMessagingEnabled(clientConfig?.isGoogleMessagingEnabled);
setGoogleCalendarEnabled(clientConfig?.isGoogleCalendarEnabled);
setIsAttachmentPreviewEnabled(clientConfig?.isAttachmentPreviewEnabled);
jotaiStore.set(
store.set(
isAttachmentPreviewEnabledStateV2.atom,
clientConfig?.isAttachmentPreviewEnabled,
);
@@ -252,6 +254,7 @@ export const useClientConfig = (): UseClientConfigResult => {
setSentryConfig,
setSupportChat,
setAllowRequestsToTwentyIcons,
store,
]);
return {
@@ -2,7 +2,7 @@ import { COMMAND_MENU_LIST_SELECTABLE_LIST_ID } from '@/command-menu/constants/C
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
@@ -16,7 +16,7 @@ export const CommandMenuDefaultSelectionEffect = ({
COMMAND_MENU_LIST_SELECTABLE_LIST_ID,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
COMMAND_MENU_LIST_SELECTABLE_LIST_ID,
);
@@ -4,8 +4,8 @@ import { IconArrowUpRight, type IconComponent } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { useCommandMenuOnItemClick } from '@/command-menu/hooks/useCommandMenuOnItemClick';
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
export type CommandMenuItemProps = {
label: string;
@@ -44,8 +44,8 @@ export const CommandMenuItem = ({
Icon = IconArrowUpRight;
}
const isSelectedItemId = useRecoilComponentFamilyValue(
isSelectedItemIdComponentFamilySelector,
const isSelectedItemId = useRecoilComponentFamilyValueV2(
isSelectedItemIdComponentFamilyState,
id,
);
@@ -4,10 +4,10 @@ import { TextInput } from '@/ui/input/components/TextInput';
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import styled from '@emotion/styled';
import { useRef, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { type IconComponent } from 'twenty-ui/display';
import {
@@ -45,7 +45,7 @@ export const CommandMenuItemNumberInput = ({
const [draftValue, setDraftValue] = useState(value);
const [hasError, setHasError] = useState(false);
const currentFocusId = useRecoilValue(currentFocusIdSelector);
const currentFocusId = useRecoilValueV2(currentFocusIdSelector);
const isNumberInputCurrentlyFocused = currentFocusId === focusId;
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
@@ -4,10 +4,10 @@ import { TextInput } from '@/ui/input/components/TextInput';
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import styled from '@emotion/styled';
import { useRef, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { type IconComponent } from 'twenty-ui/display';
type CommandMenuItemTextInputProps = {
@@ -37,7 +37,7 @@ export const CommandMenuItemTextInput = ({
const focusId = `${id}-input`;
const [draftValue, setDraftValue] = useState(value);
const currentFocusId = useRecoilValue(currentFocusIdSelector);
const currentFocusId = useRecoilValueV2(currentFocusIdSelector);
const isTextInputCurrentlyFocused = currentFocusId === focusId;
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
@@ -1,5 +1,5 @@
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
import { MenuItemToggle, type MenuItemToggleProps } from 'twenty-ui/navigation';
export type CommandMenuItemToggleProps = MenuItemToggleProps & {
@@ -7,8 +7,8 @@ export type CommandMenuItemToggleProps = MenuItemToggleProps & {
};
export const CommandMenuItemToggle = (props: CommandMenuItemToggleProps) => {
const isSelectedItemId = useRecoilComponentFamilyValue(
isSelectedItemIdComponentFamilySelector,
const isSelectedItemId = useRecoilComponentFamilyValueV2(
isSelectedItemIdComponentFamilyState,
props.id,
);
@@ -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 { useStore } from 'jotai';
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';
@@ -19,8 +20,7 @@ import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { motion } from 'framer-motion';
import { useRef } from 'react';
import { useRecoilCallback } from 'recoil';
import { useCallback, useRef } from 'react';
import { LINK_CHIP_CLICK_OUTSIDE_ID } from 'twenty-ui/components';
import { useIsMobile } from 'twenty-ui/utilities';
@@ -58,20 +58,19 @@ export const CommandMenuOpenContainer = ({
isSidePanelAnimatingStateV2,
);
const handleClickOutside = useRecoilCallback(
({ snapshot }) =>
(event: MouseEvent | TouchEvent) => {
const currentFocusId = snapshot
.getLoadable(currentFocusIdSelector)
.getValue();
const store = useStore();
if (currentFocusId === SIDE_PANEL_FOCUS_ID) {
event.stopImmediatePropagation();
event.preventDefault();
closeCommandMenu();
}
},
[closeCommandMenu],
const handleClickOutside = useCallback(
(event: MouseEvent | TouchEvent) => {
const currentFocusId = store.get(currentFocusIdSelector.atom);
if (currentFocusId === SIDE_PANEL_FOCUS_ID) {
event.stopImmediatePropagation();
event.preventDefault();
closeCommandMenu();
}
},
[closeCommandMenu, store],
);
useListenClickOutside({
@@ -10,7 +10,7 @@ import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages';
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 { useStore } from 'jotai';
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { t } from '@lingui/core/macro';
import { useCallback } from 'react';
@@ -23,6 +23,8 @@ export const useCommandMenu = () => {
const { removeFocusItemFromFocusStackById } =
useRemoveFocusItemFromFocusStackById();
const store = useStore();
const closeCommandMenu = useRecoilCallback(
({ set, snapshot }) =>
() => {
@@ -31,9 +33,9 @@ export const useCommandMenu = () => {
.getValue();
if (isCommandMenuOpened) {
jotaiStore.set(addToNavPayloadRegistryStateV2.atom, new Map());
store.set(addToNavPayloadRegistryStateV2.atom, new Map());
set(isCommandMenuOpenedState, false);
jotaiStore.set(isCommandMenuOpenedStateV2.atom, false);
store.set(isCommandMenuOpenedStateV2.atom, false);
set(isCommandMenuClosingState, true);
closeAnyOpenDropdown();
removeFocusItemFromFocusStackById({
@@ -41,7 +43,7 @@ export const useCommandMenu = () => {
});
}
},
[closeAnyOpenDropdown, removeFocusItemFromFocusStackById],
[closeAnyOpenDropdown, removeFocusItemFromFocusStackById, store],
);
const openCommandMenu = useCallback(() => {
@@ -26,7 +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 { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
@@ -39,6 +39,8 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => {
const { closeDropdown } = useCloseDropdown();
const store = useStore();
const commandMenuCloseAnimationCompleteCleanup = useRecoilCallback(
({ snapshot, set }) =>
() => {
@@ -106,7 +108,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => {
instanceId: '',
});
set(isCommandMenuOpenedState, false);
jotaiStore.set(isCommandMenuOpenedStateV2.atom, false);
store.set(isCommandMenuOpenedStateV2.atom, false);
set(commandMenuSearchState, '');
set(commandMenuNavigationMorphItemsByPageState, new Map());
set(commandMenuNavigationStackState, []);
@@ -115,7 +117,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => {
emitSidePanelCloseEvent();
set(isCommandMenuClosingState, false);
set(
store.set(
activeTabIdComponentState.atomFamily({
instanceId: WORKFLOW_LOGIC_FUNCTION_TAB_LIST_COMPONENT_ID,
}),
@@ -125,7 +127,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => {
for (const [pageId, morphItems] of snapshot
.getLoadable(commandMenuNavigationMorphItemsByPageState)
.getValue()) {
set(
store.set(
activeTabIdComponentState.atomFamily({
instanceId: getShowPageTabListComponentId({
pageId,
@@ -136,7 +138,7 @@ export const useCommandMenuCloseAnimationCompleteCleanup = () => {
);
}
},
[closeDropdown, resetContextStoreStates, resetSelectedItem],
[closeDropdown, resetContextStoreStates, resetSelectedItem, store],
);
return {
@@ -8,12 +8,15 @@ import { commandMenuPageState } from '@/command-menu/states/commandMenuPageState
import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelectedCommandState';
import { getShowPageTabListComponentId } from '@/ui/layout/show-page/utils/getShowPageTabListComponentId';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useStore } from 'jotai';
import { isNonEmptyArray } from '@sniptt/guards';
import { isDefined } from 'twenty-shared/utils';
export const useCommandMenuHistory = () => {
const { closeCommandMenu } = useCommandMenu();
const store = useStore();
const goBackFromCommandMenu = useRecoilCallback(
({ snapshot, set }) => {
return () => {
@@ -53,7 +56,7 @@ export const useCommandMenuHistory = () => {
const morphItems = currentMorphItems.get(removedItem.pageId);
if (isNonEmptyArray(morphItems)) {
set(
store.set(
activeTabIdComponentState.atomFamily({
instanceId: getShowPageTabListComponentId({
pageId: removedItem.pageId,
@@ -69,62 +72,68 @@ export const useCommandMenuHistory = () => {
set(hasUserSelectedCommandState, false);
};
},
[closeCommandMenu],
[closeCommandMenu, store],
);
const navigateCommandMenuHistory = useRecoilCallback(({ snapshot, set }) => {
return (pageIndex: number) => {
const currentNavigationStack = snapshot
.getLoadable(commandMenuNavigationStackState)
.getValue();
const navigateCommandMenuHistory = useRecoilCallback(
({ snapshot, set }) => {
return (pageIndex: number) => {
const currentNavigationStack = snapshot
.getLoadable(commandMenuNavigationStackState)
.getValue();
const newNavigationStack = currentNavigationStack.slice(0, pageIndex + 1);
set(commandMenuNavigationStackState, newNavigationStack);
const newNavigationStackItem = newNavigationStack.at(-1);
if (!isDefined(newNavigationStackItem)) {
throw new Error(
`No command menu navigation stack item found for index ${pageIndex}`,
const newNavigationStack = currentNavigationStack.slice(
0,
pageIndex + 1,
);
}
set(commandMenuPageState, newNavigationStackItem.page);
set(commandMenuPageInfoState, {
title: newNavigationStackItem.pageTitle,
Icon: newNavigationStackItem.pageIcon,
instanceId: newNavigationStackItem.pageId,
});
const currentMorphItems = snapshot
.getLoadable(commandMenuNavigationMorphItemsByPageState)
.getValue();
set(commandMenuNavigationStackState, newNavigationStack);
for (const [pageId, morphItems] of currentMorphItems.entries()) {
if (!newNavigationStack.some((item) => item.pageId === pageId)) {
set(
activeTabIdComponentState.atomFamily({
instanceId: getShowPageTabListComponentId({
pageId,
targetObjectId: morphItems[0].recordId,
}),
}),
null,
const newNavigationStackItem = newNavigationStack.at(-1);
if (!isDefined(newNavigationStackItem)) {
throw new Error(
`No command menu navigation stack item found for index ${pageIndex}`,
);
}
}
const newMorphItems = new Map(
Array.from(currentMorphItems.entries()).filter(([pageId]) =>
newNavigationStack.some((item) => item.pageId === pageId),
),
);
set(commandMenuPageState, newNavigationStackItem.page);
set(commandMenuPageInfoState, {
title: newNavigationStackItem.pageTitle,
Icon: newNavigationStackItem.pageIcon,
instanceId: newNavigationStackItem.pageId,
});
const currentMorphItems = snapshot
.getLoadable(commandMenuNavigationMorphItemsByPageState)
.getValue();
set(commandMenuNavigationMorphItemsByPageState, newMorphItems);
for (const [pageId, morphItems] of currentMorphItems.entries()) {
if (!newNavigationStack.some((item) => item.pageId === pageId)) {
store.set(
activeTabIdComponentState.atomFamily({
instanceId: getShowPageTabListComponentId({
pageId,
targetObjectId: morphItems[0].recordId,
}),
}),
null,
);
}
}
set(hasUserSelectedCommandState, false);
};
}, []);
const newMorphItems = new Map(
Array.from(currentMorphItems.entries()).filter(([pageId]) =>
newNavigationStack.some((item) => item.pageId === pageId),
),
);
set(commandMenuNavigationMorphItemsByPageState, newMorphItems);
set(hasUserSelectedCommandState, false);
};
},
[store],
);
return {
goBackFromCommandMenu,
@@ -15,7 +15,7 @@ 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 { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { type IconComponent } from 'twenty-ui/display';
import { v4 } from 'uuid';
@@ -36,6 +36,8 @@ export const useNavigateCommandMenu = () => {
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
const store = useStore();
const openCommandMenu = useRecoilCallback(
({ snapshot, set }) =>
() => {
@@ -72,13 +74,14 @@ export const useNavigateCommandMenu = () => {
});
set(isCommandMenuOpenedState, true);
jotaiStore.set(isCommandMenuOpenedStateV2.atom, true);
store.set(isCommandMenuOpenedStateV2.atom, true);
set(hasUserSelectedCommandState, false);
},
[
copyContextStoreStates,
commandMenuCloseAnimationCompleteCleanup,
pushFocusItemToFocusStack,
store,
],
);
@@ -1,7 +1,7 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
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 { useStore } from 'jotai';
import { t } from '@lingui/core/macro';
import { useCallback } from 'react';
import { IconPencil } from 'twenty-ui/display';
@@ -9,6 +9,8 @@ import { IconPencil } from 'twenty-ui/display';
export const useRichTextCommandMenu = () => {
const { navigateCommandMenu, openCommandMenu } = useCommandMenu();
const store = useStore();
const openRichTextInCommandMenu = useCallback(
({
activityId,
@@ -17,7 +19,7 @@ export const useRichTextCommandMenu = () => {
activityId: string;
activityObjectNameSingular: string;
}) => {
jotaiStore.set(viewableRichTextComponentStateV2.atom, {
store.set(viewableRichTextComponentStateV2.atom, {
activityId,
activityObjectNameSingular,
});
@@ -29,7 +31,7 @@ export const useRichTextCommandMenu = () => {
pageIcon: IconPencil,
});
},
[navigateCommandMenu, openCommandMenu],
[navigateCommandMenu, openCommandMenu, store],
);
const editRichText = useCallback(
@@ -7,6 +7,7 @@ import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDraw
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useLingui } from '@lingui/react/macro';
import { useId } from 'react';
import { isDefined } from 'twenty-shared/utils';
@@ -42,7 +43,7 @@ export const WidgetSettingsFooter = ({
closeDropdown(dropdownId);
};
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -11,7 +11,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils';
import { MenuItemSelect } from 'twenty-ui/navigation';
@@ -40,7 +40,7 @@ export const ChartAggregateOperationSelectableListItem = ({
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -10,7 +10,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { MenuItemSelect } from 'twenty-ui/navigation';
import { AxisNameDisplay } from '~/generated-metadata/graphql';
@@ -34,7 +34,7 @@ export const ChartAxisNameSelectionDropdownContent = () => {
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -13,7 +13,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { useState } from 'react';
import { capitalize, isDefined } from 'twenty-shared/utils';
@@ -35,7 +35,7 @@ export const ChartColorSelectionDropdownContent = () => {
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -15,7 +15,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { Trans } from '@lingui/react/macro';
import { useState } from 'react';
@@ -44,7 +44,7 @@ export const ChartDataSourceDropdownContent = () => {
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -13,7 +13,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { MenuItemSelect } from 'twenty-ui/navigation';
@@ -107,7 +107,7 @@ export const ChartDateGranularitySelectionDropdownContent = ({
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -13,7 +13,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { useState } from 'react';
import { useIcons } from 'twenty-ui/display';
@@ -60,7 +60,7 @@ export const ChartFieldSelectionForAggregateOperationDropdownContent = () => {
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -11,7 +11,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { IconChevronLeft, useIcons } from 'twenty-ui/display';
import { MenuItemSelect } from 'twenty-ui/navigation';
@@ -34,7 +34,7 @@ export const ChartGroupByFieldSelectionCompositeFieldView = ({
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -19,7 +19,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { useMemo, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
@@ -72,7 +72,7 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -14,7 +14,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { useMemo, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
@@ -46,7 +46,7 @@ export const ChartGroupByFieldSelectionRelationFieldView = ({
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -6,7 +6,7 @@ import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils';
import { MenuItemSelect } from 'twenty-ui/navigation';
@@ -24,7 +24,7 @@ export const ChartRatioAggregateOperationSelectableListItem = ({
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -7,7 +7,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { IconCheck, IconX } from 'twenty-ui/display';
import { MenuItemSelect } from 'twenty-ui/navigation';
import { AggregateOperations } from '~/generated-metadata/graphql';
@@ -31,7 +31,7 @@ export const ChartRatioOptionBooleanSelectableListItem = ({
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -7,7 +7,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { MenuItemSelectTag } from 'twenty-ui/navigation';
import { type ThemeColor } from 'twenty-ui/theme';
import { AggregateOperations } from '~/generated-metadata/graphql';
@@ -33,7 +33,7 @@ export const ChartRatioOptionSelectSelectableListItem = ({
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -18,12 +18,12 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils';
import { MenuItemSelect } from 'twenty-ui/navigation';
import {
type GraphOrderBy,
GraphOrderBy as GraphOrderByEnum,
GraphOrderBy,
type GraphOrderBy as GraphOrderByType,
} from '~/generated-metadata/graphql';
export const ChartSortByGroupByFieldDropdownContent = () => {
@@ -53,7 +53,7 @@ export const ChartSortByGroupByFieldDropdownContent = () => {
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -74,12 +74,12 @@ export const ChartSortByGroupByFieldDropdownContent = () => {
return null;
}
const handleSelectSortOption = (orderBy: GraphOrderBy) => {
const handleSelectSortOption = (orderBy: GraphOrderByType) => {
const configToUpdate: Record<string, unknown> = {
secondaryAxisOrderBy: orderBy,
};
if (orderBy === GraphOrderByEnum.MANUAL) {
if (orderBy === GraphOrderBy.MANUAL) {
const existingManualSortOrder =
configuration.secondaryAxisManualSortOrder;
@@ -94,7 +94,7 @@ export const ChartSortByGroupByFieldDropdownContent = () => {
return;
}
if (configuration.secondaryAxisOrderBy === GraphOrderByEnum.MANUAL) {
if (configuration.secondaryAxisOrderBy === GraphOrderBy.MANUAL) {
configToUpdate.secondaryAxisManualSortOrder = null;
}
@@ -125,7 +125,7 @@ export const ChartSortByGroupByFieldDropdownContent = () => {
selectableItemIdArray={availableOptions.map((option) => option.value)}
>
{availableOptions.map((sortOption) => {
const isManualOption = sortOption.value === GraphOrderByEnum.MANUAL;
const isManualOption = sortOption.value === GraphOrderBy.MANUAL;
return (
<SelectableListItem
@@ -138,7 +138,8 @@ export const ChartSortByGroupByFieldDropdownContent = () => {
<MenuItemSelect
text={getGroupBySortOptionLabel({
graphOrderBy: sortOption.value,
groupByFieldMetadataId: secondaryAxisField.id,
groupByFieldMetadataId:
configuration.secondaryAxisGroupByFieldMetadataId ?? '',
})}
selected={
configuration.secondaryAxisOrderBy === sortOption.value
@@ -18,7 +18,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { type CompositeFieldSubFieldName } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { MenuItemSelect } from 'twenty-ui/navigation';
@@ -41,7 +41,7 @@ export const ChartSortBySelectionDropdownContent = () => {
DropdownComponentInstanceContext,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -16,6 +16,7 @@ import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTab
import { updateWidgetMinimumSizeForGraphType } from '@/page-layout/utils/updateWidgetMinimumSizeForGraphType';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { BarChartLayout } from '~/generated-metadata/graphql';
@@ -31,11 +32,6 @@ export const useGetConfigToUpdateAfterGraphTypeChange = ({
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
const activeTabIdState = useRecoilComponentCallbackState(
activeTabIdComponentState,
tabListInstanceId,
);
const currentlyEditingWidgetIdState = useRecoilComponentCallbackState(
pageLayoutEditingWidgetIdComponentState,
pageLayoutId,
@@ -51,6 +47,8 @@ export const useGetConfigToUpdateAfterGraphTypeChange = ({
pageLayoutId,
);
const store = useStore();
const getConfigToUpdateAfterGraphTypeChange = useRecoilCallback(
({ set, snapshot }) =>
(graphType: GraphType) => {
@@ -164,7 +162,11 @@ export const useGetConfigToUpdateAfterGraphTypeChange = ({
};
}
const activeTabId = snapshot.getLoadable(activeTabIdState).getValue();
const activeTabId = store.get(
activeTabIdComponentState.atomFamily({
instanceId: tabListInstanceId,
}),
);
if (isDefined(activeTabId) && isDefined(currentlyEditingWidgetId)) {
const currentLayouts = snapshot
@@ -184,11 +186,12 @@ export const useGetConfigToUpdateAfterGraphTypeChange = ({
return configToUpdate;
},
[
activeTabIdState,
currentlyEditingWidgetIdState,
objectMetadataItems,
pageLayoutCurrentLayoutsState,
pageLayoutDraftState,
store,
tabListInstanceId,
widget.objectMetadataId,
],
);
@@ -8,6 +8,7 @@ import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTab
import { type SingleTabProps } from '@/ui/layout/tab-list/types/SingleTabProps';
import { useComponentInstanceStateContext } from '@/ui/utilities/state/component-state/hooks/useComponentInstanceStateContext';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun';
import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThrow';
@@ -59,7 +60,7 @@ export const CommandMenuWorkflowRunViewStepContent = () => {
);
}
const activeTabId = useRecoilComponentValue(
const activeTabId = useRecoilComponentValueV2(
activeTabIdComponentState,
commandMenuPageComponentInstance.instanceId,
);
@@ -25,7 +25,6 @@ import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/compo
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 { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { Droppable } from '@hello-pangea/dnd';
import { useLingui } from '@lingui/react/macro';
@@ -163,7 +162,7 @@ export const CurrentWorkspaceMemberFavorites = ({
/>
);
const isModalOpened = useRecoilComponentValue(
const isModalOpened = useRecoilComponentValueV2(
isModalOpenedComponentState,
modalId,
);
@@ -4,7 +4,7 @@ import { isKeyboardShortcutMenuOpenedStateV2 } from '@/keyboard-shortcut-menu/st
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 { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
export const KEYBOARD_SHORTCUT_MENU_INSTANCE_ID = 'keyboard-shortcut-menu';
@@ -13,8 +13,10 @@ export const useKeyboardShortcutMenu = () => {
const { removeFocusItemFromFocusStackById } =
useRemoveFocusItemFromFocusStackById();
const store = useStore();
const openKeyboardShortcutMenu = useCallback(() => {
jotaiStore.set(isKeyboardShortcutMenuOpenedStateV2.atom, true);
store.set(isKeyboardShortcutMenuOpenedStateV2.atom, true);
pushFocusItemToFocusStack({
focusId: KEYBOARD_SHORTCUT_MENU_INSTANCE_ID,
component: {
@@ -26,23 +28,23 @@ export const useKeyboardShortcutMenu = () => {
enableGlobalHotkeysWithModifiers: false,
},
});
}, [pushFocusItemToFocusStack]);
}, [pushFocusItemToFocusStack, store]);
const closeKeyboardShortcutMenu = useCallback(() => {
const isKeyboardShortcutMenuOpened = jotaiStore.get(
const isKeyboardShortcutMenuOpened = store.get(
isKeyboardShortcutMenuOpenedStateV2.atom,
);
if (isKeyboardShortcutMenuOpened) {
jotaiStore.set(isKeyboardShortcutMenuOpenedStateV2.atom, false);
store.set(isKeyboardShortcutMenuOpenedStateV2.atom, false);
removeFocusItemFromFocusStackById({
focusId: KEYBOARD_SHORTCUT_MENU_INSTANCE_ID,
});
}
}, [removeFocusItemFromFocusStackById]);
}, [removeFocusItemFromFocusStackById, store]);
const toggleKeyboardShortcutMenu = useCallback(() => {
const isKeyboardShortcutMenuOpened = jotaiStore.get(
const isKeyboardShortcutMenuOpened = store.get(
isKeyboardShortcutMenuOpenedStateV2.atom,
);
@@ -51,7 +53,7 @@ export const useKeyboardShortcutMenu = () => {
} else {
closeKeyboardShortcutMenu();
}
}, [closeKeyboardShortcutMenu, openKeyboardShortcutMenu]);
}, [store, closeKeyboardShortcutMenu, openKeyboardShortcutMenu]);
return {
toggleKeyboardShortcutMenu,
@@ -44,7 +44,6 @@ import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/compo
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 { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { isNonEmptyString } from '@sniptt/guards';
import { isDefined } from 'twenty-shared/utils';
@@ -195,7 +194,7 @@ export const CurrentWorkspaceMemberNavigationMenuItems = ({
/>
);
const isModalOpened = useRecoilComponentValue(
const isModalOpened = useRecoilComponentValueV2(
isModalOpenedComponentState,
modalId,
);
@@ -28,7 +28,7 @@ import { prefetchNavigationMenuItemsState } from '@/prefetch/states/prefetchNavi
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 { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { isNonEmptyString } from '@sniptt/guards';
import { isDefined } from 'twenty-shared/utils';
@@ -41,6 +41,7 @@ const StyledRightIconsContainer = styled.div`
export const WorkspaceNavigationMenuItems = () => {
const items = useWorkspaceSectionItems();
const store = useStore();
const enterEditMode = useRecoilCallback(
({ snapshot }) =>
() => {
@@ -50,13 +51,13 @@ export const WorkspaceNavigationMenuItems = () => {
const workspaceNavigationMenuItems = filterWorkspaceNavigationMenuItems(
prefetchNavigationMenuItems,
);
jotaiStore.set(
store.set(
navigationMenuItemsDraftStateV2.atom,
workspaceNavigationMenuItems,
);
jotaiStore.set(isNavigationMenuInEditModeStateV2.atom, true);
store.set(isNavigationMenuInEditModeStateV2.atom, true);
},
[],
[store],
);
const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled(
FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED,
@@ -20,7 +20,7 @@ import { openNavigationMenuItemFolderIdsStateV2 } from '@/navigation-menu-item/s
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 { useStore } from 'jotai';
import { isWorkspaceDroppableId } from '@/navigation-menu-item/utils/isWorkspaceDroppableId';
import { validateAndExtractWorkspaceFolderId } from '@/navigation-menu-item/utils/validateAndExtractWorkspaceFolderId';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
@@ -52,6 +52,8 @@ export const useHandleAddToNavigationDrop = () => {
openNavigationMenuItemFolderIdsStateV2,
);
const store = useStore();
const handleAddToNavigationDrop = useRecoilCallback(
() => (result: DropResult, _provided: ResponderProvided) => {
const { source, destination, draggableId } = result;
@@ -64,8 +66,7 @@ export const useHandleAddToNavigationDrop = () => {
}
const payload =
jotaiStore.get(addToNavPayloadRegistryStateV2.atom).get(draggableId) ??
null;
store.get(addToNavPayloadRegistryStateV2.atom).get(draggableId) ?? null;
if (!payload) {
return;
}
@@ -202,6 +203,7 @@ export const useHandleAddToNavigationDrop = () => {
setOpenNavigationMenuItemFolderIds,
setIsNavigationMenuInEditMode,
setSelectedNavigationMenuItemInEditMode,
store,
workspaceNavigationMenuItems,
],
);
@@ -12,7 +12,7 @@ import { navigationMenuItemsDraftStateV2 } from '@/navigation-menu-item/states/n
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 { useStore } from 'jotai';
import { prefetchNavigationMenuItemsState } from '@/prefetch/states/prefetchNavigationMenuItemsState';
export const useSaveNavigationMenuItemsDraft = () => {
@@ -23,10 +23,12 @@ export const useSaveNavigationMenuItemsDraft = () => {
refetchQueries: ['FindManyNavigationMenuItems'],
});
const store = useStore();
const saveDraft = useRecoilCallback(
({ snapshot }) =>
async () => {
const draft = jotaiStore.get(navigationMenuItemsDraftStateV2.atom);
const draft = store.get(navigationMenuItemsDraftStateV2.atom);
const prefetch = snapshot
.getLoadable(prefetchNavigationMenuItemsState)
.getValue();
@@ -190,6 +192,7 @@ export const useSaveNavigationMenuItemsDraft = () => {
updateNavigationMenuItem,
deleteNavigationMenuItem,
createNavigationMenuItemMutation,
store,
],
);
@@ -24,7 +24,7 @@ import { addToNavPayloadRegistryStateV2 } from '@/navigation-menu-item/states/ad
import { getDropTargetIdFromDestination } from '@/navigation-menu-item/utils/getDropTargetIdFromDestination';
import { isWorkspaceDroppableId } from '@/navigation-menu-item/utils/isWorkspaceDroppableId';
import { validateAndExtractWorkspaceFolderId } from '@/navigation-menu-item/utils/validateAndExtractWorkspaceFolderId';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { isDefined } from 'twenty-shared/utils';
@@ -53,6 +53,7 @@ export const PageDragDropProvider = ({
setAddToNavigationFallbackDestination,
] = useState<{ droppableId: string; index: number } | null>(null);
const store = useStore();
const { workspaceNavigationMenuItems } = useNavigationMenuItemsDraftState();
const { handleAddToNavigationDrop } = useHandleAddToNavigationDrop();
const { handleNavigationMenuItemDragAndDrop } =
@@ -95,7 +96,7 @@ export const PageDragDropProvider = ({
setActiveDropTargetId(dropTargetId);
const payload =
jotaiStore
store
.get(addToNavPayloadRegistryStateV2.atom)
.get(update.draggableId) ?? null;
const folderId = validateAndExtractWorkspaceFolderId(
@@ -112,7 +113,7 @@ export const PageDragDropProvider = ({
);
}
}) as OnDragUpdateResponder,
[addToNavigationFallbackDestination],
[addToNavigationFallbackDestination, store],
);
const handleDragEnd = (result: DropResult, provided: ResponderProvided) => {
@@ -16,7 +16,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { type ViewFilterOperand } from 'twenty-shared/types';
@@ -48,7 +48,7 @@ export const AdvancedFilterRecordFilterOperandSelectContent = ({
applyObjectFilterDropdownOperand(operand);
};
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
dropdownId,
);
@@ -1,6 +1,7 @@
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
@@ -83,7 +84,7 @@ export const AdvancedFilterSubFieldSelectMenu = ({
const { advancedFilterFieldSelectDropdownId } =
useAdvancedFilterFieldSelectDropdown(recordFilterId);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
advancedFilterFieldSelectDropdownId,
);
@@ -2,8 +2,8 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataIte
import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId';
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
import { useIcons } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
@@ -18,8 +18,8 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
}: ObjectFilterDropdownFilterSelectMenuItemProps) => {
const { resetSelectedItem } = useSelectableList(FILTER_FIELD_LIST_ID);
const isSelectedItem = useRecoilComponentFamilyValue(
isSelectedItemIdComponentFamilySelector,
const isSelectedItem = useRecoilComponentFamilyValueV2(
isSelectedItemIdComponentFamilyState,
fieldMetadataItemToSelect.id,
);
@@ -18,6 +18,7 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { isNonEmptyString } from '@sniptt/guards';
import { MAX_OPTIONS_TO_DISPLAY } from 'twenty-shared/constants';
@@ -68,7 +69,7 @@ export const ObjectFilterDropdownOptionSelect = ({
const { resetSelectedItem } = useSelectableList(componentInstanceId);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
componentInstanceId,
);
@@ -8,7 +8,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
import { t } from '@lingui/core/macro';
import { useRecoilValue, useSetRecoilState } from 'recoil';
@@ -32,7 +32,7 @@ export const ObjectOptionsDropdownCalendarViewContent = () => {
);
const { updateCurrentView } = useUpdateCurrentView();
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
@@ -13,6 +13,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { ViewKey } from '@/views/types/ViewKey';
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
@@ -104,7 +105,7 @@ export const ObjectOptionsDropdownCustomView = ({
'Delete view',
];
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
@@ -9,6 +9,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useOpenCreateViewDropdown } from '@/views/hooks/useOpenCreateViewDropown';
import { useLingui } from '@lingui/react/macro';
@@ -41,7 +42,7 @@ export const ObjectOptionsDropdownDefaultView = () => {
'Create custom view',
];
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
@@ -14,6 +14,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
import { type GraphQLView } from '@/views/types/GraphQLView';
@@ -124,7 +125,7 @@ export const ObjectOptionsDropdownLayoutContent = () => {
...(currentView?.type !== ViewType.Table ? ['Compact view'] : []),
];
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
@@ -11,7 +11,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { t } from '@lingui/core/macro';
@@ -33,7 +33,7 @@ export const ObjectOptionsDropdownLayoutOpenInContent = () => {
objectMetadataItem.nameSingular,
);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
@@ -14,6 +14,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import {
IconChevronLeft,
@@ -38,7 +39,7 @@ export const ObjectOptionsDropdownRecordGroupSortContent = () => {
setRecordGroupSort(sort);
};
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
@@ -19,6 +19,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useGetAvailableFieldsToGroupRecordsBy } from '@/views/view-picker/hooks/useGetAvailableFieldsToGroupRecordsBy';
import { useLingui } from '@lingui/react/macro';
@@ -90,7 +91,7 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
}
}, [hiddenRecordGroupIds, currentContentId, onContentChange]);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
@@ -10,7 +10,7 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
@@ -39,7 +39,7 @@ export const ObjectOptionsDropdownVisibilityContent = () => {
const hasViewsPermission = useHasPermissionFlag(PermissionFlagType.VIEWS);
const { canPersistChanges } = useCanPersistViewChanges();
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
@@ -1,7 +1,7 @@
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { recordIndexOpenRecordInStateV2 } from '@/object-record/record-index/states/recordIndexOpenRecordInStateV2';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
import { type GraphQLView } from '@/views/types/GraphQLView';
import { type ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
@@ -11,6 +11,8 @@ import { useCallback } from 'react';
import { useSetRecoilState } from 'recoil';
export const useUpdateObjectViewOptions = () => {
const store = useStore();
const setRecordIndexOpenRecordIn = useSetRecoilState(
recordIndexOpenRecordInState,
);
@@ -29,12 +31,12 @@ export const useUpdateObjectViewOptions = () => {
(openRecordIn: ViewOpenRecordInType, view: GraphQLView | undefined) => {
if (!view) return;
setRecordIndexOpenRecordIn(openRecordIn);
jotaiStore.set(recordIndexOpenRecordInStateV2.atom, openRecordIn);
store.set(recordIndexOpenRecordInStateV2.atom, openRecordIn);
updateCurrentView({
openRecordIn,
});
},
[setRecordIndexOpenRecordIn, updateCurrentView],
[setRecordIndexOpenRecordIn, updateCurrentView, store],
);
const setAndPersistViewName = useCallback(
@@ -29,6 +29,7 @@ import { useRecoilComponentState } from '@/ui/utilities/state/component-state/ho
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { Trans, useLingui } from '@lingui/react/macro';
import { useRecoilValue } from 'recoil';
import { findByProperty } from 'twenty-shared/utils';
@@ -151,12 +152,12 @@ export const ObjectSortDropdownButton = () => {
...hiddenFieldMetadataItemsSorted.map((item) => item.id),
];
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
OBJECT_SORT_DROPDOWN_ID,
);
const setSelectedItemId = useSetRecoilComponentState(
const setSelectedItemId = useSetRecoilComponentStateV2(
selectedItemIdComponentState,
OBJECT_SORT_DROPDOWN_ID,
);
@@ -15,6 +15,7 @@ import { RECORD_INDEX_REMOVE_SORTING_MODAL_ID } from '@/object-record/record-ind
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { isDefined } from 'twenty-shared/utils';
type RecordBoardContainerProps = {
@@ -55,7 +56,7 @@ export const RecordBoardContainer = ({
...args,
});
const isRecordIndexRemoveSortingModalOpened = useRecoilComponentValue(
const isRecordIndexRemoveSortingModalOpened = useRecoilComponentValueV2(
isModalOpenedComponentState,
RECORD_INDEX_REMOVE_SORTING_MODAL_ID,
);
@@ -1,9 +1,9 @@
import { scrollWrapperScrollTopComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollTopComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useEffect } from 'react';
export const RecordBoardStickyHeaderEffect = () => {
const scrollTop = useRecoilComponentValue(
const scrollTop = useRecoilComponentValueV2(
scrollWrapperScrollTopComponentState,
);
@@ -11,8 +11,8 @@ import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlin
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { useRecoilCallback } from 'recoil';
type RecordBoardCardInputContextProviderProps = {
children: React.ReactNode;
@@ -21,6 +21,7 @@ type RecordBoardCardInputContextProviderProps = {
export const RecordBoardCardInputContextProvider = ({
children,
}: RecordBoardCardInputContextProviderProps) => {
const store = useStore();
const { closeInlineCell } = useInlineCell();
const setRecordBoardCardEditModePosition = useSetRecoilComponentState(
recordBoardCardEditModePositionComponentState,
@@ -58,29 +59,27 @@ export const RecordBoardCardInputContextProvider = ({
closeInlineCellAndResetEditModePosition();
};
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
({ snapshot }) =>
({ newValue, event, skipPersist }) => {
const currentFocusId = snapshot
.getLoadable(currentFocusIdSelector)
.getValue();
const handleClickOutside: FieldInputClickOutsideEvent = useCallback(
({ newValue, event, skipPersist }) => {
const currentFocusId = store.get(currentFocusIdSelector.atom);
if (currentFocusId !== instanceId) {
return;
}
event?.preventDefault();
event?.stopImmediatePropagation();
if (currentFocusId !== instanceId) {
return;
}
event?.preventDefault();
event?.stopImmediatePropagation();
if (skipPersist !== true) {
persistFieldFromFieldInputContext(newValue);
}
if (skipPersist !== true) {
persistFieldFromFieldInputContext(newValue);
}
closeInlineCellAndResetEditModePosition();
},
closeInlineCellAndResetEditModePosition();
},
[
closeInlineCellAndResetEditModePosition,
instanceId,
persistFieldFromFieldInputContext,
store,
],
);
@@ -11,8 +11,8 @@ import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlin
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { useRecoilCallback } from 'recoil';
type RecordCalendarCardInputContextProviderProps = {
children: React.ReactNode;
@@ -21,6 +21,7 @@ type RecordCalendarCardInputContextProviderProps = {
export const RecordCalendarCardInputContextProvider = ({
children,
}: RecordCalendarCardInputContextProviderProps) => {
const store = useStore();
const { closeInlineCell } = useInlineCell();
const setRecordCalendarCardEditModePosition = useSetRecoilComponentState(
recordCalendarCardEditModePositionComponentState,
@@ -58,29 +59,27 @@ export const RecordCalendarCardInputContextProvider = ({
closeInlineCellAndResetEditModePosition();
};
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
({ snapshot }) =>
({ newValue, event, skipPersist }) => {
const currentFocusId = snapshot
.getLoadable(currentFocusIdSelector)
.getValue();
const handleClickOutside: FieldInputClickOutsideEvent = useCallback(
({ newValue, event, skipPersist }) => {
const currentFocusId = store.get(currentFocusIdSelector.atom);
if (currentFocusId !== instanceId) {
return;
}
event?.preventDefault();
event?.stopImmediatePropagation();
if (currentFocusId !== instanceId) {
return;
}
event?.preventDefault();
event?.stopImmediatePropagation();
if (skipPersist !== true) {
persistFieldFromFieldInputContext(newValue);
}
if (skipPersist !== true) {
persistFieldFromFieldInputContext(newValue);
}
closeInlineCellAndResetEditModePosition();
},
closeInlineCellAndResetEditModePosition();
},
[
closeInlineCellAndResetEditModePosition,
instanceId,
persistFieldFromFieldInputContext,
store,
],
);
@@ -14,8 +14,8 @@ import { useOpenFieldInputEditMode } from '@/object-record/record-field/ui/hooks
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useStore } from 'jotai';
import { useCallback } from 'react';
import { useRecoilCallback } from 'recoil';
type RecordFieldListInputContextProviderProps = {
children: React.ReactNode;
@@ -32,6 +32,7 @@ export const RecordFieldListInputContextProvider = ({
objectMetadataItem,
instanceIdPrefix,
}: RecordFieldListInputContextProviderProps) => {
const store = useStore();
const instanceId = useAvailableComponentInstanceId(
RecordFieldComponentInstanceContext,
);
@@ -86,29 +87,27 @@ export const RecordFieldListInputContextProvider = ({
closeInlineCellAndResetEditModePosition();
};
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
({ snapshot }) =>
({ newValue, event, skipPersist }) => {
const currentFocusId = snapshot
.getLoadable(currentFocusIdSelector)
.getValue();
const handleClickOutside: FieldInputClickOutsideEvent = useCallback(
({ newValue, event, skipPersist }) => {
const currentFocusId = store.get(currentFocusIdSelector.atom);
if (currentFocusId !== instanceId) {
return;
}
event?.preventDefault();
event?.stopImmediatePropagation();
if (currentFocusId !== instanceId) {
return;
}
event?.preventDefault();
event?.stopImmediatePropagation();
if (skipPersist !== true) {
persistFieldFromFieldInputContext(newValue);
}
if (skipPersist !== true) {
persistFieldFromFieldInputContext(newValue);
}
closeInlineCellAndResetEditModePosition();
},
closeInlineCellAndResetEditModePosition();
},
[
closeInlineCellAndResetEditModePosition,
instanceId,
persistFieldFromFieldInputContext,
store,
],
);
@@ -17,7 +17,7 @@ import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentTyp
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilValue } from 'recoil';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { CustomError, isDefined } from 'twenty-shared/utils';
import { IconCheck, IconPlus } from 'twenty-ui/display';
import { LightIconButton } from 'twenty-ui/input';
@@ -77,7 +77,7 @@ export const MultiItemFieldInput = <T,>({
RecordFieldComponentInstanceContext,
);
const currentFocusedItem = useRecoilValue(currentFocusedItemSelector);
const currentFocusedItem = useRecoilValueV2(currentFocusedItemSelector);
useListenClickOutside({
refs: [containerRef],
@@ -5,7 +5,6 @@ import { filesFieldUploadState } from '@/object-record/record-field/ui/states/fi
import { filesFieldUploadStateV2 } from '@/object-record/record-field/ui/states/filesFieldUploadStateV2';
import { type FieldFilesValue } from '@/object-record/record-field/ui/types/FieldMetadata';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { RECORD_TABLE_CELL_INPUT_ID_PREFIX } from '@/object-record/record-table/constants/RecordTableCellInputIdPrefix';
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
import { recordTableCellEditModePositionComponentState } from '@/object-record/record-table/states/recordTableCellEditModePositionComponentState';
@@ -16,6 +15,7 @@ import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePush
import { useRemoveLastFocusItemFromFocusStackByComponentType } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackByComponentType';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
import { useStore } from 'jotai';
import { useLingui } from '@lingui/react/macro';
import { useRecoilCallback } from 'recoil';
import { MULTI_ITEM_FIELD_DEFAULT_MAX_VALUES } from 'twenty-shared/constants';
@@ -34,6 +34,7 @@ export const useOpenFilesFieldInput = () => {
);
const { enqueueErrorSnackBar } = useSnackBar();
const { t } = useLingui();
const store = useStore();
const openFilesFieldInput = useRecoilCallback(
({ snapshot, set }) =>
@@ -101,7 +102,7 @@ export const useOpenFilesFieldInput = () => {
filesFieldUploadState({ recordId, fieldName }),
'UPLOAD_WINDOW_OPEN',
);
jotaiStore.set(
store.set(
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
'UPLOAD_WINDOW_OPEN',
);
@@ -115,7 +116,7 @@ export const useOpenFilesFieldInput = () => {
});
set(filesFieldUploadState({ recordId, fieldName }), null);
jotaiStore.set(
store.set(
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
null,
);
@@ -141,7 +142,7 @@ export const useOpenFilesFieldInput = () => {
filesFieldUploadState({ recordId, fieldName }),
'UPLOADING_FILE',
);
jotaiStore.set(
store.set(
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
'UPLOADING_FILE',
);
@@ -160,7 +161,7 @@ export const useOpenFilesFieldInput = () => {
}
} finally {
set(filesFieldUploadState({ recordId, fieldName }), null);
jotaiStore.set(
store.set(
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
null,
);
@@ -183,7 +184,7 @@ export const useOpenFilesFieldInput = () => {
},
onCancel: () => {
set(filesFieldUploadState({ recordId, fieldName }), null);
jotaiStore.set(
store.set(
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
null,
);
@@ -214,6 +215,7 @@ export const useOpenFilesFieldInput = () => {
removeLastFocusItemFromFocusStackByComponentType,
enqueueErrorSnackBar,
t,
store,
],
);
@@ -5,7 +5,7 @@ import { RECORD_INDEX_REMOVE_SORTING_MODAL_ID } from '@/object-record/record-ind
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers';
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
type RecordIndexTableContainerProps = {
recordTableId: string;
@@ -17,7 +17,7 @@ export const RecordIndexTableContainer = ({
const { objectNameSingular, viewBarInstanceId } =
useRecordIndexContextOrThrow();
const isRecordIndexRemoveSortingModalOpened = useRecoilComponentValue(
const isRecordIndexRemoveSortingModalOpened = useRecoilComponentValueV2(
isModalOpenedComponentState,
RECORD_INDEX_REMOVE_SORTING_MODAL_ID,
);
@@ -15,7 +15,6 @@ import { recordIndexGroupAggregateFieldMetadataItemComponentState } from '@/obje
import { recordIndexGroupAggregateOperationComponentState } from '@/object-record/record-index/states/recordIndexGroupAggregateOperationComponentState';
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
import { recordIndexOpenRecordInStateV2 } from '@/object-record/record-index/states/recordIndexOpenRecordInStateV2';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { recordIndexShouldHideEmptyRecordGroupsComponentState } from '@/object-record/record-index/states/recordIndexShouldHideEmptyRecordGroupsComponentState';
import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState';
import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState';
@@ -27,11 +26,14 @@ import { type View } from '@/views/types/View';
import { type ViewField } from '@/views/types/ViewField';
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
import { useStore } from 'jotai';
import { useRecoilCallback, useSetRecoilState } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const useLoadRecordIndexStates = () => {
const store = useStore();
const setContextStoreTargetedRecordsRuleComponentState =
useSetRecoilComponentState(contextStoreTargetedRecordsRuleComponentState);
@@ -203,7 +205,7 @@ export const useLoadRecordIndexStates = () => {
setRecordIndexViewType(view.type);
setRecordIndexOpenRecordIn(view.openRecordIn);
jotaiStore.set(recordIndexOpenRecordInStateV2.atom, view.openRecordIn);
store.set(recordIndexOpenRecordInStateV2.atom, view.openRecordIn);
setRecordIndexCalendarFieldMetadataIdState(
view.calendarFieldMetadataId ?? null,
@@ -259,6 +261,7 @@ export const useLoadRecordIndexStates = () => {
setRecordIndexGroupAggregateOperation,
getFieldMetadataItemByIdOrThrow,
setRecordIndexGroupFieldMetadataItem,
store,
],
);
@@ -19,7 +19,7 @@ import { usePersistFieldFromFieldInputContext } from '@/object-record/record-fie
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { useIcons } from 'twenty-ui/display';
import { RecordInlineCellContainer } from './RecordInlineCellContainer';
import {
@@ -46,6 +46,7 @@ export const RecordInlineCell = ({
isRecordFieldReadOnly: isReadOnly,
} = useContext(FieldContext);
const { scopeInstanceId } = useRecordFieldsScopeContextOrThrow();
const store = useStore();
const { openFieldInput, closeFieldInput } = useOpenFieldInputEditMode();
@@ -139,9 +140,7 @@ export const RecordInlineCell = ({
newValue,
skipPersist,
}: Parameters<FieldInputClickOutsideEvent>[0]) => {
const currentDropdownFocusId = jotaiStore.get(
activeDropdownFocusIdState.atom,
);
const currentDropdownFocusId = store.get(activeDropdownFocusIdState.atom);
const expectedDropdownFocusId = getDropdownFocusIdForRecordField({
recordId,
@@ -169,6 +168,7 @@ export const RecordInlineCell = ({
scopeInstanceId,
closeInlineCell,
persistFieldFromFieldInputContext,
store,
],
);
@@ -5,7 +5,7 @@ import { RightDrawerProvider } from '@/ui/layout/right-drawer/contexts/RightDraw
import { TabList } from '@/ui/layout/tab-list/components/TabList';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/contexts/TabListComponentInstanceContext';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
import { useMergeRecordsSelectedRecords } from '@/object-record/record-merge/hooks/useMergeRecordsSelectedRecords';
@@ -52,7 +52,7 @@ export const MergeRecordsContainer = ({
const instanceId = useAvailableComponentInstanceIdOrThrow(
CommandMenuPageComponentInstanceContext,
);
const activeTabId = useRecoilComponentValue(
const activeTabId = useRecoilComponentValueV2(
activeTabIdComponentState,
instanceId,
);
@@ -8,10 +8,11 @@ import { multipleRecordPickerIsSelectedComponentFamilySelector } from '@/object-
import { getMultipleRecordPickerSelectableListId } from '@/object-record/record-picker/multiple-record-picker/utils/getMultipleRecordPickerSelectableListId';
import { type RecordPickerPickableMorphItem } from '@/object-record/record-picker/types/RecordPickerPickableMorphItem';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
import { capitalize } from 'twenty-shared/utils';
import { Avatar } from 'twenty-ui/display';
import { MenuItemMultiSelectAvatar } from 'twenty-ui/navigation';
@@ -42,8 +43,8 @@ export const MultipleRecordPickerMenuItemContent = ({
const selectableListComponentInstanceId =
getMultipleRecordPickerSelectableListId(componentInstanceId);
const isSelectedByKeyboard = useRecoilComponentFamilyValue(
isSelectedItemIdComponentFamilySelector,
const isSelectedByKeyboard = useRecoilComponentFamilyValueV2(
isSelectedItemIdComponentFamilyState,
searchRecord.recordId,
selectableListComponentInstanceId,
);
@@ -7,10 +7,10 @@ import { singleRecordPickerSearchableObjectMetadataItemsComponentState } from '@
import { getSingleRecordPickerSelectableListId } from '@/object-record/record-picker/single-record-picker/utils/getSingleRecordPickerSelectableListId';
import { type RecordPickerPickableMorphItem } from '@/object-record/record-picker/types/RecordPickerPickableMorphItem';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
import { useRecoilValue } from 'recoil';
import { capitalize, isDefined } from 'twenty-shared/utils';
import { Avatar } from 'twenty-ui/display';
@@ -39,8 +39,8 @@ export const SingleRecordPickerMenuItem = ({
const selectableListComponentInstanceId =
getSingleRecordPickerSelectableListId(recordPickerComponentInstanceId);
const isSelectedByKeyboard = useRecoilComponentFamilyValue(
isSelectedItemIdComponentFamilySelector,
const isSelectedByKeyboard = useRecoilComponentFamilyValueV2(
isSelectedItemIdComponentFamilyState,
morphItem.recordId,
selectableListComponentInstanceId,
);
@@ -15,12 +15,12 @@ import { singleRecordPickerShouldShowSkeletonComponentState } from '@/object-rec
import { getSingleRecordPickerSelectableListId } from '@/object-record/record-picker/single-record-picker/utils/getSingleRecordPickerSelectableListId';
import { type RecordPickerPickableMorphItem } from '@/object-record/record-picker/types/RecordPickerPickableMorphItem';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
import { type IconComponent } from 'twenty-ui/display';
import { MenuItemSelect } from 'twenty-ui/navigation';
@@ -53,8 +53,8 @@ export const SingleRecordPickerMenuItems = ({
selectableListComponentInstanceId,
);
const isSelectedSelectNoneButton = useRecoilComponentFamilyValue(
isSelectedItemIdComponentFamilySelector,
const isSelectedSelectNoneButton = useRecoilComponentFamilyValueV2(
isSelectedItemIdComponentFamilyState,
selectableListComponentInstanceId,
'select-none',
);
@@ -5,7 +5,7 @@ import { buildFindOneRecordForShowPageOperationSignature } from '@/object-record
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { recordStoreFamilyStateV2 } from '@/object-record/record-store/states/recordStoreFamilyStateV2';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { useEffect } from 'react';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
@@ -28,6 +28,8 @@ export const RecordShowEffect = ({
objectMetadataItems,
});
const store = useStore();
const { record, loading } = useFindOneRecord({
objectRecordId: recordId,
objectNameSingular,
@@ -44,13 +46,10 @@ export const RecordShowEffect = ({
if (JSON.stringify(previousRecordValue) !== JSON.stringify(newRecord)) {
set(recordStoreFamilyState(recordId), newRecord);
jotaiStore.set(
recordStoreFamilyStateV2.atomFamily(recordId),
newRecord,
);
store.set(recordStoreFamilyStateV2.atomFamily(recordId), newRecord);
}
},
[recordId],
[recordId, store],
);
useEffect(() => {
@@ -5,7 +5,7 @@ import { type RecordGqlFields } from '@/object-record/graphql/record-gql-fields/
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { recordStoreFamilyStateV2 } from '@/object-record/record-store/states/recordStoreFamilyStateV2';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { isDefined } from 'twenty-shared/utils';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
@@ -15,6 +15,8 @@ type UpsertRecordsInStoreProps = {
};
export const useUpsertRecordsInStore = () => {
const store = useStore();
const upsertRecordsInStore = useRecoilCallback(
({ set, snapshot }) =>
({ partialRecords, recordGqlFields }: UpsertRecordsInStoreProps) => {
@@ -37,7 +39,7 @@ export const useUpsertRecordsInStore = () => {
...filteredPartialRecord,
};
set(recordStoreFamilyState(partialRecord.id), newRecord);
jotaiStore.set(
store.set(
recordStoreFamilyStateV2.atomFamily(partialRecord.id),
newRecord,
);
@@ -57,14 +59,14 @@ export const useUpsertRecordsInStore = () => {
...filteredPartialRecord,
};
set(recordStoreFamilyState(partialRecord.id), updatedRecord);
jotaiStore.set(
store.set(
recordStoreFamilyStateV2.atomFamily(partialRecord.id),
updatedRecord,
);
}
}
},
[],
[store],
);
return {
@@ -17,7 +17,7 @@ import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentFamilyCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyCallbackState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useStore } from 'jotai';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { isDefined } from 'twenty-shared/utils';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
@@ -69,6 +69,7 @@ export const useSetRecordTableData = ({
const { unfocusRecordTableCell } = useUnfocusRecordTableCell(recordTableId);
const { unfocusRecordTableRow } = useFocusedRecordTableRow(recordTableId);
const store = useStore();
return useRecoilCallback(
({ set, snapshot }) =>
@@ -92,7 +93,7 @@ export const useSetRecordTableData = ({
};
set(recordStoreFamilyState(record.id), newRecord);
jotaiStore.set(
store.set(
recordStoreFamilyStateV2.atomFamily(record.id),
newRecord,
);
@@ -162,6 +163,7 @@ export const useSetRecordTableData = ({
isRowSelectedFamilyState,
recordIdByRealIndexCallbackSelector,
isRecordTableInitialLoadingCallbackState,
store,
],
);
};
@@ -8,7 +8,7 @@ import { PAGE_ACTION_CONTAINER_CLICK_OUTSIDE_ID } from '@/ui/layout/page/constan
import { currentFocusedItemSelector } from '@/ui/utilities/focus/states/currentFocusedItemSelector';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useRecoilValue } from 'recoil';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
type RecordTableBodyFocusClickOutsideEffectProps = {
tableBodyRef: React.RefObject<HTMLDivElement>;
};
@@ -20,7 +20,7 @@ export const RecordTableBodyFocusClickOutsideEffect = ({
const leaveTableFocus = useLeaveTableFocus(recordTableId);
const currentFocusedItem = useRecoilValue(currentFocusedItemSelector);
const currentFocusedItem = useRecoilValueV2(currentFocusedItemSelector);
const componentType = currentFocusedItem?.componentInstance.componentType;
@@ -11,10 +11,12 @@ import {
import { useRecordTableBodyContextOrThrow } from '@/object-record/record-table/contexts/RecordTableBodyContext';
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
export const RecordTableCellFieldInput = () => {
const { onMoveFocus, onCloseTableCell } = useRecordTableBodyContextOrThrow();
const store = useStore();
const instanceId = useAvailableComponentInstanceId(
RecordFieldComponentInstanceContext,
@@ -44,26 +46,23 @@ export const RecordTableCellFieldInput = () => {
onCloseTableCell();
};
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
({ snapshot }) =>
({ newValue, event, skipPersist }) => {
const currentFocusId = snapshot
.getLoadable(currentFocusIdSelector)
.getValue();
const handleClickOutside: FieldInputClickOutsideEvent = useCallback(
({ newValue, event, skipPersist }) => {
const currentFocusId = store.get(currentFocusIdSelector.atom);
if (currentFocusId !== instanceId) {
return;
}
event?.preventDefault();
event?.stopImmediatePropagation();
if (currentFocusId !== instanceId) {
return;
}
event?.preventDefault();
event?.stopImmediatePropagation();
if (skipPersist !== true) {
persistFieldFromFieldInputContext(newValue);
}
if (skipPersist !== true) {
persistFieldFromFieldInputContext(newValue);
}
onCloseTableCell();
},
[onCloseTableCell, instanceId, persistFieldFromFieldInputContext],
onCloseTableCell();
},
[onCloseTableCell, instanceId, persistFieldFromFieldInputContext, store],
);
const handleEscape: FieldInputEvent = ({ newValue, skipPersist }) => {
@@ -1,5 +1,3 @@
import { useRecoilCallback } from 'recoil';
import { FOCUS_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/FocusClickOutsideListenerId';
import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId';
import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect';
@@ -8,10 +6,12 @@ import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useC
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
import { useCloseCurrentTableCellInEditMode } from '@/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode';
import { clickOutsideListenerIsActivatedComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsActivatedComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useStore } from 'jotai';
import { useCallback } from 'react';
export const useCloseRecordTableCellInGroup = () => {
const { recordTableId } = useRecordTableContextOrThrow();
const store = useStore();
const { setDragSelectionStartEnabled } = useDragSelect();
@@ -22,26 +22,22 @@ export const useCloseRecordTableCellInGroup = () => {
const closeCurrentTableCellInEditMode =
useCloseCurrentTableCellInEditMode(recordTableId);
const clickOutsideListenerIsActivatedState = useRecoilComponentCallbackState(
clickOutsideListenerIsActivatedComponentState,
RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
);
const closeTableCellInGroup = useRecoilCallback(
({ set }) =>
() => {
toggleClickOutside(true);
setDragSelectionStartEnabled(true);
closeCurrentTableCellInEditMode();
set(clickOutsideListenerIsActivatedState, true);
},
[
clickOutsideListenerIsActivatedState,
closeCurrentTableCellInEditMode,
setDragSelectionStartEnabled,
toggleClickOutside,
],
);
const closeTableCellInGroup = useCallback(() => {
toggleClickOutside(true);
setDragSelectionStartEnabled(true);
closeCurrentTableCellInEditMode();
store.set(
clickOutsideListenerIsActivatedComponentState.atomFamily({
instanceId: RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
}),
true,
);
}, [
closeCurrentTableCellInEditMode,
setDragSelectionStartEnabled,
toggleClickOutside,
store,
]);
return {
closeTableCellInGroup,
@@ -6,11 +6,12 @@ import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-t
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
import { useCloseCurrentTableCellInEditMode } from '@/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode';
import { clickOutsideListenerIsActivatedComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsActivatedComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilCallback } from 'recoil';
import { useStore } from 'jotai';
import { useCallback } from 'react';
export const useCloseRecordTableCellNoGroup = () => {
const { recordTableId } = useRecordTableContextOrThrow();
const store = useStore();
const { setDragSelectionStartEnabled } = useDragSelect();
@@ -21,26 +22,22 @@ export const useCloseRecordTableCellNoGroup = () => {
const closeCurrentTableCellInEditMode =
useCloseCurrentTableCellInEditMode(recordTableId);
const clickOutsideListenerIsActivatedState = useRecoilComponentCallbackState(
clickOutsideListenerIsActivatedComponentState,
RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
);
const closeTableCellNoGroup = useRecoilCallback(
({ set }) =>
() => {
toggleClickOutside(true);
setDragSelectionStartEnabled(true);
closeCurrentTableCellInEditMode();
set(clickOutsideListenerIsActivatedState, true);
},
[
clickOutsideListenerIsActivatedState,
closeCurrentTableCellInEditMode,
setDragSelectionStartEnabled,
toggleClickOutside,
],
);
const closeTableCellNoGroup = useCallback(() => {
toggleClickOutside(true);
setDragSelectionStartEnabled(true);
closeCurrentTableCellInEditMode();
store.set(
clickOutsideListenerIsActivatedComponentState.atomFamily({
instanceId: RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
}),
true,
);
}, [
closeCurrentTableCellInEditMode,
setDragSelectionStartEnabled,
toggleClickOutside,
store,
]);
return {
closeTableCellNoGroup,
@@ -28,8 +28,8 @@ import { useFocusedRecordTableRow } from '@/object-record/record-table/hooks/use
import { useFocusRecordTableCell } from '@/object-record/record-table/record-table-cell/hooks/useFocusRecordTableCell';
import { isRecordTableRowFocusActiveComponentState } from '@/object-record/record-table/states/isRecordTableRowFocusActiveComponentState';
import { clickOutsideListenerIsActivatedComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsActivatedComponentState';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useStore } from 'jotai';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
export type OpenTableCellArgs = {
@@ -43,11 +43,8 @@ export type OpenTableCellArgs = {
export const useOpenRecordTableCell = (recordTableId: string) => {
const { scopeInstanceId } = useRecordFieldsScopeContextOrThrow();
const store = useStore();
const clickOutsideListenerIsActivatedState = useRecoilComponentCallbackState(
clickOutsideListenerIsActivatedComponentState,
RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
);
const setCurrentTableCellInEditModePosition = useSetRecoilComponentState(
recordTableCellEditModePositionComponentState,
recordTableId,
@@ -82,7 +79,7 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
const { openRecordFromIndexView } = useOpenRecordFromIndexView();
const openTableCell = useRecoilCallback(
({ snapshot, set }) =>
({ snapshot }) =>
({
initialValue,
cellPosition,
@@ -91,7 +88,12 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
recordId,
isNavigating,
}: OpenTableCellArgs) => {
set(clickOutsideListenerIsActivatedState, false);
store.set(
clickOutsideListenerIsActivatedComponentState.atomFamily({
instanceId: RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
}),
false,
);
const isFirstColumnCell = cellPosition.column === 0;
@@ -169,7 +171,6 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
);
},
[
clickOutsideListenerIsActivatedState,
deactivateRecordTableRow,
focusRecordTableCell,
setIsRowFocusActive,
@@ -184,6 +185,7 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
openRecordFromIndexView,
activateRecordTableRow,
unfocusRecordTableRow,
store,
],
);
@@ -9,7 +9,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { t } from '@lingui/core/macro';
import { Avatar } from 'twenty-ui/display';
import { MenuItem, MenuItemMultiSelectAvatar } from 'twenty-ui/navigation';
@@ -39,7 +39,7 @@ export const MultipleSelectDropdown = ({
const { resetSelectedItem } = useSelectableList(selectableListId);
const selectedItemId = useRecoilComponentValue(
const selectedItemId = useRecoilComponentValueV2(
selectedItemIdComponentState,
selectableListId,
);
@@ -9,6 +9,7 @@ import { calculateTotalGridRows } from '@/page-layout/utils/calculateTotalGridRo
import { generateCellId } from '@/page-layout/utils/generateCellId';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import styled from '@emotion/styled';
import { useMemo } from 'react';
@@ -60,7 +61,7 @@ export const PageLayoutGridOverlay = () => {
pageLayoutCurrentLayoutsComponentState,
);
const activeTabId = useRecoilComponentValue(activeTabIdComponentState);
const activeTabId = useRecoilComponentValueV2(activeTabIdComponentState);
const { createWidgetFromClick } = useCreateWidgetFromClick();
@@ -21,6 +21,7 @@ import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTab
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
@@ -59,7 +60,7 @@ export const PageLayoutRendererContent = () => {
isPageLayoutInEditModeComponentState,
);
const activeTabId = useRecoilComponentValue(activeTabIdComponentState);
const activeTabId = useRecoilComponentValueV2(activeTabIdComponentState);
const { createPageLayoutTab } = useCreatePageLayoutTab(currentPageLayout?.id);
const { reorderTabs } = useReorderPageLayoutTabs(currentPageLayout?.id ?? '');
@@ -24,8 +24,8 @@ import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/con
import { type TabListProps } from '@/ui/layout/tab-list/types/TabListProps';
import { NodeDimension } from '@/ui/utilities/dimensions/components/NodeDimension';
import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useNavigatePageLayoutCommandMenu } from '@/command-menu/pages/page-layout/hooks/useNavigatePageLayoutCommandMenu';
import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages';
@@ -115,7 +115,7 @@ export const PageLayoutTabList = ({
const navigate = useNavigate();
const [activeTabId, setActiveTabId] = useRecoilComponentState(
const [activeTabId, setActiveTabId] = useRecoilComponentStateV2(
activeTabIdComponentState,
componentInstanceId,
);
@@ -4,7 +4,7 @@ import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingC
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { type TabListProps } from '@/ui/layout/tab-list/types/TabListProps';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useEffect } from 'react';
type PageLayoutTabListEffectProps = Pick<
@@ -21,7 +21,7 @@ export const PageLayoutTabListEffect = ({
componentInstanceId,
defaultTabToFocusOnMobileAndSidePanelId,
}: PageLayoutTabListEffectProps) => {
const [activeTabId, setActiveTabId] = useRecoilComponentState(
const [activeTabId, setActiveTabId] = useRecoilComponentStateV2(
activeTabIdComponentState,
componentInstanceId,
);
@@ -1,7 +1,12 @@
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutId';
import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/contexts/TabListComponentInstanceContext';
import { type ReactNode } from 'react';
import {
createStore,
type getDefaultStore,
Provider as JotaiProvider,
} from 'jotai';
import { type ReactNode, useState } from 'react';
import { RecoilRoot, type MutableSnapshot } from 'recoil';
export const PAGE_LAYOUT_TEST_INSTANCE_ID =
@@ -11,22 +16,28 @@ export const PageLayoutTestWrapper = ({
children,
initializeState,
instanceId: instanceIdFromProps,
store: storeFromProps,
}: {
children: ReactNode;
initializeState?: (snapshot: MutableSnapshot) => void;
instanceId?: string;
store?: ReturnType<typeof getDefaultStore>;
}) => {
const instanceId = instanceIdFromProps ?? PAGE_LAYOUT_TEST_INSTANCE_ID;
const [defaultStore] = useState(() => createStore());
const store = storeFromProps ?? defaultStore;
return (
<PageLayoutComponentInstanceContext.Provider value={{ instanceId }}>
<TabListComponentInstanceContext.Provider
value={{
instanceId: getTabListInstanceIdFromPageLayoutId(instanceId),
}}
>
<RecoilRoot initializeState={initializeState}>{children}</RecoilRoot>
</TabListComponentInstanceContext.Provider>
</PageLayoutComponentInstanceContext.Provider>
<JotaiProvider store={store}>
<PageLayoutComponentInstanceContext.Provider value={{ instanceId }}>
<TabListComponentInstanceContext.Provider
value={{
instanceId: getTabListInstanceIdFromPageLayoutId(instanceId),
}}
>
<RecoilRoot initializeState={initializeState}>{children}</RecoilRoot>
</TabListComponentInstanceContext.Provider>
</PageLayoutComponentInstanceContext.Provider>
</JotaiProvider>
);
};
@@ -6,7 +6,7 @@ import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTab
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { act, renderHook } from '@testing-library/react';
import { useSetRecoilState } from 'recoil';
import { useSetAtom } from 'jotai';
import { isDefined } from 'twenty-shared/utils';
import {
PageLayoutType,
@@ -30,7 +30,7 @@ describe('useCreatePageLayoutGraphWidget', () => {
it('should create widget in the correct tab with isolated layouts', () => {
const { result } = renderHook(
() => {
const setActiveTabId = useSetRecoilState(
const setActiveTabId = useSetAtom(
activeTabIdComponentState.atomFamily({
instanceId: `${PAGE_LAYOUT_TEST_INSTANCE_ID}-tab-list`,
}),
@@ -113,7 +113,7 @@ describe('useCreatePageLayoutGraphWidget', () => {
pageLayoutDraftComponentState,
PAGE_LAYOUT_TEST_INSTANCE_ID,
);
const setActiveTabId = useSetRecoilState(
const setActiveTabId = useSetAtom(
activeTabIdComponentState.atomFamily({
instanceId: `${PAGE_LAYOUT_TEST_INSTANCE_ID}-tab-list`,
}),
@@ -3,9 +3,10 @@ import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pag
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { act, renderHook } from '@testing-library/react';
import { useSetRecoilState } from 'recoil';
import { useSetAtom } from 'jotai';
import { PageLayoutType } from '~/generated-metadata/graphql';
import {
PAGE_LAYOUT_TEST_INSTANCE_ID,
@@ -36,7 +37,7 @@ describe('useCreatePageLayoutTab', () => {
pageLayoutCurrentLayoutsComponentState,
PAGE_LAYOUT_TEST_INSTANCE_ID,
),
activeTabId: useSetRecoilState(
activeTabId: useSetAtom(
activeTabIdComponentState.atomFamily({
instanceId: `${PAGE_LAYOUT_TEST_INSTANCE_ID}-tab-list`,
}),
@@ -174,7 +175,7 @@ describe('useCreatePageLayoutTab', () => {
const { result } = renderHook(
() => {
const getActiveTabId = useRecoilComponentValue(
const getActiveTabId = useRecoilComponentValueV2(
activeTabIdComponentState,
`${PAGE_LAYOUT_TEST_INSTANCE_ID}-tab-list`,
);
@@ -1,6 +1,7 @@
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { act, renderHook } from '@testing-library/react';
import { useSetAtom } from 'jotai';
import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState';
import { usePageLayoutHandleLayoutChange } from '@/page-layout/hooks/usePageLayoutHandleLayoutChange';
import {
@@ -17,25 +18,21 @@ describe('usePageLayoutHandleLayoutChange', () => {
pageLayoutCurrentLayoutsComponentState,
PAGE_LAYOUT_TEST_INSTANCE_ID,
),
setActiveTabId: useSetAtom(
activeTabIdComponentState.atomFamily({
instanceId: `${PAGE_LAYOUT_TEST_INSTANCE_ID}-tab-list`,
}),
),
}),
{
wrapper: ({ children }) => (
<PageLayoutTestWrapper
initializeState={({ set }) => {
set(
activeTabIdComponentState.atomFamily({
instanceId: `${PAGE_LAYOUT_TEST_INSTANCE_ID}-tab-list`,
}),
'tab-1',
);
}}
>
{children}
</PageLayoutTestWrapper>
),
wrapper: PageLayoutTestWrapper,
},
);
act(() => {
result.current.setActiveTabId('tab-1');
});
const newLayouts = {
desktop: [
{ i: 'widget-1', x: 2, y: 3, w: 4, h: 5 },
@@ -52,7 +49,7 @@ describe('usePageLayoutHandleLayoutChange', () => {
});
expect(result.current.layouts['tab-1']).toEqual(newLayouts);
expect(result.current.layouts['tab-1']).not.toBe(newLayouts); // Ensure a clone was set, not the same reference
expect(result.current.layouts['tab-1']).not.toBe(newLayouts);
expect(result.current.layouts['tab-2']).toBeUndefined();
});
@@ -64,25 +61,21 @@ describe('usePageLayoutHandleLayoutChange', () => {
pageLayoutCurrentLayoutsComponentState,
PAGE_LAYOUT_TEST_INSTANCE_ID,
),
setActiveTabId: useSetAtom(
activeTabIdComponentState.atomFamily({
instanceId: `${PAGE_LAYOUT_TEST_INSTANCE_ID}-tab-list`,
}),
),
}),
{
wrapper: ({ children }) => (
<PageLayoutTestWrapper
initializeState={({ set }) => {
set(
activeTabIdComponentState.atomFamily({
instanceId: `${PAGE_LAYOUT_TEST_INSTANCE_ID}-tab-list`,
}),
'tab-1',
);
}}
>
{children}
</PageLayoutTestWrapper>
),
wrapper: PageLayoutTestWrapper,
},
);
act(() => {
result.current.setActiveTabId('tab-1');
});
const tab1Layouts = {
desktop: [{ i: 'widget-1', x: 0, y: 0, w: 2, h: 2 }],
mobile: [{ i: 'widget-1', x: 0, y: 0, w: 1, h: 2 }],
@@ -92,8 +85,6 @@ describe('usePageLayoutHandleLayoutChange', () => {
result.current.handler.handleLayoutChange([], tab1Layouts);
});
// Unfortunately we can't properly test tab switching with the current renderHook API
// since we can't change the activeTabId after initialization in a simple way
expect(result.current.layouts['tab-1']).toEqual(tab1Layouts);
});
@@ -12,7 +12,7 @@ import { getUpdatedTabLayouts } from '@/page-layout/utils/getUpdatedTabLayouts';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { v4 as uuidv4 } from 'uuid';
@@ -26,7 +26,7 @@ export const useCreatePageLayoutFrontComponentWidget = (
pageLayoutIdFromProps,
);
const activeTabId = useRecoilComponentValue(
const activeTabId = useRecoilComponentValueV2(
activeTabIdComponentState,
getTabListInstanceIdFromPageLayoutId(pageLayoutId),
);
@@ -16,6 +16,7 @@ import { getWidgetTitle } from '@/page-layout/utils/getWidgetTitle';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { v4 as uuidv4 } from 'uuid';
@@ -33,15 +34,11 @@ export const useCreatePageLayoutGraphWidget = (
pageLayoutIdFromProps,
);
const store = useStore();
const { timeZone, calendarStartDay } = useDateTimeFormat();
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
const activeTabIdState = useRecoilComponentCallbackState(
activeTabIdComponentState,
tabListInstanceId,
);
const pageLayoutDraftState = useRecoilComponentCallbackState(
pageLayoutDraftComponentState,
pageLayoutId,
@@ -64,7 +61,11 @@ export const useCreatePageLayoutGraphWidget = (
}: {
fieldSelection?: GraphWidgetFieldSelection;
}): PageLayoutWidget => {
const activeTabId = snapshot.getLoadable(activeTabIdState).getValue();
const activeTabId = store.get(
activeTabIdComponentState.atomFamily({
instanceId: tabListInstanceId,
}),
);
if (!isDefined(activeTabId)) {
throw new Error(
@@ -166,12 +167,13 @@ export const useCreatePageLayoutGraphWidget = (
return newWidget;
},
[
activeTabIdState,
tabListInstanceId,
pageLayoutCurrentLayoutsState,
pageLayoutDraftState,
pageLayoutDraggedAreaState,
timeZone,
calendarStartDay,
store,
],
);
@@ -12,7 +12,7 @@ import { getUpdatedTabLayouts } from '@/page-layout/utils/getUpdatedTabLayouts';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { v4 as uuidv4 } from 'uuid';
@@ -26,7 +26,7 @@ export const useCreatePageLayoutIframeWidget = (
pageLayoutIdFromProps,
);
const activeTabId = useRecoilComponentValue(
const activeTabId = useRecoilComponentValueV2(
activeTabIdComponentState,
getTabListInstanceIdFromPageLayoutId(pageLayoutId),
);
@@ -11,6 +11,7 @@ import { getUpdatedTabLayouts } from '@/page-layout/utils/getUpdatedTabLayouts';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { v4 as uuidv4 } from 'uuid';
@@ -28,10 +29,8 @@ export const useCreatePageLayoutStandaloneRichTextWidget = (
pageLayoutIdFromProps,
);
const activeTabIdState = useRecoilComponentCallbackState(
activeTabIdComponentState,
getTabListInstanceIdFromPageLayoutId(pageLayoutId),
);
const store = useStore();
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
const pageLayoutCurrentLayoutsState = useRecoilComponentCallbackState(
pageLayoutCurrentLayoutsComponentState,
@@ -51,7 +50,11 @@ export const useCreatePageLayoutStandaloneRichTextWidget = (
const createPageLayoutStandaloneRichTextWidget = useRecoilCallback(
({ snapshot, set }) =>
(body: RichTextV2Body): PageLayoutWidget => {
const activeTabId = snapshot.getLoadable(activeTabIdState).getValue();
const activeTabId = store.get(
activeTabIdComponentState.atomFamily({
instanceId: tabListInstanceId,
}),
);
if (!isDefined(activeTabId)) {
throw new Error(
@@ -118,10 +121,11 @@ export const useCreatePageLayoutStandaloneRichTextWidget = (
return newWidget;
},
[
activeTabIdState,
tabListInstanceId,
pageLayoutCurrentLayoutsState,
pageLayoutDraftState,
pageLayoutDraggedAreaState,
store,
],
);
@@ -7,7 +7,7 @@ import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTab
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { useRecoilCallback } from 'recoil';
import { v4 as uuidv4 } from 'uuid';
@@ -28,7 +28,7 @@ export const useCreatePageLayoutTab = (pageLayoutIdFromProps?: string) => {
);
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
const setActiveTabId = useSetRecoilComponentState(
const setActiveTabId = useSetRecoilComponentStateV2(
activeTabIdComponentState,
tabListInstanceId,
);
@@ -7,6 +7,7 @@ import { sortTabsByPosition } from '@/page-layout/utils/sortTabsByPosition';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
export const useDeletePageLayoutTab = (pageLayoutIdFromProps?: string) => {
@@ -25,11 +26,12 @@ export const useDeletePageLayoutTab = (pageLayoutIdFromProps?: string) => {
pageLayoutId,
);
const store = useStore();
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
const activeTabIdState = useRecoilComponentCallbackState(
activeTabIdComponentState,
tabListInstanceId,
);
const activeTabIdAtom = activeTabIdComponentState.atomFamily({
instanceId: tabListInstanceId,
});
const deleteTab = useRecoilCallback(
({ set, snapshot }) =>
@@ -42,7 +44,7 @@ export const useDeletePageLayoutTab = (pageLayoutIdFromProps?: string) => {
const sorted = sortTabsByPosition(draft.tabs);
const index = sorted.findIndex((t) => t.id === tabId);
const activeTabId = snapshot.getLoadable(activeTabIdState).getValue();
const activeTabId = store.get(activeTabIdAtom);
const allLayouts = snapshot
.getLoadable(pageLayoutCurrentLayoutsState)
@@ -58,10 +60,15 @@ export const useDeletePageLayoutTab = (pageLayoutIdFromProps?: string) => {
if (activeTabId === tabId) {
const neighbor = index > 0 ? sorted[index - 1] : sorted[index + 1];
const nextActiveId = neighbor?.id ?? null;
set(activeTabIdState, nextActiveId);
store.set(activeTabIdAtom, nextActiveId);
}
},
[pageLayoutCurrentLayoutsState, pageLayoutDraftState, activeTabIdState],
[
pageLayoutCurrentLayoutsState,
pageLayoutDraftState,
activeTabIdAtom,
store,
],
);
return { deleteTab };
@@ -14,6 +14,7 @@ import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTab
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
import { useRecoilCallback } from 'recoil';
import { appendCopySuffix, isDefined } from 'twenty-shared/utils';
import { v4 as uuidv4 } from 'uuid';
@@ -35,7 +36,7 @@ export const useDuplicatePageLayoutTab = (pageLayoutIdFromProps?: string) => {
);
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
const setActiveTabId = useSetRecoilComponentState(
const setActiveTabId = useSetRecoilComponentStateV2(
activeTabIdComponentState,
tabListInstanceId,
);
@@ -3,6 +3,7 @@ import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTab
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useStore } from 'jotai';
import { type Layout, type Layouts } from 'react-grid-layout';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
@@ -18,13 +19,9 @@ export const usePageLayoutHandleLayoutChange = (
pageLayoutIdFromProps,
);
const store = useStore();
const tabListInstanceId = getTabListInstanceIdFromPageLayoutId(pageLayoutId);
const activeTabIdState = useRecoilComponentCallbackState(
activeTabIdComponentState,
tabListInstanceId,
);
const pageLayoutCurrentLayoutsState = useRecoilComponentCallbackState(
pageLayoutCurrentLayoutsComponentState,
pageLayoutId,
@@ -38,7 +35,11 @@ export const usePageLayoutHandleLayoutChange = (
const handleLayoutChange = useRecoilCallback(
({ snapshot, set }) =>
(_: Layout[], allLayouts: Layouts) => {
const activeTabId = snapshot.getLoadable(activeTabIdState).getValue();
const activeTabId = store.get(
activeTabIdComponentState.atomFamily({
instanceId: tabListInstanceId,
}),
);
if (!isDefined(activeTabId)) return;
@@ -84,7 +85,12 @@ export const usePageLayoutHandleLayoutChange = (
}));
}
},
[activeTabIdState, pageLayoutCurrentLayoutsState, pageLayoutDraftState],
[
tabListInstanceId,
pageLayoutCurrentLayoutsState,
pageLayoutDraftState,
store,
],
);
return { handleLayoutChange };
@@ -7,6 +7,7 @@ import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTab
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useStore } from 'jotai';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
@@ -18,6 +19,7 @@ export const useResetDraftPageLayoutToPersistedPageLayout = (
pageLayoutIdFromProps,
);
const store = useStore();
const tabListComponentInstanceId =
getTabListInstanceIdFromPageLayoutId(componentInstanceId);
@@ -36,10 +38,9 @@ export const useResetDraftPageLayoutToPersistedPageLayout = (
componentInstanceId,
);
const activeTabIdState = useRecoilComponentCallbackState(
activeTabIdComponentState,
tabListComponentInstanceId,
);
const activeTabIdAtom = activeTabIdComponentState.atomFamily({
instanceId: tabListComponentInstanceId,
});
const resetDraftPageLayoutToPersistedPageLayout = useRecoilCallback(
({ set, snapshot }) =>
@@ -49,9 +50,7 @@ export const useResetDraftPageLayoutToPersistedPageLayout = (
.getValue();
if (isDefined(pageLayoutPersisted)) {
const currentActiveTabId = snapshot
.getLoadable(activeTabIdState)
.getValue();
const currentActiveTabId = store.get(activeTabIdAtom);
const persistedTabIds = pageLayoutPersisted.tabs.map((tab) => tab.id);
const isActiveTabInPersistedTabs =
@@ -61,7 +60,7 @@ export const useResetDraftPageLayoutToPersistedPageLayout = (
!isActiveTabInPersistedTabs &&
pageLayoutPersisted.tabs.length > 0
) {
set(activeTabIdState, pageLayoutPersisted.tabs[0].id);
store.set(activeTabIdAtom, pageLayoutPersisted.tabs[0].id);
}
set(pageLayoutDraftState, {
@@ -80,7 +79,8 @@ export const useResetDraftPageLayoutToPersistedPageLayout = (
pageLayoutDraftState,
pageLayoutPersistedState,
pageLayoutCurrentLayoutsState,
activeTabIdState,
activeTabIdAtom,
store,
],
);

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