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
@@ -14,7 +14,7 @@ import { getSettingsPath } from 'twenty-shared/utils';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
import { NotFound } from '~/pages/not-found/NotFound';
import { useImapSmtpCaldavConnectionForm } from '../hooks/useImapSmtpCaldavConnectionForm';
import { useImapSmtpCaldavConnectionForm } from '@/settings/accounts/hooks/useImapSmtpCaldavConnectionForm';
import { SettingsAccountsConnectionForm } from './SettingsAccountsConnectionForm';
const StyledLoadingContainer = styled.div`
@@ -10,7 +10,7 @@ import { getSettingsPath } from 'twenty-shared/utils';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
import { SettingsAccountsConnectionForm } from '@/settings/accounts/components/SettingsAccountsConnectionForm';
import { useImapSmtpCaldavConnectionForm } from '../hooks/useImapSmtpCaldavConnectionForm';
import { useImapSmtpCaldavConnectionForm } from '@/settings/accounts/hooks/useImapSmtpCaldavConnectionForm';
export const SettingsAccountsNewImapSmtpCaldavConnection = () => {
const { t } = useLingui();
@@ -7,7 +7,7 @@ import {
CalendarChannelVisibility,
MessageChannelVisibility,
} from '~/generated-metadata/graphql';
import { useTriggerProviderReconnect } from '../useTriggerProviderReconnect';
import { useTriggerProviderReconnect } from '@/settings/accounts/hooks/useTriggerProviderReconnect';
const mockTriggerApisOAuth = jest.fn();
const mockNavigate = jest.fn();
@@ -1,7 +1,7 @@
import { CalendarChannelSyncStatus } from '@/accounts/types/CalendarChannel';
import { MessageChannelSyncStatus } from '@/accounts/types/MessageChannel';
import { SyncStatus } from '@/settings/accounts/constants/SyncStatus';
import { computeSyncStatus } from '../computeSyncStatus';
import { computeSyncStatus } from '@/settings/accounts/utils/computeSyncStatus';
describe('computeSyncStatus', () => {
test('should return FAILED when both sync statuses are FAILED', () => {
@@ -10,7 +10,7 @@ import { type ConfigVariableValue } from 'twenty-shared/types';
import { CustomError } from 'twenty-shared/utils';
import { MenuItemMultiSelect } from 'twenty-ui/navigation';
import { ConfigVariableType } from '~/generated/graphql';
import { type ConfigVariableOptions } from '../types/ConfigVariableOptions';
import { type ConfigVariableOptions } from '@/settings/admin-panel/config-variables/types/ConfigVariableOptions';
type ConfigVariableDatabaseInputProps = {
label: string;
@@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { AdminPanelHealthServiceStatus } from '~/generated-metadata/graphql';
import { SettingsAdminIndicatorHealthContext } from '../contexts/SettingsAdminIndicatorHealthContext';
import { SettingsAdminIndicatorHealthContext } from '@/settings/admin-panel/health-status/contexts/SettingsAdminIndicatorHealthContext';
const StyledErrorMessage = styled.div`
color: ${({ theme }) => theme.color.red};
@@ -37,7 +37,7 @@ export const SettingsNavigationDrawerItem = ({
indentationLevel={item.indentationLevel}
subItemState={subItemState}
label={item.label}
to={href || undefined}
to={href}
Icon={item.Icon}
active={isActive}
soon={item.soon}
@@ -1,7 +1,7 @@
import { type Meta, type StoryObj } from '@storybook/react';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { CancelButton } from '../SaveAndCancelButtons/CancelButton';
import { CancelButton } from '@/settings/components/SaveAndCancelButtons/CancelButton';
const meta: Meta<typeof CancelButton> = {
title: 'Modules/Settings/CancelButton',
@@ -1,6 +1,6 @@
import { type Meta, type StoryObj } from '@storybook/react';
import { SaveButton } from '../SaveAndCancelButtons/SaveButton';
import { SaveButton } from '@/settings/components/SaveAndCancelButtons/SaveButton';
const meta: Meta<typeof SaveButton> = {
title: 'Modules/Settings/SaveButton',
@@ -3,7 +3,7 @@ import {
IllustrationIconOneToMany,
} from 'twenty-ui/display';
import { RelationType } from '~/generated-metadata/graphql';
import OneToManySvg from '../assets/OneToMany.svg';
import OneToManySvg from '@/settings/data-model/assets/OneToMany.svg';
export const RELATION_TYPES: Record<
RelationType,
@@ -4,7 +4,7 @@ import { useFormContext } from 'react-hook-form';
import { FieldMetadataType } from 'twenty-shared/types';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { useAddressSettingsFormInitialValues } from '../useAddressSettingsFormInitialValues';
import { useAddressSettingsFormInitialValues } from '@/settings/data-model/fields/forms/address/hooks/useAddressSettingsFormInitialValues';
jest.mock('react-hook-form', () => ({
useFormContext: jest.fn(),
@@ -4,7 +4,7 @@ import { FormProviderDecorator } from '~/testing/decorators/FormProviderDecorato
import { ComponentDecorator } from 'twenty-ui/testing';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { SettingsDataModelFieldDescriptionForm } from '../SettingsDataModelFieldDescriptionForm';
import { SettingsDataModelFieldDescriptionForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldDescriptionForm';
const meta: Meta<typeof SettingsDataModelFieldDescriptionForm> = {
title: 'Modules/Settings/DataModel/SettingsDataModelFieldDescriptionForm',
@@ -7,7 +7,7 @@ import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecora
import { ComponentDecorator } from 'twenty-ui/testing';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { SettingsDataModelFieldIconLabelForm } from '../SettingsDataModelFieldIconLabelForm';
import { SettingsDataModelFieldIconLabelForm } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldIconLabelForm';
const StyledContainer = styled.div`
flex: 1;
@@ -10,7 +10,7 @@ import { graphqlMocks } from '~/testing/graphqlMocks';
import { ComponentDecorator } from 'twenty-ui/testing';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { SettingsDataModelFieldSettingsFormCard } from '../SettingsDataModelFieldSettingsFormCard';
import { SettingsDataModelFieldSettingsFormCard } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard';
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
@@ -1,4 +1,4 @@
import { generateNewSelectOptionLabel } from '../generateNewSelectOptionLabel';
import { generateNewSelectOptionLabel } from '@/settings/data-model/fields/forms/select/utils/generateNewSelectOptionLabel';
describe('generateNewSelectOptionLabel', () => {
it('generates a new select option label', () => {
@@ -10,7 +10,7 @@ import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadat
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { getMockFieldMetadataItemOrThrow } from '~/testing/utils/getMockFieldMetadataItemOrThrow';
import { getMockObjectMetadataItemOrThrow } from '~/testing/utils/getMockObjectMetadataItemOrThrow';
import { SettingsDataModelFieldPreviewWidget } from '../SettingsDataModelFieldPreviewWidget';
import { SettingsDataModelFieldPreviewWidget } from '@/settings/data-model/fields/preview/components/SettingsDataModelFieldPreviewWidget';
const mockedCompanyObjectMetadataItem =
getMockObjectMetadataItemOrThrow('company');
@@ -5,7 +5,7 @@ import { FieldMetadataType } from '~/generated-metadata/graphql';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { useFieldPreviewValue } from '../useFieldPreviewValue';
import { useFieldPreviewValue } from '@/settings/data-model/fields/preview/hooks/useFieldPreviewValue';
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
@@ -1,7 +1,7 @@
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { getCurrencyFieldPreviewValue } from '../getCurrencyFieldPreviewValue';
import { getCurrencyFieldPreviewValue } from '@/settings/data-model/fields/preview/utils/getCurrencyFieldPreviewValue';
import { CurrencyCode } from 'twenty-shared/constants';
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
@@ -1,6 +1,6 @@
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { getMultiSelectFieldPreviewValue } from '../getMultiSelectFieldPreviewValue';
import { getMultiSelectFieldPreviewValue } from '@/settings/data-model/fields/preview/utils/getMultiSelectFieldPreviewValue';
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
@@ -1,7 +1,7 @@
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { getSelectFieldPreviewValue } from '../getSelectFieldPreviewValue';
import { getSelectFieldPreviewValue } from '@/settings/data-model/fields/preview/utils/getSelectFieldPreviewValue';
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
@@ -1,4 +1,4 @@
import { calculateHandlePosition } from '../calculateHandlePosition';
import { calculateHandlePosition } from '@/settings/data-model/graph-overview/utils/calculateHandlePosition';
describe('calculatePosition', () => {
test('should calculate source handle', () => {
// Source node right from start of target node
@@ -28,7 +28,7 @@ import { useNavigateSettings } from '~/hooks/useNavigateSettings';
import { type SettingsObjectDetailTableItem } from '~/pages/settings/data-model/types/SettingsObjectDetailTableItem';
import { isObjectMetadataSettingsReadOnly } from '@/object-record/read-only/utils/isObjectMetadataSettingsReadOnly';
import { RELATION_TYPES } from '../../constants/RelationTypes';
import { RELATION_TYPES } from '@/settings/data-model/constants/RelationTypes';
import { SettingsObjectFieldDataType } from './SettingsObjectFieldDataType';
type SettingsObjectFieldItemTableRowProps = {
@@ -7,8 +7,8 @@ import { IconEye } from 'twenty-ui/display';
import { FloatingButton } from 'twenty-ui/input';
import { Card } from 'twenty-ui/layout';
import DarkCoverImage from '../../assets/cover-dark.png';
import LightCoverImage from '../../assets/cover-light.png';
import DarkCoverImage from '@/settings/data-model/assets/cover-dark.png';
import LightCoverImage from '@/settings/data-model/assets/cover-light.png';
const StyledCoverImageContainer = styled(Card)`
align-items: center;
@@ -3,7 +3,7 @@ import { expect, fn, userEvent, within } from '@storybook/test';
import { ComponentDecorator } from 'twenty-ui/testing';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { SettingsObjectInactiveMenuDropDown } from '../SettingsObjectInactiveMenuDropDown';
import { SettingsObjectInactiveMenuDropDown } from '@/settings/data-model/objects/components/SettingsObjectInactiveMenuDropDown';
const handleActivateMockFunction = fn();
const handleDeleteMockFunction = fn();
@@ -7,7 +7,7 @@ import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorato
import { ComponentDecorator } from 'twenty-ui/testing';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { SettingsDataModelObjectAboutForm } from '../SettingsDataModelObjectAboutForm';
import { SettingsDataModelObjectAboutForm } from '@/settings/data-model/objects/forms/components/SettingsDataModelObjectAboutForm';
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
@@ -1,7 +1,7 @@
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { getFieldPreviewValueFromRecord } from '../getFieldPreviewValueFromRecord';
import { getFieldPreviewValueFromRecord } from '@/settings/data-model/utils/getFieldPreviewValueFromRecord';
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
(item) => item.nameSingular === 'company',
);
@@ -1,6 +1,6 @@
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { isSelectOptionDefaultValue } from '../isSelectOptionDefaultValue';
import { isSelectOptionDefaultValue } from '@/settings/data-model/utils/isSelectOptionDefaultValue';
describe('isSelectOptionDefaultValue', () => {
describe('SELECT field', () => {
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { API_KEY_FRAGMENT } from '../fragments/apiKeyFragment';
import { API_KEY_FRAGMENT } from '@/settings/developers/graphql/fragments/apiKeyFragment';
export const CREATE_API_KEY = gql`
mutation CreateApiKey($input: CreateApiKeyInput!) {
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { WEBHOOK_FRAGMENT } from '../fragments/webhookFragment';
import { WEBHOOK_FRAGMENT } from '@/settings/developers/graphql/fragments/webhookFragment';
export const CREATE_WEBHOOK = gql`
mutation CreateWebhook($input: CreateWebhookInput!) {
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { API_KEY_FRAGMENT } from '../fragments/apiKeyFragment';
import { API_KEY_FRAGMENT } from '@/settings/developers/graphql/fragments/apiKeyFragment';
export const UPDATE_API_KEY = gql`
mutation UpdateApiKey($input: UpdateApiKeyInput!) {
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { WEBHOOK_FRAGMENT } from '../fragments/webhookFragment';
import { WEBHOOK_FRAGMENT } from '@/settings/developers/graphql/fragments/webhookFragment';
export const UPDATE_WEBHOOK = gql`
mutation UpdateWebhook($input: UpdateWebhookInput!) {
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { API_KEY_FRAGMENT } from '../fragments/apiKeyFragment';
import { API_KEY_FRAGMENT } from '@/settings/developers/graphql/fragments/apiKeyFragment';
export const GET_API_KEY = gql`
query GetApiKey($input: GetApiKeyInput!) {
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { API_KEY_FRAGMENT } from '../fragments/apiKeyFragment';
import { API_KEY_FRAGMENT } from '@/settings/developers/graphql/fragments/apiKeyFragment';
export const GET_API_KEYS = gql`
query GetApiKeys {
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { WEBHOOK_FRAGMENT } from '../fragments/webhookFragment';
import { WEBHOOK_FRAGMENT } from '@/settings/developers/graphql/fragments/webhookFragment';
export const GET_WEBHOOK = gql`
query GetWebhook($input: GetWebhookInput!) {
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { WEBHOOK_FRAGMENT } from '../fragments/webhookFragment';
import { WEBHOOK_FRAGMENT } from '@/settings/developers/graphql/fragments/webhookFragment';
export const GET_WEBHOOKS = gql`
query GetWebhooks {
@@ -9,7 +9,7 @@ import { CREATE_WEBHOOK } from '@/settings/developers/graphql/mutations/createWe
import { DELETE_WEBHOOK } from '@/settings/developers/graphql/mutations/deleteWebhook';
import { UPDATE_WEBHOOK } from '@/settings/developers/graphql/mutations/updateWebhook';
import { GET_WEBHOOK } from '@/settings/developers/graphql/queries/getWebhook';
import { useWebhookForm } from '../useWebhookForm';
import { useWebhookForm } from '@/settings/developers/hooks/useWebhookForm';
const mockNavigateSettings = jest.fn();
const mockEnqueueSuccessSnackBar = jest.fn();
@@ -1,6 +1,6 @@
import { WEBHOOK_EMPTY_OPERATION } from '~/pages/settings/developers/webhooks/constants/WebhookEmptyOperation';
import { type WebhookOperationType } from '~/pages/settings/developers/webhooks/types/WebhookOperationsType';
import { addEmptyOperationIfNecessary } from '../addEmptyOperationIfNecessary';
import { addEmptyOperationIfNecessary } from '@/settings/developers/utils/addEmptyOperationIfNecessary';
describe('addEmptyOperationIfNecessary', () => {
it('should add empty operation when no wildcard or null object operations exist', () => {
@@ -1,5 +1,5 @@
import { type WebhookOperationType } from '~/pages/settings/developers/webhooks/types/WebhookOperationsType';
import { cleanAndFormatOperations } from '../cleanAndFormatOperations';
import { cleanAndFormatOperations } from '@/settings/developers/utils/cleanAndFormatOperations';
describe('cleanAndFormatOperations', () => {
it('should filter out operations with null object values', () => {
@@ -2,7 +2,7 @@ import { type WebhookFormValues } from '@/settings/developers/validation-schemas
import {
createWebhookCreateInput,
createWebhookUpdateInput,
} from '../createWebhookInput';
} from '@/settings/developers/utils/createWebhookInput';
describe('createWebhookInput', () => {
const mockFormValues: WebhookFormValues = {
@@ -1,4 +1,4 @@
import { parseOperationsFromStrings } from '../parseOperationsFromStrings';
import { parseOperationsFromStrings } from '@/settings/developers/utils/parseOperationsFromStrings';
describe('parseOperationsFromStrings', () => {
it('should parse operation strings into object/action pairs', () => {
@@ -18,7 +18,7 @@ import { SnackBarComponentInstanceContext } from '@/ui/feedback/snack-bar-manage
import { i18n } from '@lingui/core';
import { I18nProvider } from '@lingui/react';
import { SOURCE_LOCALE } from 'twenty-shared/translations';
import { messages } from '../../../../locales/generated/en';
import { messages } from '~/locales/generated/en';
i18n.load({
[SOURCE_LOCALE]: messages,
@@ -1,8 +1,8 @@
import { t } from '@lingui/core/macro';
import styled from '@emotion/styled';
import PreviewBackgroundImage from '../assets/preview-background.svg';
import SyncImage from '../assets/sync.svg?react';
import PreviewBackgroundImage from '@/settings/integrations/assets/preview-background.svg';
import SyncImage from '@/settings/integrations/assets/sync.svg?react';
import { Card, CardContent } from 'twenty-ui/layout';
type SettingsIntegrationPreviewProps = {
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import DarkCoverImage from '../assets/cover-dark.png';
import LightCoverImage from '../assets/cover-light.png';
import DarkCoverImage from '@/settings/playground/assets/cover-dark.png';
import LightCoverImage from '@/settings/playground/assets/cover-light.png';
import { Card } from 'twenty-ui/layout';
export const StyledSettingsApiPlaygroundCoverImage = styled(Card)`
@@ -1,7 +1,7 @@
import { type Meta, type StoryObj } from '@storybook/react';
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { PlaygroundSetupForm } from '../PlaygroundSetupForm';
import { PlaygroundSetupForm } from '@/settings/playground/components/PlaygroundSetupForm';
const meta: Meta<typeof PlaygroundSetupForm> = {
title: 'Modules/Settings/Playground/PlaygroundSetupForm',
@@ -7,7 +7,7 @@ import { useEffect } from 'react';
import { useSetRecoilState } from 'recoil';
import { ComponentDecorator } from 'twenty-ui/testing';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { RestPlayground } from '../RestPlayground';
import { RestPlayground } from '@/settings/playground/components/RestPlayground';
const PlaygroundApiKeySetterEffect = () => {
const setPlaygroundApiKey = useSetRecoilState(playgroundApiKeyState);
@@ -13,7 +13,7 @@ import {
type UpdateWorkspaceMutation,
useUpdateWorkspaceMutation,
} from '~/generated-metadata/graphql';
import { type RoleWithPartialMembers } from '../types/RoleWithPartialMembers';
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
type SettingsRoleDefaultRoleProps = {
roles: RoleWithPartialMembers[];
@@ -16,7 +16,7 @@ import {
useIcons,
} from 'twenty-ui/display';
import { type RoleWithPartialMembers } from '../types/RoleWithPartialMembers';
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
const StyledAssignedText = styled.div`
color: ${({ theme }) => theme.font.color.secondary};
@@ -2,7 +2,7 @@ import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDr
import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settingsPersistedRoleFamilyState';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { useUpdateWorkspaceMemberRoleMutation } from '~/generated-metadata/graphql';
import { type PartialWorkspaceMember } from '../types/RoleWithPartialMembers';
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
type AddWorkspaceMemberToRoleAndUpdateStateParams = {
workspaceMemberId: string;
@@ -12,8 +12,8 @@ import { type ApiKeyForRole } from '~/generated/graphql';
import {
type PartialWorkspaceMember,
type RoleWithPartialMembers,
} from '../../types/RoleWithPartialMembers';
import { ROLE_TARGET_CONFIG } from '../constants/RoleTargetConfig';
} from '@/settings/roles/types/RoleWithPartialMembers';
import { ROLE_TARGET_CONFIG } from '@/settings/roles/role-assignment/constants/RoleTargetConfig';
const StyledAssignToMemberContainer = styled.div`
display: flex;
@@ -22,10 +22,10 @@ import {
} from '~/generated-metadata/graphql';
import { FeatureFlagKey, type ApiKeyForRole } from '~/generated/graphql';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
import { type PartialWorkspaceMember } from '../../types/RoleWithPartialMembers';
import { ROLE_ASSIGNMENT_CONFIRMATION_MODAL_ID } from '../constants/RoleAssignmentConfirmationModalId';
import { ROLE_TARGET_CONFIG } from '../constants/RoleTargetConfig';
import { buildRoleMaps } from '../utils/build-role-maps';
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
import { ROLE_ASSIGNMENT_CONFIRMATION_MODAL_ID } from '@/settings/roles/role-assignment/constants/RoleAssignmentConfirmationModalId';
import { ROLE_TARGET_CONFIG } from '@/settings/roles/role-assignment/constants/RoleTargetConfig';
import { buildRoleMaps } from '@/settings/roles/role-assignment/utils/build-role-maps';
type SettingsRoleAssignmentProps = {
roleId: string;
@@ -16,7 +16,7 @@ import { H2Title, IconSearch } from 'twenty-ui/display';
import { type Agent } from '~/generated-metadata/graphql';
import { type ApiKeyForRole } from '~/generated/graphql';
import { normalizeSearchText } from '~/utils/normalizeSearchText';
import { type PartialWorkspaceMember } from '../../types/RoleWithPartialMembers';
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
const StyledTable = styled.div`
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
@@ -17,7 +17,7 @@ import { type Agent } from '~/generated-metadata/graphql';
import { type ApiKeyForRole } from '~/generated/graphql';
import { dateLocaleState } from '~/localization/states/dateLocaleState';
import { formatDateString } from '~/utils/string/formatDateString';
import { type PartialWorkspaceMember } from '../../types/RoleWithPartialMembers';
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
const StyledIconWrapper = styled.div`
align-items: center;
@@ -8,7 +8,7 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useLingui } from '@lingui/react/macro';
import { type ChangeEvent, useState } from 'react';
import { type PartialWorkspaceMember } from '../../types/RoleWithPartialMembers';
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
type SettingsRoleAssignmentWorkspaceMemberPickerDropdownProps = {
excludedWorkspaceMemberIds: string[];
@@ -4,7 +4,7 @@ import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { MenuItem, MenuItemAvatar } from 'twenty-ui/navigation';
import { type SearchRecord } from '~/generated-metadata/graphql';
import { type PartialWorkspaceMember } from '../../types/RoleWithPartialMembers';
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
type SettingsRoleAssignmentWorkspaceMemberPickerDropdownContentProps = {
loading: boolean;
@@ -7,8 +7,8 @@ import { type ApiKeyForRole } from '~/generated/graphql';
import {
type PartialWorkspaceMember,
type RoleWithPartialMembers,
} from '../../types/RoleWithPartialMembers';
import { type RoleMaps } from '../types/role-maps';
} from '@/settings/roles/types/RoleWithPartialMembers';
import { type RoleMaps } from '@/settings/roles/role-assignment/types/role-maps';
export const ROLE_TARGET_CONFIG = {
member: {
@@ -1,5 +1,5 @@
import { type RoleWithPartialMembers } from '../../types/RoleWithPartialMembers';
import { type RoleMaps } from '../types/role-maps';
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
import { type RoleMaps } from '@/settings/roles/role-assignment/types/role-maps';
export const buildRoleMaps = (roles: RoleWithPartialMembers[]): RoleMaps => {
const maps: RoleMaps = {
@@ -7,7 +7,7 @@ import {
MOCK_ROLE_ID_REVOKES_ALL,
rolesMockHookWrapper,
} from '~/testing/mock-data/roles/roles-mock';
import { useGetObjectPermissionDerivedStates } from '../useGetObjectPermissionDerivedStates';
import { useGetObjectPermissionDerivedStates } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/hooks/useGetObjectPermissionDerivedStates';
describe('useGetObjectPermissionDerivedStates', () => {
it('should return expected for object that revoke permissions', () => {
@@ -1,5 +1,5 @@
import { type FieldPermission, type Role } from '~/generated-metadata/graphql';
import { getRoleWithRemovedFieldPermission } from '../getRoleWithRemovedFieldPermission';
import { getRoleWithRemovedFieldPermission } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/utils/getRoleWithRemovedFieldPermission';
const BASE_FIELD_PERMISSION: FieldPermission = {
id: 'field-permission-1',
@@ -1,5 +1,5 @@
import { type FieldPermission, type Role } from '~/generated-metadata/graphql';
import { getRoleWithUpsertedFieldPermission } from '../getRoleWithUpsertedFieldPermission';
import { getRoleWithUpsertedFieldPermission } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/utils/getRoleWithUpsertedFieldPermission';
const BASE_ROLE_MOCK: Role = {
canAccessAllTools: false,
@@ -1,5 +1,5 @@
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
import { type RoleWithPartialMembers } from '../types/RoleWithPartialMembers';
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
export const settingsDraftRoleFamilyState = createFamilyState<
RoleWithPartialMembers,
@@ -1,5 +1,5 @@
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
import { type RoleWithPartialMembers } from '../types/RoleWithPartialMembers';
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
export const settingsPersistedRoleFamilyState = createFamilyState<
RoleWithPartialMembers | undefined,
@@ -1,6 +1,6 @@
/* @license Enterprise */
import { parseSAMLMetadataFromXMLFile } from '../parseSAMLMetadataFromXMLFile';
import { parseSAMLMetadataFromXMLFile } from '@/settings/security/utils/parseSAMLMetadataFromXMLFile';
describe('parseSAMLMetadataFromXMLFile', () => {
it('should parse SAML metadata from XML file', () => {
@@ -14,8 +14,8 @@ import { H2Title } from 'twenty-ui/display';
import { Button } from 'twenty-ui/input';
import { useDeleteTwoFactorAuthenticationMethodMutation } from '~/generated-metadata/graphql';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
import { useCurrentUserWorkspaceTwoFactorAuthentication } from '../hooks/useCurrentUserWorkspaceTwoFactorAuthentication';
import { useCurrentWorkspaceTwoFactorAuthenticationPolicy } from '../hooks/useWorkspaceTwoFactorAuthenticationPolicy';
import { useCurrentUserWorkspaceTwoFactorAuthentication } from '@/settings/two-factor-authentication/hooks/useCurrentUserWorkspaceTwoFactorAuthentication';
import { useCurrentWorkspaceTwoFactorAuthenticationPolicy } from '@/settings/two-factor-authentication/hooks/useWorkspaceTwoFactorAuthenticationPolicy';
const DELETE_TWO_FACTOR_AUTHENTICATION_MODAL_ID =
'delete-two-factor-authentication-modal';