121788c42f
## Summary Removes the `recoil` dependency entirely from `package.json` and `twenty-front/package.json`, completing the migration to Jotai as the sole state management library. Removes all Recoil infrastructure: `RecoilRoot` wrapper from `App.tsx` and test decorators, `RecoilDebugObserver`, Recoil-specific ESLint rules (`use-getLoadable-and-getValue-to-get-atoms`, `useRecoilCallback-has-dependency-array`), and legacy Recoil utility hooks/types (`useRecoilComponentState`, `useRecoilComponentValue`, `createComponentState`, `createFamilyState`, `getSnapshotValue`, `cookieStorageEffect`, `localStorageEffect`, etc.). Renames all `V2`-suffixed Jotai state files and types to their canonical names (e.g., `ComponentStateV2` -> `ComponentState`, `agentChatInputStateV2` -> `agentChatInputState`, `SelectorCallbacksV2` -> `SelectorCallbacks`), and removes the now-redundant V1 counterparts. Updates ~433 files across the codebase to use the renamed Jotai imports, remove Recoil imports, and clean up test wrappers (`RecoilRootDecorator` -> `JotaiRootDecorator`).
68 lines
2.6 KiB
TypeScript
68 lines
2.6 KiB
TypeScript
import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId';
|
|
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
|
|
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
|
import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState';
|
|
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
|
import { addToNavPayloadRegistryState } from '@/navigation-menu-item/states/addToNavPayloadRegistryState';
|
|
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
|
import { emitSidePanelOpenEvent } from '@/ui/layout/right-drawer/utils/emitSidePanelOpenEvent';
|
|
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
|
import { t } from '@lingui/core/macro';
|
|
import { useCallback } from 'react';
|
|
import { CommandMenuPages } from 'twenty-shared/types';
|
|
import { IconDotsVertical } from 'twenty-ui/display';
|
|
import { useStore } from 'jotai';
|
|
|
|
export const useCommandMenu = () => {
|
|
const store = useStore();
|
|
const { navigateCommandMenu } = useNavigateCommandMenu();
|
|
const { closeAnyOpenDropdown } = useCloseAnyOpenDropdown();
|
|
|
|
const { removeFocusItemFromFocusStackById } =
|
|
useRemoveFocusItemFromFocusStackById();
|
|
|
|
const closeCommandMenu = useCallback(() => {
|
|
const isCommandMenuOpened = store.get(isCommandMenuOpenedState.atom);
|
|
|
|
if (isCommandMenuOpened) {
|
|
store.set(addToNavPayloadRegistryState.atom, new Map());
|
|
store.set(isCommandMenuOpenedState.atom, false);
|
|
store.set(isCommandMenuClosingState.atom, true);
|
|
closeAnyOpenDropdown();
|
|
removeFocusItemFromFocusStackById({
|
|
focusId: SIDE_PANEL_FOCUS_ID,
|
|
});
|
|
}
|
|
}, [closeAnyOpenDropdown, removeFocusItemFromFocusStackById, store]);
|
|
|
|
const openCommandMenu = useCallback(() => {
|
|
emitSidePanelOpenEvent();
|
|
closeAnyOpenDropdown();
|
|
navigateCommandMenu({
|
|
page: CommandMenuPages.Root,
|
|
pageTitle: t`Command Menu`,
|
|
pageIcon: IconDotsVertical,
|
|
resetNavigationStack: true,
|
|
});
|
|
}, [closeAnyOpenDropdown, navigateCommandMenu]);
|
|
|
|
const toggleCommandMenu = useCallback(() => {
|
|
const isCommandMenuOpened = store.get(isCommandMenuOpenedState.atom);
|
|
|
|
store.set(commandMenuSearchState.atom, '');
|
|
|
|
if (isCommandMenuOpened) {
|
|
closeCommandMenu();
|
|
} else {
|
|
openCommandMenu();
|
|
}
|
|
}, [closeCommandMenu, openCommandMenu, store]);
|
|
|
|
return {
|
|
openCommandMenu,
|
|
closeCommandMenu,
|
|
navigateCommandMenu,
|
|
toggleCommandMenu,
|
|
};
|
|
};
|