Files
twenty/packages/twenty-front/src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings.tsx
T
Charles Bochet d81f006979 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
2026-02-25 01:55:46 +01:00

127 lines
4.9 KiB
TypeScript

import { CommandGroup } from '@/command-menu/components/CommandGroup';
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { TAB_SETTINGS_SELECTABLE_ITEM_IDS } from '@/command-menu/pages/page-layout/constants/settings/TabSettingsSelectableItemIds';
import { usePageLayoutIdFromContextStoreTargetedRecord } from '@/command-menu/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord';
import { useDeletePageLayoutTab } from '@/page-layout/hooks/useDeletePageLayoutTab';
import { useDuplicatePageLayoutTab } from '@/page-layout/hooks/useDuplicatePageLayoutTab';
import { useMovePageLayoutTab } from '@/page-layout/hooks/useMovePageLayoutTab';
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
import { pageLayoutTabSettingsOpenTabIdComponentState } from '@/page-layout/states/pageLayoutTabSettingsOpenTabIdComponentState';
import { sortTabsByPosition } from '@/page-layout/utils/sortTabsByPosition';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import {
IconChevronLeft,
IconChevronRight,
IconCopyPlus,
IconTrash,
} from 'twenty-ui/display';
export const CommandMenuPageLayoutTabSettings = () => {
const { closeCommandMenu } = useCommandMenu();
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
const draft = useAtomComponentStateValue(
pageLayoutDraftComponentState,
pageLayoutId,
);
const [openTabId, setOpenTabId] = useAtomComponentState(
pageLayoutTabSettingsOpenTabIdComponentState,
pageLayoutId,
);
const { moveLeft, moveRight } = useMovePageLayoutTab(pageLayoutId);
const { deleteTab } = useDeletePageLayoutTab(pageLayoutId);
const { duplicateTab } = useDuplicatePageLayoutTab(pageLayoutId);
if (!isDefined(openTabId)) {
return null;
}
const tabsSorted = sortTabsByPosition(draft.tabs);
const currentIndex = tabsSorted.findIndex((t) => t.id === openTabId);
if (currentIndex < 0) return null;
const tab = tabsSorted[currentIndex];
const canMoveLeft = currentIndex > 0;
const canMoveRight = currentIndex < tabsSorted.length - 1;
const canDelete = tabsSorted.length > 1;
const handleDelete = () => {
deleteTab(tab.id);
setOpenTabId(null);
closeCommandMenu();
};
const selectableItemIds = [
...(canMoveLeft ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT] : []),
...(canMoveRight ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT] : []),
TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE,
...(canDelete ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE] : []),
];
return (
<>
<CommandMenuList commandGroups={[]} selectableItemIds={selectableItemIds}>
<CommandGroup heading={t`Settings`}>
{canMoveLeft && (
<SelectableListItem
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT}
onEnter={() => moveLeft(tab.id)}
>
<CommandMenuItem
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT}
Icon={IconChevronLeft}
label={t`Move left`}
onClick={() => moveLeft(tab.id)}
/>
</SelectableListItem>
)}
{canMoveRight && (
<SelectableListItem
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT}
onEnter={() => moveRight(tab.id)}
>
<CommandMenuItem
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT}
Icon={IconChevronRight}
label={t`Move right`}
onClick={() => moveRight(tab.id)}
/>
</SelectableListItem>
)}
<SelectableListItem
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE}
onEnter={() => duplicateTab(tab.id)}
>
<CommandMenuItem
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE}
Icon={IconCopyPlus}
label={t`Duplicate`}
onClick={() => duplicateTab(tab.id)}
/>
</SelectableListItem>
{canDelete && (
<SelectableListItem
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE}
onEnter={handleDelete}
>
<CommandMenuItem
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE}
Icon={IconTrash}
label={t`Delete`}
onClick={handleDelete}
/>
</SelectableListItem>
)}
</CommandGroup>
</CommandMenuList>
</>
);
};