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
This commit is contained in:
Félix Malfait
2025-12-23 22:57:51 +01:00
committed by GitHub
parent 781b96e80b
commit b27a97f2c5
725 changed files with 1114 additions and 1041 deletions
@@ -1,7 +1,7 @@
import { type FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { formatFieldMetadataItemInput } from '../formatFieldMetadataItemInput';
import { formatFieldMetadataItemInput } from '@/object-metadata/utils/formatFieldMetadataItemInput';
describe('formatFieldMetadataItemInput', () => {
it('should format the field metadata item input correctly', () => {
@@ -3,7 +3,7 @@ import { getNonUpdatableFieldMetadataIdsFromObjectPermissions } from '@/object-m
import { getObjectPermissionsFromMapByObjectMetadataId } from '@/settings/roles/role-permissions/objects-permissions/utils/getObjectPermissionsFromMapByObjectMetadataId';
import { type ObjectPermissions } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type ObjectMetadataItem } from '../types/ObjectMetadataItem';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
type enrichObjectMetadataItemsWithPermissionsArgs = {
objectMetadataItems: Omit<
@@ -4,7 +4,7 @@ import { type FieldMetadata } from '@/object-record/record-field/ui/types/FieldM
import { getFieldButtonIcon } from '@/object-record/record-field/ui/utils/getFieldButtonIcon';
import { FieldMetadataType } from 'twenty-shared/types';
import { type FieldMetadataItem } from '../types/FieldMetadataItem';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
export type FieldMetadataItemAsFieldDefinitionProps = {
field: FieldMetadataItem;
@@ -1,4 +1,4 @@
import { type ObjectMetadataItem } from '../types/ObjectMetadataItem';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
export const getRelationObjectMetadataNameSingular = ({
field,
@@ -1,5 +1,5 @@
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { type FieldMetadataItem } from '../types/FieldMetadataItem';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
type IsFieldMetadataAvailableForViewFieldArgs = {
objectNameSingular: string;
@@ -7,7 +7,7 @@ import { type RecordGqlFields } from '@/object-record/graphql/record-gql-fields/
import { isNonCompositeField } from '@/object-record/object-filter-dropdown/utils/isNonCompositeField';
import { type ObjectPermissions } from 'twenty-shared/types';
import { computeMorphRelationFieldName, isDefined } from 'twenty-shared/utils';
import { type FieldMetadataItem } from '../types/FieldMetadataItem';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
type MapFieldMetadataToGraphQLQueryArgs = {
objectMetadataItems: ObjectMetadataItem[];
@@ -2,7 +2,7 @@ import { type IndexFieldMetadataItem } from '@/object-metadata/types/IndexFieldM
import { type IndexMetadataItem } from '@/object-metadata/types/IndexMetadataItem';
import { objectMetadataItemSchema } from '@/object-metadata/validation-schemas/objectMetadataItemSchema';
import { type ObjectMetadataItemsQuery } from '~/generated-metadata/graphql';
import { type ObjectMetadataItem } from '../types/ObjectMetadataItem';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
type mapPaginatedObjectMetadataItemsToObjectMetadataItemsArgs = {
pagedObjectMetadataItems: ObjectMetadataItemsQuery | undefined;
@@ -5,7 +5,7 @@ import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
import { isFieldMorphRelation } from '@/object-record/record-field/ui/types/guards/isFieldMorphRelation';
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
import { isDefined } from 'twenty-shared/utils';
import { type FieldMetadataItem } from '../types/FieldMetadataItem';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
export const shouldFieldBeQueried = ({
gqlField,