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
@@ -2,7 +2,7 @@ import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWork
import { useReadWorkspaceUrlFromCurrentLocation } from '@/domain-manager/hooks/useReadWorkspaceUrlFromCurrentLocation';
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
import { lastAuthenticatedWorkspaceDomainState } from '@/domain-manager/states/lastAuthenticatedWorkspaceDomainState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useEffect, useCallback } from 'react';
import { useInitializeQueryParamState } from '@/app/hooks/useInitializeQueryParamState';
@@ -15,7 +15,7 @@ import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
export const WorkspaceProviderEffect = () => {
const { data: getPublicWorkspaceData } = useGetPublicWorkspaceDataByDomain();
const lastAuthenticatedWorkspaceDomain = useRecoilValueV2(
const lastAuthenticatedWorkspaceDomain = useAtomStateValue(
lastAuthenticatedWorkspaceDomainState,
);
@@ -24,7 +24,7 @@ export const WorkspaceProviderEffect = () => {
const { currentLocationHostname } = useReadWorkspaceUrlFromCurrentLocation();
const isMultiWorkspaceEnabled = useRecoilValueV2(
const isMultiWorkspaceEnabled = useAtomStateValue(
isMultiWorkspaceEnabledState,
);
@@ -8,7 +8,7 @@ import {
type CurrentWorkspace,
currentWorkspaceState,
} from '@/auth/states/currentWorkspaceState';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { useSubscriptionStatus } from '@/workspace/hooks/useSubscriptionStatus';
import {
@@ -34,7 +34,7 @@ const renderHooks = () => {
const { result } = renderHook(
() => {
const subscriptionStatus = useSubscriptionStatus();
const setCurrentWorkspace = useSetRecoilStateV2(currentWorkspaceState);
const setCurrentWorkspace = useSetAtomState(currentWorkspaceState);
return {
subscriptionStatus,
@@ -1,10 +1,10 @@
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { extractFeatureFlagMapFromWorkspace } from '@/workspace/utils/extractFeatureFlagMapFromWorkspace';
import { type FeatureFlagKey } from '~/generated-metadata/graphql';
export const useFeatureFlagsMap = (): Record<FeatureFlagKey, boolean> => {
const currentWorkspace = useRecoilValueV2(currentWorkspaceState);
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
return extractFeatureFlagMapFromWorkspace(currentWorkspace);
};
@@ -1,9 +1,9 @@
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { type FeatureFlagKey } from '~/generated-metadata/graphql';
export const useIsFeatureEnabled = (featureKey: FeatureFlagKey | null) => {
const currentWorkspace = useRecoilValueV2(currentWorkspaceState);
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
if (!featureKey) {
return false;
@@ -1,8 +1,8 @@
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
export const useIsSomeMeteredProductCapReached = (): boolean => {
const billingSubscriptionItems = useRecoilValueV2(currentWorkspaceState)
const billingSubscriptionItems = useAtomStateValue(currentWorkspaceState)
?.currentBillingSubscription?.billingSubscriptionItems;
if (!billingSubscriptionItems) {
@@ -1,10 +1,10 @@
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { type WorkspaceActivationStatus } from 'twenty-shared/workspace';
export const useIsWorkspaceActivationStatusEqualsTo = (
activationStatus: WorkspaceActivationStatus,
): boolean => {
const currentWorkspace = useRecoilValueV2(currentWorkspaceState);
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
return currentWorkspace?.activationStatus === activationStatus;
};
@@ -1,8 +1,8 @@
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { type SubscriptionStatus } from '~/generated-metadata/graphql';
export const useSubscriptionStatus = (): SubscriptionStatus | undefined => {
const currentWorkspace = useRecoilValueV2(currentWorkspaceState);
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
return currentWorkspace?.currentBillingSubscription?.status;
};
@@ -1,8 +1,8 @@
import { type AuthBypassProviders } from '~/generated-metadata/graphql';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
export const workspaceAuthBypassProvidersState =
createStateV2<AuthBypassProviders | null>({
createAtomState<AuthBypassProviders | null>({
key: 'workspaceAuthBypassProvidersState',
defaultValue: null,
});
@@ -1,7 +1,8 @@
import { type AuthProviders } from '~/generated-metadata/graphql';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
export const workspaceAuthProvidersState = createStateV2<AuthProviders | null>({
key: 'workspaceAuthProvidersState',
defaultValue: null,
});
export const workspaceAuthProvidersState =
createAtomState<AuthProviders | null>({
key: 'workspaceAuthProvidersState',
defaultValue: null,
});
@@ -1,6 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
export const workspaceBypassModeState = createStateV2<boolean>({
export const workspaceBypassModeState = createAtomState<boolean>({
key: 'workspaceBypassModeState',
defaultValue: false,
});