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
@@ -10,10 +10,10 @@ import {
IconSparkles,
IconVariable,
} from 'twenty-ui/display';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
export const SettingsAdminContent = () => {
const currentUser = useRecoilValueV2(currentUserState);
const currentUser = useAtomStateValue(currentUserState);
const canAccessFullAdminPanel = currentUser?.canAccessFullAdminPanel;
const canImpersonate = currentUser?.canImpersonate;
@@ -8,18 +8,18 @@ import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/consta
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { isNonEmptyString } from '@sniptt/guards';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useState } from 'react';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
import { useUserLookupAdminPanelMutation } from '~/generated-metadata/graphql';
import { currentUserState } from '@/auth/states/currentUserState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { SettingsAdminTableCard } from '@/settings/admin-panel/components/SettingsAdminTableCard';
import { SettingsAdminVersionContainer } from '@/settings/admin-panel/components/SettingsAdminVersionContainer';
import { SETTINGS_ADMIN_USER_LOOKUP_WORKSPACE_TABS_ID } from '@/settings/admin-panel/constants/SettingsAdminUserLookupWorkspaceTabsId';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentStateV2';
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
import { getImageAbsoluteURI, isDefined } from 'twenty-shared/utils';
import {
H2Title,
@@ -42,24 +42,24 @@ export const SettingsAdminGeneral = () => {
const [userIdentifier, setUserIdentifier] = useState('');
const { enqueueErrorSnackBar } = useSnackBar();
const [activeTabId, setActiveTabId] = useRecoilComponentStateV2(
const [activeTabId, setActiveTabId] = useAtomComponentState(
activeTabIdComponentState,
SETTINGS_ADMIN_USER_LOOKUP_WORKSPACE_TABS_ID,
);
const [userLookupResult, setUserLookupResult] = useRecoilStateV2(
const [userLookupResult, setUserLookupResult] = useAtomState(
userLookupResultStateV2,
);
const [isUserLookupLoading, setIsUserLookupLoading] = useState(false);
const [userLookup] = useUserLookupAdminPanelMutation();
const currentUser = useRecoilValueV2(currentUserState);
const currentUser = useAtomStateValue(currentUserState);
const canAccessFullAdminPanel = currentUser?.canAccessFullAdminPanel;
const canImpersonate = currentUser?.canImpersonate;
const canManageFeatureFlags = useRecoilValueV2(canManageFeatureFlagsState);
const canManageFeatureFlags = useAtomStateValue(canManageFeatureFlagsState);
const handleSearch = async () => {
setActiveTabId('');
@@ -5,10 +5,10 @@ import { SETTINGS_ADMIN_TABS } from '@/settings/admin-panel/constants/SettingsAd
import { SETTINGS_ADMIN_TABS_ID } from '@/settings/admin-panel/constants/SettingsAdminTabsId';
import { SettingsAdminHealthStatus } from '@/settings/admin-panel/health-status/components/SettingsAdminHealthStatus';
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
export const SettingsAdminTabContent = () => {
const activeTabId = useRecoilComponentValueV2(
const activeTabId = useAtomComponentStateValue(
activeTabIdComponentState,
SETTINGS_ADMIN_TABS_ID,
);
@@ -18,10 +18,10 @@ import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/consta
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { isNonEmptyString } from '@sniptt/guards';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useState } from 'react';
import { getImageAbsoluteURI, isDefined } from 'twenty-shared/utils';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { AvatarChip, Chip } from 'twenty-ui/components';
import {
H2Title,
@@ -58,10 +58,10 @@ const StyledButtonContainer = styled.div`
export const SettingsAdminWorkspaceContent = ({
activeWorkspace,
}: SettingsAdminWorkspaceContentProps) => {
const canManageFeatureFlags = useRecoilValueV2(canManageFeatureFlagsState);
const canManageFeatureFlags = useAtomStateValue(canManageFeatureFlagsState);
const { enqueueErrorSnackBar } = useSnackBar();
const [currentUser] = useRecoilStateV2(currentUserState);
const currentWorkspace = useRecoilValueV2(currentWorkspaceState);
const [currentUser] = useAtomState(currentUserState);
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
const [updateFeatureFlag] = useUpdateWorkspaceFeatureFlagMutation();
const [isImpersonateLoading, setIsImpersonationLoading] = useState(false);
@@ -70,7 +70,7 @@ export const SettingsAdminWorkspaceContent = ({
const [impersonate] = useImpersonateMutation();
const { updateFeatureFlagState } = useFeatureFlagState();
const userLookupResult = useRecoilValueV2(userLookupResultStateV2);
const userLookupResult = useAtomStateValue(userLookupResultStateV2);
const { t } = useLingui();
@@ -1,5 +1,5 @@
import { useLingui } from '@lingui/react/macro';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { isConfigVariablesInDbEnabledState } from '@/client-config/states/isConfigVariablesInDbEnabledState';
import {
@@ -29,7 +29,7 @@ export const ConfigVariableActionButtons = ({
onReset,
}: ConfigVariableActionButtonsProps) => {
const { t } = useLingui();
const isConfigVariablesInDbEnabled = useRecoilValueV2(
const isConfigVariablesInDbEnabled = useAtomStateValue(
isConfigVariablesInDbEnabledState,
);
const isFromDatabase = variable.source === ConfigSource.DATABASE;
@@ -2,7 +2,7 @@ import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { isConfigVariablesInDbEnabledState } from '@/client-config/states/isConfigVariablesInDbEnabledState';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import {
ConfigSource,
type ConfigVariable,
@@ -24,7 +24,7 @@ export const ConfigVariableHelpText = ({
variable,
hasValueChanged,
}: ConfigVariableHelpTextProps) => {
const isConfigVariablesInDbEnabled = useRecoilValueV2(
const isConfigVariablesInDbEnabled = useAtomStateValue(
isConfigVariablesInDbEnabledState,
);
const { t } = useLingui();
@@ -10,7 +10,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useTheme } from '@emotion/react';
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 { IconChevronLeft, IconEye, IconEyeOff } from 'twenty-ui/display';
import { MenuItem, MenuItemSelectTag } from 'twenty-ui/navigation';
@@ -39,7 +39,7 @@ export const ConfigVariableOptionsDropdownContent = ({
}: ConfigVariableOptionsDropdownContentProps) => {
const theme = useTheme();
const isConfigVariablesInDbEnabled = useRecoilValueV2(
const isConfigVariablesInDbEnabled = useAtomStateValue(
isConfigVariablesInDbEnabledState,
);
@@ -3,7 +3,7 @@ import { useLingui } from '@lingui/react/macro';
import { isConfigVariablesInDbEnabledState } from '@/client-config/states/isConfigVariablesInDbEnabledState';
import { TextInput } from '@/ui/input/components/TextInput';
import styled from '@emotion/styled';
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { type ConfigVariableValue } from 'twenty-shared/types';
import { type ConfigVariable } from '~/generated-metadata/graphql';
import { ConfigVariableDatabaseInput } from './ConfigVariableDatabaseInput';
@@ -26,7 +26,7 @@ export const ConfigVariableValueInput = ({
disabled,
}: ConfigVariableValueInputProps) => {
const { t } = useLingui();
const isConfigVariablesInDbEnabled = useRecoilValueV2(
const isConfigVariablesInDbEnabled = useAtomStateValue(
isConfigVariablesInDbEnabledState,
);
@@ -17,7 +17,7 @@ import {
} from '~/generated-metadata/graphql';
import { normalizeSearchText } from '~/utils/normalizeSearchText';
import { ConfigVariableSearchInput } from './ConfigVariableSearchInput';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
const StyledControlsContainer = styled.div`
display: flex;
@@ -36,12 +36,13 @@ export const SettingsAdminConfigVariables = () => {
});
const [search, setSearch] = useState('');
const [showHiddenGroupVariables, setShowHiddenGroupVariables] =
useRecoilStateV2(showHiddenGroupVariablesState);
const [showHiddenGroupVariables, setShowHiddenGroupVariables] = useAtomState(
showHiddenGroupVariablesState,
);
const [configVariableSourceFilter, setConfigVariableSourceFilter] =
useRecoilStateV2(configVariableSourceFilterState);
useAtomState(configVariableSourceFilterState);
const [configVariableGroupFilter, setConfigVariableGroupFilter] =
useRecoilStateV2(configVariableGroupFilterState);
useAtomState(configVariableGroupFilterState);
const allGroups = useMemo(
() => configVariables?.getConfigVariablesGrouped.groups ?? [],
@@ -1,8 +1,8 @@
import { type ConfigVariableGroupFilter } from '@/settings/admin-panel/config-variables/types/ConfigVariableGroupFilter';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
export const configVariableGroupFilterState =
createStateV2<ConfigVariableGroupFilter>({
createAtomState<ConfigVariableGroupFilter>({
key: 'configVariableGroupFilterState',
defaultValue: 'all',
});
@@ -1,8 +1,8 @@
import { type ConfigVariableSourceFilter } from '@/settings/admin-panel/config-variables/types/ConfigVariableSourceFilter';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
export const configVariableSourceFilterState =
createStateV2<ConfigVariableSourceFilter>({
createAtomState<ConfigVariableSourceFilter>({
key: 'configVariableSourceFilterState',
defaultValue: 'all',
});
@@ -1,6 +1,6 @@
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
export const showHiddenGroupVariablesState = createStateV2<boolean>({
export const showHiddenGroupVariablesState = createAtomState<boolean>({
key: 'showHiddenGroupVariablesState',
defaultValue: false,
});
@@ -1,10 +1,10 @@
import { userLookupResultStateV2 } from '@/settings/admin-panel/states/userLookupResultStateV2';
import { useRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilStateV2';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { type FeatureFlagKey } from '~/generated-metadata/graphql';
import { isDefined } from 'twenty-shared/utils';
export const useFeatureFlagState = () => {
const [userLookupResult, setUserLookupResult] = useRecoilStateV2(
const [userLookupResult, setUserLookupResult] = useAtomState(
userLookupResultStateV2,
);
@@ -1,10 +1,10 @@
import { isAppEffectRedirectEnabledState } from '@/app/states/isAppEffectRedirectEnabledState';
import { useAuth } from '@/auth/hooks/useAuth';
import { useSetRecoilStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilStateV2';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
export const useImpersonationAuth = () => {
const { getAuthTokensFromLoginToken } = useAuth();
const setIsAppEffectRedirectEnabled = useSetRecoilStateV2(
const setIsAppEffectRedirectEnabled = useSetAtomState(
isAppEffectRedirectEnabledState,
);
@@ -1,8 +1,8 @@
import { type UserLookup } from '@/settings/admin-panel/types/UserLookup';
import { createStateV2 } from '@/ui/utilities/state/jotai/utils/createStateV2';
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
export const userLookupResultStateV2 = createStateV2<UserLookup | null>({
export const userLookupResultStateV2 = createAtomState<UserLookup | null>({
key: 'userLookupResultStateV2',
defaultValue: null,
});