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:
Vendored
+1
@@ -31,6 +31,7 @@
|
|||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
"javascript.format.enable": false,
|
"javascript.format.enable": false,
|
||||||
|
"javascript.preferences.importModuleSpecifier": "non-relative",
|
||||||
"typescript.format.enable": false,
|
"typescript.format.enable": false,
|
||||||
"cSpell.enableFiletypes": [
|
"cSpell.enableFiletypes": [
|
||||||
"!javascript",
|
"!javascript",
|
||||||
|
|||||||
+2
-2
@@ -137,10 +137,10 @@ export default [
|
|||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
'@typescript-eslint/interface-name-prefix': 'off',
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
'@typescript-eslint/no-empty-interface': [
|
'@typescript-eslint/no-empty-object-type': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
allowSingleExtends: true,
|
allowInterfaces: 'with-single-extends',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
|||||||
@@ -521,6 +521,10 @@ export default [
|
|||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
patterns: [
|
patterns: [
|
||||||
|
{
|
||||||
|
group: ['../*'],
|
||||||
|
message: 'Relative parent imports are not allowed. Use @/ alias instead.',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
group: ['@tabler/icons-react'],
|
group: ['@tabler/icons-react'],
|
||||||
message: 'Please import icons from `twenty-ui`',
|
message: 'Please import icons from `twenty-ui`',
|
||||||
@@ -552,10 +556,10 @@ export default [
|
|||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
'@typescript-eslint/interface-name-prefix': 'off',
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
'@typescript-eslint/no-empty-interface': [
|
'@typescript-eslint/no-empty-object-type': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
allowSingleExtends: true,
|
allowInterfaces: 'with-single-extends',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'@typescript-eslint/no-empty-function': 'off',
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
@@ -689,6 +693,7 @@ export default [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// JavaScript specific configuration
|
// JavaScript specific configuration
|
||||||
{
|
{
|
||||||
files: ['*.{js,jsx}'],
|
files: ['*.{js,jsx}'],
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import {
|
|||||||
TIPTAP_MARKS_RENDER_ORDER,
|
TIPTAP_MARKS_RENDER_ORDER,
|
||||||
TIPTAP_MARK_TYPES,
|
TIPTAP_MARK_TYPES,
|
||||||
} from 'twenty-shared/utils';
|
} from 'twenty-shared/utils';
|
||||||
import { bold } from '../marks/bold';
|
import { bold } from '@/utils/email-renderer/marks/bold';
|
||||||
import { italic } from '../marks/italic';
|
import { italic } from '@/utils/email-renderer/marks/italic';
|
||||||
import { link } from '../marks/link';
|
import { link } from '@/utils/email-renderer/marks/link';
|
||||||
import { strike } from '../marks/strike';
|
import { strike } from '@/utils/email-renderer/marks/strike';
|
||||||
import { underline } from '../marks/underline';
|
import { underline } from '@/utils/email-renderer/marks/underline';
|
||||||
|
|
||||||
const MARK_RENDERERS = {
|
const MARK_RENDERERS = {
|
||||||
[TIPTAP_MARK_TYPES.BOLD]: bold,
|
[TIPTAP_MARK_TYPES.BOLD]: bold,
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { type JSONContent } from '@tiptap/core';
|
import { type JSONContent } from '@tiptap/core';
|
||||||
import { Fragment, type ReactNode } from 'react';
|
import { Fragment, type ReactNode } from 'react';
|
||||||
import { TIPTAP_NODE_TYPES, type TipTapNodeType } from 'twenty-shared/utils';
|
import { TIPTAP_NODE_TYPES, type TipTapNodeType } from 'twenty-shared/utils';
|
||||||
import { bulletList } from '../nodes/bullet-list';
|
import { bulletList } from '@/utils/email-renderer/nodes/bullet-list';
|
||||||
import { hardBreak } from '../nodes/hard-break';
|
import { hardBreak } from '@/utils/email-renderer/nodes/hard-break';
|
||||||
import { heading } from '../nodes/heading';
|
import { heading } from '@/utils/email-renderer/nodes/heading';
|
||||||
import { image } from '../nodes/image';
|
import { image } from '@/utils/email-renderer/nodes/image';
|
||||||
import { listItem } from '../nodes/list-item';
|
import { listItem } from '@/utils/email-renderer/nodes/list-item';
|
||||||
import { orderedList } from '../nodes/ordered-list';
|
import { orderedList } from '@/utils/email-renderer/nodes/ordered-list';
|
||||||
import { paragraph } from '../nodes/paragraph';
|
import { paragraph } from '@/utils/email-renderer/nodes/paragraph';
|
||||||
import { text } from '../nodes/text';
|
import { text } from '@/utils/email-renderer/nodes/text';
|
||||||
import { variableTag } from '../nodes/variable-tag';
|
import { variableTag } from '@/utils/email-renderer/nodes/variable-tag';
|
||||||
|
|
||||||
const NODE_RENDERERS = {
|
const NODE_RENDERERS = {
|
||||||
[TIPTAP_NODE_TYPES.PARAGRAPH]: paragraph,
|
[TIPTAP_NODE_TYPES.PARAGRAPH]: paragraph,
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
import { setupI18n, type I18n, type Messages } from '@lingui/core';
|
import { setupI18n, type I18n, type Messages } from '@lingui/core';
|
||||||
import { type APP_LOCALES } from 'twenty-shared/translations';
|
import { type APP_LOCALES } from 'twenty-shared/translations';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { messages as afMessages } from '../locales/generated/af-ZA';
|
import { messages as afMessages } from '@/locales/generated/af-ZA';
|
||||||
import { messages as arMessages } from '../locales/generated/ar-SA';
|
import { messages as arMessages } from '@/locales/generated/ar-SA';
|
||||||
import { messages as caMessages } from '../locales/generated/ca-ES';
|
import { messages as caMessages } from '@/locales/generated/ca-ES';
|
||||||
import { messages as csMessages } from '../locales/generated/cs-CZ';
|
import { messages as csMessages } from '@/locales/generated/cs-CZ';
|
||||||
import { messages as daMessages } from '../locales/generated/da-DK';
|
import { messages as daMessages } from '@/locales/generated/da-DK';
|
||||||
import { messages as deMessages } from '../locales/generated/de-DE';
|
import { messages as deMessages } from '@/locales/generated/de-DE';
|
||||||
import { messages as elMessages } from '../locales/generated/el-GR';
|
import { messages as elMessages } from '@/locales/generated/el-GR';
|
||||||
import { messages as enMessages } from '../locales/generated/en';
|
import { messages as enMessages } from '@/locales/generated/en';
|
||||||
import { messages as esMessages } from '../locales/generated/es-ES';
|
import { messages as esMessages } from '@/locales/generated/es-ES';
|
||||||
import { messages as fiMessages } from '../locales/generated/fi-FI';
|
import { messages as fiMessages } from '@/locales/generated/fi-FI';
|
||||||
import { messages as frMessages } from '../locales/generated/fr-FR';
|
import { messages as frMessages } from '@/locales/generated/fr-FR';
|
||||||
import { messages as heMessages } from '../locales/generated/he-IL';
|
import { messages as heMessages } from '@/locales/generated/he-IL';
|
||||||
import { messages as huMessages } from '../locales/generated/hu-HU';
|
import { messages as huMessages } from '@/locales/generated/hu-HU';
|
||||||
import { messages as itMessages } from '../locales/generated/it-IT';
|
import { messages as itMessages } from '@/locales/generated/it-IT';
|
||||||
import { messages as jaMessages } from '../locales/generated/ja-JP';
|
import { messages as jaMessages } from '@/locales/generated/ja-JP';
|
||||||
import { messages as koMessages } from '../locales/generated/ko-KR';
|
import { messages as koMessages } from '@/locales/generated/ko-KR';
|
||||||
import { messages as nlMessages } from '../locales/generated/nl-NL';
|
import { messages as nlMessages } from '@/locales/generated/nl-NL';
|
||||||
import { messages as noMessages } from '../locales/generated/no-NO';
|
import { messages as noMessages } from '@/locales/generated/no-NO';
|
||||||
import { messages as plMessages } from '../locales/generated/pl-PL';
|
import { messages as plMessages } from '@/locales/generated/pl-PL';
|
||||||
import { messages as pseudoEnMessages } from '../locales/generated/pseudo-en';
|
import { messages as pseudoEnMessages } from '@/locales/generated/pseudo-en';
|
||||||
import { messages as ptBRMessages } from '../locales/generated/pt-BR';
|
import { messages as ptBRMessages } from '@/locales/generated/pt-BR';
|
||||||
import { messages as ptPTMessages } from '../locales/generated/pt-PT';
|
import { messages as ptPTMessages } from '@/locales/generated/pt-PT';
|
||||||
import { messages as roMessages } from '../locales/generated/ro-RO';
|
import { messages as roMessages } from '@/locales/generated/ro-RO';
|
||||||
import { messages as ruMessages } from '../locales/generated/ru-RU';
|
import { messages as ruMessages } from '@/locales/generated/ru-RU';
|
||||||
import { messages as srMessages } from '../locales/generated/sr-Cyrl';
|
import { messages as srMessages } from '@/locales/generated/sr-Cyrl';
|
||||||
import { messages as svMessages } from '../locales/generated/sv-SE';
|
import { messages as svMessages } from '@/locales/generated/sv-SE';
|
||||||
import { messages as trMessages } from '../locales/generated/tr-TR';
|
import { messages as trMessages } from '@/locales/generated/tr-TR';
|
||||||
import { messages as ukMessages } from '../locales/generated/uk-UA';
|
import { messages as ukMessages } from '@/locales/generated/uk-UA';
|
||||||
import { messages as viMessages } from '../locales/generated/vi-VN';
|
import { messages as viMessages } from '@/locales/generated/vi-VN';
|
||||||
import { messages as zhHansMessages } from '../locales/generated/zh-CN';
|
import { messages as zhHansMessages } from '@/locales/generated/zh-CN';
|
||||||
import { messages as zhHantMessages } from '../locales/generated/zh-TW';
|
import { messages as zhHantMessages } from '@/locales/generated/zh-TW';
|
||||||
|
|
||||||
const messages: Record<keyof typeof APP_LOCALES, Messages> = {
|
const messages: Record<keyof typeof APP_LOCALES, Messages> = {
|
||||||
en: enMessages,
|
en: enMessages,
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
"strict": true,
|
"strict": true,
|
||||||
"types": ["vite/client"],
|
"types": ["vite/client"],
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"files": [],
|
"files": [],
|
||||||
"include": ["vite.config.ts"],
|
"include": ["vite.config.ts"],
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ import { initialize, mswLoader } from 'msw-storybook-addon';
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
//import { useDarkMode } from 'storybook-dark-mode';
|
//import { useDarkMode } from 'storybook-dark-mode';
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { RootDecorator } from '../src/testing/decorators/RootDecorator';
|
import { RootDecorator } from '../src/testing/decorators/RootDecorator';
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { mockedUserJWT } from '../src/testing/mock-data/jwt';
|
import { mockedUserJWT } from '../src/testing/mock-data/jwt';
|
||||||
|
|
||||||
import { ClickOutsideListenerContext } from '@/ui/utilities/pointer-event/contexts/ClickOutsideListenerContext';
|
|
||||||
import 'react-loading-skeleton/dist/skeleton.css';
|
import 'react-loading-skeleton/dist/skeleton.css';
|
||||||
import 'twenty-ui/style.css';
|
import 'twenty-ui/style.css';
|
||||||
import { THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
|
import { THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
|
import { ClickOutsideListenerContext } from '../src/modules/ui/utilities/pointer-event/contexts/ClickOutsideListenerContext';
|
||||||
|
|
||||||
initialize({
|
initialize({
|
||||||
onUnhandledRequest: async (request: Request) => {
|
onUnhandledRequest: async (request: Request) => {
|
||||||
@@ -29,7 +31,7 @@ initialize({
|
|||||||
const requestBody = await request.json();
|
const requestBody = await request.json();
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn(`Unhandled ${request.method} request to ${request.url}
|
console.warn(`Unhandled ${request.method} request to ${request.url}
|
||||||
with payload ${JSON.stringify(requestBody)}\n
|
with payload ${JSON.stringify(requestBody)}\n
|
||||||
This request should be mocked with MSW`);
|
This request should be mocked with MSW`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import { getActionLabel } from '@/action-menu/utils/getActionLabel';
|
|||||||
import { expect, fn, userEvent, within } from '@storybook/test';
|
import { expect, fn, userEvent, within } from '@storybook/test';
|
||||||
import { type Meta, type StoryObj } from '@storybook/react';
|
import { type Meta, type StoryObj } from '@storybook/react';
|
||||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||||
import { ActionButton } from '../ActionButton';
|
import { ActionButton } from '@/action-menu/actions/display/components/ActionButton';
|
||||||
|
|
||||||
const meta: Meta<typeof ActionButton> = {
|
const meta: Meta<typeof ActionButton> = {
|
||||||
title: 'Modules/ActionMenu/Actions/Display/ActionButton',
|
title: 'Modules/ActionMenu/Actions/Display/ActionButton',
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ import { SelectableListComponentInstanceContext } from '@/ui/layout/selectable-l
|
|||||||
import { expect, fn, userEvent, within } from '@storybook/test';
|
import { expect, fn, userEvent, within } from '@storybook/test';
|
||||||
import { type Meta, type StoryObj } from '@storybook/react';
|
import { type Meta, type StoryObj } from '@storybook/react';
|
||||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||||
import { ActionDisplay } from '../ActionDisplay';
|
import { ActionDisplay } from '@/action-menu/actions/display/components/ActionDisplay';
|
||||||
|
|
||||||
type Story = StoryObj<typeof ActionDisplay>;
|
type Story = StoryObj<typeof ActionDisplay>;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { SelectableListComponentInstanceContext } from '@/ui/layout/selectable-l
|
|||||||
import { expect, fn, userEvent, within } from '@storybook/test';
|
import { expect, fn, userEvent, within } from '@storybook/test';
|
||||||
import { type Meta, type StoryObj } from '@storybook/react';
|
import { type Meta, type StoryObj } from '@storybook/react';
|
||||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||||
import { ActionDropdownItem } from '../ActionDropdownItem';
|
import { ActionDropdownItem } from '@/action-menu/actions/display/components/ActionDropdownItem';
|
||||||
|
|
||||||
const meta: Meta<typeof ActionDropdownItem> = {
|
const meta: Meta<typeof ActionDropdownItem> = {
|
||||||
title: 'Modules/ActionMenu/Actions/Display/ActionDropdownItem',
|
title: 'Modules/ActionMenu/Actions/Display/ActionDropdownItem',
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { SelectableListComponentInstanceContext } from '@/ui/layout/selectable-l
|
|||||||
import { expect, fn, userEvent, within } from '@storybook/test';
|
import { expect, fn, userEvent, within } from '@storybook/test';
|
||||||
import { type Meta, type StoryObj } from '@storybook/react';
|
import { type Meta, type StoryObj } from '@storybook/react';
|
||||||
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing';
|
||||||
import { ActionListItem } from '../ActionListItem';
|
import { ActionListItem } from '@/action-menu/actions/display/components/ActionListItem';
|
||||||
|
|
||||||
type Story = StoryObj<typeof ActionListItem>;
|
type Story = StoryObj<typeof ActionListItem>;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { ActionScope } from '@/action-menu/actions/types/ActionScope';
|
|||||||
import { ActionType } from '@/action-menu/actions/types/ActionType';
|
import { ActionType } from '@/action-menu/actions/types/ActionType';
|
||||||
import { type DefaultRecordActionConfigKeys } from '@/action-menu/actions/types/DefaultRecordActionConfigKeys';
|
import { type DefaultRecordActionConfigKeys } from '@/action-menu/actions/types/DefaultRecordActionConfigKeys';
|
||||||
import { IconHeart, IconPlus } from 'twenty-ui/display';
|
import { IconHeart, IconPlus } from 'twenty-ui/display';
|
||||||
import { inheritActionsFromDefaultConfig } from '../inheritActionsFromDefaultConfig';
|
import { inheritActionsFromDefaultConfig } from '@/action-menu/actions/record-actions/utils/inheritActionsFromDefaultConfig';
|
||||||
|
|
||||||
const MockComponent = <div>Mock Component</div>;
|
const MockComponent = <div>Mock Component</div>;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
|
|||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import { type ReactNode } from 'react';
|
import { type ReactNode } from 'react';
|
||||||
import { RecoilRoot } from 'recoil';
|
import { RecoilRoot } from 'recoil';
|
||||||
import { useRelatedRecordActions } from '../useRelatedRecordActions';
|
import { useRelatedRecordActions } from '@/action-menu/actions/record-agnostic-actions/hooks/useRelatedRecordActions';
|
||||||
|
|
||||||
jest.mock('@/object-metadata/hooks/useObjectMetadataItems', () => ({
|
jest.mock('@/object-metadata/hooks/useObjectMetadataItems', () => ({
|
||||||
useObjectMetadataItems: () => ({
|
useObjectMetadataItems: () => ({
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { getRightDrawerActionMenuDropdownIdFromActionMenuId } from '../getRightDrawerActionMenuDropdownIdFromActionMenuId';
|
import { getRightDrawerActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getRightDrawerActionMenuDropdownIdFromActionMenuId';
|
||||||
|
|
||||||
describe('getRightDrawerActionMenuDropdownIdFromActionMenuId', () => {
|
describe('getRightDrawerActionMenuDropdownIdFromActionMenuId', () => {
|
||||||
it('should return the right drawer action menu dropdown id', () => {
|
it('should return the right drawer action menu dropdown id', () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { BlockNoteSchema, defaultBlockSpecs } from '@blocknote/core';
|
import { BlockNoteSchema, defaultBlockSpecs } from '@blocknote/core';
|
||||||
|
|
||||||
import { FileBlock } from '../components/FileBlock';
|
import { FileBlock } from '@/activities/blocks/components/FileBlock';
|
||||||
|
|
||||||
export const BLOCK_SCHEMA = BlockNoteSchema.create({
|
export const BLOCK_SCHEMA = BlockNoteSchema.create({
|
||||||
blockSpecs: {
|
blockSpecs: {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { getDefaultReactSlashMenuItems } from '@blocknote/react';
|
|||||||
|
|
||||||
import { type SuggestionItem } from '@/ui/input/editor/components/CustomSlashMenu';
|
import { type SuggestionItem } from '@/ui/input/editor/components/CustomSlashMenu';
|
||||||
|
|
||||||
import { type BLOCK_SCHEMA } from '../constants/Schema';
|
import { type BLOCK_SCHEMA } from '@/activities/blocks/constants/Schema';
|
||||||
import {
|
import {
|
||||||
IconBlockquote,
|
IconBlockquote,
|
||||||
IconCode,
|
IconCode,
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { addDays, addHours, subDays, subHours } from 'date-fns';
|
import { addDays, addHours, subDays, subHours } from 'date-fns';
|
||||||
|
|
||||||
import { hasCalendarEventEnded } from '../hasCalendarEventEnded';
|
import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEventEnded';
|
||||||
|
|
||||||
describe('hasCalendarEventEnded', () => {
|
describe('hasCalendarEventEnded', () => {
|
||||||
describe('Event with end date', () => {
|
describe('Event with end date', () => {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { addHours, subHours } from 'date-fns';
|
import { addHours, subHours } from 'date-fns';
|
||||||
|
|
||||||
import { hasCalendarEventStarted } from '../hasCalendarEventStarted';
|
import { hasCalendarEventStarted } from '@/activities/calendar/utils/hasCalendarEventStarted';
|
||||||
|
|
||||||
describe('hasCalendarEventStarted', () => {
|
describe('hasCalendarEventStarted', () => {
|
||||||
it('returns true for an event with a past start date', () => {
|
it('returns true for an event with a past start date', () => {
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import { addHours } from 'date-fns';
|
|||||||
import {
|
import {
|
||||||
sortCalendarEventsAsc,
|
sortCalendarEventsAsc,
|
||||||
sortCalendarEventsDesc,
|
sortCalendarEventsDesc,
|
||||||
} from '../sortCalendarEvents';
|
} from '@/activities/calendar/utils/sortCalendarEvents';
|
||||||
|
|
||||||
const someDate = new Date(2000, 1, 1);
|
const someDate = new Date(2000, 1, 1);
|
||||||
const someDatePlusOneHour = addHours(someDate, 1);
|
const someDatePlusOneHour = addHours(someDate, 1);
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
import { getTimelineThreadsFromCompanyId } from '../getTimelineThreadsFromCompanyId';
|
import { getTimelineThreadsFromCompanyId } from '@/activities/emails/graphql/queries/getTimelineThreadsFromCompanyId';
|
||||||
|
|
||||||
jest.mock('@apollo/client', () => ({
|
jest.mock('@apollo/client', () => ({
|
||||||
gql: jest.fn().mockImplementation((strings) => {
|
gql: jest.fn().mockImplementation((strings) => {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
import { getTimelineThreadsFromPersonId } from '../getTimelineThreadsFromPersonId';
|
import { getTimelineThreadsFromPersonId } from '@/activities/emails/graphql/queries/getTimelineThreadsFromPersonId';
|
||||||
|
|
||||||
jest.mock('@apollo/client', () => ({
|
jest.mock('@apollo/client', () => ({
|
||||||
gql: jest.fn().mockImplementation((strings) => {
|
gql: jest.fn().mockImplementation((strings) => {
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import { type EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant';
|
import { type EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant';
|
||||||
|
|
||||||
import { MessageParticipantRole } from 'twenty-shared/types';
|
import { MessageParticipantRole } from 'twenty-shared/types';
|
||||||
import { getDisplayNameFromParticipant } from '../getDisplayNameFromParticipant';
|
import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
|
||||||
|
|
||||||
describe('getDisplayNameFromParticipant', () => {
|
describe('getDisplayNameFromParticipant', () => {
|
||||||
const participantWithName: EmailThreadMessageParticipant = {
|
const participantWithName: EmailThreadMessageParticipant = {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
|
|
||||||
import { useAttachments } from '../useAttachments';
|
import { useAttachments } from '@/activities/files/hooks/useAttachments';
|
||||||
|
|
||||||
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
|
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
|
||||||
useFindManyRecords: jest.fn(),
|
useFindManyRecords: jest.fn(),
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { downloadFile } from '../downloadFile';
|
import { downloadFile } from '@/activities/files/utils/downloadFile';
|
||||||
|
|
||||||
global.fetch = jest.fn(() =>
|
global.fetch = jest.fn(() =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { getFileType } from '../getFileType';
|
import { getFileType } from '@/activities/files/utils/getFileType';
|
||||||
|
|
||||||
describe('getFileType', () => {
|
describe('getFileType', () => {
|
||||||
it('should return the correct file category for a given file name', () => {
|
it('should return the correct file category for a given file name', () => {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { type RecordGqlOperationVariables } from '@/object-record/graphql/types/
|
|||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { type ActivityTargetableObject } from '../../types/ActivityTargetableEntity';
|
import { type ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
|
|
||||||
export const useNotes = (targetableObject: ActivityTargetableObject) => {
|
export const useNotes = (targetableObject: ActivityTargetableObject) => {
|
||||||
const notesQueryVariables = useMemo(
|
const notesQueryVariables = useMemo(
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { type ActivityTargetableObject } from '../types/ActivityTargetableEntity';
|
import { type ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { createState } from 'twenty-ui/utilities';
|
import { createState } from 'twenty-ui/utilities';
|
||||||
|
|
||||||
export const activityTargetableEntityArrayState = createState<
|
export const activityTargetableEntityArrayState = createState<
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { StopPropagationContainer } from '@/object-record/record-board/record-bo
|
|||||||
import { FieldContextProvider } from '@/object-record/record-field/ui/components/FieldContextProvider';
|
import { FieldContextProvider } from '@/object-record/record-field/ui/components/FieldContextProvider';
|
||||||
import { IconCalendar, OverflowingTextWithTooltip } from 'twenty-ui/display';
|
import { IconCalendar, OverflowingTextWithTooltip } from 'twenty-ui/display';
|
||||||
import { Checkbox, CheckboxShape } from 'twenty-ui/input';
|
import { Checkbox, CheckboxShape } from 'twenty-ui/input';
|
||||||
import { useCompleteTask } from '../hooks/useCompleteTask';
|
import { useCompleteTask } from '@/activities/tasks/hooks/useCompleteTask';
|
||||||
|
|
||||||
const StyledTaskBody = styled.div`
|
const StyledTaskBody = styled.div`
|
||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
color: ${({ theme }) => theme.font.color.tertiary};
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { mockedTimelineActivities } from '~/testing/mock-data/timeline-activities';
|
import { mockedTimelineActivities } from '~/testing/mock-data/timeline-activities';
|
||||||
|
|
||||||
import { groupEventsByMonth } from '../groupEventsByMonth';
|
import { groupEventsByMonth } from '@/activities/timeline-activities/utils/groupEventsByMonth';
|
||||||
|
|
||||||
describe('groupEventsByMonth', () => {
|
describe('groupEventsByMonth', () => {
|
||||||
it('should group activities by month', () => {
|
it('should group activities by month', () => {
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { type Attachment } from '@/activities/files/types/Attachment';
|
import { type Attachment } from '@/activities/files/types/Attachment';
|
||||||
import { filterAttachmentsToRestore } from '../filterAttachmentsToRestore';
|
import { filterAttachmentsToRestore } from '@/activities/utils/filterAttachmentsToRestore';
|
||||||
|
|
||||||
describe('filterAttachmentsToRestore', () => {
|
describe('filterAttachmentsToRestore', () => {
|
||||||
it('should not return any ids if there are no attachment paths to restore', () => {
|
it('should not return any ids if there are no attachment paths to restore', () => {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { getActivityPreview } from '../getActivityPreview';
|
import { getActivityPreview } from '@/activities/utils/getActivityPreview';
|
||||||
|
|
||||||
describe('getActivityPreview', () => {
|
describe('getActivityPreview', () => {
|
||||||
it('should work for empty body', () => {
|
it('should work for empty body', () => {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { getActivitySummary } from '../getActivitySummary';
|
import { getActivitySummary } from '@/activities/utils/getActivitySummary';
|
||||||
|
|
||||||
describe('getActivitySummary', () => {
|
describe('getActivitySummary', () => {
|
||||||
it('should work for empty body ""', () => {
|
it('should work for empty body ""', () => {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { ListKit } from '@tiptap/extension-list';
|
|||||||
import { Paragraph } from '@tiptap/extension-paragraph';
|
import { Paragraph } from '@tiptap/extension-paragraph';
|
||||||
import { Text } from '@tiptap/extension-text';
|
import { Text } from '@tiptap/extension-text';
|
||||||
|
|
||||||
import { DEFAULT_SLASH_COMMANDS } from '../DefaultSlashCommands';
|
import { DEFAULT_SLASH_COMMANDS } from '@/advanced-text-editor/extensions/slash-command/DefaultSlashCommands';
|
||||||
|
|
||||||
describe('DefaultSlashCommands', () => {
|
describe('DefaultSlashCommands', () => {
|
||||||
let editor: Editor;
|
let editor: Editor;
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { ListKit } from '@tiptap/extension-list';
|
|||||||
import { Paragraph } from '@tiptap/extension-paragraph';
|
import { Paragraph } from '@tiptap/extension-paragraph';
|
||||||
import { Text } from '@tiptap/extension-text';
|
import { Text } from '@tiptap/extension-text';
|
||||||
|
|
||||||
import { SlashCommand } from '../SlashCommand';
|
import { SlashCommand } from '@/advanced-text-editor/extensions/slash-command/SlashCommand';
|
||||||
|
|
||||||
describe('SlashCommand', () => {
|
describe('SlashCommand', () => {
|
||||||
let editor: Editor;
|
let editor: Editor;
|
||||||
|
|||||||
+2
-2
@@ -3,8 +3,8 @@ import { Document } from '@tiptap/extension-document';
|
|||||||
import { Paragraph } from '@tiptap/extension-paragraph';
|
import { Paragraph } from '@tiptap/extension-paragraph';
|
||||||
import { Text } from '@tiptap/extension-text';
|
import { Text } from '@tiptap/extension-text';
|
||||||
|
|
||||||
import { type SlashCommandItem } from '../SlashCommand';
|
import { type SlashCommandItem } from '@/advanced-text-editor/extensions/slash-command/SlashCommand';
|
||||||
import { SlashCommandRenderer } from '../SlashCommandRenderer';
|
import { SlashCommandRenderer } from '@/advanced-text-editor/extensions/slash-command/SlashCommandRenderer';
|
||||||
|
|
||||||
describe('SlashCommandRenderer', () => {
|
describe('SlashCommandRenderer', () => {
|
||||||
let editor: Editor;
|
let editor: Editor;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import { AGENT_FRAGMENT } from '../fragments/agentFragment';
|
import { AGENT_FRAGMENT } from '@/ai/graphql/fragments/agentFragment';
|
||||||
|
|
||||||
export const CREATE_ONE_AGENT = gql`
|
export const CREATE_ONE_AGENT = gql`
|
||||||
${AGENT_FRAGMENT}
|
${AGENT_FRAGMENT}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import { AGENT_FRAGMENT } from '../fragments/agentFragment';
|
import { AGENT_FRAGMENT } from '@/ai/graphql/fragments/agentFragment';
|
||||||
|
|
||||||
export const DELETE_ONE_AGENT = gql`
|
export const DELETE_ONE_AGENT = gql`
|
||||||
${AGENT_FRAGMENT}
|
${AGENT_FRAGMENT}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import { AGENT_FRAGMENT } from '../fragments/agentFragment';
|
import { AGENT_FRAGMENT } from '@/ai/graphql/fragments/agentFragment';
|
||||||
|
|
||||||
export const UPDATE_ONE_AGENT = gql`
|
export const UPDATE_ONE_AGENT = gql`
|
||||||
${AGENT_FRAGMENT}
|
${AGENT_FRAGMENT}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import { AGENT_FRAGMENT } from '../fragments/agentFragment';
|
import { AGENT_FRAGMENT } from '@/ai/graphql/fragments/agentFragment';
|
||||||
|
|
||||||
export const FIND_MANY_AGENTS = gql`
|
export const FIND_MANY_AGENTS = gql`
|
||||||
${AGENT_FRAGMENT}
|
${AGENT_FRAGMENT}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import { AGENT_FRAGMENT } from '../fragments/agentFragment';
|
import { AGENT_FRAGMENT } from '@/ai/graphql/fragments/agentFragment';
|
||||||
|
|
||||||
export const FIND_ONE_AGENT = gql`
|
export const FIND_ONE_AGENT = gql`
|
||||||
${AGENT_FRAGMENT}
|
${AGENT_FRAGMENT}
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import { type ExtendedUIMessage } from 'twenty-shared/ai';
|
|||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||||
import { cookieStorage } from '~/utils/cookie-storage';
|
import { cookieStorage } from '~/utils/cookie-storage';
|
||||||
import { REST_API_BASE_URL } from '../../apollo/constant/rest-api-base-url';
|
import { REST_API_BASE_URL } from '@/apollo/constant/rest-api-base-url';
|
||||||
import { agentChatInputState } from '../states/agentChatInputState';
|
import { agentChatInputState } from '@/ai/states/agentChatInputState';
|
||||||
|
|
||||||
export const useAgentChat = (uiMessages: ExtendedUIMessage[]) => {
|
export const useAgentChat = (uiMessages: ExtendedUIMessage[]) => {
|
||||||
const setTokenPair = useSetRecoilState(tokenPairState);
|
const setTokenPair = useSetRecoilState(tokenPairState);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getFieldIcon } from '../getFieldIcon';
|
import { getFieldIcon } from '@/ai/utils/getFieldIcon';
|
||||||
|
|
||||||
describe('getFieldIcon', () => {
|
describe('getFieldIcon', () => {
|
||||||
describe('supported field types', () => {
|
describe('supported field types', () => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type AgentChatThread } from '~/generated-metadata/graphql';
|
import { type AgentChatThread } from '~/generated-metadata/graphql';
|
||||||
import { groupThreadsByDate } from '../groupThreadsByDate';
|
import { groupThreadsByDate } from '@/ai/utils/groupThreadsByDate';
|
||||||
|
|
||||||
describe('groupThreadsByDate', () => {
|
describe('groupThreadsByDate', () => {
|
||||||
const baseThread: Omit<AgentChatThread, 'createdAt' | 'id'> = {
|
const baseThread: Omit<AgentChatThread, 'createdAt' | 'id'> = {
|
||||||
|
|||||||
+4
-1
@@ -5,7 +5,10 @@ import { act, renderHook, waitFor } from '@testing-library/react';
|
|||||||
import { type ReactNode } from 'react';
|
import { type ReactNode } from 'react';
|
||||||
import { RecoilRoot } from 'recoil';
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
import { ANALYTICS_COOKIE_NAME, useEventTracker } from '../useEventTracker';
|
import {
|
||||||
|
ANALYTICS_COOKIE_NAME,
|
||||||
|
useEventTracker,
|
||||||
|
} from '@/analytics/hooks/useEventTracker';
|
||||||
import { AnalyticsType } from '~/generated/graphql';
|
import { AnalyticsType } from '~/generated/graphql';
|
||||||
|
|
||||||
// Mock document.cookie
|
// Mock document.cookie
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { MemoryRouter, useLocation } from 'react-router-dom';
|
|||||||
import { RecoilRoot } from 'recoil';
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
import { SnackBarComponentInstanceContext } from '@/ui/feedback/snack-bar-manager/contexts/SnackBarComponentInstanceContext';
|
import { SnackBarComponentInstanceContext } from '@/ui/feedback/snack-bar-manager/contexts/SnackBarComponentInstanceContext';
|
||||||
import { useApolloFactory } from '../useApolloFactory';
|
import { useApolloFactory } from '@/apollo/hooks/useApolloFactory';
|
||||||
|
|
||||||
enableFetchMocks();
|
enableFetchMocks();
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { appVersionState } from '@/client-config/states/appVersionState';
|
|||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { AppPath } from 'twenty-shared/types';
|
import { AppPath } from 'twenty-shared/types';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { ApolloFactory, type Options } from '../services/apollo.factory';
|
import { ApolloFactory, type Options } from '@/apollo/services/apollo.factory';
|
||||||
|
|
||||||
export const useApolloFactory = (options: Partial<Options<any>> = {}) => {
|
export const useApolloFactory = (options: Partial<Options<any>> = {}) => {
|
||||||
// eslint-disable-next-line @nx/workspace-no-state-useref
|
// eslint-disable-next-line @nx/workspace-no-state-useref
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { type RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
|
import { type RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
|
||||||
|
|
||||||
import { doesRecordBelongToGroup } from '../doesRecordBelongToGroup';
|
import { doesRecordBelongToGroup } from '@/apollo/optimistic-effect/group-by/utils/doesRecordBelongToGroup';
|
||||||
|
|
||||||
describe('doesRecordBelongToGroup', () => {
|
describe('doesRecordBelongToGroup', () => {
|
||||||
it('should return true when groupByConfig is undefined', () => {
|
it('should return true when groupByConfig is undefined', () => {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { normalizeGroupByDimensionValue } from '../normalizeGroupByDimensionValue';
|
import { normalizeGroupByDimensionValue } from '@/apollo/optimistic-effect/group-by/utils/normalizeGroupByDimensionValue';
|
||||||
|
|
||||||
describe('normalizeGroupByDimensionValue', () => {
|
describe('normalizeGroupByDimensionValue', () => {
|
||||||
it('should convert string to string', () => {
|
it('should convert string to string', () => {
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
|
|||||||
import { type RecordGqlRefEdge } from '@/object-record/cache/types/RecordGqlRefEdge';
|
import { type RecordGqlRefEdge } from '@/object-record/cache/types/RecordGqlRefEdge';
|
||||||
import { type RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
|
import { type RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
|
||||||
|
|
||||||
import { processGroupByConnectionWithRecords } from '../processGroupByConnectionWithRecords';
|
import { processGroupByConnectionWithRecords } from '@/apollo/optimistic-effect/group-by/utils/processGroupByConnectionWithRecords';
|
||||||
|
|
||||||
describe('processGroupByConnectionWithRecords', () => {
|
describe('processGroupByConnectionWithRecords', () => {
|
||||||
const mockObjectMetadataItem: ObjectMetadataItem = {
|
const mockObjectMetadataItem: ObjectMetadataItem = {
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import { type ApolloCache } from '@apollo/client';
|
|||||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { type RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
|
import { type RecordGqlNode } from '@/object-record/graphql/types/RecordGqlNode';
|
||||||
|
|
||||||
import { triggerUpdateGroupByQueriesOptimisticEffect } from '../triggerUpdateGroupByQueriesOptimisticEffect';
|
import { triggerUpdateGroupByQueriesOptimisticEffect } from '@/apollo/optimistic-effect/group-by/utils/triggerUpdateGroupByQueriesOptimisticEffect';
|
||||||
|
|
||||||
describe('triggerUpdateGroupByQueriesOptimisticEffect', () => {
|
describe('triggerUpdateGroupByQueriesOptimisticEffect', () => {
|
||||||
const mockObjectMetadataItem: ObjectMetadataItem = {
|
const mockObjectMetadataItem: ObjectMetadataItem = {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DEFAULT_FAST_MODEL } from '@/ai/constants/DefaultFastModel';
|
|||||||
import { DEFAULT_SMART_MODEL } from '@/ai/constants/DefaultSmartModel';
|
import { DEFAULT_SMART_MODEL } from '@/ai/constants/DefaultSmartModel';
|
||||||
import { CUSTOM_WORKSPACE_APPLICATION_MOCK } from '@/object-metadata/hooks/__tests__/constants/CustomWorkspaceApplicationMock.test.constant';
|
import { CUSTOM_WORKSPACE_APPLICATION_MOCK } from '@/object-metadata/hooks/__tests__/constants/CustomWorkspaceApplicationMock.test.constant';
|
||||||
import { WorkspaceActivationStatus } from '~/generated/graphql';
|
import { WorkspaceActivationStatus } from '~/generated/graphql';
|
||||||
import { ApolloFactory, type Options } from '../apollo.factory';
|
import { ApolloFactory, type Options } from '@/apollo/services/apollo.factory';
|
||||||
|
|
||||||
enableFetchMocks();
|
enableFetchMocks();
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ import isEmpty from 'lodash.isempty';
|
|||||||
import { getGenericOperationName, isDefined } from 'twenty-shared/utils';
|
import { getGenericOperationName, isDefined } from 'twenty-shared/utils';
|
||||||
import { cookieStorage } from '~/utils/cookie-storage';
|
import { cookieStorage } from '~/utils/cookie-storage';
|
||||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||||
import { type ApolloManager } from '../types/apolloManager.interface';
|
import { type ApolloManager } from '@/apollo/types/apolloManager.interface';
|
||||||
import { loggerLink } from '../utils/loggerLink';
|
import { loggerLink } from '@/apollo/utils/loggerLink';
|
||||||
import { StreamingRestLink } from '../utils/streamingRestLink';
|
import { StreamingRestLink } from '@/apollo/utils/streamingRestLink';
|
||||||
|
|
||||||
const logger = loggerLink(() => 'Twenty');
|
const logger = loggerLink(() => 'Twenty');
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { OperationType } from '@/apollo/types/operation-type';
|
import { OperationType } from '@/apollo/types/operation-type';
|
||||||
|
|
||||||
import formatTitle from '../formatTitle';
|
import formatTitle from '@/apollo/utils/formatTitle';
|
||||||
|
|
||||||
describe('formatTitle', () => {
|
describe('formatTitle', () => {
|
||||||
it('should correctly format the title', () => {
|
it('should correctly format the title', () => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { cookieStorage } from '~/utils/cookie-storage';
|
import { cookieStorage } from '~/utils/cookie-storage';
|
||||||
import { getTokenPair } from '../getTokenPair';
|
import { getTokenPair } from '@/apollo/utils/getTokenPair';
|
||||||
|
|
||||||
jest.mock('~/utils/cookie-storage', () => ({
|
jest.mock('~/utils/cookie-storage', () => ({
|
||||||
cookieStorage: {
|
cookieStorage: {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { getTokenPair } from '../getTokenPair';
|
import { getTokenPair } from '@/apollo/utils/getTokenPair';
|
||||||
import { hasTokenPair } from '../hasTokenPair';
|
import { hasTokenPair } from '@/apollo/utils/hasTokenPair';
|
||||||
|
|
||||||
jest.mock('../getTokenPair');
|
jest.mock('../getTokenPair');
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import { type Operation } from '@apollo/client/core';
|
import { type Operation } from '@apollo/client/core';
|
||||||
import { StreamingRestLink } from '../streamingRestLink';
|
import { StreamingRestLink } from '@/apollo/utils/streamingRestLink';
|
||||||
|
|
||||||
global.fetch = jest.fn();
|
global.fetch = jest.fn();
|
||||||
describe('StreamingRestLink', () => {
|
describe('StreamingRestLink', () => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { OperationType } from '../types/operation-type';
|
import { OperationType } from '@/apollo/types/operation-type';
|
||||||
|
|
||||||
const operationTypeColors = {
|
const operationTypeColors = {
|
||||||
// eslint-disable-next-line @nx/workspace-no-hardcoded-colors
|
// eslint-disable-next-line @nx/workspace-no-hardcoded-colors
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import { APPLICATION_FRAGMENT } from '../fragments/applicationFragment';
|
import { APPLICATION_FRAGMENT } from '@/applications/graphql/fragments/applicationFragment';
|
||||||
|
|
||||||
export const FIND_ONE_APPLICATION = gql`
|
export const FIND_ONE_APPLICATION = gql`
|
||||||
${APPLICATION_FRAGMENT}
|
${APPLICATION_FRAGMENT}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { AUTH_MODAL_ID } from '../constants/AuthModalId';
|
import { AUTH_MODAL_ID } from '@/auth/constants/AuthModalId';
|
||||||
|
|
||||||
// TODO: Remove this component when we refactor the auth modal to open it directly in the PageChangeEffect
|
// TODO: Remove this component when we refactor the auth modal to open it directly in the PageChangeEffect
|
||||||
export const AuthModalMountEffect = () => {
|
export const AuthModalMountEffect = () => {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { useRecoilValue, useSetRecoilState } from 'recoil';
|
|||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||||
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
||||||
import { EmailVerificationSent } from '../sign-in-up/components/EmailVerificationSent';
|
import { EmailVerificationSent } from '@/auth/sign-in-up/components/EmailVerificationSent';
|
||||||
|
|
||||||
export const VerifyEmailEffect = () => {
|
export const VerifyEmailEffect = () => {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
RecoilRootDecorator,
|
RecoilRootDecorator,
|
||||||
RouterDecorator,
|
RouterDecorator,
|
||||||
} from 'twenty-ui/testing';
|
} from 'twenty-ui/testing';
|
||||||
import { Logo } from '../Logo';
|
import { Logo } from '@/auth/components/Logo';
|
||||||
|
|
||||||
const logoUrl = 'https://picsum.photos/192/192';
|
const logoUrl = 'https://picsum.photos/192/192';
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
import { type Meta, type StoryObj } from '@storybook/react';
|
import { type Meta, type StoryObj } from '@storybook/react';
|
||||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||||
import { RecoilRoot } from 'recoil';
|
import { RecoilRoot } from 'recoil';
|
||||||
import { type VerifyEmailEffect } from '../VerifyEmailEffect';
|
import { type VerifyEmailEffect } from '@/auth/components/VerifyEmailEffect';
|
||||||
|
|
||||||
// Mock component that just renders the error state of VerifyEmailEffect directly
|
// Mock component that just renders the error state of VerifyEmailEffect directly
|
||||||
// (since normal VerifyEmailEffect has async logic that's hard to test in Storybook)
|
// (since normal VerifyEmailEffect has async logic that's hard to test in Storybook)
|
||||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||||
import { EmailVerificationSent } from '../../sign-in-up/components/EmailVerificationSent';
|
import { EmailVerificationSent } from '@/auth/sign-in-up/components/EmailVerificationSent';
|
||||||
|
|
||||||
const VerifyEmailEffectErrorState = ({ email = 'user@example.com' }) => {
|
const VerifyEmailEffectErrorState = ({ email = 'user@example.com' }) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ import { SnackBarComponentInstanceContext } from '@/ui/feedback/snack-bar-manage
|
|||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import { iconsState } from 'twenty-ui/display';
|
import { iconsState } from 'twenty-ui/display';
|
||||||
import { SupportDriver } from '~/generated/graphql';
|
import { SupportDriver } from '~/generated/graphql';
|
||||||
import { email, mocks, password, results, token } from '../__mocks__/useAuth';
|
import {
|
||||||
|
email,
|
||||||
|
mocks,
|
||||||
|
password,
|
||||||
|
results,
|
||||||
|
token,
|
||||||
|
} from '@/auth/hooks/__mocks__/useAuth';
|
||||||
|
|
||||||
const redirectSpy = jest.fn();
|
const redirectSpy = jest.fn();
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { RecoilRoot } from 'recoil';
|
|||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { AppPath } from 'twenty-shared/types';
|
import { AppPath } from 'twenty-shared/types';
|
||||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||||
import { useAuth } from '../useAuth';
|
import { useAuth } from '@/auth/hooks/useAuth';
|
||||||
import { useVerifyLogin } from '../useVerifyLogin';
|
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
||||||
|
|
||||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||||
import { dynamicActivate } from '~/utils/i18n/dynamicActivate';
|
import { dynamicActivate } from '~/utils/i18n/dynamicActivate';
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import {
|
|||||||
} from '~/generated-metadata/graphql';
|
} from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
import { isDeveloperDefaultSignInPrefilledState } from '@/client-config/states/isDeveloperDefaultSignInPrefilledState';
|
import { isDeveloperDefaultSignInPrefilledState } from '@/client-config/states/isDeveloperDefaultSignInPrefilledState';
|
||||||
import { tokenPairState } from '../states/tokenPairState';
|
import { tokenPairState } from '@/auth/states/tokenPairState';
|
||||||
|
|
||||||
import { isAppEffectRedirectEnabledState } from '@/app/states/isAppEffectRedirectEnabledState';
|
import { isAppEffectRedirectEnabledState } from '@/app/states/isAppEffectRedirectEnabledState';
|
||||||
import { useSignUpInNewWorkspace } from '@/auth/sign-in-up/hooks/useSignUpInNewWorkspace';
|
import { useSignUpInNewWorkspace } from '@/auth/sign-in-up/hooks/useSignUpInNewWorkspace';
|
||||||
@@ -66,7 +66,7 @@ import { iconsState } from 'twenty-ui/display';
|
|||||||
import { type AuthToken } from '~/generated/graphql';
|
import { type AuthToken } from '~/generated/graphql';
|
||||||
import { cookieStorage } from '~/utils/cookie-storage';
|
import { cookieStorage } from '~/utils/cookie-storage';
|
||||||
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
||||||
import { loginTokenState } from '../states/loginTokenState';
|
import { loginTokenState } from '@/auth/states/loginTokenState';
|
||||||
|
|
||||||
export const useAuth = () => {
|
export const useAuth = () => {
|
||||||
const setTokenPair = useSetRecoilState(tokenPairState);
|
const setTokenPair = useSetRecoilState(tokenPairState);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { tokenPairState } from '../states/tokenPairState';
|
import { tokenPairState } from '@/auth/states/tokenPairState';
|
||||||
|
|
||||||
export const useIsLogged = (): boolean => {
|
export const useIsLogged = (): boolean => {
|
||||||
const [tokenPair] = useRecoilState(tokenPairState);
|
const [tokenPair] = useRecoilState(tokenPairState);
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import { type Meta, type StoryObj } from '@storybook/react';
|
|||||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||||
import { EmailVerificationSent } from '../EmailVerificationSent';
|
import { EmailVerificationSent } from '@/auth/sign-in-up/components/EmailVerificationSent';
|
||||||
|
|
||||||
// Wrap the component in Modal.Content to reflect how it's used in the app
|
// Wrap the component in Modal.Content to reflect how it's used in the app
|
||||||
const RenderWithModal = (
|
const RenderWithModal = (
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { AppPath } from 'twenty-shared/types';
|
|||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { buildAppPathWithQueryParams } from '~/utils/buildAppPathWithQueryParams';
|
import { buildAppPathWithQueryParams } from '~/utils/buildAppPathWithQueryParams';
|
||||||
import { isMatchingLocation } from '~/utils/isMatchingLocation';
|
import { isMatchingLocation } from '~/utils/isMatchingLocation';
|
||||||
import { useAuth } from '../../hooks/useAuth';
|
import { useAuth } from '@/auth/hooks/useAuth';
|
||||||
|
|
||||||
export const useSignInUp = (form: UseFormReturn<Form>) => {
|
export const useSignInUp = (form: UseFormReturn<Form>) => {
|
||||||
const { enqueueErrorSnackBar } = useSnackBar();
|
const { enqueueErrorSnackBar } = useSnackBar();
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ import {
|
|||||||
countAvailableWorkspaces,
|
countAvailableWorkspaces,
|
||||||
getAvailableWorkspacePathAndSearchParams,
|
getAvailableWorkspacePathAndSearchParams,
|
||||||
getFirstAvailableWorkspaces,
|
getFirstAvailableWorkspaces,
|
||||||
} from '../availableWorkspacesUtils';
|
} from '@/auth/utils/availableWorkspacesUtils';
|
||||||
|
|
||||||
const createMockAvailableWorkspace = (
|
const createMockAvailableWorkspace = (
|
||||||
overrides: Partial<AvailableWorkspace> = {},
|
overrides: Partial<AvailableWorkspace> = {},
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { CaptchaDriverType } from '~/generated/graphql';
|
import { CaptchaDriverType } from '~/generated/graphql';
|
||||||
|
|
||||||
import { getCaptchaUrlByProvider } from '../getCaptchaUrlByProvider';
|
import { getCaptchaUrlByProvider } from '@/captcha/utils/getCaptchaUrlByProvider';
|
||||||
|
|
||||||
describe('getCaptchaUrlByProvider', () => {
|
describe('getCaptchaUrlByProvider', () => {
|
||||||
it('handles GoogleRecaptcha', async () => {
|
it('handles GoogleRecaptcha', async () => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { matchPath } from 'react-router-dom';
|
import { matchPath } from 'react-router-dom';
|
||||||
import { CAPTCHA_PROTECTED_PATHS } from '../constants/CaptchaProtectedPaths';
|
import { CAPTCHA_PROTECTED_PATHS } from '@/captcha/constants/CaptchaProtectedPaths';
|
||||||
|
|
||||||
export const isCaptchaRequiredForPath = (pathname: string): boolean =>
|
export const isCaptchaRequiredForPath = (pathname: string): boolean =>
|
||||||
CAPTCHA_PROTECTED_PATHS.some((path) =>
|
CAPTCHA_PROTECTED_PATHS.some((path) =>
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ import { type ClientConfig } from '@/client-config/types/ClientConfig';
|
|||||||
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
|
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||||
import { clientConfigApiStatusState } from '../states/clientConfigApiStatusState';
|
import { clientConfigApiStatusState } from '@/client-config/states/clientConfigApiStatusState';
|
||||||
import { getClientConfig } from '../utils/getClientConfig';
|
import { getClientConfig } from '@/client-config/utils/getClientConfig';
|
||||||
|
|
||||||
type UseClientConfigResult = {
|
type UseClientConfigResult = {
|
||||||
data: { clientConfig: ClientConfig } | undefined;
|
data: { clientConfig: ClientConfig } | undefined;
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||||
import { getClientConfig } from '../getClientConfig';
|
import { getClientConfig } from '@/client-config/utils/getClientConfig';
|
||||||
|
|
||||||
global.fetch = jest.fn();
|
global.fetch = jest.fn();
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ import { useRecoilValue } from 'recoil';
|
|||||||
import {
|
import {
|
||||||
COMMAND_MENU_WIDTH_VAR,
|
COMMAND_MENU_WIDTH_VAR,
|
||||||
commandMenuWidthState,
|
commandMenuWidthState,
|
||||||
} from '../states/commandMenuWidthState';
|
} from '@/command-menu/states/commandMenuWidthState';
|
||||||
|
|
||||||
export const CommandMenuWidthEffect = () => {
|
export const CommandMenuWidthEffect = () => {
|
||||||
const commandMenuWidth = useRecoilValue(commandMenuWidthState);
|
const commandMenuWidth = useRecoilValue(commandMenuWidthState);
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ import { HttpResponse, graphql } from 'msw';
|
|||||||
import { IconDotsVertical } from 'twenty-ui/display';
|
import { IconDotsVertical } from 'twenty-ui/display';
|
||||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||||
import { JestContextStoreSetter } from '~/testing/jest/JestContextStoreSetter';
|
import { JestContextStoreSetter } from '~/testing/jest/JestContextStoreSetter';
|
||||||
import { type CommandMenu } from '../CommandMenu';
|
import { type CommandMenu } from '@/command-menu/components/CommandMenu';
|
||||||
|
|
||||||
const openTimeout = 50;
|
const openTimeout = 50;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import { renderHook } from '@testing-library/react';
|
|||||||
import { act } from 'react';
|
import { act } from 'react';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
import { useCommandMenuOnItemClick } from '../useCommandMenuOnItemClick';
|
import { useCommandMenuOnItemClick } from '@/command-menu/hooks/useCommandMenuOnItemClick';
|
||||||
|
|
||||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
<RecoilRoot>
|
<RecoilRoot>
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import { ActionScope } from '@/action-menu/actions/types/ActionScope';
|
|||||||
import { ActionType } from '@/action-menu/actions/types/ActionType';
|
import { ActionType } from '@/action-menu/actions/types/ActionType';
|
||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import { IconPlus } from 'twenty-ui/display';
|
import { IconPlus } from 'twenty-ui/display';
|
||||||
import { useFilterActionsWithCommandMenuSearch } from '../useFilterActionsWithCommandMenuSearch';
|
import { useFilterActionsWithCommandMenuSearch } from '@/command-menu/hooks/useFilterActionsWithCommandMenuSearch';
|
||||||
|
|
||||||
const MockComponent = <div>Mock Component</div>;
|
const MockComponent = <div>Mock Component</div>;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ import { act } from 'react';
|
|||||||
import { IconBolt, IconSettingsAutomation, useIcons } from 'twenty-ui/display';
|
import { IconBolt, IconSettingsAutomation, useIcons } from 'twenty-ui/display';
|
||||||
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
|
||||||
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
|
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
|
||||||
import { useWorkflowCommandMenu } from '../useWorkflowCommandMenu';
|
import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandMenu';
|
||||||
|
|
||||||
jest.mock('uuid', () => ({
|
jest.mock('uuid', () => ({
|
||||||
v4: jest.fn().mockReturnValue('mocked-uuid'),
|
v4: jest.fn().mockReturnValue('mocked-uuid'),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks
|
|||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { IconDotsVertical } from 'twenty-ui/display';
|
import { IconDotsVertical } from 'twenty-ui/display';
|
||||||
import { isCommandMenuOpenedState } from '../states/isCommandMenuOpenedState';
|
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||||
|
|
||||||
export const useCommandMenu = () => {
|
export const useCommandMenu = () => {
|
||||||
const { navigateCommandMenu } = useNavigateCommandMenu();
|
const { navigateCommandMenu } = useNavigateCommandMenu();
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ import {
|
|||||||
import { MessageParticipantRole } from 'twenty-shared/types';
|
import { MessageParticipantRole } from 'twenty-shared/types';
|
||||||
import { generateEmptyJestRecordNode } from '~/testing/jest/generateEmptyJestRecordNode';
|
import { generateEmptyJestRecordNode } from '~/testing/jest/generateEmptyJestRecordNode';
|
||||||
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
|
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
|
||||||
import { useEmailThreadInCommandMenu } from '../useEmailThreadInCommandMenu';
|
import { useEmailThreadInCommandMenu } from '@/command-menu/pages/message-thread/hooks/useEmailThreadInCommandMenu';
|
||||||
|
|
||||||
const mocks = [
|
const mocks = [
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ import {
|
|||||||
GraphOrderBy,
|
GraphOrderBy,
|
||||||
GraphType,
|
GraphType,
|
||||||
} from '~/generated-metadata/graphql';
|
} from '~/generated-metadata/graphql';
|
||||||
import { useChartSettingsValues } from '../useChartSettingsValues';
|
import { useChartSettingsValues } from '@/command-menu/pages/page-layout/hooks/useChartSettingsValues';
|
||||||
|
|
||||||
const mockObjectMetadataItem: ObjectMetadataItem = {
|
const mockObjectMetadataItem: ObjectMetadataItem = {
|
||||||
id: 'obj-1',
|
id: 'obj-1',
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import {
|
|||||||
GraphOrderBy,
|
GraphOrderBy,
|
||||||
type PieChartConfiguration,
|
type PieChartConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { buildChartGroupByFieldConfigUpdate } from '../buildChartGroupByFieldConfigUpdate';
|
import { buildChartGroupByFieldConfigUpdate } from '@/command-menu/pages/page-layout/utils/buildChartGroupByFieldConfigUpdate';
|
||||||
|
|
||||||
describe('buildChartGroupByFieldConfigUpdate', () => {
|
describe('buildChartGroupByFieldConfigUpdate', () => {
|
||||||
it('sets default orderBy and dateGranularity for primary axis', () => {
|
it('sets default orderBy and dateGranularity for primary axis', () => {
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ import { SORT_BY_GROUP_BY_FIELD_SETTING } from '@/command-menu/pages/page-layout
|
|||||||
import { STACKED_BARS_SETTING } from '@/command-menu/pages/page-layout/constants/settings/StackedBarsSetting';
|
import { STACKED_BARS_SETTING } from '@/command-menu/pages/page-layout/constants/settings/StackedBarsSetting';
|
||||||
import { IconAxisX, IconAxisY } from 'twenty-ui/display';
|
import { IconAxisX, IconAxisY } from 'twenty-ui/display';
|
||||||
import { GraphType } from '~/generated-metadata/graphql';
|
import { GraphType } from '~/generated-metadata/graphql';
|
||||||
import { getBarChartSettings } from '../getBarChartSettings';
|
import { getBarChartSettings } from '@/command-menu/pages/page-layout/utils/getBarChartSettings';
|
||||||
|
|
||||||
describe('getBarChartSettings', () => {
|
describe('getBarChartSettings', () => {
|
||||||
describe('Vertical bar chart', () => {
|
describe('Vertical bar chart', () => {
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import {
|
|||||||
type AggregateChartConfiguration,
|
type AggregateChartConfiguration,
|
||||||
type BarChartConfiguration,
|
type BarChartConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { isAggregateChartConfiguration } from '../isAggregateChartConfiguration';
|
import { isAggregateChartConfiguration } from '@/command-menu/pages/page-layout/utils/isAggregateChartConfiguration';
|
||||||
|
|
||||||
describe('isAggregateChartConfiguration', () => {
|
describe('isAggregateChartConfiguration', () => {
|
||||||
it('should return true for AggregateChartConfiguration', () => {
|
it('should return true for AggregateChartConfiguration', () => {
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import {
|
|||||||
type BarChartConfiguration,
|
type BarChartConfiguration,
|
||||||
type LineChartConfiguration,
|
type LineChartConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { isBarChartConfiguration } from '../isBarChartConfiguration';
|
import { isBarChartConfiguration } from '@/command-menu/pages/page-layout/utils/isBarChartConfiguration';
|
||||||
|
|
||||||
describe('isBarChartConfiguration', () => {
|
describe('isBarChartConfiguration', () => {
|
||||||
it('should return true for BarChartConfiguration', () => {
|
it('should return true for BarChartConfiguration', () => {
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import {
|
|||||||
type LineChartConfiguration,
|
type LineChartConfiguration,
|
||||||
type PieChartConfiguration,
|
type PieChartConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { isBarOrLineChartConfiguration } from '../isBarOrLineChartConfiguration';
|
import { isBarOrLineChartConfiguration } from '@/command-menu/pages/page-layout/utils/isBarOrLineChartConfiguration';
|
||||||
|
|
||||||
describe('isBarOrLineChartConfiguration', () => {
|
describe('isBarOrLineChartConfiguration', () => {
|
||||||
it('should return true for BarChartConfiguration', () => {
|
it('should return true for BarChartConfiguration', () => {
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ import {
|
|||||||
type PieChartConfiguration,
|
type PieChartConfiguration,
|
||||||
type StandaloneRichTextConfiguration,
|
type StandaloneRichTextConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { isChartConfiguration } from '../isChartConfiguration';
|
import { isChartConfiguration } from '@/command-menu/pages/page-layout/utils/isChartConfiguration';
|
||||||
|
|
||||||
describe('isChartConfiguration', () => {
|
describe('isChartConfiguration', () => {
|
||||||
it('should return true for BarChartConfiguration', () => {
|
it('should return true for BarChartConfiguration', () => {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { FieldMetadataType } from 'twenty-shared/types';
|
import { FieldMetadataType } from 'twenty-shared/types';
|
||||||
import { isFieldOrRelationNestedFieldDateKind } from '../isFieldOrNestedFieldDateKind';
|
import { isFieldOrRelationNestedFieldDateKind } from '@/command-menu/pages/page-layout/utils/isFieldOrNestedFieldDateKind';
|
||||||
|
|
||||||
describe('isFieldOrNestedFieldDateKind', () => {
|
describe('isFieldOrNestedFieldDateKind', () => {
|
||||||
it('returns false when fieldId is null', () => {
|
it('returns false when fieldId is null', () => {
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import {
|
|||||||
type BarChartConfiguration,
|
type BarChartConfiguration,
|
||||||
type GaugeChartConfiguration,
|
type GaugeChartConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { isGaugeChartConfiguration } from '../isGaugeChartConfiguration';
|
import { isGaugeChartConfiguration } from '@/command-menu/pages/page-layout/utils/isGaugeChartConfiguration';
|
||||||
|
|
||||||
describe('isGaugeChartConfiguration', () => {
|
describe('isGaugeChartConfiguration', () => {
|
||||||
it('should return true for GaugeChartConfiguration', () => {
|
it('should return true for GaugeChartConfiguration', () => {
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import {
|
|||||||
type BarChartConfiguration,
|
type BarChartConfiguration,
|
||||||
type IframeConfiguration,
|
type IframeConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { isIframeConfiguration } from '../isIframeConfiguration';
|
import { isIframeConfiguration } from '@/command-menu/pages/page-layout/utils/isIframeConfiguration';
|
||||||
|
|
||||||
describe('isIframeConfiguration', () => {
|
describe('isIframeConfiguration', () => {
|
||||||
it('should return true for IframeConfiguration', () => {
|
it('should return true for IframeConfiguration', () => {
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import {
|
|||||||
type BarChartConfiguration,
|
type BarChartConfiguration,
|
||||||
type LineChartConfiguration,
|
type LineChartConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { isLineChartConfiguration } from '../isLineChartConfiguration';
|
import { isLineChartConfiguration } from '@/command-menu/pages/page-layout/utils/isLineChartConfiguration';
|
||||||
|
|
||||||
describe('isLineChartConfiguration', () => {
|
describe('isLineChartConfiguration', () => {
|
||||||
it('should return true for LineChartConfiguration', () => {
|
it('should return true for LineChartConfiguration', () => {
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import {
|
|||||||
type BarChartConfiguration,
|
type BarChartConfiguration,
|
||||||
type PieChartConfiguration,
|
type PieChartConfiguration,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { isPieChartConfiguration } from '../isPieChartConfiguration';
|
import { isPieChartConfiguration } from '@/command-menu/pages/page-layout/utils/isPieChartConfiguration';
|
||||||
|
|
||||||
describe('isPieChartConfiguration', () => {
|
describe('isPieChartConfiguration', () => {
|
||||||
it('should return true for PieChartConfiguration', () => {
|
it('should return true for PieChartConfiguration', () => {
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
|
|||||||
import { msg } from '@lingui/core/macro';
|
import { msg } from '@lingui/core/macro';
|
||||||
import { FieldMetadataType } from 'twenty-shared/types';
|
import { FieldMetadataType } from 'twenty-shared/types';
|
||||||
import { IconChartBar } from 'twenty-ui/display';
|
import { IconChartBar } from 'twenty-ui/display';
|
||||||
import { shouldHideChartSetting } from '../shouldHideChartSetting';
|
import { shouldHideChartSetting } from '@/command-menu/pages/page-layout/utils/shouldHideChartSetting';
|
||||||
|
|
||||||
describe('shouldHideChartSetting', () => {
|
describe('shouldHideChartSetting', () => {
|
||||||
const mockItemWithoutDependencies: ChartSettingsItem = {
|
const mockItemWithoutDependencies: ChartSettingsItem = {
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import styled from '@emotion/styled';
|
|||||||
import { lazy, Suspense } from 'react';
|
import { lazy, Suspense } from 'react';
|
||||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { viewableRichTextComponentState } from '../states/viewableRichTextComponentState';
|
import { viewableRichTextComponentState } from '@/command-menu/pages/rich-text-page/states/viewableRichTextComponentState';
|
||||||
|
|
||||||
const ActivityRichTextEditor = lazy(() =>
|
const ActivityRichTextEditor = lazy(() =>
|
||||||
import('@/activities/components/ActivityRichTextEditor').then((module) => ({
|
import('@/activities/components/ActivityRichTextEditor').then((module) => ({
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import { getForeignDataWrapperType } from '../getForeignDataWrapperType';
|
import { getForeignDataWrapperType } from '@/databases/utils/getForeignDataWrapperType';
|
||||||
|
|
||||||
describe('getForeignDataWrapperType', () => {
|
describe('getForeignDataWrapperType', () => {
|
||||||
it('should handle postgres', () => {
|
it('should handle postgres', () => {
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import {
|
|||||||
mockId,
|
mockId,
|
||||||
mockWorkspaceMember,
|
mockWorkspaceMember,
|
||||||
mocks,
|
mocks,
|
||||||
} from '../__mocks__/useFavorites';
|
} from '@/favorites/hooks/__mocks__/useFavorites';
|
||||||
|
|
||||||
jest.mock('uuid', () => ({
|
jest.mock('uuid', () => ({
|
||||||
v4: () => mockId,
|
v4: () => mockId,
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ import {
|
|||||||
initialFavorites,
|
initialFavorites,
|
||||||
mockWorkspaceMember,
|
mockWorkspaceMember,
|
||||||
mocks,
|
mocks,
|
||||||
} from '../__mocks__/useFavorites';
|
} from '@/favorites/hooks/__mocks__/useFavorites';
|
||||||
|
|
||||||
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
|
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
|
||||||
useFindManyRecords: () => ({ records: initialFavorites }),
|
useFindManyRecords: () => ({ records: initialFavorites }),
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
initialFavorites,
|
initialFavorites,
|
||||||
mockWorkspaceMember,
|
mockWorkspaceMember,
|
||||||
sortedFavorites,
|
sortedFavorites,
|
||||||
} from '../__mocks__/useFavorites';
|
} from '@/favorites/hooks/__mocks__/useFavorites';
|
||||||
|
|
||||||
const Wrapper = getJestMetadataAndApolloMocksWrapper({
|
const Wrapper = getJestMetadataAndApolloMocksWrapper({
|
||||||
apolloMocks: [],
|
apolloMocks: [],
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ import {
|
|||||||
initialFavorites,
|
initialFavorites,
|
||||||
mockWorkspaceMember,
|
mockWorkspaceMember,
|
||||||
mocks,
|
mocks,
|
||||||
} from '../__mocks__/useFavorites';
|
} from '@/favorites/hooks/__mocks__/useFavorites';
|
||||||
|
|
||||||
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
|
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
|
||||||
useFindManyRecords: () => ({ records: initialFavorites }),
|
useFindManyRecords: () => ({ records: initialFavorites }),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user