Files
twenty/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenu.ts
T
Félix Malfait b27a97f2c5 feat: enforce @/ alias for imports and fix all relative parent imports (#16787)
## Summary
This PR enforces the use of `@/` alias for imports instead of relative
parent imports (`../`).

## Changes

### ESLint Configuration
- Added `no-restricted-imports` pattern in `eslint.config.react.mjs` to
block `../*` imports with the message "Relative parent imports are not
allowed. Use @/ alias instead."
- Removed the non-working `import/no-relative-parent-imports` rule
(doesn't work properly in ESLint flat config)

### VS Code Settings
- Added `javascript.preferences.importModuleSpecifier: non-relative` to
`.vscode/settings.json` (TypeScript setting was already there)

### Code Fixes
- Fixed **941 relative parent imports** across **706 files** in
`packages/twenty-front`
- All `../` imports converted to use `@/` alias

## Why
- Consistent import style across the codebase
- Easier to move files without breaking imports
- Better IDE support for auto-imports
- Clearer understanding of where imports come from
2025-12-23 22:57:51 +01:00

83 lines
2.8 KiB
TypeScript

import { useRecoilCallback } from 'recoil';
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
import { COMMAND_MENU_SEARCH_INPUT_FOCUS_ID } from '@/command-menu/constants/CommandMenuSearchInputFocusId';
import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId';
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState';
import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages';
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 { IconDotsVertical } from 'twenty-ui/display';
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
export const useCommandMenu = () => {
const { navigateCommandMenu } = useNavigateCommandMenu();
const { closeAnyOpenDropdown } = useCloseAnyOpenDropdown();
const { removeFocusItemFromFocusStackById } =
useRemoveFocusItemFromFocusStackById();
const closeCommandMenu = useRecoilCallback(
({ set, snapshot }) =>
() => {
const isCommandMenuOpened = snapshot
.getLoadable(isCommandMenuOpenedState)
.getValue();
if (isCommandMenuOpened) {
set(isCommandMenuOpenedState, false);
set(isCommandMenuClosingState, true);
closeAnyOpenDropdown();
removeFocusItemFromFocusStackById({
focusId: COMMAND_MENU_SEARCH_INPUT_FOCUS_ID,
});
removeFocusItemFromFocusStackById({
focusId: SIDE_PANEL_FOCUS_ID,
});
}
},
[closeAnyOpenDropdown, removeFocusItemFromFocusStackById],
);
const openCommandMenu = useCallback(() => {
emitSidePanelOpenEvent();
closeAnyOpenDropdown();
navigateCommandMenu({
page: CommandMenuPages.Root,
pageTitle: t`Command Menu`,
pageIcon: IconDotsVertical,
resetNavigationStack: true,
});
}, [closeAnyOpenDropdown, navigateCommandMenu]);
const toggleCommandMenu = useRecoilCallback(
({ snapshot, set }) =>
async () => {
const isCommandMenuOpened = snapshot
.getLoadable(isCommandMenuOpenedState)
.getValue();
set(commandMenuSearchState, '');
if (isCommandMenuOpened) {
closeCommandMenu();
} else {
openCommandMenu();
}
},
[closeCommandMenu, openCommandMenu],
);
return {
openCommandMenu,
closeCommandMenu,
navigateCommandMenu,
toggleCommandMenu,
};
};