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:
@@ -25,8 +25,8 @@ import {
|
||||
type IconButtonVariant,
|
||||
LightIconButton,
|
||||
} from 'twenty-ui/input';
|
||||
import { IconPickerScrollEffect } from '../hooks/IconPickerScrollEffect';
|
||||
import { iconPickerVisibleCountState } from '../states/iconPickerVisibleCountState';
|
||||
import { IconPickerScrollEffect } from '@/ui/input/hooks/IconPickerScrollEffect';
|
||||
import { iconPickerVisibleCountState } from '@/ui/input/states/iconPickerVisibleCountState';
|
||||
|
||||
export type IconPickerProps = {
|
||||
disabled?: boolean;
|
||||
|
||||
+4
-1
@@ -7,7 +7,10 @@ import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecora
|
||||
import { sleep } from '~/utils/sleep';
|
||||
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { IconPicker, type IconPickerProps } from '../IconPicker';
|
||||
import {
|
||||
IconPicker,
|
||||
type IconPickerProps,
|
||||
} from '@/ui/input/components/IconPicker';
|
||||
|
||||
type RenderProps = IconPickerProps;
|
||||
const Render = (args: RenderProps) => {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { type Meta, type StoryObj } from '@storybook/react';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
import { workspaceLogoUrl } from '~/testing/mock-data/users';
|
||||
|
||||
import { ImageInput } from '../ImageInput';
|
||||
import { ImageInput } from '@/ui/input/components/ImageInput';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
|
||||
const meta: Meta<typeof ImageInput> = {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import { useState } from 'react';
|
||||
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { Select, type SelectProps } from '../Select';
|
||||
import { Select, type SelectProps } from '@/ui/input/components/Select';
|
||||
|
||||
type RenderProps = SelectProps<string | number | boolean | null>;
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { type Meta, type StoryObj } from '@storybook/react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { expect, userEvent, within } from '@storybook/test';
|
||||
import { TextArea, type TextAreaProps } from '../TextArea';
|
||||
import { TextArea, type TextAreaProps } from '@/ui/input/components/TextArea';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
|
||||
type RenderProps = TextAreaProps;
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { type Meta, type StoryObj } from '@storybook/react';
|
||||
import { expect, userEvent, within } from '@storybook/test';
|
||||
import { Temporal } from 'temporal-polyfill';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { DateTimePicker } from '../DateTimePicker';
|
||||
import { DateTimePicker } from '@/ui/input/components/internal/date/components/DateTimePicker';
|
||||
|
||||
const meta: Meta<typeof DateTimePicker> = {
|
||||
title: 'UI/Input/Internal/InternalDatePicker',
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import type { PartialBlock } from '@blocknote/core';
|
||||
import { getFirstNonEmptyLineOfRichText } from '../getFirstNonEmptyLineOfRichText';
|
||||
import { getFirstNonEmptyLineOfRichText } from '@/ui/input/editor/utils/getFirstNonEmptyLineOfRichText';
|
||||
|
||||
describe('getFirstNonEmptyLineOfRichText', () => {
|
||||
it('should return an empty string if the input is null', () => {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { parseInitialBlocknote } from '../parseInitialBlocknote';
|
||||
import { parseInitialBlocknote } from '@/ui/input/editor/utils/parseInitialBlocknote';
|
||||
|
||||
describe('parseInitialBlocknote', () => {
|
||||
it('should parse valid JSON array string', () => {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { prepareBodyWithSignedUrls } from '../prepareBodyWithSignedUrls';
|
||||
import { prepareBodyWithSignedUrls } from '@/ui/input/editor/utils/prepareBodyWithSignedUrls';
|
||||
|
||||
describe('prepareBodyWithSignedUrls', () => {
|
||||
it('should return empty string as-is', () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useScrollWrapperHTMLElement } from '@/ui/utilities/scroll/hooks/useScrollWrapperHTMLElement';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { iconPickerVisibleCountState } from '../states/iconPickerVisibleCountState';
|
||||
import { iconPickerVisibleCountState } from '@/ui/input/states/iconPickerVisibleCountState';
|
||||
|
||||
type IconPickerScrollEffectProps = {
|
||||
sentinelId: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { iconPickerState } from '../states/iconPickerState';
|
||||
import { iconPickerState } from '@/ui/input/states/iconPickerState';
|
||||
|
||||
export const useIconPicker = () => {
|
||||
const [iconPicker, setIconPicker] = useRecoilState(iconPickerState);
|
||||
|
||||
Reference in New Issue
Block a user