Rename Jotai state hooks and utilities to consistent Atom-based naming (#18209)

## Summary

Rename all Jotai-based state management hooks and utilities to a
consistent naming convention that:
1. Removes legacy Recoil naming (`useRecoilXxxV2`, `createXxxV2`)
2. Always includes `Atom` in the name to distinguish from jotai native
hooks
3. Follows a consistent ordering: `Atom` → `Component` → `Family` →
`Type` (`State`/`Selector`)
4. Includes the type qualifier (`State` or `Selector`) in all
value-reading hooks to avoid naming conflicts with jotai's native
`useAtomValue`

## Naming Convention

**Hooks**:
`use[Set]Atom[Component][Family][State|Selector][Value|State|CallbackState]`
**Utils**: `createAtom[Component][Family][State|Selector]`

## Changes

### Hooks renamed (definition files + all usages across ~1,500 files):

| Old Name (Recoil) | Intermediate (Atom) | Final Name |
|---|---|---|
| `useRecoilValueV2` | `useAtomValue` | **`useAtomStateValue`** |
| `useRecoilStateV2` | `useAtomState` | `useAtomState` |
| `useSetRecoilStateV2` | `useSetAtomState` | `useSetAtomState` |
| `useFamilyRecoilValueV2` | `useFamilyAtomValue` |
**`useAtomFamilyStateValue`** |
| `useSetFamilyRecoilStateV2` | `useSetFamilyAtomState` |
**`useSetAtomFamilyState`** |
| `useFamilySelectorValueV2` | `useFamilySelectorValue` |
**`useAtomFamilySelectorValue`** |
| `useFamilySelectorStateV2` | `useFamilySelectorState` |
**`useAtomFamilySelectorState`** |
| `useRecoilComponentValueV2` | `useAtomComponentValue` |
**`useAtomComponentStateValue`** |
| `useRecoilComponentStateV2` | `useAtomComponentState` |
`useAtomComponentState` |
| `useSetRecoilComponentStateV2` | `useSetAtomComponentState` |
`useSetAtomComponentState` |
| `useRecoilComponentFamilyValueV2` | `useAtomComponentFamilyValue` |
**`useAtomComponentFamilyStateValue`** |
| `useRecoilComponentFamilyStateV2` | `useAtomComponentFamilyState` |
`useAtomComponentFamilyState` |
| `useSetRecoilComponentFamilyStateV2` |
`useSetAtomComponentFamilyState` | `useSetAtomComponentFamilyState` |
| `useRecoilComponentSelectorValueV2` | `useAtomComponentSelectorValue`
| `useAtomComponentSelectorValue` |
| `useRecoilComponentFamilySelectorValueV2` |
`useAtomComponentFamilySelectorValue` |
`useAtomComponentFamilySelectorValue` |
| `useRecoilComponentStateCallbackStateV2` |
`useAtomComponentStateCallbackState` |
`useAtomComponentStateCallbackState` |
| `useRecoilComponentSelectorCallbackStateV2` |
`useAtomComponentSelectorCallbackState` |
`useAtomComponentSelectorCallbackState` |
| `useRecoilComponentFamilyStateCallbackStateV2` |
`useAtomComponentFamilyStateCallbackState` |
`useAtomComponentFamilyStateCallbackState` |
| `useRecoilComponentFamilySelectorCallbackStateV2` |
`useAtomComponentFamilySelectorCallbackState` |
`useAtomComponentFamilySelectorCallbackState` |

### Utilities renamed:

| Old Name (Recoil) | Final Name |
|---|---|
| `createStateV2` | **`createAtomState`** |
| `createFamilyStateV2` | **`createAtomFamilyState`** |
| `createSelectorV2` | **`createAtomSelector`** |
| `createFamilySelectorV2` | **`createAtomFamilySelector`** |
| `createWritableSelectorV2` | **`createAtomWritableSelector`** |
| `createWritableFamilySelectorV2` |
**`createAtomWritableFamilySelector`** |
| `createComponentStateV2` | **`createAtomComponentState`** |
| `createComponentFamilyStateV2` | **`createAtomComponentFamilyState`**
|
| `createComponentSelectorV2` | **`createAtomComponentSelector`** |
| `createComponentFamilySelectorV2` |
**`createAtomComponentFamilySelector`** |

## Details

- All definition files renamed to match new convention
- All import paths and usages updated across the entire `twenty-front`
package
- Jotai's native `useAtomValue` is aliased as `useJotaiAtomValue` in the
wrapper hook to avoid collision
- Legacy Recoil files in `state/utils/` and `component-state/utils/`
left untouched (separate naming scope)
- Typecheck passes cleanly
This commit is contained in:
Charles Bochet
2026-02-25 01:55:46 +01:00
committed by GitHub
parent eaf9fe27b2
commit d81f006979
1890 changed files with 6399 additions and 6420 deletions
@@ -16,8 +16,8 @@ import { hasUserSelectedCommandState } from '@/command-menu/states/hasUserSelect
import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState';
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { CommandMenuPages } from 'twenty-shared/types';
import { IconList } from 'twenty-ui/display';
@@ -70,9 +70,9 @@ describe('useCommandMenuCloseAnimationCompleteCleanup', () => {
const { commandMenuCloseAnimationCompleteCleanup } =
useCommandMenuCloseAnimationCompleteCleanup();
const viewableRecordId = useRecoilValueV2(viewableRecordIdState);
const viewableRecordId = useAtomStateValue(viewableRecordIdState);
const setViewableRecordId = useSetRecoilStateV2(viewableRecordIdState);
const setViewableRecordId = useSetAtomState(viewableRecordIdState);
return {
commandMenuCloseAnimationCompleteCleanup,
@@ -5,7 +5,7 @@ import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/Com
import { useOpenCalendarEventInCommandMenu } from '@/command-menu/hooks/useOpenCalendarEventInCommandMenu';
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { CommandMenuPages } from 'twenty-shared/types';
import { IconCalendarEvent } from 'twenty-ui/display';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
@@ -46,7 +46,7 @@ const renderHooks = () => {
const { openCalendarEventInCommandMenu } =
useOpenCalendarEventInCommandMenu();
const viewableRecordId = useRecoilComponentValueV2(
const viewableRecordId = useAtomComponentStateValue(
viewableRecordIdComponentState,
'mocked-uuid',
);
@@ -5,7 +5,7 @@ import { COMMAND_MENU_COMPONENT_INSTANCE_ID } from '@/command-menu/constants/Com
import { useOpenEmailThreadInCommandMenu } from '@/command-menu/hooks/useOpenEmailThreadInCommandMenu';
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { CommandMenuPages } from 'twenty-shared/types';
import { IconMail } from 'twenty-ui/display';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
@@ -46,7 +46,7 @@ const renderHooks = () => {
const { openEmailThreadInCommandMenu } =
useOpenEmailThreadInCommandMenu();
const viewableRecordId = useRecoilComponentValueV2(
const viewableRecordId = useAtomComponentStateValue(
viewableRecordIdComponentState,
'mocked-uuid',
);
@@ -12,7 +12,7 @@ import { contextStoreCurrentViewTypeComponentState } from '@/context-store/state
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { CommandMenuPages } from 'twenty-shared/types';
import { useIcons } from 'twenty-ui/display';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
@@ -52,27 +52,27 @@ const renderHooks = () => {
() => {
const { openRecordInCommandMenu } = useOpenRecordInCommandMenu();
const viewableRecordId = useRecoilComponentValueV2(
const viewableRecordId = useAtomComponentStateValue(
viewableRecordIdComponentState,
'mocked-uuid',
);
const viewableRecordNameSingular = useRecoilComponentValueV2(
const viewableRecordNameSingular = useAtomComponentStateValue(
viewableRecordNameSingularComponentState,
'mocked-uuid',
);
const currentObjectMetadataItemId = useRecoilComponentValueV2(
const currentObjectMetadataItemId = useAtomComponentStateValue(
contextStoreCurrentObjectMetadataItemIdComponentState,
'mocked-uuid',
);
const targetedRecordsRule = useRecoilComponentValueV2(
const targetedRecordsRule = useAtomComponentStateValue(
contextStoreTargetedRecordsRuleComponentState,
'mocked-uuid',
);
const numberOfSelectedRecords = useRecoilComponentValueV2(
const numberOfSelectedRecords = useAtomComponentStateValue(
contextStoreNumberOfSelectedRecordsComponentState,
'mocked-uuid',
);
const currentViewType = useRecoilComponentValueV2(
const currentViewType = useAtomComponentStateValue(
contextStoreCurrentViewTypeComponentState,
'mocked-uuid',
);
@@ -14,7 +14,7 @@ import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-sto
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import { getPeopleRecordConnectionMock } from '~/testing/mock-data/people';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
@@ -71,32 +71,32 @@ describe('useSetGlobalCommandMenuContext', () => {
const { setGlobalCommandMenuContext } =
useSetGlobalCommandMenuContext();
const targetedRecordsRule = useRecoilComponentValueV2(
const targetedRecordsRule = useAtomComponentStateValue(
contextStoreTargetedRecordsRuleComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
const numberOfSelectedRecords = useRecoilComponentValueV2(
const numberOfSelectedRecords = useAtomComponentStateValue(
contextStoreNumberOfSelectedRecordsComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
const filters = useRecoilComponentValueV2(
const filters = useAtomComponentStateValue(
contextStoreFiltersComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
const filterGroups = useRecoilComponentValueV2(
const filterGroups = useAtomComponentStateValue(
contextStoreFilterGroupsComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
const anyFieldFilterValue = useRecoilComponentValueV2(
const anyFieldFilterValue = useAtomComponentStateValue(
contextStoreAnyFieldFilterValueComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
const currentViewType = useRecoilComponentValueV2(
const currentViewType = useAtomComponentStateValue(
contextStoreCurrentViewTypeComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
@@ -11,7 +11,7 @@ import { contextStoreCurrentViewTypeComponentState } from '@/context-store/state
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { t } from '@lingui/core/macro';
import { act } from 'react';
import { CommandMenuPages } from 'twenty-shared/types';
@@ -65,35 +65,35 @@ const renderHooks = () => {
openWorkflowViewStepInCommandMenu,
} = useWorkflowCommandMenu();
const _viewableRecordId = useRecoilComponentValueV2(
const _viewableRecordId = useAtomComponentStateValue(
viewableRecordIdComponentState,
'mocked-uuid',
);
const viewableRecordNameSingular = useRecoilComponentValueV2(
const viewableRecordNameSingular = useAtomComponentStateValue(
viewableRecordNameSingularComponentState,
'mocked-uuid',
);
const currentObjectMetadataItemId = useRecoilComponentValueV2(
const currentObjectMetadataItemId = useAtomComponentStateValue(
contextStoreCurrentObjectMetadataItemIdComponentState,
'mocked-uuid',
);
const targetedRecordsRule = useRecoilComponentValueV2(
const targetedRecordsRule = useAtomComponentStateValue(
contextStoreTargetedRecordsRuleComponentState,
'mocked-uuid',
);
const numberOfSelectedRecords = useRecoilComponentValueV2(
const numberOfSelectedRecords = useAtomComponentStateValue(
contextStoreNumberOfSelectedRecordsComponentState,
'mocked-uuid',
);
const currentViewType = useRecoilComponentValueV2(
const currentViewType = useAtomComponentStateValue(
contextStoreCurrentViewTypeComponentState,
'mocked-uuid',
);
const workflowId = useRecoilComponentValueV2(
const workflowId = useAtomComponentStateValue(
commandMenuWorkflowIdComponentState,
'mocked-uuid',
);
const workflowVersionId = useRecoilComponentValueV2(
const workflowVersionId = useAtomComponentStateValue(
commandMenuWorkflowVersionIdComponentState,
'mocked-uuid',
);
@@ -11,8 +11,8 @@ import styled from '@emotion/styled';
import { useMemo } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';
import { useFamilySelectorValueV2 } from '@/ui/utilities/state/jotai/hooks/useFamilySelectorValueV2';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
const StyledIconWrapper = styled.div`
background: ${({ theme }) => theme.background.primary};
@@ -23,21 +23,21 @@ const StyledIconWrapper = styled.div`
`;
export const useCommandMenuContextChips = () => {
const commandMenuNavigationStack = useRecoilValueV2(
const commandMenuNavigationStack = useAtomStateValue(
commandMenuNavigationStackState,
);
const allowRequestsToTwentyIcons = useRecoilValueV2(
const allowRequestsToTwentyIcons = useAtomStateValue(
allowRequestsToTwentyIconsState,
);
const objectMetadataItems = useRecoilValueV2(objectMetadataItemsState);
const objectMetadataItems = useAtomStateValue(objectMetadataItemsState);
const { navigateCommandMenuHistory } = useCommandMenuHistory();
const theme = useTheme();
const commandMenuNavigationMorphItemsByPage = useRecoilValueV2(
const commandMenuNavigationMorphItemsByPage = useAtomStateValue(
commandMenuNavigationMorphItemsByPageState,
);
@@ -47,14 +47,14 @@ export const useCommandMenuContextChips = () => {
morphItems.map((morphItem) => morphItem.recordId),
);
const recordIdentifiers = useFamilySelectorValueV2(
const recordIdentifiers = useAtomFamilySelectorValue(
recordStoreIdentifiersFamilySelector,
{
recordIds: allRecordIds,
allowRequestsToTwentyIcons,
},
);
const records = useFamilySelectorValueV2(recordStoreRecordsSelectorV2, {
const records = useAtomFamilySelectorValue(recordStoreRecordsSelectorV2, {
recordIds: allRecordIds,
});
@@ -11,10 +11,10 @@ import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/s
import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu';
import { useGlobalHotkeys } from '@/ui/utilities/hotkey/hooks/useGlobalHotkeys';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { isNonEmptyString } from '@sniptt/guards';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { Key } from 'ts-key-enum';
import { CommandMenuPages } from 'twenty-shared/types';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
@@ -30,15 +30,15 @@ export const useCommandMenuHotKeys = () => {
const { setGlobalCommandMenuContext } = useSetGlobalCommandMenuContext();
const commandMenuSearch = useRecoilValueV2(commandMenuSearchState);
const commandMenuSearch = useAtomStateValue(commandMenuSearchState);
const { closeKeyboardShortcutMenu } = useKeyboardShortcutMenu();
const commandMenuPage = useRecoilValueV2(commandMenuPageState);
const commandMenuPage = useAtomStateValue(commandMenuPageState);
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const contextStoreTargetedRecordsRuleComponent = useRecoilComponentValueV2(
const contextStoreTargetedRecordsRuleComponent = useAtomComponentStateValue(
contextStoreTargetedRecordsRuleComponentState,
COMMAND_MENU_COMPONENT_INSTANCE_ID,
);
@@ -11,7 +11,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
import { getObjectPermissionsFromMapByObjectMetadataId } from '@/settings/roles/role-permissions/objects-permissions/utils/getObjectPermissionsFromMapByObjectMetadataId';
import { t } from '@lingui/core/macro';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useMemo } from 'react';
import { AppPath } from 'twenty-shared/types';
import { Avatar } from 'twenty-ui/display';
@@ -19,7 +19,7 @@ import { useDebounce } from 'use-debounce';
import { useSearchQuery } from '~/generated/graphql';
export const useCommandMenuSearchRecords = () => {
const commandMenuSearch = useRecoilValueV2(commandMenuSearchState);
const commandMenuSearch = useAtomStateValue(commandMenuSearchState);
const coreClient = useApolloCoreClient();
const [deferredCommandMenuSearch] = useDebounce(commandMenuSearch, 300);
@@ -1,6 +1,6 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { t } from '@lingui/core/macro';
import { useCallback } from 'react';
import { CommandMenuPages } from 'twenty-shared/types';
@@ -9,7 +9,7 @@ import { v4 } from 'uuid';
export const useOpenAskAIPageInCommandMenu = () => {
const { navigateCommandMenu } = useCommandMenu();
const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2);
const isCommandMenuOpened = useAtomStateValue(isCommandMenuOpenedStateV2);
const openAskAIPage = useCallback(
({
@@ -1,6 +1,6 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { isCommandMenuOpenedStateV2 } from '@/command-menu/states/isCommandMenuOpenedStateV2';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { t } from '@lingui/core/macro';
import { CommandMenuPages } from 'twenty-shared/types';
import { IconSearch } from 'twenty-ui/display';
@@ -8,7 +8,7 @@ import { v4 } from 'uuid';
export const useOpenRecordsSearchPageInCommandMenu = () => {
const { navigateCommandMenu } = useCommandMenu();
const isCommandMenuOpened = useRecoilValueV2(isCommandMenuOpenedStateV2);
const isCommandMenuOpened = useAtomStateValue(isCommandMenuOpenedStateV2);
const openRecordsSearchPage = () => {
navigateCommandMenu({