diff --git a/packages/twenty-front/nyc.config.cjs b/packages/twenty-front/nyc.config.cjs index 9ce4ed713..bf92d9cde 100644 --- a/packages/twenty-front/nyc.config.cjs +++ b/packages/twenty-front/nyc.config.cjs @@ -6,8 +6,8 @@ const globalCoverage = { }; const modulesCoverage = { - statements: 70, - lines: 70, + statements: 75, + lines: 75, functions: 70, include: ['src/modules/**/*'], exclude: ['src/**/*.ts'], diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts index 8f13a8c4c..0a0feb5f6 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts +++ b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react'; -import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar.tsx'; +import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { useEmailPasswordResetLinkMutation } from '~/generated/graphql.tsx'; export const useHandleResetPassword = () => { diff --git a/packages/twenty-front/src/modules/object-metadata/components/__stories__/ObjectMetadataNavItems.stories.tsx b/packages/twenty-front/src/modules/object-metadata/components/__stories__/ObjectMetadataNavItems.stories.tsx new file mode 100644 index 000000000..5d97e61db --- /dev/null +++ b/packages/twenty-front/src/modules/object-metadata/components/__stories__/ObjectMetadataNavItems.stories.tsx @@ -0,0 +1,37 @@ +import { expect } from '@storybook/jest'; +import { Meta, StoryObj } from '@storybook/react'; +import { within } from '@storybook/test'; + +import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator'; +import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator'; +import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator'; +import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; +import { graphqlMocks } from '~/testing/graphqlMocks'; + +import { ObjectMetadataNavItems } from '../ObjectMetadataNavItems'; + +const meta: Meta = { + title: 'Modules/ObjectMetadata/ObjectMetadataNavItems', + component: ObjectMetadataNavItems, + decorators: [ + ObjectMetadataItemsDecorator, + ComponentWithRouterDecorator, + ComponentWithRecoilScopeDecorator, + SnackBarDecorator, + ], + parameters: { + msw: graphqlMocks, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + play: async () => { + const canvas = within(document.body); + expect(await canvas.findByText('People')).toBeInTheDocument(); + expect(await canvas.findByText('Companies')).toBeInTheDocument(); + expect(await canvas.findByText('Opportunities')).toBeInTheDocument(); + }, +}; diff --git a/packages/twenty-front/src/modules/spreadsheet-import/steps/components/__stories__/Steps.stories.tsx b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/__stories__/Steps.stories.tsx new file mode 100644 index 000000000..420fccde9 --- /dev/null +++ b/packages/twenty-front/src/modules/spreadsheet-import/steps/components/__stories__/Steps.stories.tsx @@ -0,0 +1,27 @@ +import { expect } from '@storybook/jest'; +import { Meta, StoryObj } from '@storybook/react'; +import { within } from '@storybook/test'; + +import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator'; +import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; + +import { Steps } from '../Steps'; + +const meta: Meta = { + title: 'Modules/SpreadsheetImport/Steps', + component: Steps, + decorators: [ComponentWithRecoilScopeDecorator, SnackBarDecorator], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + play: async () => { + const canvas = within(document.body); + expect(await canvas.findByText('Upload file')).toBeInTheDocument(); + expect(await canvas.findByText('Match columns')).toBeInTheDocument(); + expect(await canvas.findByText('Validate data')).toBeInTheDocument(); + expect(await canvas.findByText('Select file')).toBeInTheDocument(); + }, +}; diff --git a/packages/twenty-front/src/modules/support/components/SupportChat.tsx b/packages/twenty-front/src/modules/support/components/SupportChat.tsx index 4a41c6168..e1868cfe6 100644 --- a/packages/twenty-front/src/modules/support/components/SupportChat.tsx +++ b/packages/twenty-front/src/modules/support/components/SupportChat.tsx @@ -45,26 +45,32 @@ export const SupportChat = () => { currentWorkspaceMember: Pick, ) => { const url = 'https://chat-assets.frontapp.com/v1/chat.bundle.js'; - const script = document.querySelector(`script[src="${url}"]`); + let script = document.querySelector(`script[src="${url}"]`); - if (!script) { - insertScript({ - src: url, - onLoad: () => { - window.FrontChat?.('init', { - chatId, - useDefaultLauncher: false, - email: currentUser.email, - name: - currentWorkspaceMember.name.firstName + - ' ' + - currentWorkspaceMember.name.lastName, - userHash: currentUser?.supportUserHash, - }); - setIsFrontChatLoaded(true); - }, - }); + // This function only gets called when front chat is not loaded + // If the script is already defined, but front chat is not loaded + // then there was an error loading the script; reload the script + if (isDefined(script)) { + script.parentNode?.removeChild(script); + script = null; } + + insertScript({ + src: url, + onLoad: () => { + window.FrontChat?.('init', { + chatId, + useDefaultLauncher: false, + email: currentUser.email, + name: + currentWorkspaceMember.name.firstName + + ' ' + + currentWorkspaceMember.name.lastName, + userHash: currentUser?.supportUserHash, + }); + setIsFrontChatLoaded(true); + }, + }); }, [], ); diff --git a/packages/twenty-front/src/modules/support/components/__stories__/SupportChat.stories.tsx b/packages/twenty-front/src/modules/support/components/__stories__/SupportChat.stories.tsx new file mode 100644 index 000000000..7da022306 --- /dev/null +++ b/packages/twenty-front/src/modules/support/components/__stories__/SupportChat.stories.tsx @@ -0,0 +1,52 @@ +import { expect } from '@storybook/jest'; +import { Meta, StoryObj } from '@storybook/react'; +import { within } from '@storybook/test'; +import { useSetRecoilState } from 'recoil'; + +import { currentUserState } from '@/auth/states/currentUserState'; +import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; +import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; +import { supportChatState } from '@/client-config/states/supportChatState'; +import { graphqlMocks } from '~/testing/graphqlMocks'; +import { + mockDefaultWorkspace, + mockedUsersData, + mockedWorkspaceMemberData, +} from '~/testing/mock-data/users'; + +import { SupportChat } from '../SupportChat'; + +const meta: Meta = { + title: 'Modules/Support/SupportChat', + component: SupportChat, + decorators: [ + (Story) => { + const setCurrentUser = useSetRecoilState(currentUserState); + const setSupportChat = useSetRecoilState(supportChatState); + const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); + const setCurrentWorkspaceMember = useSetRecoilState( + currentWorkspaceMemberState, + ); + + setCurrentWorkspace(mockDefaultWorkspace); + setCurrentWorkspaceMember(mockedWorkspaceMemberData); + setCurrentUser(mockedUsersData[0]); + setSupportChat({ supportDriver: 'front', supportFrontChatId: '1234' }); + + return ; + }, + ], + parameters: { + msw: graphqlMocks, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + play: async () => { + const canvas = within(document.body); + expect(await canvas.findByText('Support')).toBeInTheDocument(); + }, +}; diff --git a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.tsx b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts similarity index 100% rename from packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.tsx rename to packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts diff --git a/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.tsx b/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.ts similarity index 99% rename from packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.tsx rename to packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.ts index 9d668f3e0..12c100ed6 100644 --- a/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.tsx +++ b/packages/twenty-front/src/modules/ui/layout/selectable-list/hooks/internal/useSelectableListHotKeys.ts @@ -151,6 +151,4 @@ export const useSelectableListHotKeys = ( hotkeyScope, [], ); - - return <>; }; diff --git a/packages/twenty-front/src/pages/auth/ChooseYourPlan.tsx b/packages/twenty-front/src/pages/auth/ChooseYourPlan.tsx index 2cb36de50..6f12824d5 100644 --- a/packages/twenty-front/src/pages/auth/ChooseYourPlan.tsx +++ b/packages/twenty-front/src/pages/auth/ChooseYourPlan.tsx @@ -10,7 +10,7 @@ import { SubscriptionCard } from '@/billing/components/SubscriptionCard.tsx'; import { billingState } from '@/client-config/states/billingState.ts'; import { AppPath } from '@/types/AppPath.ts'; import { Loader } from '@/ui/feedback/loader/components/Loader.tsx'; -import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar.tsx'; +import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts'; import { MainButton } from '@/ui/input/button/components/MainButton.tsx'; import { CardPicker } from '@/ui/input/components/CardPicker.tsx'; import { diff --git a/packages/twenty-front/src/pages/settings/SettingsBilling.tsx b/packages/twenty-front/src/pages/settings/SettingsBilling.tsx index e0f9f92ee..d92d71b93 100644 --- a/packages/twenty-front/src/pages/settings/SettingsBilling.tsx +++ b/packages/twenty-front/src/pages/settings/SettingsBilling.tsx @@ -15,7 +15,7 @@ import { IconCreditCard, IconCurrencyDollar } from '@/ui/display/icon'; import { Info } from '@/ui/display/info/components/Info.tsx'; import { H1Title } from '@/ui/display/typography/components/H1Title.tsx'; import { H2Title } from '@/ui/display/typography/components/H2Title.tsx'; -import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar.tsx'; +import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar.ts'; import { Button } from '@/ui/input/button/components/Button.tsx'; import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal.tsx'; import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'; diff --git a/packages/twenty-front/src/testing/graphqlMocks.ts b/packages/twenty-front/src/testing/graphqlMocks.ts index 7bca3dbc3..763218b39 100644 --- a/packages/twenty-front/src/testing/graphqlMocks.ts +++ b/packages/twenty-front/src/testing/graphqlMocks.ts @@ -1,5 +1,5 @@ import { getOperationName } from '@apollo/client/utilities'; -import { graphql, HttpResponse } from 'msw'; +import { graphql, http, HttpResponse } from 'msw'; import { TRACK } from '@/analytics/graphql/queries/track'; import { GET_CLIENT_CONFIG } from '@/client-config/graphql/queries/getClientConfig'; @@ -315,5 +315,15 @@ export const graphqlMocks = { }, }); }), + http.get('https://chat-assets.frontapp.com/v1/chat.bundle.js', () => { + return HttpResponse.text( + ` + window.FrontChat = () => {}; + console.log("This is a mocked script response."); + // Additional JavaScript code here + `, + { status: 200 }, + ); + }), ], };