diff --git a/__tests__/pages/api/MpdxWebHandoff.test.ts b/__tests__/pages/api/MpdxWebHandoff.test.ts index b194f80fa..9955b8db6 100644 --- a/__tests__/pages/api/MpdxWebHandoff.test.ts +++ b/__tests__/pages/api/MpdxWebHandoff.test.ts @@ -1,7 +1,7 @@ import { getToken } from 'next-auth/jwt'; import { createMocks } from 'node-mocks-http'; -import mpdxWebHandoff from '../../../pages/api/mpdx-web-handoff.page'; -import { taskFiltersTabs } from '../../../src/utils/tasks/taskFilterTabs'; +import mpdxWebHandoff from 'pages/api/mpdx-web-handoff.page'; +import { taskFiltersTabs } from 'src/utils/tasks/taskFilterTabs'; jest.mock('next-auth/jwt', () => ({ getToken: jest.fn() })); diff --git a/__tests__/pages/api/handoff.test.ts b/__tests__/pages/api/handoff.test.ts index 566e1a13b..cbbe7ee8f 100644 --- a/__tests__/pages/api/handoff.test.ts +++ b/__tests__/pages/api/handoff.test.ts @@ -1,7 +1,7 @@ import { getToken } from 'next-auth/jwt'; import { createMocks } from 'node-mocks-http'; +import handoff from 'pages/api/handoff.page'; import makeSsrClient from 'src/lib/apollo/ssrClient'; -import handoff from '../../../pages/api/handoff.page'; jest.mock('next-auth/jwt', () => ({ getToken: jest.fn() })); jest.mock('src/lib/apollo/ssrClient', () => jest.fn()); diff --git a/__tests__/pages/api/stopImpersonating.test.ts b/__tests__/pages/api/stopImpersonating.test.ts index 77948942b..f1c1e96f1 100644 --- a/__tests__/pages/api/stopImpersonating.test.ts +++ b/__tests__/pages/api/stopImpersonating.test.ts @@ -1,7 +1,7 @@ import { getToken } from 'next-auth/jwt'; import { createMocks } from 'node-mocks-http'; +import stopImpersonating from 'pages/api/stop-impersonating.page'; import makeSsrClient from 'src/lib/apollo/ssrClient'; -import stopImpersonating from '../../../pages/api/stop-impersonating.page'; jest.mock('next-auth/jwt', () => ({ getToken: jest.fn() })); jest.mock('src/lib/apollo/ssrClient', () => jest.fn()); diff --git a/__tests__/util/testingLibraryReactMock.tsx b/__tests__/util/testingLibraryReactMock.tsx index 51f462bb5..562e115c4 100644 --- a/__tests__/util/testingLibraryReactMock.tsx +++ b/__tests__/util/testingLibraryReactMock.tsx @@ -2,8 +2,8 @@ import React, { ReactElement } from 'react'; import { RenderOptions, RenderResult, render } from '@testing-library/react'; import { I18nextProvider } from 'react-i18next'; +import i18n from 'src/lib/i18n'; import translation from '../../public/locales/en/translation.json'; -import i18n from '../../src/lib/i18n'; i18n.addResourceBundle('en', 'translation', translation); diff --git a/next.config.js b/next.config.js index a85f22fea..cc1dacf82 100644 --- a/next.config.js +++ b/next.config.js @@ -100,6 +100,9 @@ const config = { }, experimental: { modularizeImports: { + lodash: { + transform: 'lodash/{{member}}', + }, '@mui/material': { transform: '@mui/material/{{member}}', }, diff --git a/pages/_app.page.tsx b/pages/_app.page.tsx index 04cea5ab7..5e8c263a1 100644 --- a/pages/_app.page.tsx +++ b/pages/_app.page.tsx @@ -5,8 +5,7 @@ import React, { ReactElement, useMemo } from 'react'; import { ApolloProvider as RawApolloProvider } from '@apollo/client'; import createEmotionCache from '@emotion/cache'; import { CacheProvider } from '@emotion/react'; -import { Box } from '@mui/material'; -import StyledEngineProvider from '@mui/material/StyledEngineProvider'; +import { Box, StyledEngineProvider } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon'; import { @@ -14,7 +13,6 @@ import { LocalizationProvider as RawLocalizationProvider, } from '@mui/x-date-pickers/LocalizationProvider'; import { ErrorBoundary, Provider } from '@rollbar/react'; -import { AnimatePresence } from 'framer-motion'; import { DateTime } from 'luxon'; import { Session } from 'next-auth'; import { SessionProvider } from 'next-auth/react'; @@ -40,12 +38,6 @@ import theme from 'src/theme'; import './helpscout.css'; import './print.css'; -const handleExitComplete = (): void => { - if (typeof window !== 'undefined') { - window.scrollTo({ top: 0 }); - } -}; - export type PageWithLayout = NextPage & { layout?: React.FC; }; @@ -139,6 +131,11 @@ const App = ({ /> + - - {/* On the login page and error pages, the user isn't not authenticated and doesn't have an API token, - so don't include the session or Apollo providers because they require an API token */} - {nonAuthenticatedPages.has(router.pathname) ? ( - pageContent - ) : ( - - - {pageContent} - - - )} - + {/* On the login page and error pages, the user isn't not authenticated and doesn't have an API token, + so don't include the session or Apollo providers because they require an API token */} + {nonAuthenticatedPages.has(router.pathname) ? ( + pageContent + ) : ( + + {pageContent} + + )} diff --git a/pages/_document.page.tsx b/pages/_document.page.tsx index 85c8cf22e..5882bf865 100644 --- a/pages/_document.page.tsx +++ b/pages/_document.page.tsx @@ -10,7 +10,7 @@ import Document, { import Script from 'next/script'; import React, { ReactElement } from 'react'; import { ServerStyleSheets } from '@mui/styles'; -import theme from '../src/theme'; +import theme from 'src/theme'; class MyDocument extends Document { render(): ReactElement { diff --git a/pages/accountLists.page.tsx b/pages/accountLists.page.tsx index a0087d941..070a75e50 100644 --- a/pages/accountLists.page.tsx +++ b/pages/accountLists.page.tsx @@ -5,10 +5,10 @@ import { Session } from 'next-auth'; import { getSession } from 'next-auth/react'; import { useTranslation } from 'react-i18next'; import { logErrorOnRollbar } from 'pages/api/utils/rollBar'; +import AccountLists from 'src/components/AccountLists'; +import BaseLayout from 'src/components/Layouts/Primary'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; import makeSsrClient from 'src/lib/apollo/ssrClient'; -import AccountLists from '../src/components/AccountLists'; -import BaseLayout from '../src/components/Layouts/Primary'; import { GetAccountListsDocument, GetAccountListsQuery, diff --git a/pages/accountLists/[accountListId].page.tsx b/pages/accountLists/[accountListId].page.tsx index 03a1974d6..5b0a6d93c 100644 --- a/pages/accountLists/[accountListId].page.tsx +++ b/pages/accountLists/[accountListId].page.tsx @@ -4,15 +4,15 @@ import React, { ReactElement, useEffect, useState } from 'react'; import { Session } from 'next-auth'; import { getSession } from 'next-auth/react'; import { logErrorOnRollbar } from 'pages/api/utils/rollBar'; +import Dashboard from 'src/components/Dashboard'; import { AddMenuItemsEnum, renderDialog, } from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu'; +import useGetAppSettings from 'src/hooks/useGetAppSettings'; +import useTaskModal from 'src/hooks/useTaskModal'; import makeSsrClient from 'src/lib/apollo/ssrClient'; import { suggestArticles } from 'src/lib/helpScout'; -import Dashboard from '../../src/components/Dashboard'; -import useGetAppSettings from '../../src/hooks/useGetAppSettings'; -import useTaskModal from '../../src/hooks/useTaskModal'; import { GetDashboardDocument, GetDashboardQuery, diff --git a/pages/accountLists/[accountListId]/contacts/ContactsPage.test.tsx b/pages/accountLists/[accountListId]/contacts/ContactsWrapper.test.tsx similarity index 93% rename from pages/accountLists/[accountListId]/contacts/ContactsPage.test.tsx rename to pages/accountLists/[accountListId]/contacts/ContactsWrapper.test.tsx index 7b55b4b75..7ecd289f9 100644 --- a/pages/accountLists/[accountListId]/contacts/ContactsPage.test.tsx +++ b/pages/accountLists/[accountListId]/contacts/ContactsWrapper.test.tsx @@ -5,6 +5,11 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { render, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { + ContactsContext, + ContactsType, +} from 'src/components/Contacts/ContactsContext/ContactsContext'; import { FilterPanel } from 'src/components/Shared/Filters/FilterPanel'; import { filterPanelDefaultMock, @@ -14,9 +19,7 @@ import { } from 'src/components/Shared/Filters/FilterPanel.mocks'; import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; import theme from 'src/theme'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; -import { ContactsContext, ContactsType } from './ContactsContext'; -import { ContactsPage } from './ContactsPage'; +import { ContactsWrapper } from './ContactsWrapper'; const onSelectedFiltersChanged = jest.fn(); const onClose = jest.fn(); @@ -34,7 +37,7 @@ jest.mock('notistack', () => ({ }, })); -describe('Contacts', () => { +describe('ContactsWrapper', () => { it('opens and selects a saved filter X2', async () => { const routeReplace = jest.fn(); const router = { @@ -58,7 +61,7 @@ describe('Contacts', () => { - + { onClose={onClose} onSelectedFiltersChanged={onSelectedFiltersChanged} /> - + @@ -144,9 +147,9 @@ describe('Contacts', () => { - + - + diff --git a/pages/accountLists/[accountListId]/contacts/ContactsPage.tsx b/pages/accountLists/[accountListId]/contacts/ContactsWrapper.tsx similarity index 92% rename from pages/accountLists/[accountListId]/contacts/ContactsPage.tsx rename to pages/accountLists/[accountListId]/contacts/ContactsWrapper.tsx index 033e8b7fc..729776471 100644 --- a/pages/accountLists/[accountListId]/contacts/ContactsPage.tsx +++ b/pages/accountLists/[accountListId]/contacts/ContactsWrapper.tsx @@ -1,15 +1,15 @@ import { useRouter } from 'next/router'; import React, { useEffect, useMemo, useState } from 'react'; -import _ from 'lodash'; +import { ContactsProvider } from 'src/components/Contacts/ContactsContext/ContactsContext'; import { ContactFilterSetInput } from 'src/graphql/types.generated'; import { suggestArticles } from 'src/lib/helpScout'; import { sanitizeFilters } from 'src/lib/sanitizeFilters'; -import { ContactsProvider } from './ContactsContext'; interface Props { children?: React.ReactNode; } -export const ContactsPage: React.FC = ({ children }) => { + +export const ContactsWrapper: React.FC = ({ children }) => { const router = useRouter(); const { query, replace, pathname, isReady } = router; diff --git a/pages/accountLists/[accountListId]/contacts/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/contacts/[[...contactId]].page.tsx index a8c7aaa99..cbe165cb5 100644 --- a/pages/accountLists/[accountListId]/contacts/[[...contactId]].page.tsx +++ b/pages/accountLists/[accountListId]/contacts/[[...contactId]].page.tsx @@ -1,17 +1,81 @@ -import React from 'react'; -import _ from 'lodash'; +import Head from 'next/head'; +import React, { useContext } from 'react'; +import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import { ContactsContainer } from 'src/components/Contacts/ContactsContainer'; -import { ContactsPage } from './ContactsPage'; +import { + ContactsContext, + ContactsType, +} from 'src/components/Contacts/ContactsContext/ContactsContext'; +import { ContactsLeftPanel } from 'src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel'; +import { ContactsMainPanel } from 'src/components/Contacts/ContactsMainPanel/ContactsMainPanel'; +import { DynamicContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel'; +import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout'; +import Loading from 'src/components/Loading'; +import { + TableViewModeEnum, + headerHeight, +} from 'src/components/Shared/Header/ListHeader'; +import useGetAppSettings from 'src/hooks/useGetAppSettings'; +import { ContactsWrapper } from './ContactsWrapper'; + +const Contacts: React.FC = ({}) => { + const { t } = useTranslation(); + const { + accountListId, + filterPanelOpen, + contactDetailsOpen, + viewMode, + setContactFocus, + } = useContext(ContactsContext) as ContactsType; + const { appName } = useGetAppSettings(); -const Contacts: React.FC = () => { return ( - - - + <> + + + {appName} |{' '} + {viewMode === TableViewModeEnum.Flows + ? t('Contact Flows') + : viewMode === TableViewModeEnum.Map + ? t('Contacts Map') + : t('Contacts')} + + + {accountListId ? ( + } + leftOpen={filterPanelOpen} + leftWidth="290px" + mainContent={} + rightPanel={ + + setContactFocus( + undefined, + true, + viewMode === TableViewModeEnum.Flows, + viewMode === TableViewModeEnum.Map, + ) + } + /> + } + rightOpen={contactDetailsOpen} + rightWidth="60%" + headerHeight={headerHeight} + /> + ) : ( + + )} + ); }; -export const getServerSideProps = loadSession; +const ContactsPage: React.FC = () => ( + + + +); -export default Contacts; +export default ContactsPage; + +export const getServerSideProps = loadSession; diff --git a/pages/accountLists/[accountListId]/contacts/[[...contactId]].stories.tsx b/pages/accountLists/[accountListId]/contacts/[[...contactId]].stories.tsx new file mode 100644 index 000000000..4fe5bf11e --- /dev/null +++ b/pages/accountLists/[accountListId]/contacts/[[...contactId]].stories.tsx @@ -0,0 +1,15 @@ +import React, { ReactElement } from 'react'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import ContactsPage from './[[...contactId]].page'; + +export default { + title: 'Contacts/Page', +}; + +export const Default = (): ReactElement => { + return ( + + + + ); +}; diff --git a/pages/accountLists/[accountListId]/contacts/contacts.test.tsx b/pages/accountLists/[accountListId]/contacts/contacts.test.tsx index 22169c9a2..18b437d3f 100644 --- a/pages/accountLists/[accountListId]/contacts/contacts.test.tsx +++ b/pages/accountLists/[accountListId]/contacts/contacts.test.tsx @@ -3,16 +3,16 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { VirtuosoMockContext } from 'react-virtuoso'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ListHeaderCheckBoxState } from 'src/components/Shared/Header/ListHeader'; import { PledgeFrequencyEnum, SendNewsletterEnum, StatusEnum, } from 'src/graphql/types.generated'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; -import { ListHeaderCheckBoxState } from '../../../../src/components/Shared/Header/ListHeader'; -import { useMassSelection } from '../../../../src/hooks/useMassSelection'; -import theme from '../../../../src/theme'; +import { useMassSelection } from 'src/hooks/useMassSelection'; +import theme from 'src/theme'; import { ContactsQuery } from './Contacts.generated'; import Contacts from './[[...contactId]].page'; @@ -51,7 +51,7 @@ const mockResponse = { }, }; -jest.mock('../../../../src/hooks/useMassSelection'); +jest.mock('src/hooks/useMassSelection'); (useMassSelection as jest.Mock).mockReturnValue({ ids: [], diff --git a/pages/accountLists/[accountListId]/contacts/flows/setup.page.tsx b/pages/accountLists/[accountListId]/contacts/flows/setup.page.tsx index 2195b0cca..6fd629a8f 100644 --- a/pages/accountLists/[accountListId]/contacts/flows/setup.page.tsx +++ b/pages/accountLists/[accountListId]/contacts/flows/setup.page.tsx @@ -1,34 +1,34 @@ import Head from 'next/head'; import React, { useCallback, useEffect, useState } from 'react'; -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; -import _ from 'lodash'; +import { isEqual } from 'lodash'; import { useSnackbar } from 'notistack'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import { useTranslation } from 'react-i18next'; import { v4 as uuidv4 } from 'uuid'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; -import theme from 'src/theme'; import { ContactFlowOption, colorMap, statusMap, -} from '../../../../../src/components/Contacts/ContactFlow/ContactFlow'; -import { ContactFlowSetupColumn } from '../../../../../src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn'; -import { UnusedStatusesColumn } from '../../../../../src/components/Contacts/ContactFlow/ContactFlowSetup/Column/UnusedStatusesColumn'; -import { ContactFlowSetupDragLayer } from '../../../../../src/components/Contacts/ContactFlow/ContactFlowSetup/DragLayer/ContactFlowSetupDragLayer'; -import { ContactFlowSetupHeader } from '../../../../../src/components/Contacts/ContactFlow/ContactFlowSetup/Header/ContactFlowSetupHeader'; -import { useUpdateUserOptionsMutation } from '../../../../../src/components/Contacts/ContactFlow/ContactFlowSetup/UpdateUserOptions.generated'; +} from 'src/components/Contacts/ContactFlow/ContactFlow'; +import { ContactFlowSetupColumn } from 'src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn'; +import { UnusedStatusesColumn } from 'src/components/Contacts/ContactFlow/ContactFlowSetup/Column/UnusedStatusesColumn'; +import { ContactFlowSetupDragLayer } from 'src/components/Contacts/ContactFlow/ContactFlowSetup/DragLayer/ContactFlowSetupDragLayer'; +import { ContactFlowSetupHeader } from 'src/components/Contacts/ContactFlow/ContactFlowSetup/Header/ContactFlowSetupHeader'; +import { useUpdateUserOptionsMutation } from 'src/components/Contacts/ContactFlow/ContactFlowSetup/UpdateUserOptions.generated'; import { GetUserOptionsDocument, GetUserOptionsQuery, useGetUserOptionsQuery, -} from '../../../../../src/components/Contacts/ContactFlow/GetUserOptions.generated'; -import Loading from '../../../../../src/components/Loading'; -import { useAccountListId } from '../../../../../src/hooks/useAccountListId'; -import useGetAppSettings from '../../../../../src/hooks/useGetAppSettings'; +} from 'src/components/Contacts/ContactFlow/GetUserOptions.generated'; +import Loading from 'src/components/Loading'; +import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; +import { useAccountListId } from 'src/hooks/useAccountListId'; +import useGetAppSettings from 'src/hooks/useGetAppSettings'; +import theme from 'src/theme'; const StickyBox = styled(Box)(() => ({ ['@media (min-width:900px)']: { @@ -180,7 +180,7 @@ const ContactFlowSetupPage: React.FC = () => { const originalOptions = userOptions?.userOptions.find( (option) => option.key === 'flows', )?.value; - if (!_.isEqual(originalOptions, flowOptions)) { + if (!isEqual(originalOptions, flowOptions)) { updateOptions(flowOptions); } }; diff --git a/pages/accountLists/[accountListId]/contacts/helpers.ts b/pages/accountLists/[accountListId]/contacts/helpers.ts index 2414e0e90..acf908b08 100644 --- a/pages/accountLists/[accountListId]/contacts/helpers.ts +++ b/pages/accountLists/[accountListId]/contacts/helpers.ts @@ -1,8 +1,8 @@ import { DateTime } from 'luxon'; +import { Coordinates } from 'src/components/Contacts/ContactsMap/coordinates'; import { TableViewModeEnum } from 'src/components/Shared/Header/ListHeader'; -import { dateFormatShort } from 'src/lib/intlFormat/intlFormat'; +import { dateFormatShort } from 'src/lib/intlFormat'; import { ContactsQuery } from './Contacts.generated'; -import { Coordinates } from './map/map'; export const getRedirectPathname = ({ routerPathname, @@ -63,7 +63,7 @@ export const coordinatesFromContacts = ( contacts: ContactsQuery['contacts'], locale: string, ): Coordinates[] => - contacts.nodes.map((contact): Coordinates => { + contacts.nodes.map((contact) => { const address = contact.primaryAddress; if (!address?.geo) { return { diff --git a/pages/accountLists/[accountListId]/reports/coaching.page.tsx b/pages/accountLists/[accountListId]/reports/coaching.page.tsx index 191364333..7b0fa12f8 100644 --- a/pages/accountLists/[accountListId]/reports/coaching.page.tsx +++ b/pages/accountLists/[accountListId]/reports/coaching.page.tsx @@ -6,10 +6,10 @@ import { AccountListTypeEnum, CoachingDetail, } from 'src/components/Coaching/CoachingDetail/CoachingDetail'; +import Loading from 'src/components/Loading'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; import { suggestArticles } from 'src/lib/helpScout'; -import Loading from '../../../../src/components/Loading'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const CoachingReportPage = (): ReactElement => { const { t } = useTranslation(); diff --git a/pages/accountLists/[accountListId]/reports/designationAccounts.page.tsx b/pages/accountLists/[accountListId]/reports/designationAccounts.page.tsx index 370759f2d..df3626875 100644 --- a/pages/accountLists/[accountListId]/reports/designationAccounts.page.tsx +++ b/pages/accountLists/[accountListId]/reports/designationAccounts.page.tsx @@ -1,6 +1,6 @@ import Head from 'next/head'; import React, { useEffect, useState } from 'react'; -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; diff --git a/pages/accountLists/[accountListId]/reports/donations/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/reports/donations/[[...contactId]].page.tsx index 5706db243..20945c7fc 100644 --- a/pages/accountLists/[accountListId]/reports/donations/[[...contactId]].page.tsx +++ b/pages/accountLists/[accountListId]/reports/donations/[[...contactId]].page.tsx @@ -1,11 +1,11 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import React, { useEffect, useState } from 'react'; -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import { ContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/ContactsRightPanel'; +import { DynamicContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel'; import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout'; import Loading from 'src/components/Loading'; import { DonationsReport } from 'src/components/Reports/DonationsReport/DonationsReport'; @@ -17,7 +17,7 @@ import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; import { suggestArticles } from 'src/lib/helpScout'; import { getQueryParam } from 'src/utils/queryParam'; -import { ContactsPage } from '../../contacts/ContactsPage'; +import { ContactsWrapper } from '../../contacts/ContactsWrapper'; const DonationsReportPageWrapper = styled(Box)(({ theme }) => ({ backgroundColor: theme.palette.common.white, @@ -82,9 +82,11 @@ const DonationsReportPage: React.FC = () => { } rightPanel={ selectedContactId ? ( - - handleSelectContact('')} /> - + + handleSelectContact('')} + /> + ) : undefined } rightOpen={typeof selectedContactId !== 'undefined'} diff --git a/pages/accountLists/[accountListId]/reports/partnerCurrency/[[...contactId]].page.test.tsx b/pages/accountLists/[accountListId]/reports/partnerCurrency/[[...contactId]].page.test.tsx index 62a5d8da4..2582589f2 100644 --- a/pages/accountLists/[accountListId]/reports/partnerCurrency/[[...contactId]].page.test.tsx +++ b/pages/accountLists/[accountListId]/reports/partnerCurrency/[[...contactId]].page.test.tsx @@ -66,12 +66,12 @@ describe('partnerCurrency page', () => { ).toBeInTheDocument(); }); - it('renders contact panel', () => { - const { getByRole } = render( + it('renders contact panel', async () => { + const { findByRole } = render( , ); - expect(getByRole('tab', { name: 'Tasks' })).toBeInTheDocument(); + expect(await findByRole('tab', { name: 'Tasks' })).toBeInTheDocument(); }); it('toggles filter panel', async () => { diff --git a/pages/accountLists/[accountListId]/reports/partnerCurrency/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/reports/partnerCurrency/[[...contactId]].page.tsx index c9d81e530..277ee217f 100644 --- a/pages/accountLists/[accountListId]/reports/partnerCurrency/[[...contactId]].page.tsx +++ b/pages/accountLists/[accountListId]/reports/partnerCurrency/[[...contactId]].page.tsx @@ -1,11 +1,11 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import React, { useEffect, useState } from 'react'; -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import { ContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/ContactsRightPanel'; +import { DynamicContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel'; import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout'; import Loading from 'src/components/Loading'; import { FourteenMonthReport } from 'src/components/Reports/FourteenMonthReports/FourteenMonthReport'; @@ -18,7 +18,7 @@ import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; import { suggestArticles } from 'src/lib/helpScout'; import { getQueryParam } from 'src/utils/queryParam'; -import { ContactsPage } from '../../contacts/ContactsPage'; +import { ContactsWrapper } from '../../contacts/ContactsWrapper'; const PartnerCurrencyReportPageWrapper = styled(Box)(({ theme }) => ({ backgroundColor: theme.palette.common.white, @@ -83,9 +83,11 @@ const PartnerCurrencyReportPage: React.FC = () => { } rightPanel={ selectedContactId ? ( - - handleSelectContact('')} /> - + + handleSelectContact('')} + /> + ) : undefined } rightOpen={typeof selectedContactId !== 'undefined'} diff --git a/pages/accountLists/[accountListId]/reports/partnerGivingAnalysis/[[...contactId]].page.test.tsx b/pages/accountLists/[accountListId]/reports/partnerGivingAnalysis/[[...contactId]].page.test.tsx index fd91ef2af..0907ff862 100644 --- a/pages/accountLists/[accountListId]/reports/partnerGivingAnalysis/[[...contactId]].page.test.tsx +++ b/pages/accountLists/[accountListId]/reports/partnerGivingAnalysis/[[...contactId]].page.test.tsx @@ -5,10 +5,10 @@ import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsProvider } from 'src/components/Contacts/ContactsContext/ContactsContext'; import { GetPartnerGivingAnalysisReportQuery } from 'src/components/Reports/PartnerGivingAnalysisReport/PartnerGivingAnalysisReport.generated'; import theme from 'src/theme'; import { ContactFiltersQuery } from '../../contacts/Contacts.generated'; -import { ContactsProvider } from '../../contacts/ContactsContext'; import PartnerGivingAnalysisPage from './[[...contactId]].page'; const push = jest.fn(); @@ -108,12 +108,12 @@ describe('partnerGivingAnalysis page', () => { ).toBeInTheDocument(); }); - it('renders contact panel', () => { - const { getByRole } = render( + it('renders contact panel', async () => { + const { findByRole } = render( , ); - expect(getByRole('tab', { name: 'Tasks' })).toBeInTheDocument(); + expect(await findByRole('tab', { name: 'Tasks' })).toBeInTheDocument(); }); it('renders navigation panel', () => { diff --git a/pages/accountLists/[accountListId]/reports/partnerGivingAnalysis/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/reports/partnerGivingAnalysis/[[...contactId]].page.tsx index 15aeb37b0..bbdd7426b 100644 --- a/pages/accountLists/[accountListId]/reports/partnerGivingAnalysis/[[...contactId]].page.tsx +++ b/pages/accountLists/[accountListId]/reports/partnerGivingAnalysis/[[...contactId]].page.tsx @@ -5,7 +5,8 @@ import { sortBy } from 'lodash'; import { useTranslation } from 'react-i18next'; import { ReportContactFilterSetInput } from 'pages/api/graphql-rest.page.generated'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import { ContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/ContactsRightPanel'; +import { ContactsProvider } from 'src/components/Contacts/ContactsContext/ContactsContext'; +import { DynamicContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel'; import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout'; import Loading from 'src/components/Loading'; import { @@ -13,7 +14,7 @@ import { PartnerGivingAnalysisReport, PartnerGivingAnalysisReportRef, } from 'src/components/Reports/PartnerGivingAnalysisReport/PartnerGivingAnalysisReport'; -import { FilterPanel } from 'src/components/Shared/Filters/FilterPanel'; +import { DynamicFilterPanel } from 'src/components/Shared/Filters/DynamicFilterPanel'; import { MultiPageMenu, NavTypeEnum, @@ -24,8 +25,7 @@ import useGetAppSettings from 'src/hooks/useGetAppSettings'; import { suggestArticles } from 'src/lib/helpScout'; import { getQueryParam } from 'src/utils/queryParam'; import { useContactFiltersQuery } from '../../contacts/Contacts.generated'; -import { ContactsProvider } from '../../contacts/ContactsContext'; -import { ContactsPage } from '../../contacts/ContactsPage'; +import { ContactsWrapper } from '../../contacts/ContactsWrapper'; // The order here is also the sort order and the display order const reportFilters = [ @@ -134,7 +134,7 @@ const PartnerGivingAnalysisReportPage: React.FC = () => { contactId={[]} searchTerm={''} > - { } rightPanel={ selectedContactId ? ( - - handleSelectContact('')} /> - + + handleSelectContact('')} + /> + ) : undefined } rightOpen={typeof selectedContactId !== 'undefined'} diff --git a/pages/accountLists/[accountListId]/reports/responsibilityCenters.page.tsx b/pages/accountLists/[accountListId]/reports/responsibilityCenters.page.tsx index d9d219a9e..0eba1be51 100644 --- a/pages/accountLists/[accountListId]/reports/responsibilityCenters.page.tsx +++ b/pages/accountLists/[accountListId]/reports/responsibilityCenters.page.tsx @@ -1,6 +1,6 @@ import Head from 'next/head'; import React, { useEffect, useState } from 'react'; -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; diff --git a/pages/accountLists/[accountListId]/reports/salaryCurrency/[[...contactId]].page.test.tsx b/pages/accountLists/[accountListId]/reports/salaryCurrency/[[...contactId]].page.test.tsx index 3932bdc76..c202f718e 100644 --- a/pages/accountLists/[accountListId]/reports/salaryCurrency/[[...contactId]].page.test.tsx +++ b/pages/accountLists/[accountListId]/reports/salaryCurrency/[[...contactId]].page.test.tsx @@ -66,12 +66,12 @@ describe('salaryCurrency page', () => { ).toBeInTheDocument(); }); - it('renders contact panel', () => { - const { getByRole } = render( + it('renders contact panel', async () => { + const { findByRole } = render( , ); - expect(getByRole('tab', { name: 'Tasks' })).toBeInTheDocument(); + expect(await findByRole('tab', { name: 'Tasks' })).toBeInTheDocument(); }); it('toggles filter panel', async () => { diff --git a/pages/accountLists/[accountListId]/reports/salaryCurrency/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/reports/salaryCurrency/[[...contactId]].page.tsx index 0fae84254..b143d37ac 100644 --- a/pages/accountLists/[accountListId]/reports/salaryCurrency/[[...contactId]].page.tsx +++ b/pages/accountLists/[accountListId]/reports/salaryCurrency/[[...contactId]].page.tsx @@ -1,11 +1,11 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import React, { useEffect, useState } from 'react'; -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import { ContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/ContactsRightPanel'; +import { DynamicContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel'; import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout'; import Loading from 'src/components/Loading'; import { FourteenMonthReport } from 'src/components/Reports/FourteenMonthReports/FourteenMonthReport'; @@ -18,7 +18,7 @@ import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; import { suggestArticles } from 'src/lib/helpScout'; import { getQueryParam } from 'src/utils/queryParam'; -import { ContactsPage } from '../../contacts/ContactsPage'; +import { ContactsWrapper } from '../../contacts/ContactsWrapper'; const SalaryCurrencyReportPageWrapper = styled(Box)(({ theme }) => ({ backgroundColor: theme.palette.common.white, @@ -83,9 +83,11 @@ const SalaryCurrencyReportPage: React.FC = () => { } rightPanel={ selectedContactId ? ( - - handleSelectContact('')} /> - + + handleSelectContact('')} + /> + ) : undefined } rightOpen={typeof selectedContactId !== 'undefined'} diff --git a/pages/accountLists/[accountListId]/settings/preferences.page.test.tsx b/pages/accountLists/[accountListId]/settings/preferences.page.test.tsx index 06242311f..70c3d0ad5 100644 --- a/pages/accountLists/[accountListId]/settings/preferences.page.test.tsx +++ b/pages/accountLists/[accountListId]/settings/preferences.page.test.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; -import theme from '../../../../src/theme'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import theme from 'src/theme'; import Preferences from './preferences.page'; const accountListId = 'account-list-1'; diff --git a/pages/accountLists/[accountListId]/tasks/Tasks.test.tsx b/pages/accountLists/[accountListId]/tasks/Tasks.test.tsx index 7e16d11a3..3a4e75833 100644 --- a/pages/accountLists/[accountListId]/tasks/Tasks.test.tsx +++ b/pages/accountLists/[accountListId]/tasks/Tasks.test.tsx @@ -3,11 +3,11 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { VirtuosoMockContext } from 'react-virtuoso'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import useTaskModal from 'src/hooks/useTaskModal'; import { dispatch } from 'src/lib/analytics'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; -import useTaskModal from '../../../../src/hooks/useTaskModal'; -import theme from '../../../../src/theme'; +import theme from 'src/theme'; import { TasksQuery } from './Tasks.generated'; import Tasks from './[[...contactId]].page'; @@ -24,13 +24,14 @@ const task = { contacts: { nodes: [{ id: '2', name: 'Test Person' }] }, }; -jest.mock('../../../../src/hooks/useTaskModal'); +jest.mock('src/hooks/useTaskModal'); const openTaskModal = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); @@ -72,59 +73,60 @@ const MocksProviders = (props: { children: JSX.Element }) => ( ); -it('should render list of tasks', async () => { - const { getByText } = render( - - - , - ); - await waitFor(() => expect(getByText('Test Person')).toBeInTheDocument()); - await waitFor(() => expect(getByText('Test Subject')).toBeInTheDocument()); -}); +describe('tasks page', () => { + it('should render list of tasks', async () => { + const { getByText } = render( + + + , + ); + await waitFor(() => expect(getByText('Test Person')).toBeInTheDocument()); + await waitFor(() => expect(getByText('Test Subject')).toBeInTheDocument()); + }); -it('should render contact detail panel', async () => { - const { findAllByRole, getByText } = render( - - - , - ); - await waitFor(() => expect(getByText('Test Subject')).toBeInTheDocument()); - const row = getByText('Test Person'); + it('should render contact detail panel', async () => { + const { findAllByRole, getByText } = render( + + + , + ); + await waitFor(() => expect(getByText('Test Subject')).toBeInTheDocument()); + const row = getByText('Test Person'); - userEvent.click(row); + userEvent.click(row); - const detailsTabList = (await findAllByRole('tablist'))[0]; + const detailsTabList = (await findAllByRole('tablist'))[0]; - expect(detailsTabList).toBeInTheDocument(); -}); + expect(detailsTabList).toBeInTheDocument(); + }); -it('should open add task panel', async () => { - const { getByText } = render( - - - , - ); - await waitFor(() => expect(getByText('Test Person')).toBeInTheDocument()); - await waitFor(() => expect(getByText('Test Subject')).toBeInTheDocument()); - userEvent.click(getByText('Add Task')); - await waitFor(() => expect(openTaskModal).toHaveBeenCalled()); -}); + it('should open add task panel', async () => { + const { getByText } = render( + + + , + ); + await waitFor(() => expect(getByText('Test Person')).toBeInTheDocument()); + await waitFor(() => expect(getByText('Test Subject')).toBeInTheDocument()); + userEvent.click(getByText('Add Task')); + await waitFor(() => expect(openTaskModal).toHaveBeenCalled()); + }); -it('should show Completed', async () => { - const { getByText } = render( - - - , - ); - - await waitFor(() => expect(getByText('Completed')).toBeInTheDocument()); - await waitFor(() => expect(getByText('Overdue')).toBeInTheDocument()); - await waitFor(() => expect(getByText('Today')).toBeInTheDocument()); - userEvent.click(getByText('Completed')); - userEvent.click(getByText('Overdue')); - userEvent.click(getByText('Today')); - await waitFor(() => - expect(router).toMatchInlineSnapshot(` + it('should show Completed', async () => { + const { getByText } = render( + + + , + ); + + await waitFor(() => expect(getByText('Completed')).toBeInTheDocument()); + await waitFor(() => expect(getByText('Overdue')).toBeInTheDocument()); + await waitFor(() => expect(getByText('Today')).toBeInTheDocument()); + userEvent.click(getByText('Completed')); + userEvent.click(getByText('Overdue')); + userEvent.click(getByText('Today')); + await waitFor(() => + expect(router).toMatchInlineSnapshot(` Object { "isReady": true, "query": Object { @@ -132,64 +134,65 @@ it('should show Completed', async () => { }, } `), - ); -}); + ); + }); -it('should dispatch one analytics event per task', async () => { - const { getAllByTestId, getByRole } = render( - - - mocks={{ - Tasks: { - tasks: { - nodes: [ - { id: '1', subject: 'Task 1' }, - { id: '2', subject: 'Task 2' }, - { id: '3', subject: 'Task 3' }, - ], - totalCount: 3, - pageInfo: { hasNextPage: false }, + it('should dispatch one analytics event per task', async () => { + const { getAllByTestId, getByRole, findByRole } = render( + + + mocks={{ + Tasks: { + tasks: { + nodes: [ + { id: '1', subject: 'Task 1' }, + { id: '2', subject: 'Task 2' }, + { id: '3', subject: 'Task 3' }, + ], + totalCount: 3, + pageInfo: { hasNextPage: false }, + }, }, - }, - }} - > - - - , - ); - - await waitFor(() => expect(getAllByTestId('task-row')).toHaveLength(3)); - userEvent.click(getAllByTestId('task-row')[0]); - userEvent.click(getAllByTestId('task-row')[1]); - userEvent.click(getAllByTestId('task-row')[2]); - userEvent.click(getByRole('button', { name: 'Actions' })); - userEvent.click(getByRole('menuitem', { name: 'Complete Tasks' })); - userEvent.click(getByRole('button', { name: 'Yes' })); - await waitFor(() => expect(dispatch).toHaveBeenCalledTimes(3)); -}); + }} + > + + + , + ); + + await waitFor(() => expect(getAllByTestId('task-row')).toHaveLength(3)); + userEvent.click(getAllByTestId('task-row')[0]); + userEvent.click(getAllByTestId('task-row')[1]); + userEvent.click(getAllByTestId('task-row')[2]); + userEvent.click(getByRole('button', { name: 'Actions' })); + userEvent.click(getByRole('menuitem', { name: 'Complete Tasks' })); + userEvent.click(await findByRole('button', { name: 'Yes' })); + await waitFor(() => expect(dispatch).toHaveBeenCalledTimes(3)); + }); -it('should update URL which in turns updates the buttons classes.', async () => { - const { getByText } = render( - - - , - ); - - await waitFor(() => expect(getByText('Upcoming')).toBeInTheDocument()); - userEvent.click(getByText('Upcoming')); - await waitFor(() => - expect(getByText('Upcoming')).toHaveClass('MuiButton-contained'), - ); - - await waitFor(() => expect(getByText('No Due Date')).toBeInTheDocument()); - userEvent.click(getByText('No Due Date')); - await waitFor(() => - expect(getByText('No Due Date')).toHaveClass('MuiButton-contained'), - ); - - await waitFor(() => expect(getByText('All Tasks')).toBeInTheDocument()); - userEvent.click(getByText('All Tasks')); - await waitFor(() => - expect(getByText('All Tasks')).toHaveClass('MuiButton-contained'), - ); + it('should update URL which in turns updates the buttons classes.', async () => { + const { getByText } = render( + + + , + ); + + await waitFor(() => expect(getByText('Upcoming')).toBeInTheDocument()); + userEvent.click(getByText('Upcoming')); + await waitFor(() => + expect(getByText('Upcoming')).toHaveClass('MuiButton-contained'), + ); + + await waitFor(() => expect(getByText('No Due Date')).toBeInTheDocument()); + userEvent.click(getByText('No Due Date')); + await waitFor(() => + expect(getByText('No Due Date')).toHaveClass('MuiButton-contained'), + ); + + await waitFor(() => expect(getByText('All Tasks')).toBeInTheDocument()); + userEvent.click(getByText('All Tasks')); + await waitFor(() => + expect(getByText('All Tasks')).toHaveClass('MuiButton-contained'), + ); + }); }); diff --git a/pages/accountLists/[accountListId]/tasks/[[...contactId]].page.tsx b/pages/accountLists/[accountListId]/tasks/[[...contactId]].page.tsx index ed69828f1..2b5a7fb49 100644 --- a/pages/accountLists/[accountListId]/tasks/[[...contactId]].page.tsx +++ b/pages/accountLists/[accountListId]/tasks/[[...contactId]].page.tsx @@ -5,37 +5,37 @@ import AddIcon from '@mui/icons-material/Add'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; import { Box, Button, ButtonGroup, Hidden } from '@mui/material'; import { styled } from '@mui/material/styles'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; -import { ContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/ContactsRightPanel'; +import { ContactsProvider } from 'src/components/Contacts/ContactsContext/ContactsContext'; +import { DynamicContactsRightPanel } from 'src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel'; +import { InfiniteList } from 'src/components/InfiniteList/InfiniteList'; import { navBarHeight } from 'src/components/Layouts/Primary/Primary'; +import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout'; +import Loading from 'src/components/Loading'; +import { DynamicFilterPanel } from 'src/components/Shared/Filters/DynamicFilterPanel'; +import { UserOptionFragment } from 'src/components/Shared/Filters/FilterPanel.generated'; +import NullState from 'src/components/Shared/Filters/NullState/NullState'; +import { + ListHeader, + headerHeight, +} from 'src/components/Shared/Header/ListHeader'; +import { TaskRow } from 'src/components/Task/TaskRow/TaskRow'; import { TaskFilterSetInput } from 'src/graphql/types.generated'; import { useGetTaskIdsForMassSelectionQuery } from 'src/hooks/GetIdsForMassSelection.generated'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; +import { useMassSelection } from 'src/hooks/useMassSelection'; import useTaskModal from 'src/hooks/useTaskModal'; import { suggestArticles } from 'src/lib/helpScout'; import { sanitizeFilters } from 'src/lib/sanitizeFilters'; import theme from 'src/theme'; -import { InfiniteList } from '../../../../src/components/InfiniteList/InfiniteList'; -import { SidePanelsLayout } from '../../../../src/components/Layouts/SidePanelsLayout'; -import Loading from '../../../../src/components/Loading'; -import { FilterPanel } from '../../../../src/components/Shared/Filters/FilterPanel'; -import { UserOptionFragment } from '../../../../src/components/Shared/Filters/FilterPanel.generated'; -import NullState from '../../../../src/components/Shared/Filters/NullState/NullState'; -import { - ListHeader, - headerHeight, -} from '../../../../src/components/Shared/Header/ListHeader'; -import { TaskRow } from '../../../../src/components/Task/TaskRow/TaskRow'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; -import { useMassSelection } from '../../../../src/hooks/useMassSelection'; import { TaskFilterTabsTypes, taskFiltersTabs, -} from '../../../../src/utils/tasks/taskFilterTabs'; -import { ContactsProvider } from '../contacts/ContactsContext'; +} from 'src/utils/tasks/taskFilterTabs'; import { TaskFiltersQuery, useTaskFiltersQuery, @@ -315,7 +315,7 @@ const TasksPage: React.FC = () => { { } rightPanel={ contactDetailsId ? ( - setContactFocus(undefined)} /> ) : undefined diff --git a/pages/accountLists/[accountListId]/tools/appeals.page.tsx b/pages/accountLists/[accountListId]/tools/appeals.page.tsx index 685c01930..b45e93234 100644 --- a/pages/accountLists/[accountListId]/tools/appeals.page.tsx +++ b/pages/accountLists/[accountListId]/tools/appeals.page.tsx @@ -5,11 +5,11 @@ import { motion } from 'framer-motion'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import Loading from 'src/components/Loading'; +import AddAppealForm from 'src/components/Tool/Appeal/AddAppealForm'; +import Appeals from 'src/components/Tool/Appeal/Appeals'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import Loading from '../../../../src/components/Loading'; -import AddAppealForm from '../../../../src/components/Tool/Appeal/AddAppealForm'; -import Appeals from '../../../../src/components/Tool/Appeal/Appeals'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const useStyles = makeStyles()((theme: Theme) => ({ container: { diff --git a/pages/accountLists/[accountListId]/tools/appeals/[appealId].page.tsx b/pages/accountLists/[accountListId]/tools/appeals/[appealId].page.tsx index 3c61b9a8d..19330855f 100644 --- a/pages/accountLists/[accountListId]/tools/appeals/[appealId].page.tsx +++ b/pages/accountLists/[accountListId]/tools/appeals/[appealId].page.tsx @@ -4,10 +4,10 @@ import { Box, Container, Theme } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import { AppealProvider } from 'src/components/Tool/Appeal/AppealContextProvider/AppealContextProvider'; +import AppealDetailsMain from 'src/components/Tool/Appeal/AppealDetails/AppealDetailsMain'; +import AppealDrawer from 'src/components/Tool/Appeal/AppealDrawer/AppealDrawer'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import { AppealProvider } from '../../../../../src/components/Tool/Appeal/AppealContextProvider/AppealContextProvider'; -import AppealDetailsMain from '../../../../../src/components/Tool/Appeal/AppealDetails/AppealDetailsMain'; -import AppealDrawer from '../../../../../src/components/Tool/Appeal/AppealDrawer/AppealDrawer'; import { testAppeal2 } from './testAppeal'; const useStyles = makeStyles()((theme: Theme) => ({ diff --git a/pages/accountLists/[accountListId]/tools/fixCommitmentInfo.page.tsx b/pages/accountLists/[accountListId]/tools/fixCommitmentInfo.page.tsx index a61dab337..527e3d63d 100644 --- a/pages/accountLists/[accountListId]/tools/fixCommitmentInfo.page.tsx +++ b/pages/accountLists/[accountListId]/tools/fixCommitmentInfo.page.tsx @@ -2,10 +2,10 @@ import Head from 'next/head'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import Loading from 'src/components/Loading'; +import FixCommitmentInfo from 'src/components/Tool/FixCommitmentInfo/FixCommitmentInfo'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import Loading from '../../../../src/components/Loading'; -import FixCommitmentInfo from '../../../../src/components/Tool/FixCommitmentInfo/FixCommitmentInfo'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const FixCommitmentInfoPage: React.FC = () => { const { t } = useTranslation(); diff --git a/pages/accountLists/[accountListId]/tools/fixEmailAddresses.page.tsx b/pages/accountLists/[accountListId]/tools/fixEmailAddresses.page.tsx index 5934d84f4..9d60eae40 100644 --- a/pages/accountLists/[accountListId]/tools/fixEmailAddresses.page.tsx +++ b/pages/accountLists/[accountListId]/tools/fixEmailAddresses.page.tsx @@ -2,10 +2,10 @@ import Head from 'next/head'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import Loading from 'src/components/Loading'; +import { FixEmailAddresses } from 'src/components/Tool/FixEmailAddresses/FixEmailAddresses'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import Loading from '../../../../src/components/Loading'; -import { FixEmailAddresses } from '../../../../src/components/Tool/FixEmailAddresses/FixEmailAddresses'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const FixEmailAddressesPage: React.FC = () => { const { t } = useTranslation(); diff --git a/pages/accountLists/[accountListId]/tools/fixMailingAddresses.page.tsx b/pages/accountLists/[accountListId]/tools/fixMailingAddresses.page.tsx index b083c3136..e8ff7f206 100644 --- a/pages/accountLists/[accountListId]/tools/fixMailingAddresses.page.tsx +++ b/pages/accountLists/[accountListId]/tools/fixMailingAddresses.page.tsx @@ -2,10 +2,10 @@ import Head from 'next/head'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import Loading from 'src/components/Loading'; +import FixMailingAddresses from 'src/components/Tool/FixMailingAddresses/FixMailingAddresses'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import Loading from '../../../../src/components/Loading'; -import FixMailingAddresses from '../../../../src/components/Tool/FixMailingAddresses/FixMailingAddresses'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const FixMailingAddressesPage: React.FC = () => { const { t } = useTranslation(); diff --git a/pages/accountLists/[accountListId]/tools/fixPhoneNumbers.page.tsx b/pages/accountLists/[accountListId]/tools/fixPhoneNumbers.page.tsx index 3ec8034f2..16e2123e2 100644 --- a/pages/accountLists/[accountListId]/tools/fixPhoneNumbers.page.tsx +++ b/pages/accountLists/[accountListId]/tools/fixPhoneNumbers.page.tsx @@ -2,10 +2,10 @@ import Head from 'next/head'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import Loading from 'src/components/Loading'; +import FixPhoneNumbers from 'src/components/Tool/FixPhoneNumbers/FixPhoneNumbers'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import Loading from '../../../../src/components/Loading'; -import FixPhoneNumbers from '../../../../src/components/Tool/FixPhoneNumbers/FixPhoneNumbers'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const FixPhoneNumbersPage: React.FC = () => { const { t } = useTranslation(); diff --git a/pages/accountLists/[accountListId]/tools/fixSendNewsletter.page.tsx b/pages/accountLists/[accountListId]/tools/fixSendNewsletter.page.tsx index b976e6c9b..3559c3c8b 100644 --- a/pages/accountLists/[accountListId]/tools/fixSendNewsletter.page.tsx +++ b/pages/accountLists/[accountListId]/tools/fixSendNewsletter.page.tsx @@ -2,10 +2,10 @@ import Head from 'next/head'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import Loading from 'src/components/Loading'; +import FixSendNewsletter from 'src/components/Tool/FixSendNewsletter/FixSendNewsletter'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import Loading from '../../../../src/components/Loading'; -import FixSendNewsletter from '../../../../src/components/Tool/FixSendNewsletter/FixSendNewsletter'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const FixSendNewsletterPage: React.FC = () => { const { t } = useTranslation(); diff --git a/pages/accountLists/[accountListId]/tools/mergeContacts.page.tsx b/pages/accountLists/[accountListId]/tools/mergeContacts.page.tsx index 659b2fa07..6606fd09c 100644 --- a/pages/accountLists/[accountListId]/tools/mergeContacts.page.tsx +++ b/pages/accountLists/[accountListId]/tools/mergeContacts.page.tsx @@ -2,10 +2,10 @@ import Head from 'next/head'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import Loading from 'src/components/Loading'; +import MergeContacts from 'src/components/Tool/MergeContacts/MergeContacts'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import Loading from '../../../../src/components/Loading'; -import MergeContacts from '../../../../src/components/Tool/MergeContacts/MergeContacts'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const MergeContactsPage: React.FC = () => { const { t } = useTranslation(); diff --git a/pages/accountLists/[accountListId]/tools/mergePeople.page.tsx b/pages/accountLists/[accountListId]/tools/mergePeople.page.tsx index 69b84842d..1136b2038 100644 --- a/pages/accountLists/[accountListId]/tools/mergePeople.page.tsx +++ b/pages/accountLists/[accountListId]/tools/mergePeople.page.tsx @@ -2,10 +2,10 @@ import Head from 'next/head'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { loadSession } from 'pages/api/utils/pagePropsHelpers'; +import Loading from 'src/components/Loading'; +import MergePeople from 'src/components/Tool/MergePeople/MergePeople'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import Loading from '../../../../src/components/Loading'; -import MergePeople from '../../../../src/components/Tool/MergePeople/MergePeople'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; const MergePeoplePage: React.FC = () => { const { t } = useTranslation(); diff --git a/pages/api/Schema/Settings/Integrations/Mailchimp/updateMailchimpAccount/datahandler.ts b/pages/api/Schema/Settings/Integrations/Mailchimp/updateMailchimpAccount/datahandler.ts index 1d3b3856b..44e9ec9a9 100644 --- a/pages/api/Schema/Settings/Integrations/Mailchimp/updateMailchimpAccount/datahandler.ts +++ b/pages/api/Schema/Settings/Integrations/Mailchimp/updateMailchimpAccount/datahandler.ts @@ -1,4 +1,4 @@ -import { snakeToCamel } from '../../../../../../../src/lib/snakeToCamel'; +import { snakeToCamel } from 'src/lib/snakeToCamel'; export interface UpdateMailchimpAccountResponse { attributes: Omit; diff --git a/pages/api/auth/apiOauthSignIn.ts b/pages/api/auth/apiOauthSignIn.ts index faebc8e2f..c81eb4a08 100644 --- a/pages/api/auth/apiOauthSignIn.ts +++ b/pages/api/auth/apiOauthSignIn.ts @@ -1,8 +1,7 @@ /* eslint-disable */ -import * as Types from 'src/graphql/types.generated'; - -import { gql } from '@apollo/client'; -import * as Apollo from '@apollo/client'; +import type * as Types from 'src/graphql/types.generated'; +import { gql, useMutation } from '@apollo/client'; +import type * as Apollo from '@apollo/client'; const defaultOptions = {} as const; export type ApiOauthSignInMutationVariables = Types.Exact<{ accessToken: Types.Scalars['String']; @@ -74,10 +73,10 @@ export function useApiOauthSignInMutation( >, ) { const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - ApiOauthSignInMutation, - ApiOauthSignInMutationVariables - >(ApiOauthSignInDocument, options); + return useMutation( + ApiOauthSignInDocument, + options, + ); } export type ApiOauthSignInMutationHookResult = ReturnType< typeof useApiOauthSignInMutation diff --git a/pages/api/mpdx-web-handoff.page.ts b/pages/api/mpdx-web-handoff.page.ts index 7abcf84b7..61426b6f1 100644 --- a/pages/api/mpdx-web-handoff.page.ts +++ b/pages/api/mpdx-web-handoff.page.ts @@ -1,6 +1,6 @@ import { NextApiRequest, NextApiResponse } from 'next'; import { getToken } from 'next-auth/jwt'; -import { taskFiltersTabs } from '../../src/utils/tasks/taskFilterTabs'; +import { taskFiltersTabs } from 'src/utils/tasks/taskFilterTabs'; import { clearNextAuthSessionCookies, cookieDefaultInfo, diff --git a/src/components/AccountLists/AccountLists.tsx b/src/components/AccountLists/AccountLists.tsx index 7ee375c92..9b84ba3a4 100644 --- a/src/components/AccountLists/AccountLists.tsx +++ b/src/components/AccountLists/AccountLists.tsx @@ -12,8 +12,8 @@ import { import { motion } from 'framer-motion'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { GetAccountListsQuery } from 'pages/GetAccountLists.generated'; import { useLocale } from 'src/hooks/useLocale'; -import { GetAccountListsQuery } from '../../../pages/GetAccountLists.generated'; import { currencyFormat, percentageFormat } from '../../lib/intlFormat'; import AnimatedCard from '../AnimatedCard'; import PageHeading from '../PageHeading'; diff --git a/src/components/Coaching/AppealProgress/AppealProgress.tsx b/src/components/Coaching/AppealProgress/AppealProgress.tsx index dff3cccc1..ccc7eae5c 100644 --- a/src/components/Coaching/AppealProgress/AppealProgress.tsx +++ b/src/components/Coaching/AppealProgress/AppealProgress.tsx @@ -1,6 +1,5 @@ import React, { ReactElement } from 'react'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; +import { Box, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import StyledProgress from 'src/components/StyledProgress'; diff --git a/src/components/Coaching/CoachingDetail/CoachingSidebar.tsx b/src/components/Coaching/CoachingDetail/CoachingSidebar.tsx index 34546a860..2dd7b6dd9 100644 --- a/src/components/Coaching/CoachingDetail/CoachingSidebar.tsx +++ b/src/components/Coaching/CoachingDetail/CoachingSidebar.tsx @@ -15,8 +15,7 @@ import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { GetTaskAnalyticsQuery } from 'src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.generated'; import { useLocale } from 'src/hooks/useLocale'; -import { currencyFormat } from 'src/lib/intlFormat'; -import { dateFormat } from 'src/lib/intlFormat/intlFormat'; +import { currencyFormat, dateFormat } from 'src/lib/intlFormat'; import theme from 'src/theme'; import { CollapsibleEmailList } from '../../Shared/CollapsibleContactInfo/CollapsibleEmailList'; import { CollapsiblePhoneList } from '../../Shared/CollapsibleContactInfo/CollapsiblePhoneList'; diff --git a/src/components/Coaching/CoachingDetail/MonthlyCommitment/MonthlyCommitment.tsx b/src/components/Coaching/CoachingDetail/MonthlyCommitment/MonthlyCommitment.tsx index b64ce129b..b5f758ed8 100644 --- a/src/components/Coaching/CoachingDetail/MonthlyCommitment/MonthlyCommitment.tsx +++ b/src/components/Coaching/CoachingDetail/MonthlyCommitment/MonthlyCommitment.tsx @@ -1,6 +1,11 @@ import React from 'react'; -import { Box, CardContent, CardHeader, Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { + Box, + CardContent, + CardHeader, + Skeleton, + Typography, +} from '@mui/material'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { diff --git a/src/components/Coaching/CoachingDetail/StyledComponents.tsx b/src/components/Coaching/CoachingDetail/StyledComponents.ts similarity index 100% rename from src/components/Coaching/CoachingDetail/StyledComponents.tsx rename to src/components/Coaching/CoachingDetail/StyledComponents.ts diff --git a/src/components/Coaching/CoachingList.stories.tsx b/src/components/Coaching/CoachingList.stories.tsx index 9c845f6c6..abeeabe2d 100644 --- a/src/components/Coaching/CoachingList.stories.tsx +++ b/src/components/Coaching/CoachingList.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; -import { GqlMockedProvider } from '../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { CoachingList } from './CoachingList'; import { LoadCoachingListDocument, diff --git a/src/components/Coaching/CoachingList.tsx b/src/components/Coaching/CoachingList.tsx index 06fea7868..947a3cb95 100644 --- a/src/components/Coaching/CoachingList.tsx +++ b/src/components/Coaching/CoachingList.tsx @@ -1,8 +1,7 @@ import React from 'react'; -import { Box, Divider, Typography } from '@mui/material'; +import { Box, Divider, Skeleton, Typography } from '@mui/material'; // TODO: This icon is not defined on @mui/icons-material, find replacement. // import { EcoOutlined } from '@mui/icons-material'; -import Skeleton from '@mui/material/Skeleton'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { CoachingRow } from './CoachingRow/CoachingRow'; diff --git a/src/components/Coaching/CoachingRow/CoachingRow.stories.tsx b/src/components/Coaching/CoachingRow/CoachingRow.stories.tsx index d6488a766..0237a7a2c 100644 --- a/src/components/Coaching/CoachingRow/CoachingRow.stories.tsx +++ b/src/components/Coaching/CoachingRow/CoachingRow.stories.tsx @@ -1,5 +1,5 @@ import React, { ReactElement } from 'react'; -import { gqlMock } from '../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { CoachedPersonFragment, CoachedPersonFragmentDoc, diff --git a/src/components/Coaching/CoachingRow/CoachingRow.tsx b/src/components/Coaching/CoachingRow/CoachingRow.tsx index 6ecdf6b50..0cd7e60d2 100644 --- a/src/components/Coaching/CoachingRow/CoachingRow.tsx +++ b/src/components/Coaching/CoachingRow/CoachingRow.tsx @@ -1,10 +1,7 @@ import NextLink from 'next/link'; import React, { useState } from 'react'; import VisibilityOff from '@mui/icons-material/VisibilityOff'; -import { Link } from '@mui/material'; -import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; -import Typography from '@mui/material/Typography'; +import { Box, Button, Link, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { useRequiredSession } from 'src/hooks/useRequiredSession'; diff --git a/src/components/Coaching/LoadCoachingList.test.tsx b/src/components/Coaching/LoadCoachingList.test.tsx index cb3a59f27..466afd4e8 100644 --- a/src/components/Coaching/LoadCoachingList.test.tsx +++ b/src/components/Coaching/LoadCoachingList.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { render } from '__tests__/util/testingLibraryReactMock'; -import { GqlMockedProvider } from '../../../__tests__/util/graphqlMocking'; import { CoachingList } from './CoachingList'; import { LoadCoachingListQuery, diff --git a/src/components/Constants/UseApiConstants.test.tsx b/src/components/Constants/UseApiConstants.test.tsx index d37053911..3bea5f63d 100644 --- a/src/components/Constants/UseApiConstants.test.tsx +++ b/src/components/Constants/UseApiConstants.test.tsx @@ -1,5 +1,5 @@ import { renderHook } from '@testing-library/react-hooks'; -import { GqlMockedProvider } from '../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { useApiConstants } from './UseApiConstants'; describe('LoadConstants', () => { diff --git a/src/components/Contacts/CelebrationIcons/CelebrationIcons.tsx b/src/components/Contacts/CelebrationIcons/CelebrationIcons.tsx index 80a9307e6..c76927488 100644 --- a/src/components/Contacts/CelebrationIcons/CelebrationIcons.tsx +++ b/src/components/Contacts/CelebrationIcons/CelebrationIcons.tsx @@ -1,6 +1,6 @@ import React from 'react'; import Cake from '@mui/icons-material/Cake'; -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; import { DateTime, Interval } from 'luxon'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/Contacts/CelebrationIcons/Celebrationicons.test.tsx b/src/components/Contacts/CelebrationIcons/Celebrationicons.test.tsx index ee5835226..6e9e8c482 100644 --- a/src/components/Contacts/CelebrationIcons/Celebrationicons.test.tsx +++ b/src/components/Contacts/CelebrationIcons/Celebrationicons.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { DateTime } from 'luxon'; -import { gqlMock } from '../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { CelebrationIcons } from './CelebrationIcons'; import { CelebrationItemsFragment, diff --git a/src/components/Contacts/ContactDetails/ContactDetailContext.tsx b/src/components/Contacts/ContactDetails/ContactDetailContext.tsx index cc57c068b..ee92bd47a 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailContext.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailContext.tsx @@ -1,7 +1,7 @@ import { useRouter } from 'next/router'; import React, { useState } from 'react'; import { TabKey } from './ContactDetails'; -import { DonationTabKey } from './ContactDonationsTab/ContactDonationsTab'; +import { DonationTabKey } from './ContactDonationsTab/DonationTabKey'; export type ContactDetailsType = { selectedTabKey: TabKey; diff --git a/src/components/Contacts/ContactDetails/ContactDetails.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetails.stories.tsx index 5f14bb6cd..e8c6a8895 100644 --- a/src/components/Contacts/ContactDetails/ContactDetails.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetails.stories.tsx @@ -1,8 +1,8 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; import TestRouter from '__tests__/util/TestRouter'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactDetailProvider } from './ContactDetailContext'; import { ContactDetails } from './ContactDetails'; import { GetContactDetailsHeaderDocument } from './ContactDetailsHeader/ContactDetailsHeader.generated'; @@ -23,11 +23,11 @@ export const Default = (): ReactElement => { return ( - + {}} /> - + ); @@ -51,11 +51,11 @@ export const Loading = (): ReactElement => { }, ]} > - + {}} /> - + ); diff --git a/src/components/Contacts/ContactDetails/ContactDetails.test.tsx b/src/components/Contacts/ContactDetails/ContactDetails.test.tsx index 2fb9cb54b..41570f127 100644 --- a/src/components/Contacts/ContactDetails/ContactDetails.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetails.test.tsx @@ -4,8 +4,8 @@ import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import theme from '../../../theme'; import { ContactDetailProvider } from './ContactDetailContext'; import { ContactDetails } from './ContactDetails'; @@ -24,11 +24,11 @@ describe('ContactDetails', () => { - + {}} /> - + diff --git a/src/components/Contacts/ContactDetails/ContactDetails.tsx b/src/components/Contacts/ContactDetails/ContactDetails.tsx index 0356d6309..82e6691d3 100644 --- a/src/components/Contacts/ContactDetails/ContactDetails.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetails.tsx @@ -5,20 +5,32 @@ import TabPanel from '@mui/lab/TabPanel'; import { Box, Tab } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; +import theme from '../../../theme'; import { ContactsContext, ContactsType, -} from '../../../../pages/accountLists/[accountListId]/contacts/ContactsContext'; -import theme from '../../../theme'; +} from '../ContactsContext/ContactsContext'; import { ContactDetailContext, ContactDetailsType, } from './ContactDetailContext'; import { ContactDetailsHeader } from './ContactDetailsHeader/ContactDetailsHeader'; -import { ContactDetailsTab } from './ContactDetailsTab/ContactDetailsTab'; -import { ContactDonationsTab } from './ContactDonationsTab/ContactDonationsTab'; -import { ContactNotesTab } from './ContactNotesTab/ContactNotesTab'; -import { ContactReferralTab } from './ContactReferralTab/ContactReferralTab'; +import { + DynamicContactDetailsTab, + preloadContactDetailsTab, +} from './ContactDetailsTab/DynamicContactDetailsTab'; +import { + DynamicContactDonationsTab, + preloadContactDonationsTab, +} from './ContactDonationsTab/DynamicContactDonationsTab'; +import { + DynamicContactNotesTab, + preloadContactNotesTab, +} from './ContactNotesTab/DynamicContactNotesTab'; +import { + DynamicContactReferralTab, + preloadContactReferralTab, +} from './ContactReferralTab/DynamicContactReferralTab'; import { ContactTasksTab } from './ContactTasksTab/ContactTasksTab'; interface Props { @@ -103,13 +115,26 @@ export const ContactDetails: React.FC = ({ onClose }) => { TabIndicatorProps={{ children: }} > - - + + + - @@ -123,22 +148,24 @@ export const ContactDetails: React.FC = ({ onClose }) => { {contactId && accountListId && ( - )} - + {contactId && accountListId && ( + + )} {contactId && accountListId && ( - = ({ onClose }) => { {contactId && accountListId && ( - diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.stories.tsx index 5270346a4..ed14915e3 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.stories.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactDetailProvider } from '../ContactDetailContext'; import { ContactDetailsHeader } from './ContactDetailsHeader'; import { GetContactDetailsHeaderDocument } from './ContactDetailsHeader.generated'; @@ -16,7 +16,7 @@ export default { export const Default = (): ReactElement => { return ( - + { /> - + ); }; export const Loading = (): ReactElement => { return ( - + { /> - + ); }; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.test.tsx index a96e248a5..55282fd23 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.test.tsx @@ -4,9 +4,9 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import theme from 'src/theme'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; import { ContactDetailProvider } from '../ContactDetailContext'; import { ContactDetailsHeader } from './ContactDetailsHeader'; import { GetContactDetailsHeaderQuery } from './ContactDetailsHeader.generated'; @@ -37,7 +37,7 @@ describe('ContactDetails', () => { - + { contactDetailsLoaded={false} /> - + @@ -75,7 +75,7 @@ describe('ContactDetails', () => { }, }} > - + { contactDetailsLoaded={false} /> - + @@ -107,7 +107,7 @@ describe('ContactDetails', () => { }> mocks={mocks} > - + { contactDetailsLoaded={false} /> - + @@ -139,7 +139,7 @@ describe('ContactDetails', () => { }> mocks={mocks} > - + { contactDetailsLoaded={false} /> - + @@ -174,7 +174,7 @@ describe('ContactDetails', () => { }> mocks={mocks} > - + { contactDetailsLoaded={false} /> - + @@ -212,7 +212,7 @@ describe('ContactDetails', () => { }> mocks={mocks} > - + { contactDetailsLoaded={false} /> - + diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.tsx index cb8f4d235..a24537348 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsHeader.tsx @@ -1,7 +1,6 @@ import React, { useEffect } from 'react'; import Close from '@mui/icons-material/Close'; -import { Avatar, Box, IconButton, Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { Avatar, Box, IconButton, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { StatusEnum } from 'src/graphql/types.generated'; @@ -11,8 +10,8 @@ import { ContactDetailContext, ContactDetailsType, } from '../ContactDetailContext'; -import { ContactDetailEditIcon } from '../ContactDetailsTab/ContactDetailsTab'; import { EditContactDetailsModal } from '../ContactDetailsTab/People/Items/EditContactDetailsModal/EditContactDetailsModal'; +import { EditIcon } from '../ContactDetailsTab/StyledComponents'; import { useGetContactDetailsHeaderQuery } from './ContactDetailsHeader.generated'; import { ContactDetailsMoreAcitions } from './ContactDetailsMoreActions/ContactDetailsMoreActions'; import { ContactHeaderAddressSection } from './ContactHeaderSection/ContactHeaderAddressSection'; @@ -112,7 +111,7 @@ export const ContactDetailsHeader: React.FC = ({ onClick={() => setEditModalOpen(true)} aria-label={t('Edit Icon')} > - + ) : null} diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/ContactDetailsMoreActions.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/ContactDetailsMoreActions.test.tsx index 19d0667b2..33cc151a5 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/ContactDetailsMoreActions.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/ContactDetailsMoreActions.test.tsx @@ -3,10 +3,10 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { StatusEnum } from 'src/graphql/types.generated'; -import TestRouter from '../../../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; import useTaskModal from '../../../../../hooks/useTaskModal'; import theme from '../../../../../theme'; import { ContactDetailProvider } from '../../ContactDetailContext'; @@ -41,6 +41,7 @@ const openTaskModal = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); @@ -51,7 +52,7 @@ describe('ContactDetailsMoreActions', () => { - + { onClose={onClose} /> - + @@ -81,7 +82,7 @@ describe('ContactDetailsMoreActions', () => { - + { onClose={onClose} /> - + @@ -114,7 +115,7 @@ describe('ContactDetailsMoreActions', () => { - + { onClose={onClose} /> - + @@ -142,7 +143,7 @@ describe('ContactDetailsMoreActions', () => { }); it('handles hiding contact', async () => { - const { queryByText, getByRole, getByText } = render( + const { queryByText, getByRole, getByText, findByText } = render( @@ -159,7 +160,7 @@ describe('ContactDetailsMoreActions', () => { }, }} > - + { onClose={onClose} /> - + @@ -179,7 +180,7 @@ describe('ContactDetailsMoreActions', () => { ); expect(getByText('Hide Contact')).toBeInTheDocument(); userEvent.click(getByText('Hide Contact')); - userEvent.click(getByText('Hide')); + userEvent.click(await findByText('Hide')); await waitFor(() => expect(mockEnqueue).toHaveBeenCalledWith('Contact hidden successfully!', { variant: 'success', @@ -200,7 +201,7 @@ describe('ContactDetailsMoreActions', () => { - + { onClose={onClose} /> - + @@ -233,12 +234,13 @@ describe('ContactDetailsMoreActions', () => { getByLabelText, getByText, getByRole, + findByText, } = render( - + { onClose={onClose} /> - + @@ -259,7 +261,7 @@ describe('ContactDetailsMoreActions', () => { expect(getByText('Delete Contact')).toBeInTheDocument(); expect(queryByText('Cancel')).not.toBeInTheDocument(); userEvent.click(queryAllByText('Delete Contact')[0]); - expect(getByText('Cancel')).toBeInTheDocument(); + expect(await findByText('Cancel')).toBeInTheDocument(); userEvent.click(getByLabelText('Close')); await waitFor(() => expect(queryByText('Cancel')).not.toBeInTheDocument()); }); @@ -270,7 +272,7 @@ describe('ContactDetailsMoreActions', () => { - + { onClose={onClose} /> - + diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/ContactDetailsMoreActions.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/ContactDetailsMoreActions.tsx index 63f5c00d2..ef6fad0d2 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/ContactDetailsMoreActions.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/ContactDetailsMoreActions.tsx @@ -1,3 +1,4 @@ +import { useRouter } from 'next/router'; import React, { ReactElement, useState } from 'react'; import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; @@ -16,8 +17,11 @@ import { import { ContactsContext, ContactsType, -} from 'pages/accountLists/[accountListId]/contacts/ContactsContext'; -import { CreateMultipleContacts } from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts'; +} from 'src/components/Contacts/ContactsContext/ContactsContext'; +import { + DynamicCreateMultipleContacts, + preloadCreateMultipleContacts, +} from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContacts'; import { StatusEnum } from 'src/graphql/types.generated'; import useTaskModal from '../../../../../hooks/useTaskModal'; import Modal from '../../../../common/Modal/Modal'; @@ -27,8 +31,14 @@ import { } from '../../ContactDetailContext'; import { useDeleteContactMutation } from '../../ContactDetailsTab/ContactDetailsTab.generated'; import { useUpdateContactOtherMutation } from '../../ContactDetailsTab/Other/EditContactOtherModal/EditContactOther.generated'; -import { DeleteContactModal } from '../DeleteContactModal/DeleteContactModal'; -import { MoreActionHideContactModal } from './MoreActionHideContactModal'; +import { + DynamicDeleteContactModal, + preloadDeleteContactModal, +} from '../DeleteContactModal/DynamicDeleteContactModal'; +import { + DynamicMoreActionHideContactModal, + preloadMoreActionHideContactModal, +} from './DynamicMoreActionHideContactModal'; type AddMenuItem = { visibility: boolean; @@ -36,6 +46,7 @@ type AddMenuItem = { // eslint-disable-next-line @typescript-eslint/no-explicit-any icon: any; onClick: () => void; + onMouseEnter: () => void; }; const MoreButtonIcon = styled(MoreVert)(({ theme }) => ({ @@ -86,8 +97,13 @@ const ActionPanel = ({ {actionContent .filter((i: AddMenuItem) => i.visibility) - .map(({ text, icon, onClick }, index) => ( - + .map(({ text, icon, onClick, onMouseEnter }, index) => ( + {icon} @@ -105,9 +121,10 @@ interface ContactDetailsMoreAcitionsProps { export const ContactDetailsMoreAcitions: React.FC< ContactDetailsMoreAcitionsProps > = ({ contactId, status, onClose }) => { - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const { t } = useTranslation(); - const { accountListId, searchTerm, router } = React.useContext( + const { query, push } = useRouter(); + const { accountListId, searchTerm } = React.useContext( ContactsContext, ) as ContactsType; @@ -126,7 +143,6 @@ export const ContactDetailsMoreAcitions: React.FC< const [openHideModal, setOpenHideModal] = useState(false); const [updateHiding, setUpdateHiding] = useState(false); - const { query, push } = router; const { contactId: _, ...queryWithoutContactId } = query; const hideContact = async (): Promise => { setUpdateHiding(true); @@ -206,6 +222,7 @@ export const ContactDetailsMoreAcitions: React.FC< setReferralsModalOpen(true); setAnchorEl(undefined); }, + onMouseEnter: preloadCreateMultipleContacts, }, { visibility: true, @@ -218,6 +235,7 @@ export const ContactDetailsMoreAcitions: React.FC< }); setAnchorEl(undefined); }, + onMouseEnter: () => preloadTaskModal('add'), }, { visibility: true, @@ -230,6 +248,7 @@ export const ContactDetailsMoreAcitions: React.FC< }); setAnchorEl(undefined); }, + onMouseEnter: () => preloadTaskModal('log'), }, { visibility: status !== StatusEnum.NeverAsk, @@ -239,6 +258,7 @@ export const ContactDetailsMoreAcitions: React.FC< setOpenHideModal(true); setAnchorEl(undefined); }, + onMouseEnter: preloadMoreActionHideContactModal, }, { visibility: true, @@ -248,6 +268,7 @@ export const ContactDetailsMoreAcitions: React.FC< setDeleteModalOpen(true); setAnchorEl(undefined); }, + onMouseEnter: preloadDeleteContactModal, }, ]; @@ -283,26 +304,28 @@ export const ContactDetailsMoreAcitions: React.FC< fullWidth size={'xl'} // TODO: Expand logic as more menu modals are added > - { - - } + - - + {deleteModalOpen && ( + + )} + {openHideModal && ( + + )} ); }; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/DynamicMoreActionHideContactModal.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/DynamicMoreActionHideContactModal.tsx new file mode 100644 index 000000000..8e5a27cb0 --- /dev/null +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactDetailsMoreActions/DynamicMoreActionHideContactModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMoreActionHideContactModal = () => + import( + /* webpackChunkName: "MoreActionHideContactModal" */ './MoreActionHideContactModal' + ).then(({ MoreActionHideContactModal }) => MoreActionHideContactModal); + +export const DynamicMoreActionHideContactModal = dynamic( + preloadMoreActionHideContactModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.stories.tsx index 6851bf884..098f36f26 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { DateTime } from 'luxon'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailsHeaderFragment, ContactDetailsHeaderFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.test.tsx index e6ac44b36..2c1492cc1 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailsHeaderFragment, ContactDetailsHeaderFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.tsx index 0b38b43c4..8a0ab07e1 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderAddressSection.tsx @@ -1,7 +1,6 @@ import React, { ReactElement } from 'react'; import LocationOn from '@mui/icons-material/LocationOn'; -import { Box, Link, Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { Box, Link, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import theme from '../../../../../theme'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.stories.tsx index 69b7f42b6..e8102e074 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { DateTime } from 'luxon'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailsHeaderFragment, ContactDetailsHeaderFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.test.tsx index a2987bdc0..e72b6143f 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailsHeaderFragment, ContactDetailsHeaderFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.tsx index 203ff7ba3..bbfe17fe7 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderEmailSection.tsx @@ -1,7 +1,6 @@ import React, { ReactElement } from 'react'; import Email from '@mui/icons-material/Email'; -import { Link, Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { Link, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import theme from '../../../../../theme'; import { ContactHeaderEmailFragment } from './ContactHeaderEmail.generated'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderNewsletterSection.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderNewsletterSection.test.tsx index 59fc6d4e9..f8f4ab605 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderNewsletterSection.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderNewsletterSection.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { render } from '@testing-library/react'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { SendNewsletterEnum } from 'src/graphql/types.generated'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; import { ContactDetailsHeaderFragment, ContactDetailsHeaderFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderNewsletterSection.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderNewsletterSection.tsx index f1959b00e..7110eac15 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderNewsletterSection.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderNewsletterSection.tsx @@ -1,8 +1,7 @@ import React, { ReactElement } from 'react'; import { mdiNewspaperVariantOutline } from '@mdi/js'; import Icon from '@mdi/react'; -import Skeleton from '@mui/material/Skeleton'; -import Typography from '@mui/material/Typography'; +import { Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { getLocalizedSendNewsletter } from 'src/utils/functions/getLocalizedSendNewsletter'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPartnerSection.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPartnerSection.tsx index 7c85ea34b..54595f47b 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPartnerSection.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPartnerSection.tsx @@ -1,6 +1,5 @@ import React, { Fragment } from 'react'; -import { Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { ContactHeaderSection } from './ContactHeaderSection'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.stories.tsx index 05ff92aed..657d8c1fb 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { DateTime } from 'luxon'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailsHeaderFragment, ContactDetailsHeaderFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.test.tsx index e0c5c7a9e..4dd3c9e57 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailsHeaderFragment, ContactDetailsHeaderFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.tsx index bfd05de70..c3d4935c3 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderPhoneSection.tsx @@ -1,7 +1,6 @@ import React, { ReactElement } from 'react'; import Phone from '@mui/icons-material/Phone'; -import { Box, Link, Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { Box, Link, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import theme from '../../../../../theme'; import { ContactHeaderPhoneFragment } from './ContactHeaderPhone.generated'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderSection.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderSection.tsx index d00f16584..8c1b33430 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderSection.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderSection.tsx @@ -1,5 +1,5 @@ import React, { ReactElement, ReactNode } from 'react'; -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; interface Props { diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.stories.tsx index cb037f3a9..227bd5db3 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.stories.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from 'react'; import { DateTime } from 'luxon'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { StatusEnum } from 'src/graphql/types.generated'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; import { ContactDetailsHeaderFragment, ContactDetailsHeaderFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.test.tsx index 6e82f0b6b..fec1871d8 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.test.tsx @@ -2,11 +2,11 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; import { I18nextProvider } from 'react-i18next'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { StatusEnum as ContactPartnershipStatusEnum, PledgeFrequencyEnum, } from 'src/graphql/types.generated'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; import i18n from '../../../../../lib/i18n'; import theme from '../../../../../theme'; import { diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.tsx index aa9cafd49..896732ab0 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/ContactHeaderStatusSection.tsx @@ -1,9 +1,6 @@ import React, { useMemo, useState } from 'react'; import CreateIcon from '@mui/icons-material/Create'; -import Box from '@mui/material/Box'; -import IconButton from '@mui/material/IconButton'; -import Skeleton from '@mui/material/Skeleton'; -import Typography from '@mui/material/Typography'; +import { Box, IconButton, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/HandshakeIcon.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/HandshakeIcon.tsx index 74b57f45a..4fbcfcec4 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/HandshakeIcon.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/ContactHeaderSection/HandshakeIcon.tsx @@ -1,5 +1,5 @@ import React, { ReactElement } from 'react'; -import SvgIcon from '@mui/material/SvgIcon'; +import { SvgIcon } from '@mui/material'; import { styled } from '@mui/material/styles'; import theme from '../../../../../theme'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsHeader/DeleteContactModal/DynamicDeleteContactModal.tsx b/src/components/Contacts/ContactDetails/ContactDetailsHeader/DeleteContactModal/DynamicDeleteContactModal.tsx new file mode 100644 index 000000000..aa74b670c --- /dev/null +++ b/src/components/Contacts/ContactDetails/ContactDetailsHeader/DeleteContactModal/DynamicDeleteContactModal.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadDeleteContactModal = () => + import( + /* webpackChunkName: "DeleteContactModal" */ './DeleteContactModal' + ).then(({ DeleteContactModal }) => DeleteContactModal); + +export const DynamicDeleteContactModal = dynamic(preloadDeleteContactModal, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.stories.tsx index f54d0a89c..5de8f1928 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.stories.tsx @@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; import { CssBaseline } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../theme'; import { ContactDetailProvider } from '../ContactDetailContext'; import { ContactDetailsTab } from './ContactDetailsTab'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.test.tsx index ce062d112..730e8c5d5 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.test.tsx @@ -8,9 +8,9 @@ import userEvent from '@testing-library/user-event'; import { ApolloErgonoMockMap } from 'graphql-ergonomock'; import { SnackbarProvider } from 'notistack'; import { DeepPartial } from 'ts-essentials'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; -import TestRouter from '../../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import theme from '../../../../theme'; import { ContactDetailProvider } from '../ContactDetailContext'; import { ContactDetailsTab } from './ContactDetailsTab'; @@ -97,7 +97,7 @@ const TestComponent: React.FC = (props) => ( mocks={(props.mocks ?? mocks) as ApolloErgonoMockMap} > - + = (props) => ( onContactSelected={onContactSelected} /> - + diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.tsx index 9d96f7808..3945a7faf 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/ContactDetailsTab.tsx @@ -1,7 +1,5 @@ import React from 'react'; -import CreateIcon from '@mui/icons-material/Create'; -import { Box, Divider, Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { Box, Divider, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { @@ -33,13 +31,6 @@ const ContactDetailHeadingContainer = styled(Box)(() => ({ alignItems: 'center', })); -export const ContactDetailEditIcon = styled(CreateIcon)(({ theme }) => ({ - width: '18px', - height: '18px', - margin: theme.spacing(0), - color: theme.palette.cruGrayMedium.main, -})); - const ContactDetailHeadingText = styled(Typography)(() => ({ flexGrow: 5, fontWeight: 'bold', diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/DynamicContactDetailsTab.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/DynamicContactDetailsTab.tsx new file mode 100644 index 000000000..376ba4748 --- /dev/null +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/DynamicContactDetailsTab.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadContactDetailsTab = () => + import( + /* webpackChunkName: "ContactDetailsTab" */ './ContactDetailsTab' + ).then(({ ContactDetailsTab }) => ContactDetailsTab); + +export const DynamicContactDetailsTab = dynamic(preloadContactDetailsTab, { + loading: DynamicComponentPlaceholder, +}); diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/AddAddressModal/AddAddressModal.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/AddAddressModal/AddAddressModal.test.tsx index a70f6fb13..f5ecb6267 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/AddAddressModal/AddAddressModal.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/AddAddressModal/AddAddressModal.test.tsx @@ -4,7 +4,7 @@ import { act, render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import { placePromise, setupMocks } from '__tests__/util/googlePlacesMock'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../../../theme'; import { AddAddressModal } from './AddAddressModal'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.stories.tsx index 06628cf7a..6a83dbdb9 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { Box } from '@mui/material'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailProvider } from '../../ContactDetailContext'; import { ContactDetailsTabMailing } from './ContactDetailsTabMailing'; import { diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.test.tsx index dfbec1b8f..554d238aa 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.test.tsx @@ -3,7 +3,7 @@ import { render, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import TestRouter from '__tests__/util/TestRouter'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { SendNewsletterEnum } from 'src/graphql/types.generated'; import theme from '../../../../../theme'; import { ContactDetailProvider } from '../../ContactDetailContext'; @@ -63,14 +63,14 @@ describe('ContactDetailsTabMailing', () => { - + - + , @@ -84,14 +84,14 @@ describe('ContactDetailsTabMailing', () => { - + - + , @@ -114,14 +114,14 @@ describe('ContactDetailsTabMailing', () => { - + - + , diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.tsx index c233aac8e..36804fb31 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/ContactDetailsTabMailing.tsx @@ -6,19 +6,14 @@ import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormat } from 'src/lib/intlFormat/intlFormat'; +import { dateFormat } from 'src/lib/intlFormat'; import { getLocalizedSendNewsletter } from 'src/utils/functions/getLocalizedSendNewsletter'; import { sourceToStr } from 'src/utils/sourceToStr'; import { ContactDetailContext, ContactDetailsType, } from '../../ContactDetailContext'; -import { ContactDetailEditIcon } from '../ContactDetailsTab'; -import { - ContactDetailsAddButton, - ContactDetailsAddIcon, - ContactDetailsAddText, -} from '../People/ContactDetailsTabPeople'; +import { AddButton, AddIcon, AddText, EditIcon } from '../StyledComponents'; import { AddAddressModal } from './AddAddressModal/AddAddressModal'; import { ContactMailingFragment } from './ContactMailing.generated'; import { EditContactAddressModal } from './EditContactAddressModal/EditContactAddressModal'; @@ -230,7 +225,7 @@ export const ContactDetailsTabMailing: React.FC = ({ onClick={() => setEditMailingModalOpen(true)} aria-label={t('Edit Mailing')} > - + {/* Envelope Name Section */} @@ -252,12 +247,10 @@ export const ContactDetailsTabMailing: React.FC = ({ - setAddAddressModalOpen(true)}> - - - {t('Add Address')} - - + setAddAddressModalOpen(true)}> + + {t('Add Address')} + {selectedAddress ? ( diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditContactAddressModal/EditContactAddressModal.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditContactAddressModal/EditContactAddressModal.test.tsx index 53c82793a..1ff480dc6 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditContactAddressModal/EditContactAddressModal.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditContactAddressModal/EditContactAddressModal.test.tsx @@ -4,10 +4,7 @@ import { act, render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import { placePromise, setupMocks } from '__tests__/util/googlePlacesMock'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; import theme from '../../../../../../theme'; import { ContactMailingFragment, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditMailingInfoModal/EditMailingInfoModal.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditMailingInfoModal/EditMailingInfoModal.test.tsx index 574f59704..afd9fd45d 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditMailingInfoModal/EditMailingInfoModal.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/EditMailingInfoModal/EditMailingInfoModal.test.tsx @@ -3,8 +3,8 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { SendNewsletterEnum } from 'src/graphql/types.generated'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../../../theme'; import { EditMailingInfoModal } from './EditMailingInfoModal'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/ContactDetailsOther.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/ContactDetailsOther.stories.tsx index 21340f614..196bad7ee 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/ContactDetailsOther.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/ContactDetailsOther.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { Box } from '@mui/material'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailProvider } from '../../ContactDetailContext'; import { ContactDetailsOther } from './ContactDetailsOther'; import { diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/ContactDetailsOther.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/ContactDetailsOther.tsx index 00a44c628..2b56e4b15 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/ContactDetailsOther.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/ContactDetailsOther.tsx @@ -1,12 +1,10 @@ import React from 'react'; -import Box from '@mui/material/Box'; -import IconButton from '@mui/material/IconButton'; -import Typography from '@mui/material/Typography'; +import { Box, IconButton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import i18n from 'i18next'; import { useTranslation } from 'react-i18next'; import { PreferredContactMethodEnum } from 'src/graphql/types.generated'; -import { ContactDetailEditIcon } from '../ContactDetailsTab'; +import { EditIcon } from '../StyledComponents'; import { ContactOtherFragment } from './ContactOther.generated'; const ContactOtherContainer = styled(Box)(({ theme }) => ({ @@ -96,7 +94,7 @@ export const ContactDetailsOther: React.FC = ({ aria-label={t('Edit Other Icon')} style={{ marginLeft: 16 }} > - + diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOtherModal.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOtherModal.test.tsx index 279afdb67..151c5640c 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOtherModal.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOtherModal.test.tsx @@ -4,13 +4,10 @@ import { act, render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactOptionsQuery } from 'src/components/Task/Modal/Form/Inputs/ContactsAutocomplete/ContactsAutocomplete.generated'; import { PreferredContactMethodEnum } from 'src/graphql/types.generated'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../../../theme'; import { ContactDetailProvider } from '../../../ContactDetailContext'; import { @@ -67,7 +64,7 @@ describe('EditContactOtherModal', () => { - + { referral={referral} /> - + @@ -112,7 +109,7 @@ describe('EditContactOtherModal', () => { }, }} > - + { referral={referral} /> - + @@ -157,7 +154,7 @@ describe('EditContactOtherModal', () => { }, }} > - + { referral={referral} /> - + @@ -192,7 +189,7 @@ describe('EditContactOtherModal', () => { - + { referral={referral} /> - + @@ -220,7 +217,7 @@ describe('EditContactOtherModal', () => { - + { referral={referral} /> - + @@ -250,7 +247,7 @@ describe('EditContactOtherModal', () => { - + { referral={undefined} /> - + @@ -286,7 +283,7 @@ describe('EditContactOtherModal', () => { - + { referral={undefined} /> - + @@ -379,7 +376,7 @@ describe('EditContactOtherModal', () => { }, }} > - + { referral={referral} /> - + diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOtherModal.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOtherModal.tsx index 89f13561f..3df961517 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOtherModal.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOtherModal.tsx @@ -15,7 +15,7 @@ import { } from '@mui/material'; import { styled } from '@mui/material/styles'; import { Formik } from 'formik'; -import debounce from 'lodash/fp/debounce'; +import { debounce } from 'lodash'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import * as yup from 'yup'; @@ -109,9 +109,9 @@ export const EditContactOtherModal: React.FC = ({ const [searchTerm, setSearchTerm] = useState(referral?.referredBy.name ?? ''); const handleSearchTermChange = useCallback( - debounce(500, (event) => { + debounce((event) => { setSearchTerm(event.target.value); - }), + }, 500), [], ); diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/PartnerAccounts/ContactDetailsPartnerAccounts.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/PartnerAccounts/ContactDetailsPartnerAccounts.test.tsx index 9b3c0c214..ab8ba0796 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/PartnerAccounts/ContactDetailsPartnerAccounts.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/PartnerAccounts/ContactDetailsPartnerAccounts.test.tsx @@ -4,7 +4,7 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../../theme'; import { ContactDetailProvider } from '../../ContactDetailContext'; import { ContactDetailsPartnerAccounts } from './ContactDetailsPartnerAccounts'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/PartnerAccounts/ContactDetailsPartnerAccounts.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/PartnerAccounts/ContactDetailsPartnerAccounts.tsx index 558665f90..7d904d1a8 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/PartnerAccounts/ContactDetailsPartnerAccounts.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/PartnerAccounts/ContactDetailsPartnerAccounts.tsx @@ -1,10 +1,7 @@ import React, { ReactElement, useState } from 'react'; import Add from '@mui/icons-material/Add'; import Delete from '@mui/icons-material/Delete'; -import { TextField } from '@mui/material'; -import Box from '@mui/material/Box'; -import IconButton from '@mui/material/IconButton'; -import Typography from '@mui/material/Typography'; +import { Box, IconButton, TextField, Typography } from '@mui/material'; import { styled } from '@mui/system'; import { Formik } from 'formik'; import { useSnackbar } from 'notistack'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.stories.tsx index 308a0d9fc..ecd1a0452 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { Box } from '@mui/material'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailProvider } from '../../ContactDetailContext'; import { ContactDetailsTabPeople } from './ContactDetailsTabPeople'; import { diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.test.tsx index 623d4570f..cd3e5f022 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.test.tsx @@ -6,12 +6,12 @@ import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; import { render, waitFor, within, -} from '../../../../../../__tests__/util/testingLibraryReactMock'; +} from '__tests__/util/testingLibraryReactMock'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import theme from '../../../../../theme'; import { ContactDetailProvider } from '../../ContactDetailContext'; import { ContactDetailsTabPeople } from './ContactDetailsTabPeople'; @@ -123,14 +123,14 @@ describe('ContactDetailsTabPeople', () => { - + - + , @@ -152,14 +152,14 @@ describe('ContactDetailsTabPeople', () => { - + - + @@ -182,14 +182,14 @@ describe('ContactDetailsTabPeople', () => { - + - + , @@ -230,14 +230,14 @@ describe('ContactDetailsTabPeople', () => { - + - + , @@ -270,14 +270,14 @@ describe('ContactDetailsTabPeople', () => { - + - + , diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.tsx index 7a057e350..661084114 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/ContactDetailsTabPeople.tsx @@ -1,14 +1,11 @@ import React, { useState } from 'react'; -import AddIcon from '@mui/icons-material/Add'; import Cake from '@mui/icons-material/Cake'; -import CreateIcon from '@mui/icons-material/Create'; import Email from '@mui/icons-material/Email'; import MergeIcon from '@mui/icons-material/Merge'; import Phone from '@mui/icons-material/Phone'; import { Avatar, Box, - Button, Grid, IconButton, Link, @@ -20,12 +17,13 @@ import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { MergePeopleModal } from 'src/components/Contacts/MassActions/MergePeople/MergePeopleModal'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFromParts } from 'src/lib/intlFormat/intlFormat'; +import { dateFromParts } from 'src/lib/intlFormat'; import { RingIcon } from '../../../RingIcon'; import { ContactDetailContext, ContactDetailsType, } from '../../ContactDetailContext'; +import { AddButton, AddIcon, AddText, EditIcon } from '../StyledComponents'; import { ContactPeopleFragment, ContactPersonFragment, @@ -70,31 +68,10 @@ const ContactPersonIconContainer = styled(Box)(() => ({ marginRight: '35px', })); -const ContactDetailEditIcon = styled(CreateIcon)(({ theme }) => ({ - width: '18px', - height: '18px', - margin: theme.spacing(0), - color: theme.palette.cruGrayMedium.main, -})); - -export const ContactDetailsAddButton = styled(Button)(({ theme }) => ({ - margin: theme.spacing(1), -})); - -export const ContactDetailsAddIcon = styled(AddIcon)(({ theme }) => ({ +const MergePeopleIcon = styled(MergeIcon)(({ theme }) => ({ color: theme.palette.info.main, })); -export const MergePeopleIcon = styled(MergeIcon)(({ theme }) => ({ - color: theme.palette.info.main, -})); - -export const ContactDetailsAddText = styled(Typography)(({ theme }) => ({ - color: theme.palette.info.main, - textTransform: 'uppercase', - fontWeight: 'bold', -})); - const ContactEditIconContainer = styled(IconButton)(({ theme }) => ({ margin: theme.spacing(0, 1), })); @@ -199,7 +176,7 @@ export const ContactDetailsTabPeople: React.FC = ({ onClick={() => setEditPersonModalOpen(person.id)} aria-label={t('Edit Icon')} > - + {/* Phone Number */} @@ -288,51 +265,42 @@ export const ContactDetailsTabPeople: React.FC = ({ person.id !== primaryPerson?.id ? personView(person) : null, )} {!selecting && ( - setCreatePersonModalOpen(true)}> + setCreatePersonModalOpen(true)}> - - - {t('Add Person')} - + + {t('Add Person')} - + )} {people.nodes.length > 1 && (selecting ? ( <> - setSelecting(false)}> + setSelecting(false)}> - - {t('Cancel')} - + {t('Cancel')} - + - setMergePeopleModalOpen(true)} variant="contained" disabled={selectedPeople.length < 2} > - + {t('Merge Selected People')} - + - + ) : ( - setSelecting(true)}> + setSelecting(true)}> - - {t('Merge People')} - + {t('Merge People')} - + ))} {createPersonModalOpen ? ( ({ textDecoration: destroyed ? 'line-through' : 'none', })); -export const VerticallyCenteredGrid = styled(Grid)(() => ({ - margin: 'auto', -})); export const PersonEmailItem: React.FC = ({ emailAddress, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.stories.tsx index f7b40fb81..14316fb27 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.stories.tsx @@ -1,7 +1,7 @@ import React, { ReactElement, useState } from 'react'; import { Box, Button } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; -import { gqlMock } from '../../../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import theme from '../../../../../../../theme'; import { ContactDetailsTabQuery } from '../../../ContactDetailsTab.generated'; import { diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.test.tsx index ddecca699..274475c25 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.test.tsx @@ -6,11 +6,8 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { cleanup, render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailProvider } from 'src/components/Contacts/ContactDetails/ContactDetailContext'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../../../../theme'; import { ContactDetailsTabDocument, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.tsx index 362a08d47..2d79ab3fb 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.tsx @@ -6,13 +6,10 @@ import { CircularProgress, DialogActions, DialogContent, - FormControlLabel, - TextField, Typography, } from '@mui/material'; import { styled } from '@mui/material/styles'; import { Formik } from 'formik'; -import _ from 'lodash'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import { useUpdateUserMutation } from 'src/components/Settings/preferences/UpdateUser.generated'; @@ -51,18 +48,6 @@ import { PersonShowMore } from './PersonShowMore/PersonShowMore'; import { formatSubmittedFields, getPersonSchema } from './personModalHelper'; import { uploadAvatar, validateAvatar } from './uploadAvatar'; -export const ContactInputField = styled(TextField, { - shouldForwardProp: (prop) => prop !== 'destroyed', -})(({ destroyed }: { destroyed: boolean }) => ({ - textDecoration: destroyed ? 'line-through' : 'none', -})); - -export const PrimaryControlLabel = styled(FormControlLabel, { - shouldForwardProp: (prop) => prop !== 'destroyed', -})(({ destroyed }: { destroyed: boolean }) => ({ - textDecoration: destroyed ? 'line-through' : 'none', -})); - const ContactPersonContainer = styled(Box)(({ theme }) => ({ margin: theme.spacing(2, 0), })); diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModalSave.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModalSave.test.tsx index dcc82cd2c..f4c0ec88d 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModalSave.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModalSave.test.tsx @@ -6,11 +6,8 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDetailProvider } from 'src/components/Contacts/ContactDetails/ContactDetailContext'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../../../../theme'; import { ContactPeopleFragment, diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonPhoneNumber/PersonPhoneNumberItem.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonPhoneNumber/PersonPhoneNumberItem.tsx index 4dafbfb09..ccc4f6e93 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonPhoneNumber/PersonPhoneNumberItem.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonPhoneNumber/PersonPhoneNumberItem.tsx @@ -19,12 +19,12 @@ import { } from 'src/graphql/types.generated'; import { ModalSectionContainer } from '../ModalSectionContainer/ModalSectionContainer'; import { ModalSectionDeleteIcon } from '../ModalSectionDeleteIcon/ModalSectionDeleteIcon'; -import { VerticallyCenteredGrid } from '../PersonEmail/PersonEmailItem'; +import { NewSocial } from '../PersonModal'; import { ContactInputField, - NewSocial, PrimaryControlLabel, -} from '../PersonModal'; + VerticallyCenteredGrid, +} from '../StyledComponents'; interface Props { phoneNumber: PersonPhoneNumberInput & { source?: string }; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/StyledComponents.ts b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/StyledComponents.ts new file mode 100644 index 000000000..bf4e0c176 --- /dev/null +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/StyledComponents.ts @@ -0,0 +1,18 @@ +import { FormControlLabel, Grid, TextField } from '@mui/material'; +import { styled } from '@mui/material/styles'; + +export const ContactInputField = styled(TextField, { + shouldForwardProp: (prop) => prop !== 'destroyed', +})(({ destroyed }: { destroyed: boolean }) => ({ + textDecoration: destroyed ? 'line-through' : 'none', +})); + +export const PrimaryControlLabel = styled(FormControlLabel, { + shouldForwardProp: (prop) => prop !== 'destroyed', +})(({ destroyed }: { destroyed: boolean }) => ({ + textDecoration: destroyed ? 'line-through' : 'none', +})); + +export const VerticallyCenteredGrid = styled(Grid)(() => ({ + margin: 'auto', +})); diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/StyledComponents.ts b/src/components/Contacts/ContactDetails/ContactDetailsTab/StyledComponents.ts new file mode 100644 index 000000000..1f1437701 --- /dev/null +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/StyledComponents.ts @@ -0,0 +1,25 @@ +import Add from '@mui/icons-material/Add'; +import Create from '@mui/icons-material/Create'; +import { Button, Typography } from '@mui/material'; +import { styled } from '@mui/material/styles'; + +export const AddIcon = styled(Add)(({ theme }) => ({ + color: theme.palette.info.main, +})); + +export const EditIcon = styled(Create)(({ theme }) => ({ + width: '18px', + height: '18px', + margin: theme.spacing(0), + color: theme.palette.cruGrayMedium.main, +})); + +export const AddButton = styled(Button)(({ theme }) => ({ + margin: theme.spacing(1), +})); + +export const AddText = styled(Typography)(({ theme }) => ({ + color: theme.palette.info.main, + textTransform: 'uppercase', + fontWeight: 'bold', +})); diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.stories.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.stories.tsx index 73222d6d7..61df6882f 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.stories.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from 'react'; import { Box } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../../theme'; import { ContactTags } from './ContactTags'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.test.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.test.tsx index 13e8aae7c..a7c3f655d 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.test.tsx @@ -2,11 +2,8 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; -import { - render, - waitFor, -} from '../../../../../../__tests__/util/testingLibraryReactMock'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../../../theme'; import { ContactTags } from './ContactTags'; import { UpdateContactTagsMutation } from './ContactTags.generated'; diff --git a/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.tsx b/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.tsx index 69f52213a..7c2e40183 100644 --- a/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.tsx +++ b/src/components/Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags.tsx @@ -1,11 +1,11 @@ import React, { ReactElement } from 'react'; -import TagIcon from '@mui/icons-material/LocalOfferOutlined'; -import { Autocomplete, Box, Button, Chip, TextField } from '@mui/material'; +import { Autocomplete, Box, Button, Chip } from '@mui/material'; import { styled } from '@mui/material/styles'; import { Formik, FormikHelpers } from 'formik'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import * as yup from 'yup'; +import { ContactTagIcon, ContactTagInput } from 'src/components/Tags/Tags'; import { useGetContactTagListQuery, useUpdateContactTagsMutation, @@ -24,36 +24,6 @@ const ContactTagChip = styled(Chip)(({ theme }) => ({ marginLeft: '0', })); -export const ContactTagIcon = styled(TagIcon)(({ theme }) => ({ - color: theme.palette.cruGrayMedium.main, - marginRight: theme.spacing(1), -})); - -export const ContactTagInput = styled(TextField)(({ theme }) => ({ - '&& .MuiInput-underline:before ': { - borderBottom: `2px solid ${theme.palette.divider}`, - }, - '&& .MuiInput-underline:after ': { - borderBottom: `2px solid ${theme.palette.divider}`, - }, - '&& .MuiInputBase-input': { - minWidth: '200px', - }, - '& ::placeholder': { - color: theme.palette.info.main, - opacity: 1, - }, - '& :hover::placeholder': { - textDecoration: 'underline', - }, - '& :focus::placeholder': { - textDecoration: 'none', - color: theme.palette.cruGrayMedium.main, - }, - margin: theme.spacing(1), - marginLeft: '0', -})); - const SaveButton = styled(Button)(({ theme }) => ({ color: theme.palette.info.main, height: theme.spacing(4), diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.stories.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.stories.tsx index a9776bc06..c65561334 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { DateTime } from 'luxon'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { ContactDonationsList } from './ContactDonationsList'; import { ContactDonationsListQuery } from './ContactDonationsList.generated'; diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.test.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.test.tsx index c90fd73be..fcb83db67 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.test.tsx @@ -121,13 +121,13 @@ describe('ContactDonationsList', () => { }); it('edits donations', async () => { - const { findAllByRole, getByText } = render(); + const { findAllByRole, findByText } = render(); const rows = await findAllByRole('row'); expect(rows).toHaveLength(6); const donationRow = rows[1]; userEvent.click(within(donationRow).getByRole('button')); - expect(getByText('Edit Donation')).toBeInTheDocument(); + expect(await findByText('Edit Donation')).toBeInTheDocument(); }); }); diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.tsx index d4c29ce74..0b9cb85bc 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsList/ContactDonationsList.tsx @@ -3,24 +3,24 @@ import EditIcon from '@mui/icons-material/Edit'; import { Button, IconButton, + Skeleton, Table, TableBody, TableCell, TableHead, TableRow, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; -import { EditDonationModal } from 'src/components/EditDonationModal/EditDonationModal'; +import { + DynamicEditDonationModal, + preloadEditDonationModal, +} from 'src/components/EditDonationModal/DynamicEditDonationModal'; import { EditDonationModalDonationFragment } from 'src/components/EditDonationModal/EditDonationModal.generated'; import { useGetAccountListCurrencyQuery } from 'src/components/Reports/DonationsReport/GetDonationsTable.generated'; import { useLocale } from 'src/hooks/useLocale'; -import { - currencyFormat, - dateFormat, -} from '../../../../../lib/intlFormat/intlFormat'; +import { currencyFormat, dateFormat } from 'src/lib/intlFormat'; import { useContactDonationsListQuery } from './ContactDonationsList.generated'; interface ContactDonationsListProp { @@ -123,6 +123,7 @@ export const ContactDonationsList: React.FC = ({ onClick={() => { setEditingDonation(donation); }} + onMouseEnter={preloadEditDonationModal} > @@ -149,7 +150,7 @@ export const ContactDonationsList: React.FC = ({ )} {editingDonation && ( - setEditingDonation(null)} diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.stories.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.stories.tsx index e93754289..cef938479 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.stories.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; import { DateTime } from 'luxon'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { ContactDetailProvider } from '../ContactDetailContext'; import { ContactDonationsTab } from './ContactDonationsTab'; import { diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.test.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.test.tsx index 38984e339..d7f6c006f 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { DateTime } from 'luxon'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; -import { render } from '../../../../../__tests__/util/testingLibraryReactMock'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render } from '__tests__/util/testingLibraryReactMock'; import { ContactDetailProvider } from '../ContactDetailContext'; import { ContactDonationsTab } from './ContactDonationsTab'; import { GetContactDonationsQuery } from './ContactDonationsTab.generated'; diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.tsx index 958f483bf..78ef0b8c9 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/ContactDonationsTab.tsx @@ -2,8 +2,7 @@ import React from 'react'; import TabContext from '@mui/lab/TabContext'; import TabList from '@mui/lab/TabList'; import TabPanel from '@mui/lab/TabPanel'; -import { Box, Tab } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { Box, Skeleton, Tab } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next/'; import { @@ -15,6 +14,7 @@ import { GetContactDonationsQueryVariables, useGetContactDonationsQuery, } from './ContactDonationsTab.generated'; +import { DonationTabKey } from './DonationTabKey'; import { DonationsGraph } from './DonationsGraph/DonationsGraph'; import { PartnershipInfo } from './PartnershipInfo/PartnershipInfo'; @@ -61,11 +61,6 @@ export type ContactDonationsFilter = Omit< 'accountListId' >; -export enum DonationTabKey { - Donations = 'Donations', - PartnershipInfo = 'Partnership Info', -} - export const ContactDonationsTab: React.FC = ({ accountListId, contactId, diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationTabKey.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationTabKey.tsx new file mode 100644 index 000000000..86a689081 --- /dev/null +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationTabKey.tsx @@ -0,0 +1,4 @@ +export enum DonationTabKey { + Donations = 'Donations', + PartnershipInfo = 'Partnership Info', +} diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.stories.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.stories.tsx index 99eb1037c..8ea13785e 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.stories.tsx @@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; import { Box } from '@mui/material'; import { DateTime } from 'luxon'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { GetContactDonationsQuery } from '../ContactDonationsTab.generated'; import { DonationsGraph } from './DonationsGraph'; import { GetDonationsGraphDocument } from './DonationsGraph.generated'; diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.test.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.test.tsx index e6927735c..8938b5b70 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.test.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { MockedProvider } from '@apollo/client/testing'; import { renderHook } from '@testing-library/react-hooks'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; -import { render } from '../../../../../../__tests__/util/testingLibraryReactMock'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render } from '__tests__/util/testingLibraryReactMock'; import { DonationsGraph } from './DonationsGraph'; import { GetDonationsGraphDocument, diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.tsx index 2168ab0d5..70b09f60e 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.tsx @@ -1,7 +1,5 @@ import React, { useMemo } from 'react'; -import Box from '@mui/material/Box'; -import Skeleton from '@mui/material/Skeleton'; -import Typography from '@mui/material/Typography'; +import { Box, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/DynamicContactDonationsTab.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/DynamicContactDonationsTab.tsx new file mode 100644 index 000000000..2421d0538 --- /dev/null +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/DynamicContactDonationsTab.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadContactDonationsTab = () => + import( + /* webpackChunkName: "ContactDonationsTab" */ './ContactDonationsTab' + ).then(({ ContactDonationsTab }) => ContactDonationsTab); + +export const DynamicContactDonationsTab = dynamic(preloadContactDonationsTab, { + loading: DynamicComponentPlaceholder, +}); diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/EditPartnershipInfoModal/EditPartnershipInfoModal.test.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/EditPartnershipInfoModal/EditPartnershipInfoModal.test.tsx index ea0333b13..d8b0e3354 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/EditPartnershipInfoModal/EditPartnershipInfoModal.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/EditPartnershipInfoModal/EditPartnershipInfoModal.test.tsx @@ -5,16 +5,13 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; import { LikelyToGiveEnum, PledgeFrequencyEnum, SendNewsletterEnum, StatusEnum, } from 'src/graphql/types.generated'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../../../theme'; import { ContactDonorAccountsFragment, diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.stories.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.stories.tsx index f7e544205..8701b6cc2 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { DateTime } from 'luxon'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ContactDonorAccountsFragment, ContactDonorAccountsFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.test.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.test.tsx index c2303fc76..6da1c81f5 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.test.tsx @@ -6,13 +6,10 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import userEvent from '@testing-library/user-event'; import { DateTime } from 'luxon'; import { SnackbarProvider } from 'notistack'; +import { gqlMock } from '__tests__/util/graphqlMocking'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import { LoadConstantsDocument } from 'src/components/Constants/LoadConstants.generated'; import { PledgeFrequencyEnum, StatusEnum } from 'src/graphql/types.generated'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; -import { - render, - waitFor, -} from '../../../../../../__tests__/util/testingLibraryReactMock'; import theme from '../../../../../theme'; import { ContactDonorAccountsFragment, diff --git a/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.tsx b/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.tsx index b1c151596..0b3700b56 100644 --- a/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.tsx +++ b/src/components/Contacts/ContactDetails/ContactDonationsTab/PartnershipInfo/PartnershipInfo.tsx @@ -10,7 +10,7 @@ import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { useLoadConstantsQuery } from 'src/components/Constants/LoadConstants.generated'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormat } from 'src/lib/intlFormat/intlFormat'; +import { dateFormat } from 'src/lib/intlFormat'; import { getLocalizedPledgeFrequency } from 'src/utils/functions/getLocalizedPledgeFrequency'; import { currencyFormat } from '../../../../../lib/intlFormat'; import { HandshakeIcon } from '../../ContactDetailsHeader/ContactHeaderSection/HandshakeIcon'; diff --git a/src/components/Contacts/ContactDetails/ContactNotesTab/ContactNotesTab.test.tsx b/src/components/Contacts/ContactDetails/ContactNotesTab/ContactNotesTab.test.tsx index 4f8c8d805..446d934e0 100644 --- a/src/components/Contacts/ContactDetails/ContactNotesTab/ContactNotesTab.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactNotesTab/ContactNotesTab.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { ContactDetailProvider } from '../ContactDetailContext'; import { ContactNotesTab } from './ContactNotesTab'; diff --git a/src/components/Contacts/ContactDetails/ContactNotesTab/ContactNotesTab.tsx b/src/components/Contacts/ContactDetails/ContactNotesTab/ContactNotesTab.tsx index 31de750e2..fcd038a64 100644 --- a/src/components/Contacts/ContactDetails/ContactNotesTab/ContactNotesTab.tsx +++ b/src/components/Contacts/ContactDetails/ContactNotesTab/ContactNotesTab.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect } from 'react'; import { TextField } from '@mui/material'; -import debounce from 'lodash/debounce'; +import { debounce } from 'lodash'; import { DateTime } from 'luxon'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/Contacts/ContactDetails/ContactNotesTab/DynamicContactNotesTab.tsx b/src/components/Contacts/ContactDetails/ContactNotesTab/DynamicContactNotesTab.tsx new file mode 100644 index 000000000..a478b9634 --- /dev/null +++ b/src/components/Contacts/ContactDetails/ContactNotesTab/DynamicContactNotesTab.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadContactNotesTab = () => + import(/* webpackChunkName: "ContactNotesTab" */ './ContactNotesTab').then( + ({ ContactNotesTab }) => ContactNotesTab, + ); + +export const DynamicContactNotesTab = dynamic(preloadContactNotesTab, { + loading: DynamicComponentPlaceholder, +}); diff --git a/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.stories.tsx b/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.stories.tsx index ac2c189fc..24cf06c8f 100644 --- a/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.stories.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; import { Box } from '@mui/material'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { ContactReferralTab } from './ContactReferralTab'; import { ContactReferralTabDocument } from './ContactReferralTab.generated'; diff --git a/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.test.tsx b/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.test.tsx index cae106f2d..17c6cf4a8 100644 --- a/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.test.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; import userEvent from '@testing-library/user-event'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; -import { render } from '../../../../../__tests__/util/testingLibraryReactMock'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render } from '__tests__/util/testingLibraryReactMock'; import { ContactReferralTab } from './ContactReferralTab'; import { ContactReferralTabQuery, diff --git a/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.tsx b/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.tsx index 8e08eec2d..906d810d6 100644 --- a/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.tsx +++ b/src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.tsx @@ -4,6 +4,7 @@ import { Box, Button, Paper, + Skeleton, Table, TableBody, TableCell, @@ -12,15 +13,17 @@ import { TableRow, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; -import { CreateMultipleContacts } from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts'; +import { + DynamicCreateMultipleContacts, + preloadCreateMultipleContacts, +} from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContacts'; import Modal from 'src/components/common/Modal/Modal'; import { useFetchAllPages } from 'src/hooks/useFetchAllPages'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormat } from 'src/lib/intlFormat/intlFormat'; +import { dateFormat } from 'src/lib/intlFormat'; import { useContactReferralTabQuery } from './ContactReferralTab.generated'; const ContactReferralContainer = styled(Box)(({ theme }) => ({ @@ -99,7 +102,10 @@ export const ContactReferralTab: React.FC = ({ ) : ( <> - + {t('Add Referrals')} @@ -149,7 +155,7 @@ export const ContactReferralTab: React.FC = ({ fullWidth size={'xl'} // TODO: Expand logic as more menu modals are added > - + import( + /* webpackChunkName: "ContactReferralTab" */ './ContactReferralTab' + ).then(({ ContactReferralTab }) => ContactReferralTab); + +export const DynamicContactReferralTab = dynamic(preloadContactReferralTab, { + loading: DynamicComponentPlaceholder, +}); diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.stories.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.stories.tsx index d25cfb576..ae49c40ed 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ResultEnum } from 'src/graphql/types.generated'; -import { gqlMock } from '../../../../../../__tests__/util/graphqlMocking'; import { TaskRowFragment, TaskRowFragmentDoc, diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.test.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.test.tsx index 3f878a496..ce7e9c185 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.test.tsx @@ -2,11 +2,8 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; import { ActivityTypeEnum, ResultEnum } from 'src/graphql/types.generated'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../../../__tests__/util/graphqlMocking'; import useTaskModal from '../../../../../hooks/useTaskModal'; import theme from '../../../../../theme'; import { @@ -26,6 +23,7 @@ const onTaskCheckToggle = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.tsx index 0f8ca0111..7f36f2ed3 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/ContactTaskRow.tsx @@ -1,6 +1,5 @@ import React, { useState } from 'react'; -import { Box, Checkbox, Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { Box, Checkbox, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; @@ -101,7 +100,7 @@ export const ContactTaskRow: React.FC = ({ const { t } = useTranslation(); const [hasBeenDeleted, setHasBeenDeleted] = useState(false); - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const handleCompleteButtonPressed = () => { openTaskModal({ @@ -167,9 +166,13 @@ export const ContactTaskRow: React.FC = ({ preloadTaskModal('complete')} /> - + preloadTaskModal('edit')} + > {getLocalizedTaskType(t, activityType)} {subject} @@ -183,6 +186,7 @@ export const ContactTaskRow: React.FC = ({ isComplete={isComplete} numberOfComments={comments?.totalCount} onClick={handleCommentButtonPressed} + onMouseEnter={() => preloadTaskModal('comments')} detailsPage /> diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCommentsButton/TaskCommentsButton.test.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCommentsButton/TaskCommentsButton.test.tsx index 16beb1df7..a91618d62 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCommentsButton/TaskCommentsButton.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCommentsButton/TaskCommentsButton.test.tsx @@ -71,6 +71,6 @@ describe('TaskCommentsButton', () => { userEvent.click(commentsButton); - expect(onClick).toHaveBeenCalledWith(); + expect(onClick).toHaveBeenCalled(); }); }); diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCommentsButton/TaskCommentsButton.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCommentsButton/TaskCommentsButton.tsx index 7f53dc4a6..b6efcc7a1 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCommentsButton/TaskCommentsButton.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCommentsButton/TaskCommentsButton.tsx @@ -1,6 +1,6 @@ import React from 'react'; import ChatBubbleOutline from '@mui/icons-material/ChatBubbleOutline'; -import { Button, Typography } from '@mui/material'; +import { Button, ButtonProps, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import theme from 'src/theme'; @@ -34,10 +34,9 @@ const TaskCommentNumber = styled(Typography, { margin: theme.spacing(0.5), })); -interface TaskCommentsButtonProps { +interface TaskCommentsButtonProps extends ButtonProps { isComplete: boolean; numberOfComments: number; - onClick: () => void; small?: boolean; detailsPage?: boolean; } @@ -45,15 +44,15 @@ interface TaskCommentsButtonProps { export const TaskCommentsButton: React.FC = ({ isComplete, numberOfComments = 0, - onClick, small, detailsPage, + ...props }) => { return ( onClick()} small={small || false} detailsPage={detailsPage || false} + {...props} > diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCompleteButton/TaskCompleteButton.test.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCompleteButton/TaskCompleteButton.test.tsx index 7c0144932..c66be3f1e 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCompleteButton/TaskCompleteButton.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCompleteButton/TaskCompleteButton.test.tsx @@ -73,6 +73,6 @@ describe('TaskCompleteButton', () => { userEvent.click(completeButton); - expect(onClick).toHaveBeenCalledWith(); + expect(onClick).toHaveBeenCalled(); }); }); diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCompleteButton/TaskCompleteButton.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCompleteButton/TaskCompleteButton.tsx index 0b8be1f04..7ea00352a 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCompleteButton/TaskCompleteButton.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTaskRow/TaskCompleteButton/TaskCompleteButton.tsx @@ -1,6 +1,6 @@ import React from 'react'; import Check from '@mui/icons-material/Check'; -import { Button } from '@mui/material'; +import { Button, ButtonProps } from '@mui/material'; import { styled } from '@mui/material/styles'; import theme from 'src/theme'; @@ -23,17 +23,16 @@ const ButtonWrap = styled(Button, { }, })); -interface TaskCompleteButtonProps { +interface TaskCompleteButtonProps extends ButtonProps { isComplete: boolean; - onClick: () => void; } export const TaskCompleteButton: React.FC = ({ isComplete, - onClick, + ...props }) => { return ( - onClick()}> + ); diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.stories.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.stories.tsx index b442e52f5..b220c8bdb 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.stories.tsx @@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; import { CssBaseline } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../theme'; import { ContactTasksTab } from './ContactTasksTab'; import { ContactTasksTabDocument } from './ContactTasksTab.generated'; diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.test.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.test.tsx index 4b3c45bae..57bdc55cb 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.test.tsx @@ -3,8 +3,8 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { DateTime } from 'luxon'; import { VirtuosoMockContext } from 'react-virtuoso'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { useAccountListId } from 'src/hooks/useAccountListId'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; import useTaskModal from '../../../../hooks/useTaskModal'; import theme from '../../../../theme'; import { TasksMassActionsDropdown } from '../../../Shared/MassActions/TasksMassActionsDropdown'; @@ -31,6 +31,7 @@ const router = { beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); (useAccountListId as jest.Mock).mockReturnValue(router); }); diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.tsx index 075348c1a..b48380af5 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/ContactTasksTab.tsx @@ -143,7 +143,7 @@ export const ContactTasksTab: React.FC = ({ deselectAll, } = useMassSelection(data?.tasks?.totalCount ?? 0, allTaskIds); - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const { t } = useTranslation(); @@ -165,6 +165,7 @@ export const ContactTasksTab: React.FC = ({ defaultValues: { contactIds: [contactId] }, }) } + onMouseEnter={() => preloadTaskModal('add')} > {t('add task')} @@ -179,6 +180,7 @@ export const ContactTasksTab: React.FC = ({ }, }) } + onMouseEnter={() => preloadTaskModal('log')} > {t('log task')} diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/DeleteTaskIconButton/DeleteTaskIconButton.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/DeleteTaskIconButton/DeleteTaskIconButton.tsx index ca5a6e820..4de903911 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/DeleteTaskIconButton/DeleteTaskIconButton.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/DeleteTaskIconButton/DeleteTaskIconButton.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { DialogActions, IconButton } from '@mui/material'; +import { IconButton } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { DeletedItemIcon } from '../../../../common/DeleteItemIcon/DeleteItemIcon'; @@ -9,10 +9,6 @@ const DeleteButton = styled(IconButton)(({ theme }) => ({ margin: theme.spacing(1), })); -export const StyledDialogActions = styled(DialogActions)(({ theme }) => ({ - padding: `${theme.spacing(2)}px ${theme.spacing(3)}px`, -})); - interface DeleteTaskIconButtonProps { accountListId: string; taskId: string; diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/NullState/ContactTasksTabNullState.test.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/NullState/ContactTasksTabNullState.test.tsx index 349c57fc7..df9bceb55 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/NullState/ContactTasksTabNullState.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/NullState/ContactTasksTabNullState.test.tsx @@ -2,11 +2,8 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import TestWrapper from '../../../../../../__tests__/util/TestWrapper'; -import { - render, - waitFor, -} from '../../../../../../__tests__/util/testingLibraryReactMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import useTaskModal from '../../../../../hooks/useTaskModal'; import theme from '../../../../../theme'; import { ContactTasksTabNullState } from './ContactTasksTabNullState'; @@ -14,12 +11,13 @@ import { ContactTasksTabNullState } from './ContactTasksTabNullState'; const contactId = 'abc'; const openTaskModal = jest.fn(); -jest.mock('../../../../../../src/hooks/useTaskModal'); +jest.mock('src/hooks/useTaskModal'); describe('ContactTasksTabNullState', () => { beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/NullState/ContactTasksTabNullState.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/NullState/ContactTasksTabNullState.tsx index 52720464b..14c1be4c5 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/NullState/ContactTasksTabNullState.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/NullState/ContactTasksTabNullState.tsx @@ -24,7 +24,7 @@ export const ContactTasksTabNullState: React.FC< ContactTasksTabNullStateProps > = ({ contactId }) => { const { t } = useTranslation(); - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); return ( @@ -43,6 +43,7 @@ export const ContactTasksTabNullState: React.FC< defaultValues: { contactIds: [contactId] }, }) } + onMouseEnter={() => preloadTaskModal('add')} > {t('Add New Task')} diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.stories.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.stories.tsx index 868f082d4..8722f15e4 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.stories.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.stories.tsx @@ -1,5 +1,5 @@ import React, { ReactElement } from 'react'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { SetTaskStarredMutation } from './SetTaskStarred.generated'; import { StarTaskIconButton } from './StarTaskIconButton'; diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.test.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.test.tsx index fac8eba49..43529364a 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.test.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; -import { GqlMockedProvider } from '../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../../theme'; import { StarTaskIconButton } from './StarTaskIconButton'; diff --git a/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.tsx b/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.tsx index 0edca541b..412527bdf 100644 --- a/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.tsx +++ b/src/components/Contacts/ContactDetails/ContactTasksTab/StarTaskIconButton/StarTaskIconButton.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import IconButton from '@mui/material/IconButton'; +import { IconButton } from '@mui/material'; import { styled } from '@mui/material/styles'; import { StarredItemIcon } from '../../../../common/StarredItemIcon/StarredItemIcon'; import { useSetTaskStarredMutation } from './SetTaskStarred.generated'; diff --git a/src/components/Contacts/ContactFlow/ContactFlow.tsx b/src/components/Contacts/ContactFlow/ContactFlow.tsx index 0e4d787cc..13f571d1e 100644 --- a/src/components/Contacts/ContactFlow/ContactFlow.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlow.tsx @@ -1,7 +1,10 @@ import React from 'react'; import { Box } from '@mui/material'; import { useSnackbar } from 'notistack'; +import { DndProvider } from 'react-dnd'; +import { HTML5Backend } from 'react-dnd-html5-backend'; import { useTranslation } from 'react-i18next'; +import { ContactsDocument } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; import { ActivityTypeEnum, ContactFilterSetInput, @@ -10,11 +13,11 @@ import { StatusEnum, } from 'src/graphql/types.generated'; import useTaskModal from 'src/hooks/useTaskModal'; -import { ContactsDocument } from '../../../../pages/accountLists/[accountListId]/contacts/Contacts.generated'; import theme from '../../../theme'; import Loading from '../../Loading'; import { useUpdateContactOtherMutation } from '../ContactDetails/ContactDetailsTab/Other/EditContactOtherModal/EditContactOther.generated'; import { ContactFlowColumn } from './ContactFlowColumn/ContactFlowColumn'; +import { ContactFlowDragLayer } from './ContactFlowDragLayer/ContactFlowDragLayer'; import { useGetUserOptionsQuery } from './GetUserOptions.generated'; interface Props { @@ -133,40 +136,43 @@ export const ContactFlow: React.FC = ({ ) : ( flowOptions && ( - - {flowOptions.map((column) => ( - - statusMap[status] as ContactFilterStatusEnum, - )} - changeContactStatus={changeContactStatus} - searchTerm={searchTerm} - /> - - ))} - + + + + {flowOptions.map((column) => ( + + statusMap[status] as ContactFilterStatusEnum, + )} + changeContactStatus={changeContactStatus} + searchTerm={searchTerm} + /> + + ))} + + ) ); }; diff --git a/src/components/Contacts/ContactFlow/ContactFlowColumn/ContactFlowColumn.test.tsx b/src/components/Contacts/ContactFlow/ContactFlowColumn/ContactFlowColumn.test.tsx index 7a18f935f..7eb0add7d 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowColumn/ContactFlowColumn.test.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowColumn/ContactFlowColumn.test.tsx @@ -5,14 +5,14 @@ import { SnackbarProvider } from 'notistack'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import { VirtuosoMockContext } from 'react-virtuoso'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsQuery } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactFilterStatusEnum, StatusEnum, } from 'src/graphql/types.generated'; -import TestRouter from '../../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; -import { ContactsQuery } from '../../../../../pages/accountLists/[accountListId]/contacts/Contacts.generated'; import theme from '../../../../theme'; import { ContactFlowColumn } from './ContactFlowColumn'; @@ -52,7 +52,7 @@ describe('ContactFlowColumn', () => { }, }} > - + @@ -66,7 +66,7 @@ describe('ContactFlowColumn', () => { statuses={[ContactFilterStatusEnum.PartnerFinancial]} /> - + diff --git a/src/components/Contacts/ContactFlow/ContactFlowColumn/ContactFlowColumn.tsx b/src/components/Contacts/ContactFlow/ContactFlowColumn/ContactFlowColumn.tsx index ff0da5061..2e28e0b5b 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowColumn/ContactFlowColumn.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowColumn/ContactFlowColumn.tsx @@ -7,16 +7,16 @@ import { Typography, } from '@mui/material'; import { useDrop } from 'react-dnd'; +import { useContactsQuery } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; import { ContactsContext, ContactsType, -} from 'pages/accountLists/[accountListId]/contacts/ContactsContext'; +} from 'src/components/Contacts/ContactsContext/ContactsContext'; import { ContactFilterSetInput, ContactFilterStatusEnum, IdValue, } from 'src/graphql/types.generated'; -import { useContactsQuery } from '../../../../../pages/accountLists/[accountListId]/contacts/Contacts.generated'; import theme from '../../../../theme'; import { useLoadConstantsQuery } from '../../../Constants/LoadConstants.generated'; import { InfiniteList } from '../../../InfiniteList/InfiniteList'; diff --git a/src/components/Contacts/ContactFlow/ContactFlowDropZone/ContactFlowDropZone.tsx b/src/components/Contacts/ContactFlow/ContactFlowDropZone/ContactFlowDropZone.tsx index df6d68432..6a13a37f8 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowDropZone/ContactFlowDropZone.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowDropZone/ContactFlowDropZone.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; +import { Box, Typography } from '@mui/material'; import { useDrop } from 'react-dnd'; import { useTranslation } from 'react-i18next'; import { IdValue } from 'src/graphql/types.generated'; diff --git a/src/components/Contacts/ContactFlow/ContactFlowRow/ContactFlowRow.test.tsx b/src/components/Contacts/ContactFlow/ContactFlowRow/ContactFlowRow.test.tsx index 711b87cb1..8370adbad 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowRow/ContactFlowRow.test.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowRow/ContactFlowRow.test.tsx @@ -4,8 +4,8 @@ import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; +import TestWrapper from '__tests__/util/TestWrapper'; import { StatusEnum } from 'src/graphql/types.generated'; -import TestWrapper from '../../../../../__tests__/util/TestWrapper'; import theme from '../../../../theme'; import { ContactFlowRow } from './ContactFlowRow'; diff --git a/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn.test.tsx b/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn.test.tsx index ded4a2651..0833a2777 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn.test.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn.test.tsx @@ -5,8 +5,8 @@ import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; +import TestRouter from '__tests__/util/TestRouter'; import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; -import TestRouter from '../../../../../../__tests__/util/TestRouter'; import theme from '../../../../../theme'; import { ContactFlowSetupColumn } from './ContactFlowSetupColumn'; diff --git a/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn.tsx b/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn.tsx index 4ab799cda..1b58e295f 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/ContactFlowSetupColumn.tsx @@ -11,7 +11,7 @@ import FiberManualRecord from '@mui/icons-material/FiberManualRecord'; import Menu from '@mui/icons-material/Menu'; import { Box, Card, CardContent, IconButton, TextField } from '@mui/material'; import { styled } from '@mui/material/styles'; -import debounce from 'lodash/fp/debounce'; +import { debounce } from 'lodash'; import { DropTargetMonitor, useDrag, useDrop } from 'react-dnd'; import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; import theme from 'src/theme'; @@ -117,9 +117,9 @@ export const ContactFlowSetupColumn: React.FC = ({ onTitleChange(event, index); }; const onTitleChange = useCallback( - debounce(200, (event, index) => { + debounce((event, index) => { changeTitle(event, index); - }), + }, 200), [flowOptions], ); diff --git a/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/UnusedStatusesColumn.test.tsx b/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/UnusedStatusesColumn.test.tsx index b2bb2c5eb..ed104866a 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/UnusedStatusesColumn.test.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowSetup/Column/UnusedStatusesColumn.test.tsx @@ -4,8 +4,8 @@ import { render, waitFor } from '@testing-library/react'; import { SnackbarProvider } from 'notistack'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; +import TestRouter from '__tests__/util/TestRouter'; import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; -import TestRouter from '../../../../../../__tests__/util/TestRouter'; import theme from '../../../../../theme'; import { UnusedStatusesColumn } from './UnusedStatusesColumn'; diff --git a/src/components/Contacts/ContactFlow/ContactFlowSetup/DropZone/ContactFlowSetupDropZone.test.tsx b/src/components/Contacts/ContactFlow/ContactFlowSetup/DropZone/ContactFlowSetupDropZone.test.tsx index dcb29c5ee..63394bd7c 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowSetup/DropZone/ContactFlowSetupDropZone.test.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowSetup/DropZone/ContactFlowSetupDropZone.test.tsx @@ -4,8 +4,8 @@ import { fireEvent, render, waitFor } from '@testing-library/react'; import { SnackbarProvider } from 'notistack'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; +import TestRouter from '__tests__/util/TestRouter'; import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; -import TestRouter from '../../../../../../__tests__/util/TestRouter'; import theme from '../../../../../theme'; import { ContactFlowSetupColumn } from '../Column/ContactFlowSetupColumn'; diff --git a/src/components/Contacts/ContactFlow/ContactFlowSetup/Row/ContactFlowSetupStatusRow.test.tsx b/src/components/Contacts/ContactFlow/ContactFlowSetup/Row/ContactFlowSetupStatusRow.test.tsx index 0a748b562..d66d9697b 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowSetup/Row/ContactFlowSetupStatusRow.test.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowSetup/Row/ContactFlowSetupStatusRow.test.tsx @@ -3,8 +3,8 @@ import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; +import TestWrapper from '__tests__/util/TestWrapper'; import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; -import TestWrapper from '../../../../../../__tests__/util/TestWrapper'; import theme from '../../../../../theme'; import { ContactFlowSetupStatusRow } from './ContactFlowSetupStatusRow'; diff --git a/src/components/Contacts/ContactFlow/ContactFlowSetup/Row/ContactFlowSetupStatusRow.tsx b/src/components/Contacts/ContactFlow/ContactFlowSetup/Row/ContactFlowSetupStatusRow.tsx index 7ebeb69f1..64fdf9345 100644 --- a/src/components/Contacts/ContactFlow/ContactFlowSetup/Row/ContactFlowSetupStatusRow.tsx +++ b/src/components/Contacts/ContactFlow/ContactFlowSetup/Row/ContactFlowSetupStatusRow.tsx @@ -1,6 +1,5 @@ import React, { useEffect } from 'react'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; +import { Box, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useDrag } from 'react-dnd'; import { getEmptyImage } from 'react-dnd-html5-backend'; @@ -8,7 +7,7 @@ import { useTranslation } from 'react-i18next'; import { ContactFilterStatusEnum } from 'src/graphql/types.generated'; import theme from '../../../../../theme'; -export const StatusRow = styled(Box)(() => ({ +const StatusRow = styled(Box)(() => ({ padding: theme.spacing(1.5), borderBottom: `1px solid ${theme.palette.cruGrayMedium.main}`, '&:hover': { diff --git a/src/components/Contacts/ContactFlow/ContactsFlow.test.tsx b/src/components/Contacts/ContactFlow/ContactsFlow.test.tsx index 6da639283..5927f3a66 100644 --- a/src/components/Contacts/ContactFlow/ContactsFlow.test.tsx +++ b/src/components/Contacts/ContactFlow/ContactsFlow.test.tsx @@ -5,8 +5,8 @@ import { SnackbarProvider } from 'notistack'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import TestRouter from '__tests__/util/TestRouter'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import theme from '../../../theme'; import { ContactFlow } from './ContactFlow'; import { GetUserOptionsQuery } from './GetUserOptions.generated'; @@ -43,7 +43,7 @@ describe('ContactFlow', () => { - + { selectedFilters={{}} /> - + @@ -69,7 +69,7 @@ describe('ContactFlow', () => { mocks={mocks} > - + { selectedFilters={{}} /> - + diff --git a/src/components/Contacts/ContactFlow/DynamicContactFlow.tsx b/src/components/Contacts/ContactFlow/DynamicContactFlow.tsx new file mode 100644 index 000000000..f1920a759 --- /dev/null +++ b/src/components/Contacts/ContactFlow/DynamicContactFlow.tsx @@ -0,0 +1,10 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const DynamicContactFlow = dynamic( + () => + import(/* webpackChunkName: "ContactFlow" */ './ContactFlow').then( + ({ ContactFlow }) => ContactFlow, + ), + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Contacts/ContactPartnershipStatus/ContactLateStatusLabel/ContactLateStatusLabel.tsx b/src/components/Contacts/ContactPartnershipStatus/ContactLateStatusLabel/ContactLateStatusLabel.tsx index 8b1ee0705..e0cf5451d 100644 --- a/src/components/Contacts/ContactPartnershipStatus/ContactLateStatusLabel/ContactLateStatusLabel.tsx +++ b/src/components/Contacts/ContactPartnershipStatus/ContactLateStatusLabel/ContactLateStatusLabel.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import Typography from '@mui/material/Typography'; +import { Typography } from '@mui/material'; import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import type { Theme } from '@mui/material/styles/createTheme'; diff --git a/src/components/Contacts/ContactRow/ContactRow.stories.tsx b/src/components/Contacts/ContactRow/ContactRow.stories.tsx index 412c10d98..77f90a2fb 100644 --- a/src/components/Contacts/ContactRow/ContactRow.stories.tsx +++ b/src/components/Contacts/ContactRow/ContactRow.stories.tsx @@ -2,8 +2,8 @@ import React from 'react'; import { Meta, Story } from '@storybook/react'; import { DateTime } from 'luxon'; import { withDesign } from 'storybook-addon-designs'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; -import { gqlMock } from '../../../../__tests__/util/graphqlMocking'; +import { gqlMock } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactRow } from './ContactRow'; import { ContactRowFragment, @@ -25,9 +25,9 @@ export const Default: Story = () => { }); return ( - + - + ); }; diff --git a/src/components/Contacts/ContactRow/ContactRow.test.tsx b/src/components/Contacts/ContactRow/ContactRow.test.tsx index ef23d2561..81204b97c 100644 --- a/src/components/Contacts/ContactRow/ContactRow.test.tsx +++ b/src/components/Contacts/ContactRow/ContactRow.test.tsx @@ -2,13 +2,10 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import theme from 'src/theme'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../__tests__/util/graphqlMocking'; import useTaskModal from '../../../hooks/useTaskModal'; import { ContactRow } from './ContactRow'; import { @@ -64,6 +61,7 @@ const openTaskModal = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); @@ -73,9 +71,9 @@ describe('ContactsRow', () => { - + - + , @@ -98,9 +96,9 @@ describe('ContactsRow', () => { - + - + , @@ -117,9 +115,9 @@ describe('ContactsRow', () => { - + - + , @@ -141,9 +139,9 @@ describe('ContactsRow', () => { - + - + , diff --git a/src/components/Contacts/ContactRow/ContactRow.tsx b/src/components/Contacts/ContactRow/ContactRow.tsx index 7e2c6f839..436e0f9de 100644 --- a/src/components/Contacts/ContactRow/ContactRow.tsx +++ b/src/components/Contacts/ContactRow/ContactRow.tsx @@ -14,7 +14,7 @@ import { styled } from '@mui/material/styles'; import { ContactsContext, ContactsType, -} from 'pages/accountLists/[accountListId]/contacts/ContactsContext'; +} from 'src/components/Contacts/ContactsContext/ContactsContext'; import { CelebrationIcons } from '../CelebrationIcons/CelebrationIcons'; import { ContactPartnershipStatus } from '../ContactPartnershipStatus/ContactPartnershipStatus'; import { ContactUncompletedTasksCount } from '../ContactUncompletedTasksCount/ContactUncompletedTasksCount'; diff --git a/src/components/Contacts/ContactUncompletedTasksCount/ContactUncompletedTasksCount.tsx b/src/components/Contacts/ContactUncompletedTasksCount/ContactUncompletedTasksCount.tsx index 6c36d9ad6..9235b3561 100644 --- a/src/components/Contacts/ContactUncompletedTasksCount/ContactUncompletedTasksCount.tsx +++ b/src/components/Contacts/ContactUncompletedTasksCount/ContactUncompletedTasksCount.tsx @@ -1,7 +1,6 @@ import React from 'react'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; +import { Box, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import useTaskModal from 'src/hooks/useTaskModal'; @@ -22,7 +21,7 @@ export const ContactUncompletedTasksCount: React.FC< ContactUncompletedTasksCountProps > = ({ uncompletedTasksCount, contactId }) => { const { t } = useTranslation(); - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); return ( @@ -36,6 +35,7 @@ export const ContactUncompletedTasksCount: React.FC< }, }) } + onMouseEnter={() => preloadTaskModal('log')} /> { - return ( - - - - - - ); -}; diff --git a/src/components/Contacts/ContactsContainer.tsx b/src/components/Contacts/ContactsContainer.tsx deleted file mode 100644 index 889eac6db..000000000 --- a/src/components/Contacts/ContactsContainer.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import Head from 'next/head'; -import React, { useContext } from 'react'; -import Box from '@mui/material/Box'; -import { styled } from '@mui/material/styles'; -import _ from 'lodash'; -import { DndProvider } from 'react-dnd'; -import { HTML5Backend } from 'react-dnd-html5-backend'; -import { useTranslation } from 'react-i18next'; -import useGetAppSettings from 'src/hooks/useGetAppSettings'; -import { - ContactsContext, - ContactsType, -} from '../../../pages/accountLists/[accountListId]/contacts/ContactsContext'; -import { SidePanelsLayout } from '../Layouts/SidePanelsLayout'; -import Loading from '../Loading'; -import { TableViewModeEnum, headerHeight } from '../Shared/Header/ListHeader'; -import { ContactFlowDragLayer } from './ContactFlow/ContactFlowDragLayer/ContactFlowDragLayer'; -import { ContactsLeftPanel } from './ContactsLeftPanel/ContactsLeftPanel'; -import { ContactsMainPanel } from './ContactsMainPanel/ContactsMainPanel'; -import { ContactsRightPanel } from './ContactsRightPanel/ContactsRightPanel'; - -const WhiteBackground = styled(Box)(({ theme }) => ({ - backgroundColor: theme.palette.common.white, -})); - -export const ContactsContainer: React.FC = ({}) => { - const { t } = useTranslation(); - const { - accountListId, - filterPanelOpen, - contactDetailsOpen, - viewMode, - setContactFocus, - } = useContext(ContactsContext) as ContactsType; - const { appName } = useGetAppSettings(); - - return ( - <> - - - {appName} |{' '} - {viewMode === TableViewModeEnum.Flows - ? t('Contact Flows') - : viewMode === TableViewModeEnum.Map - ? t('Contacts Map') - : t('Contacts')} - - - {accountListId ? ( - - - - } - leftOpen={filterPanelOpen} - leftWidth="290px" - mainContent={} - rightPanel={ - - setContactFocus( - undefined, - true, - viewMode === TableViewModeEnum.Flows, - viewMode === TableViewModeEnum.Map, - ) - } - /> - } - rightOpen={contactDetailsOpen} - rightWidth="60%" - headerHeight={headerHeight} - /> - - - ) : ( - - )} - - ); -}; diff --git a/pages/accountLists/[accountListId]/contacts/ContactsContext.test.tsx b/src/components/Contacts/ContactsContext/ContactsContext.test.tsx similarity index 91% rename from pages/accountLists/[accountListId]/contacts/ContactsContext.test.tsx rename to src/components/Contacts/ContactsContext/ContactsContext.test.tsx index 008899a7e..107efadda 100644 --- a/pages/accountLists/[accountListId]/contacts/ContactsContext.test.tsx +++ b/src/components/Contacts/ContactsContext/ContactsContext.test.tsx @@ -3,28 +3,28 @@ import { Box, Button, Typography } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactFiltersQuery } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { GetUserOptionsQuery } from 'src/components/Contacts/ContactFlow/GetUserOptions.generated'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { useMassSelection } from '../../../hooks/useMassSelection'; +import theme from '../../../theme'; import { ListHeaderCheckBoxState, TableViewModeEnum, -} from '../../../../src/components/Shared/Header/ListHeader'; -import { useMassSelection } from '../../../../src/hooks/useMassSelection'; -import theme from '../../../../src/theme'; -import { ContactFiltersQuery } from './Contacts.generated'; +} from '../../Shared/Header/ListHeader'; import { ContactsContext, ContactsContextSavedFilters, ContactsType, } from './ContactsContext'; -import { ContactsPage } from './ContactsPage'; const accountListId = 'account-list-1'; const push = jest.fn(); const isReady = true; -jest.mock('../../../../src/hooks/useMassSelection'); +jest.mock('src/hooks/useMassSelection'); (useMassSelection as jest.Mock).mockReturnValue({ selectionType: ListHeaderCheckBoxState.Unchecked, @@ -121,9 +121,9 @@ describe('ContactsPageContext', () => { }, }} > - + - + , @@ -164,9 +164,9 @@ describe('ContactsPageContext', () => { }, }} > - + - + , @@ -215,9 +215,9 @@ describe('ContactsPageContext', () => { }, }} > - + - + , @@ -259,9 +259,9 @@ describe('ContactsPageContext', () => { }, }} > - + - + , @@ -295,9 +295,9 @@ describe('ContactsPageContext', () => { }, }} > - + - + , diff --git a/pages/accountLists/[accountListId]/contacts/ContactsContext.tsx b/src/components/Contacts/ContactsContext/ContactsContext.tsx similarity index 91% rename from pages/accountLists/[accountListId]/contacts/ContactsContext.tsx rename to src/components/Contacts/ContactsContext/ContactsContext.tsx index e2c40e691..5f930228e 100644 --- a/pages/accountLists/[accountListId]/contacts/ContactsContext.tsx +++ b/src/components/Contacts/ContactsContext/ContactsContext.tsx @@ -1,4 +1,4 @@ -import { NextRouter, useRouter } from 'next/router'; +import { useRouter } from 'next/router'; import React, { Dispatch, SetStateAction, @@ -8,34 +8,36 @@ import React, { useRef, useState, } from 'react'; -import _, { debounce } from 'lodash'; +import { type DebouncedFunc, debounce, omit } from 'lodash'; +import { + ContactFiltersQuery, + useContactFiltersQuery, + useContactsQuery, +} from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; +import { + coordinatesFromContacts, + getRedirectPathname, +} from 'pages/accountLists/[accountListId]/contacts/helpers'; import { ContactFilterSetInput } from 'src/graphql/types.generated'; import { useGetIdsForMassSelectionQuery } from 'src/hooks/GetIdsForMassSelection.generated'; import { useLocale } from 'src/hooks/useLocale'; import { sanitizeFilters } from 'src/lib/sanitizeFilters'; -import { useUpdateUserOptionsMutation } from '../../../../src/components/Contacts/ContactFlow/ContactFlowSetup/UpdateUserOptions.generated'; -import { useGetUserOptionsQuery } from '../../../../src/components/Contacts/ContactFlow/GetUserOptions.generated'; -import { UserOptionFragment } from '../../../../src/components/Shared/Filters/FilterPanel.generated'; +import { useAccountListId } from '../../../hooks/useAccountListId'; +import { useMassSelection } from '../../../hooks/useMassSelection'; +import { UserOptionFragment } from '../../Shared/Filters/FilterPanel.generated'; import { ListHeaderCheckBoxState, TableViewModeEnum, -} from '../../../../src/components/Shared/Header/ListHeader'; -import { useAccountListId } from '../../../../src/hooks/useAccountListId'; -import { useMassSelection } from '../../../../src/hooks/useMassSelection'; -import { - ContactFiltersQuery, - useContactFiltersQuery, - useContactsQuery, -} from './Contacts.generated'; -import { coordinatesFromContacts, getRedirectPathname } from './helpers'; -import { Coordinates } from './map/map'; +} from '../../Shared/Header/ListHeader'; +import { useUpdateUserOptionsMutation } from '../ContactFlow/ContactFlowSetup/UpdateUserOptions.generated'; +import { useGetUserOptionsQuery } from '../ContactFlow/GetUserOptions.generated'; +import { Coordinates } from '../ContactsMap/coordinates'; export type ContactsType = { accountListId: string | undefined; contactId: string | string[] | undefined; searchTerm: string | string[] | undefined; - loading: boolean; - router: NextRouter; + contactsQueryResult: ReturnType; selectionType: ListHeaderCheckBoxState; isRowChecked: (id: string) => boolean; toggleSelectAll: () => void; @@ -51,7 +53,7 @@ export type ContactsType = { flows?: boolean, map?: boolean, ) => void; - setSearchTerm: _.DebouncedFunc<(searchTerm: string) => void>; + setSearchTerm: DebouncedFunc<(searchTerm: string) => void>; handleViewModeChange: ( event: React.MouseEvent, view: string, @@ -176,7 +178,7 @@ export const ContactsProvider: React.FC = ({ [sanitizedFilters, starredFilter, searchTerm], ); - const { data, loading, fetchMore } = useContactsQuery({ + const contactsQueryResult = useContactsQuery({ variables: { accountListId: accountListId ?? '', contactsFilters, @@ -184,6 +186,7 @@ export const ContactsProvider: React.FC = ({ }, skip: !accountListId, }); + const { data, loading, fetchMore } = contactsQueryResult; //#region Mass Actions @@ -209,7 +212,7 @@ export const ContactsProvider: React.FC = ({ toggleSelectionById, deselectAll, } = useMassSelection( - data?.contacts?.totalCount ?? 0, + contactCount, allContactIds, activeFilters, searchTerm as string, @@ -295,7 +298,7 @@ export const ContactsProvider: React.FC = ({ filteredQuery.filters = encodeURI(JSON.stringify({ ids })); } if (viewMode !== TableViewModeEnum.Map && urlFilters && urlFilters.ids) { - const newFilters = _.omit(activeFilters, 'ids'); + const newFilters = omit(activeFilters, 'ids'); if (Object.keys(newFilters).length > 0) { filteredQuery.filters = encodeURI(JSON.stringify(newFilters)); } else { @@ -392,8 +395,7 @@ export const ContactsProvider: React.FC = ({ accountListId: accountListId ?? '', contactId: contactId, searchTerm: searchTerm, - loading: loading, - router: router, + contactsQueryResult: contactsQueryResult, selectionType: selectionType, isRowChecked: isRowChecked, toggleSelectAll: toggleSelectAll, diff --git a/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.stories.tsx b/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.stories.tsx index 1e59871f0..ae3f2cdf3 100644 --- a/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.stories.tsx +++ b/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactsLeftPanel } from './ContactsLeftPanel'; export default { @@ -10,9 +10,9 @@ export default { export const Default = (): ReactElement => { return ( - + - + ); }; diff --git a/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.test.tsx b/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.test.tsx index 9942c9074..4cd3baf6e 100644 --- a/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.test.tsx +++ b/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.test.tsx @@ -4,11 +4,11 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import TestRouter from '__tests__/util/TestRouter'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactsContext, ContactsType, -} from 'pages/accountLists/[accountListId]/contacts/ContactsContext'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +} from 'src/components/Contacts/ContactsContext/ContactsContext'; import theme from 'src/theme'; import { GetUserOptionsQuery } from '../ContactFlow/GetUserOptions.generated'; import { ContactsLeftPanel } from './ContactsLeftPanel'; @@ -82,12 +82,12 @@ describe('ContactsLeftPanel', () => { mocks={mocks} > - + <> - + , diff --git a/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.tsx b/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.tsx index 009bcd0ea..f8854d6fa 100644 --- a/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.tsx +++ b/src/components/Contacts/ContactsLeftPanel/ContactsLeftPanel.tsx @@ -1,12 +1,11 @@ import React from 'react'; -import _ from 'lodash'; +import { DynamicFilterPanel } from 'src/components/Shared/Filters/DynamicFilterPanel'; +import { TableViewModeEnum } from '../../Shared/Header/ListHeader'; import { ContactsContext, ContactsType, -} from '../../../../pages/accountLists/[accountListId]/contacts/ContactsContext'; -import { FilterPanel } from '../../Shared/Filters/FilterPanel'; -import { TableViewModeEnum } from '../../Shared/Header/ListHeader'; -import { ContactsMapPanel } from '../ContactsMap/ContactsMapPanel'; +} from '../ContactsContext/ContactsContext'; +import { DynamicContactsMapPanel } from '../ContactsMap/DynamicContactsMapPanel'; export const ContactsLeftPanel: React.FC = () => { const { @@ -24,7 +23,7 @@ export const ContactsLeftPanel: React.FC = () => { } = React.useContext(ContactsContext) as ContactsType; return viewMode === TableViewModeEnum.Map ? ( - { onClose={toggleFilterPanel} /> ) : filterData && !filtersLoading ? ( - { return ( - + - + ); }; diff --git a/src/components/Contacts/ContactsList/ContactsList.tsx b/src/components/Contacts/ContactsList/ContactsList.tsx index 6817a8202..b1553cc88 100644 --- a/src/components/Contacts/ContactsList/ContactsList.tsx +++ b/src/components/Contacts/ContactsList/ContactsList.tsx @@ -3,47 +3,21 @@ import { Box } from '@mui/material'; import { ContactsContext, ContactsType, -} from 'pages/accountLists/[accountListId]/contacts/ContactsContext'; +} from 'src/components/Contacts/ContactsContext/ContactsContext'; import { InfiniteList } from 'src/components/InfiniteList/InfiniteList'; import { navBarHeight } from 'src/components/Layouts/Primary/Primary'; import NullState from 'src/components/Shared/Filters/NullState/NullState'; -import { - TableViewModeEnum, - headerHeight, -} from 'src/components/Shared/Header/ListHeader'; -import { useContactsQuery } from '../../../../pages/accountLists/[accountListId]/contacts/Contacts.generated'; +import { headerHeight } from 'src/components/Shared/Header/ListHeader'; import { ContactRow } from '../ContactRow/ContactRow'; export const ContactsList: React.FC = () => { const { - contactId, - accountListId, - sanitizedFilters, + contactsQueryResult: { data, loading, fetchMore }, searchTerm, - starredFilter, - viewMode, - urlFilters, isFiltered, setActiveFilters, } = React.useContext(ContactsContext) as ContactsType; - const { data, loading, fetchMore } = useContactsQuery({ - variables: { - accountListId: accountListId ?? '', - contactsFilters: { - ...sanitizedFilters, - wildcardSearch: searchTerm as string, - ...starredFilter, - ids: - viewMode === TableViewModeEnum.Map && urlFilters - ? urlFilters.ids - : [], - }, - first: contactId?.includes('map') ? 20000 : 25, - }, - skip: !accountListId, - }); - return ( + import(/* webpackChunkName: "ContactsList" */ './ContactsList').then( + ({ ContactsList }) => ContactsList, + ), + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Contacts/ContactsMainPanel/ContactsMainPanel.stories.tsx b/src/components/Contacts/ContactsMainPanel/ContactsMainPanel.stories.tsx index 1c73766cf..30160a8cd 100644 --- a/src/components/Contacts/ContactsMainPanel/ContactsMainPanel.stories.tsx +++ b/src/components/Contacts/ContactsMainPanel/ContactsMainPanel.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactsMainPanel } from './ContactsMainPanel'; export default { @@ -10,9 +10,9 @@ export default { export const Default = (): ReactElement => { return ( - + - + ); }; diff --git a/src/components/Contacts/ContactsMainPanel/ContactsMainPanel.tsx b/src/components/Contacts/ContactsMainPanel/ContactsMainPanel.tsx index e1656ae57..473188f50 100644 --- a/src/components/Contacts/ContactsMainPanel/ContactsMainPanel.tsx +++ b/src/components/Contacts/ContactsMainPanel/ContactsMainPanel.tsx @@ -1,13 +1,12 @@ import React from 'react'; -import _ from 'lodash'; import { TableViewModeEnum } from 'src/components/Shared/Header/ListHeader'; +import { DynamicContactFlow } from '../ContactFlow/DynamicContactFlow'; import { ContactsContext, ContactsType, -} from '../../../../pages/accountLists/[accountListId]/contacts/ContactsContext'; -import { ContactsMap } from '../../../../pages/accountLists/[accountListId]/contacts/map/map'; -import { ContactFlow } from '../ContactFlow/ContactFlow'; -import { ContactsList } from '../ContactsList/ContactsList'; +} from '../ContactsContext/ContactsContext'; +import { DynamicContactsList } from '../ContactsList/DynamicContactsList'; +import { DynamicContactsMap } from '../ContactsMap/DynamicContactsMap'; import { ContactsMainPanelHeader } from './ContactsMainPanelHeader'; export const ContactsMainPanel: React.FC = () => { @@ -26,9 +25,9 @@ export const ContactsMainPanel: React.FC = () => { {!userOptionsLoading && (viewMode === TableViewModeEnum.List ? ( - + ) : viewMode === TableViewModeEnum.Flows ? ( - { onContactSelected={setContactFocus} /> ) : ( - + ))} ); diff --git a/src/components/Contacts/ContactsMainPanel/ContactsMainPanelHeader.tsx b/src/components/Contacts/ContactsMainPanel/ContactsMainPanelHeader.tsx index 09ed6eac3..05e9e5f28 100644 --- a/src/components/Contacts/ContactsMainPanel/ContactsMainPanelHeader.tsx +++ b/src/components/Contacts/ContactsMainPanel/ContactsMainPanelHeader.tsx @@ -4,15 +4,15 @@ import FormatListBulleted from '@mui/icons-material/FormatListBulleted'; import Map from '@mui/icons-material/Map'; import Settings from '@mui/icons-material/Settings'; import ViewColumn from '@mui/icons-material/ViewColumn'; -import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; -import Hidden from '@mui/material/Hidden'; -import ToggleButton from '@mui/material/ToggleButton'; -import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; +import { + Box, + Button, + Hidden, + ToggleButton, + ToggleButtonGroup, +} from '@mui/material'; import { styled } from '@mui/material/styles'; -import _ from 'lodash'; import { useTranslation } from 'react-i18next'; -import { useContactsQuery } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; import { ListHeader, TableViewModeEnum, @@ -20,7 +20,7 @@ import { import { ContactsContext, ContactsType, -} from '../../../../pages/accountLists/[accountListId]/contacts/ContactsContext'; +} from '../ContactsContext/ContactsContext'; const ViewSettingsButton = styled(Button)(({ theme }) => ({ textTransform: 'none', @@ -46,7 +46,7 @@ export const ContactsMainPanelHeader: React.FC = () => { const { accountListId, sanitizedFilters, - contactId, + contactsQueryResult, toggleFilterPanel, toggleSelectAll, setSearchTerm, @@ -57,28 +57,10 @@ export const ContactsMainPanelHeader: React.FC = () => { filterPanelOpen, contactDetailsOpen, viewMode, - urlFilters, handleViewModeChange, selectedIds, } = React.useContext(ContactsContext) as ContactsType; - const { data } = useContactsQuery({ - variables: { - accountListId: accountListId ?? '', - contactsFilters: { - ...sanitizedFilters, - wildcardSearch: searchTerm as string, - ...starredFilter, - ids: - viewMode === TableViewModeEnum.Map && urlFilters - ? urlFilters.ids - : [], - }, - first: contactId?.includes('map') ? 20000 : 25, - }, - skip: !accountListId, - }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any return ( { contactsView={viewMode} onSearchTermChanged={setSearchTerm} searchTerm={searchTerm} - totalItems={data?.contacts?.totalCount} + totalItems={contactsQueryResult.data?.contacts.totalCount} starredFilter={starredFilter} toggleStarredFilter={setStarredFilter} headerCheckboxState={selectionType} diff --git a/src/components/Contacts/ContactsMap/ContactsMap.test.tsx b/src/components/Contacts/ContactsMap/ContactsMap.test.tsx new file mode 100644 index 000000000..a6ad7ef81 --- /dev/null +++ b/src/components/Contacts/ContactsMap/ContactsMap.test.tsx @@ -0,0 +1,33 @@ +import { render, waitForElementToBeRemoved } from '@testing-library/react'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { ContactsProvider } from '../ContactsContext/ContactsContext'; +import { ContactsMap } from './ContactsMap'; + +describe('ContactsMap', () => { + it('renders loading spinner until map loads', () => { + const { getByRole } = render( + + + + + + + , + ); + + const loadingSpinner = getByRole('progressbar'); + expect(loadingSpinner).toBeInTheDocument(); + waitForElementToBeRemoved(loadingSpinner); + }); +}); diff --git a/pages/accountLists/[accountListId]/contacts/map/map.tsx b/src/components/Contacts/ContactsMap/ContactsMap.tsx similarity index 94% rename from pages/accountLists/[accountListId]/contacts/map/map.tsx rename to src/components/Contacts/ContactsMap/ContactsMap.tsx index 23903eec8..1e148ae82 100644 --- a/pages/accountLists/[accountListId]/contacts/map/map.tsx +++ b/src/components/Contacts/ContactsMap/ContactsMap.tsx @@ -12,7 +12,10 @@ import { useTranslation } from 'react-i18next'; import { StatusEnum } from 'src/graphql/types.generated'; import theme from 'src/theme'; import { sourceToStr } from 'src/utils/sourceToStr'; -import { ContactsContext, ContactsType } from '../ContactsContext'; +import { + ContactsContext, + ContactsType, +} from '../ContactsContext/ContactsContext'; const ContactLink = styled(Typography)(({ theme }) => ({ color: theme.palette.mpdxBlue.main, @@ -28,22 +31,6 @@ const MapLoading = styled(CircularProgress)(() => ({ left: '50%', })); -export interface Coordinates { - id: string; - name: string; - avatar: string; - status?: StatusEnum | null; - lat?: number; - lng?: number; - street?: string | null; - city?: string | null; - state?: string | null; - country?: string | null; - postal?: string | null; - source?: string; - date?: string; -} - const mapContainerStyle = { height: '100%', width: '100%', diff --git a/src/components/Contacts/ContactsMap/ContactsMapPanel.test.tsx b/src/components/Contacts/ContactsMap/ContactsMapPanel.test.tsx index 34a70390f..19062f85a 100644 --- a/src/components/Contacts/ContactsMap/ContactsMapPanel.test.tsx +++ b/src/components/Contacts/ContactsMap/ContactsMapPanel.test.tsx @@ -2,10 +2,10 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import TestRouter from '__tests__/util/TestRouter'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { StatusEnum } from 'src/graphql/types.generated'; -import TestRouter from '../../../../__tests__/util/TestRouter'; import theme from '../../../theme'; import { ContactsMapPanel } from './ContactsMapPanel'; @@ -50,7 +50,7 @@ describe('ContactsMapPanel', () => { - + { panTo={panTo} onClose={onClose} /> - + , @@ -77,7 +77,7 @@ describe('ContactsMapPanel', () => { - + { panTo={panTo} onClose={onClose} /> - + , diff --git a/src/components/Contacts/ContactsMap/ContactsMapPanel.tsx b/src/components/Contacts/ContactsMap/ContactsMapPanel.tsx index 205316b0a..f013cee9b 100644 --- a/src/components/Contacts/ContactsMap/ContactsMapPanel.tsx +++ b/src/components/Contacts/ContactsMap/ContactsMapPanel.tsx @@ -18,10 +18,10 @@ import { } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; -import { Coordinates } from 'pages/accountLists/[accountListId]/contacts/map/map'; import { StatusEnum } from 'src/graphql/types.generated'; import theme from 'src/theme'; import { sourceToStr } from 'src/utils/sourceToStr'; +import { Coordinates } from './coordinates'; interface ContactMapsPanelProps { data: Coordinates[] | undefined; diff --git a/src/components/Contacts/ContactsMap/DynamicContactsMap.tsx b/src/components/Contacts/ContactsMap/DynamicContactsMap.tsx new file mode 100644 index 000000000..fe764f4a3 --- /dev/null +++ b/src/components/Contacts/ContactsMap/DynamicContactsMap.tsx @@ -0,0 +1,10 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const DynamicContactsMap = dynamic( + () => + import(/* webpackChunkName: "ContactsMap" */ './ContactsMap').then( + ({ ContactsMap }) => ContactsMap, + ), + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Contacts/ContactsMap/DynamicContactsMapPanel.tsx b/src/components/Contacts/ContactsMap/DynamicContactsMapPanel.tsx new file mode 100644 index 000000000..0ec5050db --- /dev/null +++ b/src/components/Contacts/ContactsMap/DynamicContactsMapPanel.tsx @@ -0,0 +1,10 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const DynamicContactsMapPanel = dynamic( + () => + import( + /* webpackChunkName: "ContactsMapPanel" */ './ContactsMapPanel' + ).then(({ ContactsMapPanel }) => ContactsMapPanel), + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Contacts/ContactsMap/coordinates.ts b/src/components/Contacts/ContactsMap/coordinates.ts new file mode 100644 index 000000000..fe6d1d5b7 --- /dev/null +++ b/src/components/Contacts/ContactsMap/coordinates.ts @@ -0,0 +1,17 @@ +import { StatusEnum } from 'src/graphql/types.generated'; + +export interface Coordinates { + id: string; + name: string; + avatar: string; + status?: StatusEnum | null; + lat?: number; + lng?: number; + street?: string | null; + city?: string | null; + state?: string | null; + country?: string | null; + postal?: string | null; + source?: string; + date?: string; +} diff --git a/src/components/Contacts/ContactsRightPanel/ContactsRightPanel.stories.tsx b/src/components/Contacts/ContactsRightPanel/ContactsRightPanel.stories.tsx index 80df53b76..4df45420d 100644 --- a/src/components/Contacts/ContactsRightPanel/ContactsRightPanel.stories.tsx +++ b/src/components/Contacts/ContactsRightPanel/ContactsRightPanel.stories.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { ContactsPage } from 'pages/accountLists/[accountListId]/contacts/ContactsPage'; +import { ContactsWrapper } from 'pages/accountLists/[accountListId]/contacts/ContactsWrapper'; import { ContactDetailProvider } from '../ContactDetails/ContactDetailContext'; import { ContactsRightPanel } from './ContactsRightPanel'; @@ -9,10 +9,10 @@ export default { export const Default = (): React.ReactElement => { return ( - + {}} /> - + ); }; diff --git a/src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel.tsx b/src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel.tsx new file mode 100644 index 000000000..665bb0e74 --- /dev/null +++ b/src/components/Contacts/ContactsRightPanel/DynamicContactsRightPanel.tsx @@ -0,0 +1,10 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const DynamicContactsRightPanel = dynamic( + () => + import( + /* webpackChunkName: "ContactsRightPanel" */ './ContactsRightPanel' + ).then(({ ContactsRightPanel }) => ContactsRightPanel), + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/AddTags/DynamicMassActionsAddTagsModal.tsx b/src/components/Contacts/MassActions/AddTags/DynamicMassActionsAddTagsModal.tsx new file mode 100644 index 000000000..96d86c449 --- /dev/null +++ b/src/components/Contacts/MassActions/AddTags/DynamicMassActionsAddTagsModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsAddTagsModal = () => + import( + /* webpackChunkName: "MassActionsAddTagsModal" */ './MassActionsAddTagsModal' + ).then(({ MassActionsAddTagsModal }) => MassActionsAddTagsModal); + +export const DynamicMassActionsAddTagsModal = dynamic( + preloadMassActionsAddTagsModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/AddTags/MassActionsAddTagsModal.tsx b/src/components/Contacts/MassActions/AddTags/MassActionsAddTagsModal.tsx index d3ee96902..84005beca 100644 --- a/src/components/Contacts/MassActions/AddTags/MassActionsAddTagsModal.tsx +++ b/src/components/Contacts/MassActions/AddTags/MassActionsAddTagsModal.tsx @@ -15,6 +15,7 @@ import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import * as yup from 'yup'; import { ContactsDocument } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; +import { ContactTagIcon, ContactTagInput } from 'src/components/Tags/Tags'; import { CancelButton, SubmitButton, @@ -22,10 +23,6 @@ import { import { ContactUpdateInput } from 'src/graphql/types.generated'; import theme from 'src/theme'; import Modal from '../../../common/Modal/Modal'; -import { - ContactTagIcon, - ContactTagInput, -} from '../../ContactDetails/ContactDetailsTab/Tags/ContactTags'; import { useGetContactTagListQuery } from '../../ContactDetails/ContactDetailsTab/Tags/ContactTags.generated'; import { useContactsAddTagsMutation, diff --git a/src/components/Contacts/MassActions/AddToAppeal/DynamicMassActionsAddToAppealModal.tsx b/src/components/Contacts/MassActions/AddToAppeal/DynamicMassActionsAddToAppealModal.tsx new file mode 100644 index 000000000..2d16052f6 --- /dev/null +++ b/src/components/Contacts/MassActions/AddToAppeal/DynamicMassActionsAddToAppealModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsAddToAppealModal = () => + import( + /* webpackChunkName: "MassActionsAddToAppealModal" */ './MassActionsAddToAppealModal' + ).then(({ MassActionsAddToAppealModal }) => MassActionsAddToAppealModal); + +export const DynamicMassActionsAddToAppealModal = dynamic( + preloadMassActionsAddToAppealModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/AddToAppeal/DynamicMassActionsCreateAppealModal.tsx b/src/components/Contacts/MassActions/AddToAppeal/DynamicMassActionsCreateAppealModal.tsx new file mode 100644 index 000000000..9bb99f3f1 --- /dev/null +++ b/src/components/Contacts/MassActions/AddToAppeal/DynamicMassActionsCreateAppealModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsCreateAppealModal = () => + import( + /* webpackChunkName: "MassActionsCreateAppealModal" */ './MassActionsCreateAppealModal' + ).then(({ MassActionsCreateAppealModal }) => MassActionsCreateAppealModal); + +export const DynamicMassActionsCreateAppealModal = dynamic( + preloadMassActionsCreateAppealModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/EditFields/DynamicMassActionsEditFieldsModal.tsx b/src/components/Contacts/MassActions/EditFields/DynamicMassActionsEditFieldsModal.tsx new file mode 100644 index 000000000..2af618bf4 --- /dev/null +++ b/src/components/Contacts/MassActions/EditFields/DynamicMassActionsEditFieldsModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsEditFieldsModal = () => + import( + /* webpackChunkName: "MassActionsEditFieldsModal" */ './MassActionsEditFieldsModal' + ).then(({ MassActionsEditFieldsModal }) => MassActionsEditFieldsModal); + +export const DynamicMassActionsEditFieldsModal = dynamic( + preloadMassActionsEditFieldsModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/Exports/DynamicExportsModal.tsx b/src/components/Contacts/MassActions/Exports/DynamicExportsModal.tsx new file mode 100644 index 000000000..4af38e809 --- /dev/null +++ b/src/components/Contacts/MassActions/Exports/DynamicExportsModal.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadExportsModal = () => + import(/* webpackChunkName: "ExportsModal" */ './ExportsModal').then( + ({ ExportsModal }) => ExportsModal, + ); + +export const DynamicExportsModal = dynamic(preloadExportsModal, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/Contacts/MassActions/Exports/Emails/DynamicMassActionsExportEmailsModal.tsx b/src/components/Contacts/MassActions/Exports/Emails/DynamicMassActionsExportEmailsModal.tsx new file mode 100644 index 000000000..f0260010e --- /dev/null +++ b/src/components/Contacts/MassActions/Exports/Emails/DynamicMassActionsExportEmailsModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsExportEmailsModal = () => + import( + /* webpackChunkName: "MassActionsExportEmailsModal" */ './MassActionsExportEmailsModal' + ).then(({ MassActionsExportEmailsModal }) => MassActionsExportEmailsModal); + +export const DynamicMassActionsExportEmailsModal = dynamic( + preloadMassActionsExportEmailsModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/Exports/MailMergedLabelModal/DynamicMailMergedLabelModal.tsx b/src/components/Contacts/MassActions/Exports/MailMergedLabelModal/DynamicMailMergedLabelModal.tsx new file mode 100644 index 000000000..8e7ef9331 --- /dev/null +++ b/src/components/Contacts/MassActions/Exports/MailMergedLabelModal/DynamicMailMergedLabelModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMailMergedLabelModal = () => + import( + /* webpackChunkName: "MailMergedLabelModal" */ './MailMergedLabelModal' + ).then(({ MailMergedLabelModal }) => MailMergedLabelModal); + +export const DynamicMailMergedLabelModal = dynamic( + preloadMailMergedLabelModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/Merge/DynamicMassActionsMergeModal.tsx b/src/components/Contacts/MassActions/Merge/DynamicMassActionsMergeModal.tsx new file mode 100644 index 000000000..0fd9e3360 --- /dev/null +++ b/src/components/Contacts/MassActions/Merge/DynamicMassActionsMergeModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsMergeModal = () => + import( + /* webpackChunkName: "MassActionsMergeModal" */ './MassActionsMergeModal' + ).then(({ MassActionsMergeModal }) => MassActionsMergeModal); + +export const DynamicMassActionsMergeModal = dynamic( + preloadMassActionsMergeModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/Merge/MassActionsMergeModal.test.tsx b/src/components/Contacts/MassActions/Merge/MassActionsMergeModal.test.tsx index 8604374bc..1cb8f151a 100644 --- a/src/components/Contacts/MassActions/Merge/MassActionsMergeModal.test.tsx +++ b/src/components/Contacts/MassActions/Merge/MassActionsMergeModal.test.tsx @@ -4,13 +4,13 @@ import { queryByText, render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { ContactsContext, ContactsProvider, ContactsType, -} from 'pages/accountLists/[accountListId]/contacts/ContactsContext'; +} from 'src/components/Contacts/ContactsContext/ContactsContext'; import { StatusEnum } from 'src/graphql/types.generated'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../theme'; import { GetContactsForMergingQuery } from './MassActionsMerge.generated'; import { MassActionsMergeModal } from './MassActionsMergeModal'; diff --git a/src/components/Contacts/MassActions/Merge/MassActionsMergeModal.tsx b/src/components/Contacts/MassActions/Merge/MassActionsMergeModal.tsx index 51efb45bd..06c9b8e9f 100644 --- a/src/components/Contacts/MassActions/Merge/MassActionsMergeModal.tsx +++ b/src/components/Contacts/MassActions/Merge/MassActionsMergeModal.tsx @@ -17,14 +17,14 @@ import { SubmitButton, } from 'src/components/common/Modal/ActionButtons/ActionButtons'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormatShort } from 'src/lib/intlFormat/intlFormat'; +import { dateFormatShort } from 'src/lib/intlFormat'; import theme from 'src/theme'; import { getLocalizedContactStatus } from 'src/utils/functions/getLocalizedContactStatus'; +import Modal from '../../../common/Modal/Modal'; import { ContactsContext, ContactsType, -} from '../../../../../pages/accountLists/[accountListId]/contacts/ContactsContext'; -import Modal from '../../../common/Modal/Modal'; +} from '../../ContactsContext/ContactsContext'; import { useGetContactsForMergingQuery, useMassActionsMergeMutation, diff --git a/src/components/Contacts/MassActions/MergePeople/MergePeopleModal.test.tsx b/src/components/Contacts/MassActions/MergePeople/MergePeopleModal.test.tsx index 1dc8bf13b..2a4966a74 100644 --- a/src/components/Contacts/MassActions/MergePeople/MergePeopleModal.test.tsx +++ b/src/components/Contacts/MassActions/MergePeople/MergePeopleModal.test.tsx @@ -3,7 +3,7 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../theme'; import { MergePeopleModal } from './MergePeopleModal'; diff --git a/src/components/Contacts/MassActions/RemoveTags/DynamicMassActionsRemoveTagsModal.tsx b/src/components/Contacts/MassActions/RemoveTags/DynamicMassActionsRemoveTagsModal.tsx new file mode 100644 index 000000000..78f1b4823 --- /dev/null +++ b/src/components/Contacts/MassActions/RemoveTags/DynamicMassActionsRemoveTagsModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsRemoveTagsModal = () => + import( + /* webpackChunkName: "MassActionsRemoveTagsModal" */ './MassActionsRemoveTagsModal' + ).then(({ MassActionsRemoveTagsModal }) => MassActionsRemoveTagsModal); + +export const DynamicMassActionsRemoveTagsModal = dynamic( + preloadMassActionsRemoveTagsModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Contacts/MassActions/RemoveTags/MassActionsRemoveTagsModal.test.tsx b/src/components/Contacts/MassActions/RemoveTags/MassActionsRemoveTagsModal.test.tsx index 225e2b4e4..414930275 100644 --- a/src/components/Contacts/MassActions/RemoveTags/MassActionsRemoveTagsModal.test.tsx +++ b/src/components/Contacts/MassActions/RemoveTags/MassActionsRemoveTagsModal.test.tsx @@ -5,7 +5,7 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../theme'; import { MassActionsRemoveTagsModal } from './MassActionsRemoveTagsModal'; diff --git a/src/components/Contacts/StarContactIconButton/StarContactIconButton.stories.tsx b/src/components/Contacts/StarContactIconButton/StarContactIconButton.stories.tsx index 26ac27c94..6918f41a7 100644 --- a/src/components/Contacts/StarContactIconButton/StarContactIconButton.stories.tsx +++ b/src/components/Contacts/StarContactIconButton/StarContactIconButton.stories.tsx @@ -1,5 +1,5 @@ import React, { ReactElement } from 'react'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { SetContactStarredMutation } from './SetContactStarred.generated'; import { StarContactIconButton } from './StarContactIconButton'; diff --git a/src/components/Contacts/StarContactIconButton/StarContactIconButton.test.tsx b/src/components/Contacts/StarContactIconButton/StarContactIconButton.test.tsx index dd51460d9..05129ac39 100644 --- a/src/components/Contacts/StarContactIconButton/StarContactIconButton.test.tsx +++ b/src/components/Contacts/StarContactIconButton/StarContactIconButton.test.tsx @@ -3,7 +3,7 @@ import { ThemeProvider } from '@mui/material/styles'; import { waitFor } from '@testing-library/dom'; import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../theme'; import { StarContactIconButton } from './StarContactIconButton'; diff --git a/src/components/Dashboard/Balance/Balance.test.tsx b/src/components/Dashboard/Balance/Balance.test.tsx index 3b0d34bf1..b60911100 100644 --- a/src/components/Dashboard/Balance/Balance.test.tsx +++ b/src/components/Dashboard/Balance/Balance.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import Balance from '.'; jest.mock('next/router', () => ({ diff --git a/src/components/Dashboard/Balance/Balance.tsx b/src/components/Dashboard/Balance/Balance.tsx index d7010a1da..207986cf7 100644 --- a/src/components/Dashboard/Balance/Balance.tsx +++ b/src/components/Dashboard/Balance/Balance.tsx @@ -5,10 +5,10 @@ import { Button, CardActions, CardContent, + Skeleton, Theme, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { useAccountListId } from 'src/hooks/useAccountListId'; diff --git a/src/components/Dashboard/Dashboard.stories.tsx b/src/components/Dashboard/Dashboard.stories.tsx index decc4cc5e..67f1a5180 100644 --- a/src/components/Dashboard/Dashboard.stories.tsx +++ b/src/components/Dashboard/Dashboard.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; -import { GetDashboardQuery } from '../../../pages/accountLists/GetDashboard.generated'; +import { GetDashboardQuery } from 'pages/accountLists/GetDashboard.generated'; import { GetThisWeekDefaultMocks } from './ThisWeek/ThisWeek.mock'; import Dashboard from '.'; diff --git a/src/components/Dashboard/Dashboard.test.tsx b/src/components/Dashboard/Dashboard.test.tsx index f7b6bce86..de12a92a2 100644 --- a/src/components/Dashboard/Dashboard.test.tsx +++ b/src/components/Dashboard/Dashboard.test.tsx @@ -3,12 +3,12 @@ import { MockedProvider } from '@apollo/client/testing'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import { SnackbarProvider } from 'notistack'; -import matchMediaMock from '../../../__tests__/util/matchMediaMock'; +import matchMediaMock from '__tests__/util/matchMediaMock'; import { afterTestResizeObserver, beforeTestResizeObserver, -} from '../../../__tests__/util/windowResizeObserver'; -import { GetDashboardQuery } from '../../../pages/accountLists/GetDashboard.generated'; +} from '__tests__/util/windowResizeObserver'; +import { GetDashboardQuery } from 'pages/accountLists/GetDashboard.generated'; import useTaskModal from '../../hooks/useTaskModal'; import theme from '../../theme'; import { GetThisWeekDefaultMocks } from './ThisWeek/ThisWeek.mock'; @@ -27,6 +27,7 @@ jest.mock('next/router', () => ({ beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal: jest.fn(), + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Dashboard/Dashboard.tsx b/src/components/Dashboard/Dashboard.tsx index 8a09c7fe3..a0abbdf05 100644 --- a/src/components/Dashboard/Dashboard.tsx +++ b/src/components/Dashboard/Dashboard.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from 'react'; import { Box, Container, Grid } from '@mui/material'; import { motion } from 'framer-motion'; -import { GetDashboardQuery } from '../../../pages/accountLists/GetDashboard.generated'; +import { GetDashboardQuery } from 'pages/accountLists/GetDashboard.generated'; import Balance from './Balance'; import DonationHistories from './DonationHistories'; import MonthlyGoal from './MonthlyGoal/MonthlyGoal'; diff --git a/src/components/Dashboard/DonationHistories/DonationHistories.tsx b/src/components/Dashboard/DonationHistories/DonationHistories.tsx index bdc779424..581685c8b 100644 --- a/src/components/Dashboard/DonationHistories/DonationHistories.tsx +++ b/src/components/Dashboard/DonationHistories/DonationHistories.tsx @@ -5,10 +5,10 @@ import { CardContent, CardHeader, Grid, + Skeleton, Theme, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { diff --git a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.test.tsx b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.test.tsx index 8fe63bc1f..ca2f2c32b 100644 --- a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.test.tsx +++ b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import matchMediaMock from '../../../../__tests__/util/matchMediaMock'; +import matchMediaMock from '__tests__/util/matchMediaMock'; import MonthlyGoal from './MonthlyGoal'; describe('MonthlyGoal', () => { diff --git a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.tsx b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.tsx index c8e06e74f..ffe4040c3 100644 --- a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.tsx +++ b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.tsx @@ -5,10 +5,10 @@ import { CardContent, Grid, Hidden, + Skeleton, Theme, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { diff --git a/src/components/Dashboard/ThisWeek/Appeals/Appeals.test.tsx b/src/components/Dashboard/ThisWeek/Appeals/Appeals.test.tsx index e3e810e18..d43edf7f8 100644 --- a/src/components/Dashboard/ThisWeek/Appeals/Appeals.test.tsx +++ b/src/components/Dashboard/ThisWeek/Appeals/Appeals.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import Appeals from '.'; jest.mock('next/router', () => ({ diff --git a/src/components/Dashboard/ThisWeek/Appeals/Appeals.tsx b/src/components/Dashboard/ThisWeek/Appeals/Appeals.tsx index 962fd90bd..1c2d2f55e 100644 --- a/src/components/Dashboard/ThisWeek/Appeals/Appeals.tsx +++ b/src/components/Dashboard/ThisWeek/Appeals/Appeals.tsx @@ -7,10 +7,10 @@ import { CardHeader, Grid, Link, + Skeleton, Theme, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { motion } from 'framer-motion'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; diff --git a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.test.tsx b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.test.tsx index 9148e18bc..a533e7dff 100644 --- a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.test.tsx +++ b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; -import { render } from '../../../../../__tests__/util/testingLibraryReactMock'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render } from '__tests__/util/testingLibraryReactMock'; import LateCommitments from './LateCommitments'; jest.mock('next/router', () => ({ diff --git a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.tsx b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.tsx index 06ebdc141..94afa4d42 100644 --- a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.tsx +++ b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.tsx @@ -8,8 +8,8 @@ import { List, ListItem, ListItemText, + Skeleton, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { styled } from '@mui/material/styles'; import { motion } from 'framer-motion'; import { DateTime } from 'luxon'; @@ -23,7 +23,7 @@ import { } from 'src/graphql/types.generated'; import { useAccountListId } from 'src/hooks/useAccountListId'; import { useLocale } from 'src/hooks/useLocale'; -import { numberFormat } from 'src/lib/intlFormat/intlFormat'; +import { numberFormat } from 'src/lib/intlFormat'; import illustration14 from '../../../../images/drawkit/grape/drawkit-grape-pack-illustration-14.svg'; import AnimatedCard from '../../../AnimatedCard'; import { GetThisWeekQuery } from '../GetThisWeek.generated'; diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/DynamicExportEmail.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/DynamicExportEmail.tsx new file mode 100644 index 000000000..9a542182d --- /dev/null +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/DynamicExportEmail.tsx @@ -0,0 +1,9 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadExportEmail = () => + import(/* webpackChunkName: "ExportEmail" */ './ExportEmail'); + +export const DynamicExportEmail = dynamic(preloadExportEmail, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.stories.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.stories.tsx index 84f491fa8..b8dbee590 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.stories.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import ExportEmail from './ExportEmail'; import { GetEmailNewsletterContactsDocument, diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.test.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.test.tsx index eee07fa87..12847e786 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.test.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../../../theme'; import ExportEmail from './ExportEmail'; import { GetEmailNewsletterContactsQuery } from './GetNewsletterContacts.generated'; diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.tsx index d744e178e..75ea51492 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportEmail/ExportEmail.tsx @@ -7,9 +7,9 @@ import { DialogContentText, DialogTitle, IconButton, + Skeleton, TextareaAutosize, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { useFetchAllPages } from 'src/hooks/useFetchAllPages'; diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/DynamicExportPhysical.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/DynamicExportPhysical.tsx new file mode 100644 index 000000000..6893c29f1 --- /dev/null +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/DynamicExportPhysical.tsx @@ -0,0 +1,9 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadExportPhysical = () => + import(/* webpackChunkName: "ExportPhysical" */ './ExportPhysical'); + +export const DynamicExportPhysical = dynamic(preloadExportPhysical, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/ExportPhysical.stories.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/ExportPhysical.stories.tsx index bf132f94b..ff828397d 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/ExportPhysical.stories.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/ExportPhysical.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { SessionProvider } from 'next-auth/react'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import ExportPhysical from './ExportPhysical'; export default { diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/ExportPhysical.test.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/ExportPhysical.test.tsx index 9f76e94b8..0d789f81c 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/ExportPhysical.test.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/ExportPhysical/ExportPhysical.test.tsx @@ -2,12 +2,12 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { ExportFormatEnum, ExportLabelTypeEnum, ExportSortEnum, } from 'src/graphql/types.generated'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../../../theme'; import ExportPhysical from './ExportPhysical'; import { CreateExportedContactsMutation } from './ExportPhysical.generated'; diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/DynamicLogNewsletter.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/DynamicLogNewsletter.tsx new file mode 100644 index 000000000..5cccf7ffb --- /dev/null +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/DynamicLogNewsletter.tsx @@ -0,0 +1,9 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadLogNewsletter = () => + import(/* webpackChunkName: "LogNewsletter" */ './LogNewsletter'); + +export const DynamicLogNewsletter = dynamic(preloadLogNewsletter, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/LogNewsletter.stories.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/LogNewsletter.stories.tsx index 31bbc570c..560d20994 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/LogNewsletter.stories.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/LogNewsletter.stories.tsx @@ -1,5 +1,5 @@ import React, { ReactElement } from 'react'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import LogNewsletter from './LogNewsletter'; export default { diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/LogNewsletter.test.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/LogNewsletter.test.tsx index 4d57ba2c2..4f7fd08d3 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/LogNewsletter.test.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/MenuItems/LogNewsLetter/LogNewsletter.test.tsx @@ -6,9 +6,9 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { Settings } from 'luxon'; import { SnackbarProvider } from 'notistack'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { ActivityTypeEnum } from 'src/graphql/types.generated'; -import TestWrapper from '../../../../../../../__tests__/util/TestWrapper'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../../../theme'; import { createNewsletterTaskMutationMock } from './LogNewsLetter.mock'; import LogNewsletter from './LogNewsletter'; diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.stories.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.stories.tsx index 0395b4b4b..10e020edc 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.stories.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.stories.tsx @@ -1,7 +1,7 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; import { GraphQLError } from 'graphql'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { GetEmailNewsletterContactsDocument, GetEmailNewsletterContactsQuery, diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.test.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.test.tsx index 6bbc6307a..49ae4b3c2 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.test.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import NewsletterMenu from './NewsletterMenu'; import { GetTaskAnalyticsQuery } from './NewsletterMenu.generated'; diff --git a/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.tsx b/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.tsx index f0807ce84..e16c5b85c 100644 --- a/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.tsx +++ b/src/components/Dashboard/ThisWeek/NewsletterMenu/NewsletterMenu.tsx @@ -1,15 +1,30 @@ import React, { ReactElement, useState } from 'react'; import ArrowDropDown from '@mui/icons-material/ArrowDropDown'; -import { Button, Dialog, ListItemText, Menu, MenuItem } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { + Button, + Dialog, + ListItemText, + Menu, + MenuItem, + Skeleton, +} from '@mui/material'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormat } from 'src/lib/intlFormat/intlFormat'; -import ExportEmail from './MenuItems/ExportEmail/ExportEmail'; -import ExportPhysical from './MenuItems/ExportPhysical/ExportPhysical'; -import LogNewsletter from './MenuItems/LogNewsLetter/LogNewsletter'; +import { dateFormat } from 'src/lib/intlFormat'; +import { + DynamicExportEmail, + preloadExportEmail, +} from './MenuItems/ExportEmail/DynamicExportEmail'; +import { + DynamicExportPhysical, + preloadExportPhysical, +} from './MenuItems/ExportPhysical/DynamicExportPhysical'; +import { + DynamicLogNewsletter, + preloadLogNewsletter, +} from './MenuItems/LogNewsLetter/DynamicLogNewsletter'; import { useGetTaskAnalyticsQuery } from './NewsletterMenu.generated'; interface Props { @@ -85,21 +100,21 @@ const NewsletterMenu = ({ accountListId }: Props): ReactElement => { switch (selectedMenuItem) { case 0: return ( - ); case 1: return ( - ); case 2: return ( - @@ -153,13 +168,22 @@ const NewsletterMenu = ({ accountListId }: Props): ReactElement => { anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} transformOrigin={{ vertical: 'top', horizontal: 'center' }} > - handleMenuItemClick(0)}> + handleMenuItemClick(0)} + onMouseEnter={preloadLogNewsletter} + > - handleMenuItemClick(1)}> + handleMenuItemClick(1)} + onMouseEnter={preloadExportEmail} + > - handleMenuItemClick(2)}> + handleMenuItemClick(2)} + onMouseEnter={preloadExportPhysical} + > diff --git a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.test.tsx b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.test.tsx index 94266e54b..53f6d54c6 100644 --- a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.test.tsx +++ b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.test.tsx @@ -1,11 +1,8 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; +import { fireEvent, render } from '__tests__/util/testingLibraryReactMock'; import { ActivityTypeEnum } from 'src/graphql/types.generated'; -import { - fireEvent, - render, -} from '../../../../../__tests__/util/testingLibraryReactMock'; import useTaskModal from '../../../../hooks/useTaskModal'; import theme from '../../../../theme'; import { GetThisWeekQuery } from '../GetThisWeek.generated'; @@ -18,6 +15,7 @@ const openTaskModal = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); const prayerRequestTasks: GetThisWeekQuery['prayerRequestTasks'] = { diff --git a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.tsx b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.tsx index d1f2a3b92..cc0b85c01 100644 --- a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.tsx +++ b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.tsx @@ -17,11 +17,11 @@ import { ListItemIcon, ListItemSecondaryAction, ListItemText, + Skeleton, Tab, Tabs, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { styled } from '@mui/material/styles'; import { motion } from 'framer-motion'; import { useTranslation } from 'react-i18next'; @@ -143,7 +143,7 @@ const PartnerCare = ({ const { t } = useTranslation(); const locale = useLocale(); const [value, setValue] = useState(0); - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const handleClick = ({ id: taskId, @@ -467,6 +467,7 @@ const PartnerCare = ({ person, ) } + onMouseEnter={() => preloadTaskModal('add')} > diff --git a/src/components/Dashboard/ThisWeek/Referrals/Referrals.test.tsx b/src/components/Dashboard/ThisWeek/Referrals/Referrals.test.tsx index 467380725..e78c86fa9 100644 --- a/src/components/Dashboard/ThisWeek/Referrals/Referrals.test.tsx +++ b/src/components/Dashboard/ThisWeek/Referrals/Referrals.test.tsx @@ -1,9 +1,6 @@ import React from 'react'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; -import { - fireEvent, - render, -} from '../../../../../__tests__/util/testingLibraryReactMock'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { fireEvent, render } from '__tests__/util/testingLibraryReactMock'; import Referrals from '.'; jest.mock('next/router', () => ({ diff --git a/src/components/Dashboard/ThisWeek/Referrals/Referrals.tsx b/src/components/Dashboard/ThisWeek/Referrals/Referrals.tsx index 8e03dedca..d6f728886 100644 --- a/src/components/Dashboard/ThisWeek/Referrals/Referrals.tsx +++ b/src/components/Dashboard/ThisWeek/Referrals/Referrals.tsx @@ -9,12 +9,12 @@ import { ListItem, ListItemSecondaryAction, ListItemText, + Skeleton, Tab, Tabs, Theme, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { motion } from 'framer-motion'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; @@ -22,7 +22,7 @@ import { makeStyles } from 'tss-react/mui'; import { StatusEnum } from 'src/graphql/types.generated'; import { useAccountListId } from 'src/hooks/useAccountListId'; import { useLocale } from 'src/hooks/useLocale'; -import { numberFormat } from 'src/lib/intlFormat/intlFormat'; +import { numberFormat } from 'src/lib/intlFormat'; import illustration4 from '../../../../images/drawkit/grape/drawkit-grape-pack-illustration-4.svg'; import AnimatedCard from '../../../AnimatedCard'; import { GetThisWeekQuery } from '../GetThisWeek.generated'; diff --git a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.test.tsx b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.test.tsx index 6fa12d9ec..0e033b2ca 100644 --- a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.test.tsx +++ b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.test.tsx @@ -2,9 +2,9 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render } from '__tests__/util/testingLibraryReactMock'; import { LoadConstantsQuery } from 'src/components/Constants/LoadConstants.generated'; import { ActivityTypeEnum } from 'src/graphql/types.generated'; -import { render } from '../../../../../__tests__/util/testingLibraryReactMock'; import useTaskModal from '../../../../hooks/useTaskModal'; import theme from '../../../../theme'; import { GetThisWeekQuery } from '../GetThisWeek.generated'; @@ -17,6 +17,7 @@ const openTaskModal = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.tsx b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.tsx index 1bcc485f6..62fb05e3e 100644 --- a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.tsx +++ b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.tsx @@ -10,10 +10,10 @@ import { ListItem, ListItemSecondaryAction, ListItemText, + Skeleton, Theme, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { motion } from 'framer-motion'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; @@ -22,7 +22,7 @@ import { useLoadConstantsQuery } from 'src/components/Constants/LoadConstants.ge import { ActivityTypeEnum } from 'src/graphql/types.generated'; import { useLocale } from 'src/hooks/useLocale'; import useTaskModal from 'src/hooks/useTaskModal'; -import { numberFormat } from 'src/lib/intlFormat/intlFormat'; +import { numberFormat } from 'src/lib/intlFormat'; import { constantIdFromActivityType } from 'src/utils/tasks/taskActivity'; import illustration8 from '../../../../images/drawkit/grape/drawkit-grape-pack-illustration-8.svg'; import AnimatedCard from '../../../AnimatedCard'; @@ -77,7 +77,7 @@ const TasksDueThisWeek = ({ const { classes } = useStyles(); const { t } = useTranslation(); const locale = useLocale(); - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const { data } = useLoadConstantsQuery(); const [activityTypes, setActivityTypes] = React.useState( data?.constant.activities, @@ -156,6 +156,7 @@ const TasksDueThisWeek = ({ button data-testid={`TasksDueThisWeekListItem-${task.id}`} onClick={(): void => handleClick(task)} + onMouseEnter={() => preloadTaskModal('edit')} > ({ beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal: jest.fn(), + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.tsx b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.tsx index 570b3600f..8780953b5 100644 --- a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.tsx +++ b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.tsx @@ -7,6 +7,7 @@ import { CardActions, CardHeader, IconButton, + Skeleton, Table, TableBody, TableCell, @@ -15,16 +16,19 @@ import { TableRow, Theme, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { styled } from '@mui/material/styles'; import { motion } from 'framer-motion'; import { DateTime, Interval } from 'luxon'; import { useTranslation } from 'react-i18next'; -import { makeStyles, withStyles } from 'tss-react/mui'; +import { makeStyles } from 'tss-react/mui'; import { useLocale } from 'src/hooks/useLocale'; import { numberFormat } from '../../../../lib/intlFormat'; import AnimatedCard from '../../../AnimatedCard'; import { useGetWeeklyActivityQuery } from './GetWeeklyActivity.generated'; -import { WeeklyReportModal } from './WeeklyReportModal/WeeklyReportModal'; +import { + DynamicWeeklyReportModal, + preloadWeeklyReportModal, +} from './WeeklyReportModal/DynamicWeeklyReportModal'; const useStyles = makeStyles()((theme: Theme) => ({ div: { @@ -58,12 +62,9 @@ interface Props { accountListId: string; } -const StyledTableCell = withStyles(TableCell, () => ({ - root: { - paddingLeft: 4, - paddingRight: 4, - }, -})); +const StyledTableCell = styled(TableCell)({ + paddingInline: 4, +}); const WeeklyActivity = ({ accountListId }: Props): ReactElement => { const { classes } = useStyles(); @@ -258,14 +259,21 @@ const WeeklyActivity = ({ accountListId }: Props): ReactElement => { {t('View Activity Detail')} - - + {openWeeklyReportModal && ( + + )} diff --git a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyReportModal/DynamicWeeklyReportModal.tsx b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyReportModal/DynamicWeeklyReportModal.tsx new file mode 100644 index 000000000..6bd8c2578 --- /dev/null +++ b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyReportModal/DynamicWeeklyReportModal.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadWeeklyReportModal = () => + import( + /* webpackChunkName: "WeeklyReportModal" */ './WeeklyReportModal' + ).then(({ WeeklyReportModal }) => WeeklyReportModal); + +export const DynamicWeeklyReportModal = dynamic(preloadWeeklyReportModal, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/Dashboard/Welcome/Welcome.test.tsx b/src/components/Dashboard/Welcome/Welcome.test.tsx index 77c52a091..2599858c1 100644 --- a/src/components/Dashboard/Welcome/Welcome.test.tsx +++ b/src/components/Dashboard/Welcome/Welcome.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { Settings } from 'luxon'; -import { render } from '../../../../__tests__/util/testingLibraryReactMock'; +import { render } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../theme'; import Welcome from '.'; diff --git a/src/components/DynamicPlaceholders/DynamicComponentPlaceholder.tsx b/src/components/DynamicPlaceholders/DynamicComponentPlaceholder.tsx new file mode 100644 index 000000000..a5bd6f670 --- /dev/null +++ b/src/components/DynamicPlaceholders/DynamicComponentPlaceholder.tsx @@ -0,0 +1,7 @@ +import { Box, CircularProgress } from '@mui/material'; + +export const DynamicComponentPlaceholder: React.FC = () => ( + + + +); diff --git a/src/components/EditDonationModal/DynamicEditDonationModal.tsx b/src/components/EditDonationModal/DynamicEditDonationModal.tsx new file mode 100644 index 000000000..9d10ecbec --- /dev/null +++ b/src/components/EditDonationModal/DynamicEditDonationModal.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadEditDonationModal = () => + import( + /* webpackChunkName: "EditDonationModal" */ './EditDonationModal' + ).then(({ EditDonationModal }) => EditDonationModal); + +export const DynamicEditDonationModal = dynamic(preloadEditDonationModal, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/HandoffLink/HandoffLink.test.tsx b/src/components/HandoffLink/HandoffLink.test.tsx index 26fe314fc..0ab0ba635 100644 --- a/src/components/HandoffLink/HandoffLink.test.tsx +++ b/src/components/HandoffLink/HandoffLink.test.tsx @@ -2,7 +2,7 @@ import * as nextRouter from 'next/router'; import React from 'react'; import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { GqlMockedProvider } from '../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import HandoffLink from '.'; describe('HandoffLink', () => { diff --git a/src/components/InfiniteList/InfiniteList.tsx b/src/components/InfiniteList/InfiniteList.tsx index 77a7fb874..28532a697 100644 --- a/src/components/InfiniteList/InfiniteList.tsx +++ b/src/components/InfiniteList/InfiniteList.tsx @@ -1,6 +1,5 @@ import React, { ReactElement, useMemo } from 'react'; -import { List, ListItem, Typography } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; +import { List, ListItem, Skeleton, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { GroupedVirtuoso, diff --git a/src/components/Layouts/Basic/TopBar/TopBar.test.tsx b/src/components/Layouts/Basic/TopBar/TopBar.test.tsx index 9d77bad41..a17e6359b 100644 --- a/src/components/Layouts/Basic/TopBar/TopBar.test.tsx +++ b/src/components/Layouts/Basic/TopBar/TopBar.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; -import TestRouter from '../../../../../__tests__/util/TestRouter'; +import TestRouter from '__tests__/util/TestRouter'; import theme from '../../../../theme'; import TopBar from '.'; diff --git a/src/components/Layouts/Primary/NavBar/NavItem/NavItem.tsx b/src/components/Layouts/Primary/NavBar/NavItem/NavItem.tsx index 7465042c8..d796249ff 100644 --- a/src/components/Layouts/Primary/NavBar/NavItem/NavItem.tsx +++ b/src/components/Layouts/Primary/NavBar/NavItem/NavItem.tsx @@ -6,6 +6,7 @@ import ExpandLessIcon from '@mui/icons-material/ExpandLess'; import { Button, Collapse, ListItemButton } from '@mui/material'; import { styled, useTheme } from '@mui/material/styles'; import HandoffLink from 'src/components/HandoffLink'; +import { LeafButton, LeafListItem, Title } from '../StyledComponents'; interface NavItemProps { children?: ReactNode; @@ -18,19 +19,13 @@ interface NavItemProps { title: string; } -export const StyledListItem = styled(ListItemButton)(() => ({ +const StyledListItem = styled(ListItemButton)(() => ({ display: 'block', paddingTop: 0, paddingBottom: 0, })); -export const LeafListItem = styled(ListItemButton)(() => ({ - display: 'flex', - paddingTop: 0, - paddingBottom: 0, -})); - -export const StyledButton = styled(Button)(({ theme }) => ({ +const StyledButton = styled(Button)(({ theme }) => ({ color: theme.palette.common.white, padding: '10px 8px', justifyContent: 'flex-start', @@ -40,31 +35,14 @@ export const StyledButton = styled(Button)(({ theme }) => ({ width: '100%', })); -export const LeafButton = styled(Button)(({ theme }) => ({ - color: theme.palette.text.secondary, - padding: '10px 8px', - justifyContent: 'flex-start', - textTransform: 'none', - letterSpacing: 0, - width: '100%', -})); - -export const ExpandItemIcon = styled(ExpandLessIcon)(({ theme }) => ({ +const ExpandItemIcon = styled(ExpandLessIcon)(({ theme }) => ({ color: theme.palette.cruGrayMedium.main, })); -export const CollapseItemIcon = styled(ChevronRightIcon)(({ theme }) => ({ +const CollapseItemIcon = styled(ChevronRightIcon)(({ theme }) => ({ color: theme.palette.cruGrayMedium.main, })); -export const Title = styled('span')(({ theme }) => ({ - color: theme.palette.common.white, - fontSize: 16, - marginRight: 'auto', - textAlign: 'left', - lineHeight: 1.5, -})); - export const NavItem: FC = ({ children, depth = 0, diff --git a/src/components/Layouts/Primary/NavBar/NavTools/AddMenuPanel/AddMenuPanel.tsx b/src/components/Layouts/Primary/NavBar/NavTools/AddMenuPanel/AddMenuPanel.tsx index e6aa50e9e..1a5c518c7 100644 --- a/src/components/Layouts/Primary/NavBar/NavTools/AddMenuPanel/AddMenuPanel.tsx +++ b/src/components/Layouts/Primary/NavBar/NavTools/AddMenuPanel/AddMenuPanel.tsx @@ -12,20 +12,24 @@ import { renderDialog, } from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu'; import useTaskModal from 'src/hooks/useTaskModal'; -import { LeafButton, LeafListItem, Title } from '../../NavItem/NavItem'; +import { preloadAddDonation } from '../../../TopBar/Items/AddMenu/Items/AddDonation/DynamicAddDonation'; +import { preloadCreateContact } from '../../../TopBar/Items/AddMenu/Items/CreateContact/DynamicCreateContact'; +import { preloadCreateMultipleContacts } from '../../../TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContacts'; +import { LeafButton, LeafListItem, Title } from '../../StyledComponents'; type MenuContent = { text: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any icon: any; onClick: () => void; + onMouseEnter: () => void; }; export const AddMenuPanel = (): ReactElement => { const [selectedMenuItem, changeSelectedMenuItem] = useState(null); const [dialogOpen, changeDialogOpen] = useState(false); - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const theme = useTheme(); const { t } = useTranslation(); @@ -37,6 +41,7 @@ export const AddMenuPanel = (): ReactElement => { changeSelectedMenuItem(AddMenuItemsEnum.NewContact); changeDialogOpen(true); }, + onMouseEnter: preloadCreateContact, }, { text: 'Add Multiple Contacts', @@ -45,6 +50,7 @@ export const AddMenuPanel = (): ReactElement => { changeSelectedMenuItem(AddMenuItemsEnum.MultipleContacts); changeDialogOpen(true); }, + onMouseEnter: preloadCreateMultipleContacts, }, { text: 'Add Donation', @@ -53,6 +59,7 @@ export const AddMenuPanel = (): ReactElement => { changeSelectedMenuItem(AddMenuItemsEnum.AddDonation); changeDialogOpen(true); }, + onMouseEnter: preloadAddDonation, }, { text: 'Add Task', @@ -60,12 +67,15 @@ export const AddMenuPanel = (): ReactElement => { onClick: () => { openTaskModal({ view: 'add' }); }, + onMouseEnter: () => preloadTaskModal('add'), }, { text: 'Log Task', icon: EditIcon, - // eslint-disable-next-line no-console - onClick: () => console.log('log task'), + onClick: () => { + openTaskModal({ view: 'log' }); + }, + onMouseEnter: () => preloadTaskModal('log'), }, ]; @@ -79,14 +89,21 @@ export const AddMenuPanel = (): ReactElement => { return ( <> - {addMenuContent.map(({ text, icon: Icon, onClick }, index) => ( - - - - {t(text)} - - - ))} + {addMenuContent.map( + ({ text, icon: Icon, onClick, onMouseEnter }, index) => ( + + + + {t(text)} + + + ), + )} {renderDialog(selectedMenuItem, dialogOpen, changeDialogOpen)} diff --git a/src/components/Layouts/Primary/NavBar/NavTools/ProfileMenuPanel/ProfileMenuPanel.test.tsx b/src/components/Layouts/Primary/NavBar/NavTools/ProfileMenuPanel/ProfileMenuPanel.test.tsx index 7dd7591ac..f38295459 100644 --- a/src/components/Layouts/Primary/NavBar/NavTools/ProfileMenuPanel/ProfileMenuPanel.test.tsx +++ b/src/components/Layouts/Primary/NavBar/NavTools/ProfileMenuPanel/ProfileMenuPanel.test.tsx @@ -3,8 +3,8 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { signOut } from 'next-auth/react'; -import TestRouter from '../../../../../../../__tests__/util/TestRouter'; -import TestWrapper from '../../../../../../../__tests__/util/TestWrapper'; +import TestRouter from '__tests__/util/TestRouter'; +import TestWrapper from '__tests__/util/TestWrapper'; import theme from '../../../../../../theme'; import { getTopBarMock } from '../../../TopBar/TopBar.mock'; import { ProfileMenuPanel } from './ProfileMenuPanel'; diff --git a/src/components/Layouts/Primary/NavBar/NavTools/ProfileMenuPanel/ProfileMenuPanel.tsx b/src/components/Layouts/Primary/NavBar/NavTools/ProfileMenuPanel/ProfileMenuPanel.tsx index 0ec34ecff..0b9877b3b 100644 --- a/src/components/Layouts/Primary/NavBar/NavTools/ProfileMenuPanel/ProfileMenuPanel.tsx +++ b/src/components/Layouts/Primary/NavBar/NavTools/ProfileMenuPanel/ProfileMenuPanel.tsx @@ -13,7 +13,7 @@ import { useAccountListId } from '../../../../../../hooks/useAccountListId'; import theme from '../../../../../../theme'; import HandoffLink from '../../../../../HandoffLink'; import { useGetTopBarQuery } from '../../../TopBar/GetTopBar.generated'; -import { LeafListItem, Title } from '../../NavItem/NavItem'; +import { LeafListItem, Title } from '../../StyledComponents'; type ProfileMenuContent = { text: string; diff --git a/src/components/Layouts/Primary/NavBar/StyledComponents.ts b/src/components/Layouts/Primary/NavBar/StyledComponents.ts new file mode 100644 index 000000000..3921b2357 --- /dev/null +++ b/src/components/Layouts/Primary/NavBar/StyledComponents.ts @@ -0,0 +1,25 @@ +import { Button, ListItemButton } from '@mui/material'; +import { styled } from '@mui/material/styles'; + +export const LeafListItem = styled(ListItemButton)(() => ({ + display: 'flex', + paddingTop: 0, + paddingBottom: 0, +})); + +export const LeafButton = styled(Button)(({ theme }) => ({ + color: theme.palette.text.secondary, + padding: '10px 8px', + justifyContent: 'flex-start', + textTransform: 'none', + letterSpacing: 0, + width: '100%', +})); + +export const Title = styled('span')(({ theme }) => ({ + color: theme.palette.common.white, + fontSize: 16, + marginRight: 'auto', + textAlign: 'left', + lineHeight: 1.5, +})); diff --git a/src/components/Layouts/Primary/Primary.test.tsx b/src/components/Layouts/Primary/Primary.test.tsx index 99bbf3808..5d1ecf2aa 100644 --- a/src/components/Layouts/Primary/Primary.test.tsx +++ b/src/components/Layouts/Primary/Primary.test.tsx @@ -2,8 +2,8 @@ import * as nextRouter from 'next/router'; import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; -import matchMediaMock from '../../../../__tests__/util/matchMediaMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import matchMediaMock from '__tests__/util/matchMediaMock'; import theme from '../../../theme'; import { getNotificationsMocks } from './TopBar/Items/NotificationMenu/NotificationMenu.mock'; import { getTopBarMock } from './TopBar/TopBar.mock'; diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu.test.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu.test.tsx index cc8277867..417604d02 100644 --- a/src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu.test.tsx @@ -3,8 +3,8 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import TestRouter from '../../../../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import useTaskModal from '../../../../../../hooks/useTaskModal'; import theme from '../../../../../../theme'; import AddMenu from './AddMenu'; @@ -23,6 +23,7 @@ describe('AddMenu', () => { beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu.tsx index 5ae70bb38..bab5c0624 100644 --- a/src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/AddMenu.tsx @@ -11,9 +11,18 @@ import { useTranslation } from 'react-i18next'; import { useAccountListId } from '../../../../../../hooks/useAccountListId'; import useTaskModal from '../../../../../../hooks/useTaskModal'; import Modal from '../../../../../common/Modal/Modal'; -import { AddDonation } from './Items/AddDonation/AddDonation'; -import CreateContact from './Items/CreateContact/CreateContact'; -import { CreateMultipleContacts } from './Items/CreateMultipleContacts/CreateMultipleContacts'; +import { + DynamicAddDonation, + preloadAddDonation, +} from './Items/AddDonation/DynamicAddDonation'; +import { + DynamicCreateContact, + preloadCreateContact, +} from './Items/CreateContact/DynamicCreateContact'; +import { + DynamicCreateMultipleContacts, + preloadCreateMultipleContacts, +} from './Items/CreateMultipleContacts/DynamicCreateMultipleContacts'; interface AddMenuProps { isInDrawer?: boolean; @@ -24,6 +33,7 @@ type AddMenuItem = { // eslint-disable-next-line @typescript-eslint/no-explicit-any icon: any; onClick: () => void; + onMouseEnter: () => void; }; export enum AddMenuItemsEnum { @@ -102,21 +112,21 @@ export const renderDialog = ( switch (selectedMenuItem) { case AddMenuItemsEnum.NewContact: return ( - ); case AddMenuItemsEnum.MultipleContacts: return ( - ); case AddMenuItemsEnum.AddDonation: return ( - @@ -158,8 +168,13 @@ const AddMenuPanel = ({ return ( - {addMenuContent.map(({ text, icon, onClick }, index) => ( - + {addMenuContent.map(({ text, icon, onClick, onMouseEnter }, index) => ( + {icon} @@ -169,7 +184,7 @@ const AddMenuPanel = ({ }; const AddMenu = ({ isInDrawer = false }: AddMenuProps): ReactElement => { - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const [selectedMenuItem, changeSelectedMenuItem] = useState(null); const [dialogOpen, changeDialogOpen] = useState(false); @@ -183,6 +198,7 @@ const AddMenu = ({ isInDrawer = false }: AddMenuProps): ReactElement => { changeDialogOpen(true); setAnchorEl(undefined); }, + onMouseEnter: preloadCreateContact, }, { text: 'Add Multiple Contacts', @@ -192,6 +208,7 @@ const AddMenu = ({ isInDrawer = false }: AddMenuProps): ReactElement => { changeDialogOpen(true); setAnchorEl(undefined); }, + onMouseEnter: preloadCreateMultipleContacts, }, { text: 'Add Donation', @@ -201,6 +218,7 @@ const AddMenu = ({ isInDrawer = false }: AddMenuProps): ReactElement => { changeDialogOpen(true); setAnchorEl(undefined); }, + onMouseEnter: preloadAddDonation, }, { text: 'Add Task', @@ -209,6 +227,7 @@ const AddMenu = ({ isInDrawer = false }: AddMenuProps): ReactElement => { openTaskModal({ view: 'add' }); setAnchorEl(undefined); }, + onMouseEnter: () => preloadTaskModal('add'), }, { text: 'Log Task', @@ -217,6 +236,7 @@ const AddMenu = ({ isInDrawer = false }: AddMenuProps): ReactElement => { openTaskModal({ view: 'log' }); setAnchorEl(undefined); }, + onMouseEnter: () => preloadTaskModal('log'), }, ]; diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/AddDonation.test.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/AddDonation.test.tsx index e2dcb2ba6..a8dd40adf 100644 --- a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/AddDonation.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/AddDonation.test.tsx @@ -4,7 +4,7 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import { GqlMockedProvider } from '../../../../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../../../../../theme'; import { AddDonation } from './AddDonation'; import { AddDonationMutation } from './AddDonation.generated'; diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/DynamicAddDonation.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/DynamicAddDonation.tsx new file mode 100644 index 000000000..54de581ec --- /dev/null +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/DynamicAddDonation.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadAddDonation = () => + import(/* webpackChunkName: "AddDonation" */ './AddDonation').then( + ({ AddDonation }) => AddDonation, + ); + +export const DynamicAddDonation = dynamic(preloadAddDonation, { + loading: DynamicComponentPlaceholder, +}); diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/CreateContact.stories.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/CreateContact.stories.tsx index 797ee6177..cc84a2299 100644 --- a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/CreateContact.stories.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/CreateContact.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { MockedProvider } from '@apollo/client/testing'; -import { GqlMockedProvider } from '../../../../../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import CreateContact from './CreateContact'; export default { diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/CreateContact.test.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/CreateContact.test.tsx index a225ff9d8..b5260b06d 100644 --- a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/CreateContact.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/CreateContact.test.tsx @@ -3,8 +3,8 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import TestRouter from '../../../../../../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../../../../../__tests__/util/graphqlMocking'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../../../../../theme'; import CreateContact from './CreateContact'; diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/DynamicCreateContact.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/DynamicCreateContact.tsx new file mode 100644 index 000000000..459ae2734 --- /dev/null +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateContact/DynamicCreateContact.tsx @@ -0,0 +1,9 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadCreateContact = () => + import(/* webpackChunkName: "CreateContact" */ './CreateContact'); + +export const DynamicCreateContact = dynamic(preloadCreateContact, { + loading: DynamicComponentPlaceholder, +}); diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts.test.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts.test.tsx index 682cfc562..5553d312a 100644 --- a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts.test.tsx @@ -3,10 +3,10 @@ import { ThemeProvider } from '@mui/material/styles'; import { act, render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; +import TestRouter from '__tests__/util/TestRouter'; import { placePromise, setupMocks } from '__tests__/util/googlePlacesMock'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { CreateContactAddressMutation } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/AddAddressModal/CreateContactAddress.generated'; -import TestRouter from '../../../../../../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../../../../../__tests__/util/graphqlMocking'; import theme from '../../../../../../../../theme'; import { CreateContactMutation } from '../CreateContact/CreateContact.generated'; import { CreateMultipleContacts } from './CreateMultipleContacts'; diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts.tsx index 884365f7d..6eed0bd53 100644 --- a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContacts.tsx @@ -9,20 +9,16 @@ import { TableContainer, TableHead, TableRow, - TextField, } from '@mui/material'; import { styled } from '@mui/material/styles'; -import { Field, FieldArray, FieldProps, Form, Formik } from 'formik'; +import { Form, Formik } from 'formik'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import * as yup from 'yup'; import { ContactsDocument } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; import { useCreateContactAddressMutation } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/AddAddressModal/CreateContactAddress.generated'; import { useSetContactPrimaryAddressMutation } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/SetPrimaryAddress.generated'; -import { - AddressFields, - StreetAutocomplete, -} from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/StreetAutocomplete/StreetAutocomplete'; +import { AddressFields } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/StreetAutocomplete/StreetAutocomplete'; import { useCreatePersonMutation } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/People/Items/PersonModal/PersonModal.generated'; import { ContactReferralTabDocument } from 'src/components/Contacts/ContactDetails/ContactReferralTab/ContactReferralTab.generated'; import { @@ -32,16 +28,7 @@ import { import { PersonCreateInput } from 'src/graphql/types.generated'; import theme from '../../../../../../../../theme'; import { useCreateContactMutation } from '../CreateContact/CreateContact.generated'; - -const InputRow = styled(TableRow)(() => ({ - display: 'flex', - '&:nth-child(odd)': { - backgroundColor: '#f9f9f9', - }, - '&:last-child .MuiTableCell-root': { - borderBottom: 'none', - }, -})); +import { DynamicCreateMultipleContactsFieldArray } from './DynamicCreateMultipleContactsFieldArray'; const InputCell = styled(TableCell)(() => ({ flex: 1, @@ -65,7 +52,7 @@ interface Props { rows?: number; } -interface ContactRow { +export interface ContactRow { firstName: string; spouseName: string; lastName: string; @@ -268,156 +255,10 @@ export const CreateMultipleContacts = ({ - - contacts.map((contact, index) => ( - - - - {({ field }: FieldProps) => ( - - setFieldValue( - `contacts.${index}.firstName`, - e.target.value, - ) - } - /> - )} - - - - - {({ field }: FieldProps) => ( - - setFieldValue( - `contacts.${index}.spouseName`, - e.target.value, - ) - } - /> - )} - - - - - {({ field }: FieldProps) => ( - - setFieldValue( - `contacts.${index}.lastName`, - e.target.value, - ) - } - /> - )} - - - - - {({ field }: FieldProps) => ( - - setFieldValue(`contacts.${index}.address`, { - street, - }) - } - onPredictionChosen={(fields) => { - setFieldValue( - `contacts.${index}.address`, - fields, - ); - }} - /> - )} - - - - - {({ field }: FieldProps) => ( - - setFieldValue( - `contacts.${index}.phone`, - e.target.value, - ) - } - /> - )} - - - - - {({ field }: FieldProps) => ( - - setFieldValue( - `contacts.${index}.email`, - e.target.value, - ) - } - /> - )} - - - - )) - } + diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContactsFieldArray.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContactsFieldArray.tsx new file mode 100644 index 000000000..a9a5842ad --- /dev/null +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/CreateMultipleContactsFieldArray.tsx @@ -0,0 +1,193 @@ +import React, { memo } from 'react'; +import { TableCell, TableRow, TextField } from '@mui/material'; +import { styled } from '@mui/material/styles'; +import { Field, FieldArray, FieldProps } from 'formik'; +import { TFunction } from 'i18next'; +import { StreetAutocomplete } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/Mailing/StreetAutocomplete/StreetAutocomplete'; +import theme from '../../../../../../../../theme'; +import { ContactRow } from './CreateMultipleContacts'; + +const InputRow = styled(TableRow)(() => ({ + display: 'flex', + '&:nth-child(odd)': { + backgroundColor: '#f9f9f9', + }, + '&:last-child .MuiTableCell-root': { + borderBottom: 'none', + }, +})); + +const InputCell = styled(TableCell)(() => ({ + flex: 1, + [theme.breakpoints.down('lg')]: { + minWidth: '150px', + }, + [theme.breakpoints.down('md')]: { + minWidth: '130px', + }, +})); + +type CreateMultipleContactsFieldArrayProps = { + t: TFunction; + setFieldValue: ( + field: string, + value: any, + shouldValidate?: boolean | undefined, + ) => void; + contacts: ContactRow[]; +}; + +const CreateMultipleContactsFieldArray = memo( + function CreateMultipleContactsFieldArray({ + t, + setFieldValue, + contacts, + }: CreateMultipleContactsFieldArrayProps) { + return ( + + contacts.map((contact, index) => ( + + + + {({ field }: FieldProps) => ( + + setFieldValue( + `contacts.${index}.firstName`, + e.target.value, + ) + } + /> + )} + + + + + {({ field }: FieldProps) => ( + + setFieldValue( + `contacts.${index}.spouseName`, + e.target.value, + ) + } + /> + )} + + + + + {({ field }: FieldProps) => ( + + setFieldValue( + `contacts.${index}.lastName`, + e.target.value, + ) + } + /> + )} + + + + + {({ field }: FieldProps) => ( + + setFieldValue(`contacts.${index}.address`, { + street, + }) + } + onPredictionChosen={(fields) => { + setFieldValue(`contacts.${index}.address`, fields); + }} + /> + )} + + + + + {({ field }: FieldProps) => ( + + setFieldValue(`contacts.${index}.phone`, e.target.value) + } + /> + )} + + + + + {({ field }: FieldProps) => ( + + setFieldValue(`contacts.${index}.email`, e.target.value) + } + /> + )} + + + + )) + } + /> + ); + }, +); + +export default CreateMultipleContactsFieldArray; diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContacts.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContacts.tsx new file mode 100644 index 000000000..ab02481fd --- /dev/null +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContacts.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadCreateMultipleContacts = () => + import( + /* webpackChunkName: "CreateMultipleContacts" */ './CreateMultipleContacts' + ).then(({ CreateMultipleContacts }) => CreateMultipleContacts); + +export const DynamicCreateMultipleContacts = dynamic( + preloadCreateMultipleContacts, + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContactsFieldArray.tsx b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContactsFieldArray.tsx new file mode 100644 index 000000000..e539f83d2 --- /dev/null +++ b/src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/CreateMultipleContacts/DynamicCreateMultipleContactsFieldArray.tsx @@ -0,0 +1,10 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const DynamicCreateMultipleContactsFieldArray = dynamic( + () => + import( + /* webpackChunkName: "DynamicCreateMultipleContactsFieldArray" */ './CreateMultipleContactsFieldArray' + ), + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Layouts/Primary/TopBar/Items/NavMenu/NavMenu.stories.tsx b/src/components/Layouts/Primary/TopBar/Items/NavMenu/NavMenu.stories.tsx index 0fccf2dfc..28ec5d3a7 100644 --- a/src/components/Layouts/Primary/TopBar/Items/NavMenu/NavMenu.stories.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/NavMenu/NavMenu.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { AppBar, Box } from '@mui/material'; -import TestWrapper from '../../../../../../../__tests__/util/TestWrapper'; +import TestWrapper from '__tests__/util/TestWrapper'; import NavMenu from './NavMenu'; export default { diff --git a/src/components/Layouts/Primary/TopBar/Items/NavMenu/NavMenu.test.tsx b/src/components/Layouts/Primary/TopBar/Items/NavMenu/NavMenu.test.tsx index 96db1b86a..4149d930e 100644 --- a/src/components/Layouts/Primary/TopBar/Items/NavMenu/NavMenu.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/NavMenu/NavMenu.test.tsx @@ -1,13 +1,10 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import theme from 'src/theme'; -import TestRouter from '../../../../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; -import { - render, - waitFor, -} from '../../../../../../../__tests__/util/testingLibraryReactMock'; import { GetToolNotificationsQuery } from './GetToolNotifcations.generated'; import NavMenu from './NavMenu'; diff --git a/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/Item/Item.test.tsx b/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/Item/Item.test.tsx index 5bef81964..acea2f6e5 100644 --- a/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/Item/Item.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/Item/Item.test.tsx @@ -2,12 +2,9 @@ import React from 'react'; import { InMemoryCache } from '@apollo/client'; import userEvent from '@testing-library/user-event'; import { DateTime } from 'luxon'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import { NotificationTypeTypeEnum } from 'src/graphql/types.generated'; -import TestWrapper from '../../../../../../../../__tests__/util/TestWrapper'; -import { - render, - waitFor, -} from '../../../../../../../../__tests__/util/testingLibraryReactMock'; import { GetNotificationsDocument, GetNotificationsQuery, diff --git a/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/Item/Item.tsx b/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/Item/Item.tsx index 00227c072..974b12288 100644 --- a/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/Item/Item.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/Item/Item.tsx @@ -9,19 +9,19 @@ import { ListItemAvatar, ListItemText, ListSubheader, + Skeleton, Typography, } from '@mui/material'; -import Skeleton from '@mui/material/Skeleton'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { NotificationTypeTypeEnum } from 'src/graphql/types.generated'; +import { useAccountListId } from 'src/hooks/useAccountListId'; import { useLocale } from 'src/hooks/useLocale'; -import { useAccountListId } from '../../../../../../../hooks/useAccountListId'; import { currencyFormat, dateFormat, monthYearFormat, -} from '../../../../../../../lib/intlFormat/intlFormat'; +} from 'src/lib/intlFormat'; import { GetNotificationsDocument, GetNotificationsQuery, diff --git a/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/NotificationMenu.test.tsx b/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/NotificationMenu.test.tsx index 9134af78f..fbbc9683f 100644 --- a/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/NotificationMenu.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/NotificationMenu/NotificationMenu.test.tsx @@ -1,11 +1,8 @@ import React from 'react'; import { InMemoryCache } from '@apollo/client'; import userEvent from '@testing-library/user-event'; -import TestWrapper from '../../../../../../../__tests__/util/TestWrapper'; -import { - render, - waitFor, -} from '../../../../../../../__tests__/util/testingLibraryReactMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import { GetNotificationsDocument } from './GetNotificationsQuery.generated'; import NotificationMenu from './NotificationMenu'; import { diff --git a/src/components/Layouts/Primary/TopBar/Items/ProfileMenu/ProfileMenu.test.tsx b/src/components/Layouts/Primary/TopBar/Items/ProfileMenu/ProfileMenu.test.tsx index d114c0eb3..f8dcfb12b 100644 --- a/src/components/Layouts/Primary/TopBar/Items/ProfileMenu/ProfileMenu.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/ProfileMenu/ProfileMenu.test.tsx @@ -4,12 +4,9 @@ import userEvent from '@testing-library/user-event'; import fetchMock from 'jest-fetch-mock'; import { signOut, useSession } from 'next-auth/react'; import { session } from '__tests__/fixtures/session'; -import TestRouter from '../../../../../../../__tests__/util/TestRouter'; -import TestWrapper from '../../../../../../../__tests__/util/TestWrapper'; -import { - render, - waitFor, -} from '../../../../../../../__tests__/util/testingLibraryReactMock'; +import TestRouter from '__tests__/util/TestRouter'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../../../../theme'; import { getTopBarMock, diff --git a/src/components/Layouts/Primary/TopBar/Items/SearchMenu/DynamicSearchDialog.tsx b/src/components/Layouts/Primary/TopBar/Items/SearchMenu/DynamicSearchDialog.tsx new file mode 100644 index 000000000..c3e9e4503 --- /dev/null +++ b/src/components/Layouts/Primary/TopBar/Items/SearchMenu/DynamicSearchDialog.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadSearchDialog = () => + import(/* webpackChunkName: "SearchDialog" */ './SearchDialog').then( + ({ SearchDialog }) => SearchDialog, + ); + +export const DynamicSearchDialog = dynamic(preloadSearchDialog, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchDialog.tsx b/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchDialog.tsx new file mode 100644 index 000000000..e7b213218 --- /dev/null +++ b/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchDialog.tsx @@ -0,0 +1,371 @@ +import NextLink from 'next/link'; +import { useRouter } from 'next/router'; +import React, { ReactElement, useCallback, useState } from 'react'; +import AddIcon from '@mui/icons-material/Add'; +import CompassIcon from '@mui/icons-material/Explore'; +import PeopleIcon from '@mui/icons-material/People'; +import PersonIcon from '@mui/icons-material/Person'; +import SearchIcon from '@mui/icons-material/Search'; +import { + Autocomplete, + Box, + Dialog, + IconButton, + Popper, + TextField, + Typography, +} from '@mui/material'; +import { styled } from '@mui/material/styles'; +import { debounce } from 'lodash'; +import { useSnackbar } from 'notistack'; +import { useTranslation } from 'react-i18next'; +import { + ContactFilterStatusEnum, + StatusEnum, +} from 'src/graphql/types.generated'; +import { contactPartnershipStatus } from 'src/utils/contacts/contactPartnershipStatus'; +import { useAccountListId } from '../../../../../../hooks/useAccountListId'; +import { useCreateContactMutation } from '../AddMenu/Items/CreateContact/CreateContact.generated'; +import { useGetSearchMenuContactsLazyQuery } from './SearchMenu.generated'; + +const StyledDialog = styled(Dialog)(() => ({ + '& .MuiPaper-root': { + position: 'absolute', + top: 50, + }, +})); + +const ClickableBox = styled(Box)(({ theme }) => ({ + cursor: 'pointer', + '&:hover': { + backgroundColor: theme.palette.cruGrayLight.main, + }, +})); + +const SearchPopper = styled(Popper)(() => ({ + '& .MuiAutocomplete-option': { + padding: 0, + }, +})); + +interface Option { + name: string; + status?: StatusEnum | null; + icon: ReactElement; + link: string; +} + +interface SearchDialogProps { + handleClose: () => void; +} + +export const SearchDialog: React.FC = ({ handleClose }) => { + const { t } = useTranslation(); + const accountListId = useAccountListId(); + const { enqueueSnackbar } = useSnackbar(); + const { push } = useRouter(); + + //#region Search + const [wildcardSearch, setWildcardSearch] = useState(''); + + const [searchForContacts, { loading, data }] = + useGetSearchMenuContactsLazyQuery(); + + const [createContact] = useCreateContactMutation(); + + const handleUpdateWildcardSearch = useCallback( + debounce( + (wildcardSearch: string) => + searchForContacts({ + variables: { + accountListId: accountListId ?? '', + contactsFilter: { + status: [ + ContactFilterStatusEnum.Active, + ContactFilterStatusEnum.Null, + ContactFilterStatusEnum.Hidden, + ], + wildcardSearch, + }, + }, + }), + 1000, + ), + [accountListId], + ); + + const defaultOptions: Option[] = [ + { + name: t('Contacts'), + icon: , + link: `/accountLists/${accountListId}/contacts`, + }, + { + name: t('Tasks'), + icon: , + link: `/accountLists/${accountListId}/tasks`, + }, + { + name: t('Preferences - Manage Accounts'), + icon: , + link: `/accountLists/${accountListId}/preferences/manageAccounts`, + }, + { + name: t('Preferences - Manage Coaches'), + icon: , + link: `/accountLists/${accountListId}/preferences/coaching`, + }, + { + name: t('Preferences - Connect Services'), + icon: , + link: `/accountLists/${accountListId}/preferences/connectServices`, + }, + { + name: t('Reports - Donations'), + icon: , + link: `/accountLists/${accountListId}/reports/partnerGivingAnalysis`, + }, + { + name: t('Reports - Monthly Report (Partner Currency)'), + icon: , + link: `/accountLists/${accountListId}/reports/partnerCurrency`, + }, + { + name: t('Reports - Monthly Report (Salary Currency)'), + icon: , + link: `/accountLists/${accountListId}/reports/salaryCurrency`, + }, + { + name: t('Reports - Designation Accounts'), + icon: , + link: `/accountLists/${accountListId}/reports/designationAccounts`, + }, + { + name: t('Reports - Responsibility Centers'), + icon: , + link: `/accountLists/${accountListId}/reports/responsibilityCenters`, + }, + { + name: t('Reports - Expected Monthly Total'), + icon: , + link: `/accountLists/${accountListId}/reports/expectedMonthlyTotal`, + }, + { + name: t('Reports - Partner Giving Analysis'), + icon: , + link: `/accountLists/${accountListId}/reports/PartnerGivingAnalysis`, + }, + { + name: t('Reports - Coaching'), + icon: , + link: `/accountLists/${accountListId}/reports/coaching`, + }, + { + name: t('Tools'), + icon: , + link: `/accountLists/${accountListId}/tools`, + }, + { + name: t('Coaching'), + icon: , + link: `/accountLists/${accountListId}/coaching`, + }, + { + name: t('Tools - Fix - Commitment Info'), + icon: , + link: `/accountLists/${accountListId}/tools/fixCommitmentInfo`, + }, + { + name: t('Tools - Fix - Mailing Addresses'), + icon: , + link: `/accountLists/${accountListId}/tools/fixMailingAddresses`, + }, + { + name: t('Tools - Fix - Send Newsletter'), + icon: , + link: `/accountLists/${accountListId}/tools/fixSendNewsletter`, + }, + { + name: t('Tools - Fix - Merge Contacts'), + icon: , + link: `/accountLists/${accountListId}/tools/mergeContacts`, + }, + { + name: t('Tools - Fix - Email Addresses'), + icon: , + link: `/accountLists/${accountListId}/tools/fixEmailAddresses`, + }, + { + name: t('Tools - Fix - Phone Numbers'), + icon: , + link: `/accountLists/${accountListId}/tools/fixPhoneNumbers`, + }, + { + name: t('Tools - Fix - Merge People'), + icon: , + link: `/accountLists/${accountListId}/tools/mergePeople`, + }, + { + name: t('Tools - Import - Google'), + icon: , + link: `/accountLists/${accountListId}/tools/google`, + }, + { + name: t('Tools - Import - TntConnect'), + icon: , + link: `/accountLists/${accountListId}/tools/tntConnect`, + }, + { + name: t('Tools - Import - CSV'), + icon: , + link: `/accountLists/${accountListId}/tools/csv`, + }, + ]; + + const options: Option[] = [ + ...(data?.contacts.nodes.map(({ name, status, id }) => ({ + name, + status, + icon: , + link: `/accountLists/${accountListId}/contacts/${id}`, + })) ?? []), + ...defaultOptions, + ]; + + const handleCreateContact = async () => { + const { data } = await createContact({ + variables: { + accountListId: accountListId ?? '', + attributes: { + name: wildcardSearch, + }, + }, + }); + const contactId = data?.createContact?.contact.id; + + if (contactId) { + push({ + pathname: '/accountLists/[accountListId]/contacts/[contactId]', + query: { accountListId, contactId }, + }); + } + enqueueSnackbar(t('Contact successfully created'), { + variant: 'success', + }); + }; + //#endregion + + return ( + + + option.name} + renderOption={(props, option) => { + if (option.link === 'createContact') { + return ( + + + {option.icon} + + + {option.name} + + + ); + } + + return ( + + + + {option.icon} + + + {option.name} + + {option.status && contactPartnershipStatus[option.status]} + + + + + ); + }} + options={wildcardSearch !== '' ? options : []} + filterOptions={(options, params) => { + if (params.inputValue !== '') { + if ( + data?.contacts.totalCount && + data?.contacts.totalCount > data.contacts.nodes.length + ) { + options.splice(5, 0, { + name: t( + `And ${ + data?.contacts.totalCount - data.contacts.nodes.length + } more`, + ), + icon: , + link: `/accountLists/${accountListId}/contacts?searchTerm=${wildcardSearch}`, + }); + } + options.push({ + name: t('Create a new contact for "{{ name }}"', { + name: params.inputValue, + }), + icon: , + link: 'createContact', + }); + } + + return options; + }} + renderInput={(params): ReactElement => ( + + + + ), + endAdornment: null, + }} + onChange={(e) => { + setWildcardSearch(e.target.value); + handleUpdateWildcardSearch(e.target.value); + }} + // eslint-disable-next-line + autoFocus + /> + )} + /> + + + ); +}; diff --git a/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchMenu.test.tsx b/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchMenu.test.tsx index 3a65f0d4f..045c9b462 100644 --- a/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchMenu.test.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchMenu.test.tsx @@ -3,11 +3,11 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { I18nextProvider } from 'react-i18next'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { StatusEnum } from 'src/graphql/types.generated'; import i18n from 'src/lib/i18n'; import theme from 'src/theme'; -import TestRouter from '../../../../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../../../__tests__/util/graphqlMocking'; import SearchMenu from './SearchMenu'; import { GetSearchMenuContactsQuery } from './SearchMenu.generated'; diff --git a/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchMenu.tsx b/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchMenu.tsx index 13df93caa..c30eeaa3e 100644 --- a/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchMenu.tsx +++ b/src/components/Layouts/Primary/TopBar/Items/SearchMenu/SearchMenu.tsx @@ -1,52 +1,11 @@ -import NextLink from 'next/link'; -import { useRouter } from 'next/router'; -import React, { ReactElement, useCallback, useState } from 'react'; -import AddIcon from '@mui/icons-material/Add'; -import CompassIcon from '@mui/icons-material/Explore'; -import PeopleIcon from '@mui/icons-material/People'; -import PersonIcon from '@mui/icons-material/Person'; +import React, { useState } from 'react'; import SearchIcon from '@mui/icons-material/Search'; -import { - Autocomplete, - Box, - Dialog, - IconButton, - Popper, - TextField, - Typography, -} from '@mui/material'; +import { IconButton } from '@mui/material'; import { styled } from '@mui/material/styles'; -import debounce from 'lodash/debounce'; -import { useSnackbar } from 'notistack'; -import { useTranslation } from 'react-i18next'; import { - ContactFilterStatusEnum, - StatusEnum, -} from 'src/graphql/types.generated'; -import { contactPartnershipStatus } from 'src/utils/contacts/contactPartnershipStatus'; -import { useAccountListId } from '../../../../../../hooks/useAccountListId'; -import { useCreateContactMutation } from '../AddMenu/Items/CreateContact/CreateContact.generated'; -import { useGetSearchMenuContactsLazyQuery } from './SearchMenu.generated'; - -const SearchDialog = styled(Dialog)(() => ({ - '& .MuiPaper-root': { - position: 'absolute', - top: 50, - }, -})); - -const ClickableBox = styled(Box)(({ theme }) => ({ - cursor: 'pointer', - '&:hover': { - backgroundColor: theme.palette.cruGrayLight.main, - }, -})); - -const SearchPopper = styled(Popper)(() => ({ - '& .MuiAutocomplete-option': { - padding: 0, - }, -})); + DynamicSearchDialog, + preloadSearchDialog, +} from './DynamicSearchDialog'; const SearchButton = styled(IconButton)(() => ({ textTransform: 'none', @@ -57,342 +16,22 @@ const SearchButton = styled(IconButton)(() => ({ }, })); -interface Option { - name: string; - status?: StatusEnum | null; - icon: ReactElement; - link: string; -} - -const SearchMenu = (): ReactElement => { - const { t } = useTranslation(); - const accountListId = useAccountListId(); - const { enqueueSnackbar } = useSnackbar(); - const { push } = useRouter(); - - const [isOpen, setIsOpen] = useState(false); - - //#region Search - const [wildcardSearch, setWildcardSearch] = useState(''); +const SearchMenu: React.FC = () => { + const [open, setOpen] = useState(false); - const [searchForContacts, { loading, data }] = - useGetSearchMenuContactsLazyQuery(); - - const [createContact] = useCreateContactMutation(); - - const handleUpdateWildcardSearch = useCallback( - debounce( - (wildcardSearch: string) => - searchForContacts({ - variables: { - accountListId: accountListId ?? '', - contactsFilter: { - status: [ - ContactFilterStatusEnum.Active, - ContactFilterStatusEnum.Null, - ContactFilterStatusEnum.Hidden, - ], - wildcardSearch, - }, - }, - }), - 1000, - ), - [], - ); - - const handleClose = () => { - setIsOpen(false); - setWildcardSearch(''); - }; - - const defaultOptions: Option[] = [ - { - name: t('Contacts'), - icon: , - link: `/accountLists/${accountListId}/contacts`, - }, - { - name: t('Tasks'), - icon: , - link: `/accountLists/${accountListId}/tasks`, - }, - { - name: t('Preferences - Manage Accounts'), - icon: , - link: `/accountLists/${accountListId}/preferences/manageAccounts`, - }, - { - name: t('Preferences - Manage Coaches'), - icon: , - link: `/accountLists/${accountListId}/preferences/coaching`, - }, - { - name: t('Preferences - Connect Services'), - icon: , - link: `/accountLists/${accountListId}/preferences/connectServices`, - }, - { - name: t('Reports - Donations'), - icon: , - link: `/accountLists/${accountListId}/reports/partnerGivingAnalysis`, - }, - { - name: t('Reports - Monthly Report (Partner Currency)'), - icon: , - link: `/accountLists/${accountListId}/reports/partnerCurrency`, - }, - { - name: t('Reports - Monthly Report (Salary Currency)'), - icon: , - link: `/accountLists/${accountListId}/reports/salaryCurrency`, - }, - { - name: t('Reports - Designation Accounts'), - icon: , - link: `/accountLists/${accountListId}/reports/designationAccounts`, - }, - { - name: t('Reports - Responsibility Centers'), - icon: , - link: `/accountLists/${accountListId}/reports/responsibilityCenters`, - }, - { - name: t('Reports - Expected Monthly Total'), - icon: , - link: `/accountLists/${accountListId}/reports/expectedMonthlyTotal`, - }, - { - name: t('Reports - Partner Giving Analysis'), - icon: , - link: `/accountLists/${accountListId}/reports/PartnerGivingAnalysis`, - }, - { - name: t('Reports - Coaching'), - icon: , - link: `/accountLists/${accountListId}/reports/coaching`, - }, - { - name: t('Tools'), - icon: , - link: `/accountLists/${accountListId}/tools`, - }, - { - name: t('Coaching'), - icon: , - link: `/accountLists/${accountListId}/coaching`, - }, - { - name: t('Tools - Fix - Commitment Info'), - icon: , - link: `/accountLists/${accountListId}/tools/fixCommitmentInfo`, - }, - { - name: t('Tools - Fix - Mailing Addresses'), - icon: , - link: `/accountLists/${accountListId}/tools/fixMailingAddresses`, - }, - { - name: t('Tools - Fix - Send Newsletter'), - icon: , - link: `/accountLists/${accountListId}/tools/fixSendNewsletter`, - }, - { - name: t('Tools - Fix - Merge Contacts'), - icon: , - link: `/accountLists/${accountListId}/tools/mergeContacts`, - }, - { - name: t('Tools - Fix - Email Addresses'), - icon: , - link: `/accountLists/${accountListId}/tools/fixEmailAddresses`, - }, - { - name: t('Tools - Fix - Phone Numbers'), - icon: , - link: `/accountLists/${accountListId}/tools/fixPhoneNumbers`, - }, - { - name: t('Tools - Fix - Merge People'), - icon: , - link: `/accountLists/${accountListId}/tools/mergePeople`, - }, - { - name: t('Tools - Import - Google'), - icon: , - link: `/accountLists/${accountListId}/tools/google`, - }, - { - name: t('Tools - Import - TntConnect'), - icon: , - link: `/accountLists/${accountListId}/tools/tntConnect`, - }, - { - name: t('Tools - Import - CSV'), - icon: , - link: `/accountLists/${accountListId}/tools/csv`, - }, - ]; - - const options: Option[] = [ - ...(data?.contacts.nodes.map(({ name, status, id }) => ({ - name, - status, - icon: , - link: `/accountLists/${accountListId}/contacts/${id}`, - })) ?? []), - ...defaultOptions, - ]; - - const handleCreateContact = async () => { - const { data } = await createContact({ - variables: { - accountListId: accountListId ?? '', - attributes: { - name: wildcardSearch, - }, - }, - }); - const contactId = data?.createContact?.contact.id; - - if (contactId) { - push({ - pathname: '/accountLists/[accountListId]/contacts/[contactId]', - query: { accountListId, contactId }, - }); - } - enqueueSnackbar(t('Contact successfully created'), { - variant: 'success', - }); - }; - //#endregion - - //#region JSX return ( <> setIsOpen(true)} + onClick={() => setOpen(true)} + onMouseEnter={preloadSearchDialog} > - - - - option.name} - renderOption={(props, option) => { - if (option.link === 'createContact') { - return ( - - - {option.icon} - - - {option.name} - - - ); - } - - return ( - - - - {option.icon} - - - {option.name} - - {option.status && - contactPartnershipStatus[option.status]} - - - - - ); - }} - options={wildcardSearch !== '' ? options : []} - filterOptions={(options, params) => { - if (params.inputValue !== '') { - if ( - data?.contacts.totalCount && - data?.contacts.totalCount > data.contacts.nodes.length - ) { - options.splice(5, 0, { - name: t( - `And ${ - data?.contacts.totalCount - data.contacts.nodes.length - } more`, - ), - icon: , - link: `/accountLists/${accountListId}/contacts?searchTerm=${wildcardSearch}`, - }); - } - options.push({ - name: t('Create a new contact for "{{ name }}"', { - name: params.inputValue, - }), - icon: , - link: 'createContact', - }); - } - - return options; - }} - renderInput={(params): ReactElement => ( - - - - ), - endAdornment: null, - }} - onChange={(e) => { - setWildcardSearch(e.target.value); - handleUpdateWildcardSearch(e.target.value); - }} - // eslint-disable-next-line - autoFocus - /> - )} - /> - - + {open && setOpen(false)} />} ); - //#endregion }; export default SearchMenu; diff --git a/src/components/Layouts/Primary/TopBar/TopBar.test.tsx b/src/components/Layouts/Primary/TopBar/TopBar.test.tsx index c69f67ce2..72e056a2a 100644 --- a/src/components/Layouts/Primary/TopBar/TopBar.test.tsx +++ b/src/components/Layouts/Primary/TopBar/TopBar.test.tsx @@ -4,7 +4,7 @@ import { MockedProvider } from '@apollo/client/testing'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; import { SnackbarProvider } from 'notistack'; -import TestRouter from '../../../../../__tests__/util/TestRouter'; +import TestRouter from '__tests__/util/TestRouter'; import theme from '../../../../theme'; import { getNotificationsMocks } from './Items/NotificationMenu/NotificationMenu.mock'; import TopBar from './TopBar'; diff --git a/src/components/Layouts/SidePanelsLayout.tsx b/src/components/Layouts/SidePanelsLayout.tsx index 56763e606..90edde9ad 100644 --- a/src/components/Layouts/SidePanelsLayout.tsx +++ b/src/components/Layouts/SidePanelsLayout.tsx @@ -130,7 +130,7 @@ export const SidePanelsLayout: FC = ({ style={{ transform: leftOpen ? 'none' : 'translate(-100%)' }} data-testid="SidePanelsLayoutLeftPanel" > - {leftPanel} + {leftOpen && leftPanel} {mainContent} @@ -143,7 +143,7 @@ export const SidePanelsLayout: FC = ({ transform: rightOpen ? 'none' : 'translate(100%)', }} > - {rightPanel} + {rightOpen && rightPanel} ); diff --git a/src/components/Loading/Loading.test.tsx b/src/components/Loading/Loading.test.tsx index f6c481a0e..32fabe1af 100644 --- a/src/components/Loading/Loading.test.tsx +++ b/src/components/Loading/Loading.test.tsx @@ -1,7 +1,7 @@ import { NextRouter } from 'next/router'; import React from 'react'; import { render, waitFor } from '@testing-library/react'; -import TestRouter from '../../../__tests__/util/TestRouter'; +import TestRouter from '__tests__/util/TestRouter'; import Loading from '.'; describe('Loading', () => { @@ -64,29 +64,24 @@ describe('Loading', () => { }); it('changes loading state', async () => { - const { queryByTestId } = render( + const { getByTestId } = render( , ); - await waitFor(() => { - expect(queryByTestId('Loading')).not.toBeInTheDocument(); - }); + const spinner = getByTestId('Loading'); + await waitFor(() => expect(spinner).not.toHaveClass('visible')); + router.events.emit('routeChangeStart'); - await waitFor(() => { - expect(queryByTestId('Loading')).toBeInTheDocument(); - }); + await waitFor(() => expect(spinner).toHaveClass('visible')); + router.events.emit('routeChangeComplete'); - await waitFor(() => { - expect(queryByTestId('Loading')).not.toBeInTheDocument(); - }); + await waitFor(() => expect(spinner).not.toHaveClass('visible')); + router.events.emit('routeChangeStart'); - await waitFor(() => { - expect(queryByTestId('Loading')).toBeInTheDocument(); - }); + await waitFor(() => expect(spinner).toHaveClass('visible')); + router.events.emit('routeChangeError'); - await waitFor(() => { - expect(queryByTestId('Loading')).not.toBeInTheDocument(); - }); + await waitFor(() => expect(spinner).not.toHaveClass('visible')); }); }); diff --git a/src/components/Loading/Loading.tsx b/src/components/Loading/Loading.tsx index e8630fc40..8384774a0 100644 --- a/src/components/Loading/Loading.tsx +++ b/src/components/Loading/Loading.tsx @@ -1,7 +1,7 @@ import { useRouter } from 'next/router'; -import React, { ReactElement, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { CircularProgress, Fab, Theme } from '@mui/material'; -import { AnimatePresence, motion } from 'framer-motion'; +import clsx from 'clsx'; import { makeStyles } from 'tss-react/mui'; const useStyles = makeStyles()((theme: Theme) => ({ @@ -11,6 +11,17 @@ const useStyles = makeStyles()((theme: Theme) => ({ left: '50%', marginLeft: '-28px', marginTop: '-28px', + zIndex: 10, + opacity: 0, + transition: theme.transitions.create(['opacity', 'visibility'], { + duration: theme.transitions.duration.short, + }), + visibility: 'hidden', + + '.visible': { + opacity: 1, + visibility: 'visible', + }, }, fab: { backgroundColor: theme.palette.common.white, @@ -25,7 +36,7 @@ interface Props { loading?: boolean; } -const Loading = ({ loading = false }: Props): ReactElement => { +const Loading: React.FC = ({ loading = false }) => { const { classes } = useStyles(); const router = useRouter(); @@ -49,24 +60,17 @@ const Loading = ({ loading = false }: Props): ReactElement => { router.events.off('routeChangeComplete', handleComplete); router.events.off('routeChangeError', handleComplete); }; - }); + }, []); return ( - - {currentlyLoading && ( - - - - - - )} - +
+ + + +
); }; diff --git a/src/components/Notification/Notification.tsx b/src/components/Notification/Notification.tsx index 88aa4a947..db955b700 100644 --- a/src/components/Notification/Notification.tsx +++ b/src/components/Notification/Notification.tsx @@ -1,8 +1,7 @@ import React from 'react'; import ErrorIcon from '@mui/icons-material/Error'; import InfoIcon from '@mui/icons-material/Info'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; +import { Box, Typography } from '@mui/material'; interface Props { message: string; diff --git a/src/components/Reports/AccountsListLayout/List/List.tsx b/src/components/Reports/AccountsListLayout/List/List.tsx index 47f8faa7d..3a016b6ff 100644 --- a/src/components/Reports/AccountsListLayout/List/List.tsx +++ b/src/components/Reports/AccountsListLayout/List/List.tsx @@ -1,5 +1,5 @@ import React, { FC } from 'react'; -import List from '@mui/material/List'; +import { List } from '@mui/material'; import { styled } from '@mui/material/styles'; import { Account, AccountListItem as ListItem } from './ListItem/ListItem'; import { AccountListSubheader as ListSubheader } from './ListSubheader/ListSubheader'; diff --git a/src/components/Reports/AccountsListLayout/List/ListItem/ListItem.tsx b/src/components/Reports/AccountsListLayout/List/ListItem/ListItem.tsx index 3cff2be92..0fbd23a97 100644 --- a/src/components/Reports/AccountsListLayout/List/ListItem/ListItem.tsx +++ b/src/components/Reports/AccountsListLayout/List/ListItem/ListItem.tsx @@ -15,8 +15,7 @@ import { useTranslation } from 'react-i18next'; import HandoffLink from 'src/components/HandoffLink'; import { EntryHistoriesQuery } from 'src/components/Reports/ResponsibilityCentersReport/GetEntryHistories.generated'; import { useLocale } from 'src/hooks/useLocale'; -import { currencyFormat } from 'src/lib/intlFormat'; -import { dateFormat } from 'src/lib/intlFormat/intlFormat'; +import { currencyFormat, dateFormat } from 'src/lib/intlFormat'; import { Unarray } from '../../../Reports.type'; import { AccountListItemChart as Chart } from './Chart/Chart'; diff --git a/src/components/Reports/DonationsReport/DonationsReport.stories.tsx b/src/components/Reports/DonationsReport/DonationsReport.stories.tsx index 994cd548a..74709c9c3 100644 --- a/src/components/Reports/DonationsReport/DonationsReport.stories.tsx +++ b/src/components/Reports/DonationsReport/DonationsReport.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { DateTime } from 'luxon'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { DonationsReport } from './DonationsReport'; export default { diff --git a/src/components/Reports/DonationsReport/DonationsReport.test.tsx b/src/components/Reports/DonationsReport/DonationsReport.test.tsx index 76a8d26a2..6ea148a50 100644 --- a/src/components/Reports/DonationsReport/DonationsReport.test.tsx +++ b/src/components/Reports/DonationsReport/DonationsReport.test.tsx @@ -4,11 +4,11 @@ import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { DateTime } from 'luxon'; import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { afterTestResizeObserver, beforeTestResizeObserver, } from '__tests__/util/windowResizeObserver'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; import theme from '../../../theme'; import { GetDonationsGraphQuery } from '../../Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.generated'; import { DonationsReport } from './DonationsReport'; diff --git a/src/components/Reports/DonationsReport/Table/DonationsReportTable.stories.tsx b/src/components/Reports/DonationsReport/Table/DonationsReportTable.stories.tsx index 0230cc732..79107704c 100644 --- a/src/components/Reports/DonationsReport/Table/DonationsReportTable.stories.tsx +++ b/src/components/Reports/DonationsReport/Table/DonationsReportTable.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { DateTime } from 'luxon'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { GetDonationsTableQuery } from '../GetDonationsTable.generated'; import { DonationsReportTable } from './DonationsReportTable'; diff --git a/src/components/Reports/DonationsReport/Table/DonationsReportTable.test.tsx b/src/components/Reports/DonationsReport/Table/DonationsReportTable.test.tsx index e77416ffc..f56672228 100644 --- a/src/components/Reports/DonationsReport/Table/DonationsReportTable.test.tsx +++ b/src/components/Reports/DonationsReport/Table/DonationsReportTable.test.tsx @@ -8,7 +8,7 @@ import { cloneDeep } from 'lodash'; import { DateTime } from 'luxon'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../../theme'; import { GetDonationsTableQuery } from '../GetDonationsTable.generated'; import { DonationsReportTable } from './DonationsReportTable'; @@ -125,7 +125,7 @@ describe('DonationsReportTable', () => { }); it('opens and closes the edit donation modal', async () => { - const { queryByRole, queryByText, getByText, getByTestId, getByRole } = + const { queryByRole, queryByText, findByText, getByTestId, getByRole } = render( @@ -159,7 +159,7 @@ describe('DonationsReportTable', () => { userEvent.click(getByTestId('edit-abc')); - expect(getByText('Edit Donation')).toBeInTheDocument(); + expect(await findByText('Edit Donation')).toBeInTheDocument(); userEvent.click(getByRole('button', { name: 'Cancel' })); diff --git a/src/components/Reports/DonationsReport/Table/DonationsReportTable.tsx b/src/components/Reports/DonationsReport/Table/DonationsReportTable.tsx index 84e770b77..8eb197604 100644 --- a/src/components/Reports/DonationsReport/Table/DonationsReportTable.tsx +++ b/src/components/Reports/DonationsReport/Table/DonationsReportTable.tsx @@ -7,6 +7,7 @@ import { Button, CircularProgress, Divider, + IconButton, LinearProgress, Link, Table, @@ -16,15 +17,17 @@ import { TableRow, Typography, } from '@mui/material'; -import IconButton from '@mui/material/IconButton'; import { styled } from '@mui/material/styles'; import { DataGrid, GridColDef, GridSortModel } from '@mui/x-data-grid'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; -import { EditDonationModal } from 'src/components/EditDonationModal/EditDonationModal'; +import { + DynamicEditDonationModal, + preloadEditDonationModal, +} from 'src/components/EditDonationModal/DynamicEditDonationModal'; import { useFetchAllPages } from 'src/hooks/useFetchAllPages'; import { useLocale } from 'src/hooks/useLocale'; -import { currencyFormat, dateFormatShort } from 'src/lib/intlFormat/intlFormat'; +import { currencyFormat, dateFormatShort } from 'src/lib/intlFormat'; import { EmptyDonationsTable } from '../../../common/EmptyDonationsTable/EmptyDonationsTable'; import { DonationTableRowFragment, @@ -227,6 +230,7 @@ export const DonationsReportTable: React.FC = ({ onClick={() => { setSelectedDonation(donation); }} + onMouseEnter={preloadEditDonationModal} > @@ -462,7 +466,7 @@ export const DonationsReportTable: React.FC = ({ /> )} {selectedDonation && ( - handleClose()} diff --git a/src/components/Reports/EmptyReport/EmptyReport.tsx b/src/components/Reports/EmptyReport/EmptyReport.tsx index 003507475..afcd0b5fc 100644 --- a/src/components/Reports/EmptyReport/EmptyReport.tsx +++ b/src/components/Reports/EmptyReport/EmptyReport.tsx @@ -3,12 +3,12 @@ import LocalAtmIcon from '@mui/icons-material/LocalAtm'; import { Box, Button, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; -import { AddDonation } from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/AddDonation'; -import { NextLinkComposed } from 'src/components/common/Links/NextLinkComposed'; import { - DynamicModal, - preloadModal, -} from 'src/components/common/Modal/DynamicModal'; + DynamicAddDonation, + preloadAddDonation, +} from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/DynamicAddDonation'; +import { NextLinkComposed } from 'src/components/common/Links/NextLinkComposed'; +import Modal from 'src/components/common/Modal/Modal'; import { useAccountListId } from 'src/hooks/useAccountListId'; interface Props { @@ -59,7 +59,7 @@ export const EmptyReport: React.FC = ({ + {renderDialog( + AddMenuItemsEnum.NewContact, + contactsDialogOpen, + setContactsDialogOpen, + )} + + ); +}; + interface Props { page: 'contact' | 'task'; totalCount: number; @@ -31,8 +79,6 @@ const NullState: React.FC = ({ changeFilters, }: Props) => { const { t } = useTranslation(); - const { openTaskModal } = useTaskModal(); - const [dialogOpen, changeDialogOpen] = useState(false); return ( @@ -57,21 +103,7 @@ const NullState: React.FC = ({ - +
) : ( @@ -92,25 +124,10 @@ const NullState: React.FC = ({ - +
)} - {renderDialog(AddMenuItemsEnum.NewContact, dialogOpen, changeDialogOpen)}
); }; diff --git a/src/components/Shared/Filters/NullState/NullStateBox.tsx b/src/components/Shared/Filters/NullState/NullStateBox.tsx index b5577cdd1..6e751feb7 100644 --- a/src/components/Shared/Filters/NullState/NullStateBox.tsx +++ b/src/components/Shared/Filters/NullState/NullStateBox.tsx @@ -1,4 +1,4 @@ -import Box from '@mui/material/Box'; +import { Box } from '@mui/material'; import { styled } from '@mui/material/styles'; export const NullStateBox = styled(Box)(({ theme }) => ({ diff --git a/src/components/Shared/Filters/SaveFilterModal/SaveFilterModal.test.tsx b/src/components/Shared/Filters/SaveFilterModal/SaveFilterModal.test.tsx index 51bd1b120..fed72c0cf 100644 --- a/src/components/Shared/Filters/SaveFilterModal/SaveFilterModal.test.tsx +++ b/src/components/Shared/Filters/SaveFilterModal/SaveFilterModal.test.tsx @@ -2,10 +2,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; import theme from '../../../../theme'; import { UserOptionFragment, diff --git a/src/components/Shared/Filters/helpers.ts b/src/components/Shared/Filters/helpers.ts new file mode 100644 index 000000000..73e241a0d --- /dev/null +++ b/src/components/Shared/Filters/helpers.ts @@ -0,0 +1,44 @@ +const reverseFiltersOptions = { + alma_mater: 'reverseAlmaMater', + appeal: 'reverseAppeal', + church: 'reverseChurch', + city: 'reverseCity', + contact_type: 'reverseContactType', + country: 'reverseCountry', + designation_account_id: 'reverseDesignationAccountId', + donation: 'reverseDonation', + likely: 'reverseLikely', + locale: 'reverseLocale', + metro_area: 'reverseMetroArea', + pledge_amount: 'reversePledgeAmount', + pledge_currency: 'reversePledgeCurrency', + pledge_frequency: 'reversePledgeFrequency', + referrer: 'reverseReferrer', + region: 'reverseRegion', + related_task_action: 'reverseRelatedTaskAction', + source: 'reverseSource', + state: 'reverseState', + status: 'reverseStatus', + activity_type: 'reverseActivityType', + contact_appeal: 'reverseContactAppeal', + contact_church: 'reverseContactChurch', + contact_city: 'reverseContactCity', + contact_country: 'reverseContactCountry', + contact_designation_account_id: 'reverseContactDesignationAccountId', + contact_ids: 'reverseContactIds', + contact_likely: 'reverseContactLikely', + contact_metro_area: 'reverseContactMetroArea', + contact_pledge_frequency: 'reverseContactPledgeFrequency', + contact_referrer: 'reverseContactReferrer', + contact_region: 'reverseContactRegion', + contact_state: 'reverseContactState', + contact_status: 'reverseContactStatus', + contact_timezone: 'reverseContactTimezone', + next_action: 'reverseNextAction', + result: 'reverseResult', + timezone: 'reverseTimezone', + donation_amount: 'reverseDonationAmount', + user_ids: 'reverseUserIds', +}; + +export const reverseFiltersMap = new Map(Object.entries(reverseFiltersOptions)); diff --git a/src/components/Shared/Forms/FormWrapper.tsx b/src/components/Shared/Forms/FormWrapper.tsx index db739b3d5..60acba143 100644 --- a/src/components/Shared/Forms/FormWrapper.tsx +++ b/src/components/Shared/Forms/FormWrapper.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import Button from '@mui/material/Button'; +import { Button } from '@mui/material'; import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/Shared/Header/ListHeader.test.tsx b/src/components/Shared/Header/ListHeader.test.tsx index 28912e58a..877525651 100644 --- a/src/components/Shared/Header/ListHeader.test.tsx +++ b/src/components/Shared/Header/ListHeader.test.tsx @@ -1,12 +1,14 @@ import React from 'react'; -import Button from '@mui/material/Button'; +import { Button } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; +import { I18nextProvider } from 'react-i18next'; import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { useAccountListId } from 'src/hooks/useAccountListId'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import i18n from 'src/lib/i18n'; import theme from '../../../theme'; import { TasksMassActionsDropdown } from '../MassActions/TasksMassActionsDropdown'; import { @@ -29,7 +31,7 @@ const mockedProps = { const push = jest.fn(); const mockEnqueue = jest.fn(); -jest.mock('../../../../src/hooks/useAccountListId'); +jest.mock('src/hooks/useAccountListId'); jest.mock('notistack', () => ({ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -50,9 +52,11 @@ jest.mock('../../Shared/MassActions/TasksMassActionsDropdown', () => ({ const MocksProviders = (props: { children: JSX.Element }) => ( - - {props.children} - + + + {props.children} + + ); @@ -173,22 +177,27 @@ describe('ListHeader', () => { }); }); - it('opens the more actions menu and clicks the add tags action', () => { - const { getByPlaceholderText, getByTestId, getByText, queryByText } = - render( - - - , - ); + it('opens the more actions menu and clicks the add tags action', async () => { + const { + findByText, + getByPlaceholderText, + getByTestId, + getByText, + queryByText, + } = render( + + + , + ); expect(getByPlaceholderText('Search Contacts')).toBeInTheDocument(); expect(queryByText('Add Tags')).not.toBeInTheDocument(); @@ -197,7 +206,9 @@ describe('ListHeader', () => { expect(getByText('Add Tags')).toBeInTheDocument(); userEvent.click(getByText('Add Tags')); expect( - queryByText('Create New Tags (separate multiple tags with Enter key) *'), + await findByText( + 'Create New Tags (separate multiple tags with Enter key) *', + ), ).toBeInTheDocument(); expect(getByTestId('star-filter-button')).toBeInTheDocument(); expect(getByTestId('showing-text')).toBeInTheDocument(); diff --git a/src/components/Shared/Header/StarFilterButton/StarFilterButton.tsx b/src/components/Shared/Header/StarFilterButton/StarFilterButton.tsx index 91d015428..45984c979 100644 --- a/src/components/Shared/Header/StarFilterButton/StarFilterButton.tsx +++ b/src/components/Shared/Header/StarFilterButton/StarFilterButton.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import Box from '@mui/material/Box'; -import IconButton from '@mui/material/IconButton'; +import { Box, IconButton } from '@mui/material'; import { styled } from '@mui/material/styles'; import { ContactFilterSetInput, diff --git a/src/components/Shared/HideContactsModal/DynamicHideContactsModal.tsx b/src/components/Shared/HideContactsModal/DynamicHideContactsModal.tsx new file mode 100644 index 000000000..ff2bad136 --- /dev/null +++ b/src/components/Shared/HideContactsModal/DynamicHideContactsModal.tsx @@ -0,0 +1,11 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadHideContactsModal = () => + import( + /* webpackChunkName: "HideContactsModal" */ './HideContactsModal' + ).then(({ HideContactsModal }) => HideContactsModal); + +export const DynamicHideContactsModal = dynamic(preloadHideContactsModal, { + loading: DynamicModalPlaceholder, +}); diff --git a/src/components/Shared/MassActions/ContactsMassActionsDropdown.test.tsx b/src/components/Shared/MassActions/ContactsMassActionsDropdown.test.tsx index af4c83692..14ca92adb 100644 --- a/src/components/Shared/MassActions/ContactsMassActionsDropdown.test.tsx +++ b/src/components/Shared/MassActions/ContactsMassActionsDropdown.test.tsx @@ -7,7 +7,7 @@ import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; -import { ContactsProvider } from 'pages/accountLists/[accountListId]/contacts/ContactsContext'; +import { ContactsProvider } from 'src/components/Contacts/ContactsContext/ContactsContext'; import { AppSettingsProvider } from 'src/components/common/AppSettings/AppSettingsProvider'; import { useAccountListId } from 'src/hooks/useAccountListId'; import theme from 'src/theme'; @@ -21,7 +21,7 @@ const mockEnqueue = jest.fn(); const openTaskModal = jest.fn(); jest.mock('../../../hooks/useTaskModal'); -jest.mock('../../../../src/hooks/useAccountListId'); +jest.mock('src/hooks/useAccountListId'); jest.mock('next-auth/react'); jest.mock('notistack', () => ({ // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -57,29 +57,30 @@ describe('ContactsMassActionsDropdown', () => { beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); (useAccountListId as jest.Mock).mockReturnValue('123456789'); massDeselectAll.mockClear(); }); it('opens the more actions menu and clicks the add tags action', async () => { - const { queryByText, getByTestId } = render(); + const { queryByText, getByTestId, findByText } = render( + , + ); expect(queryByText('Add Tags')).not.toBeInTheDocument(); const actionsButton = queryByText('Actions') as HTMLInputElement; userEvent.click(actionsButton); const button = queryByText('Add Tags') as HTMLInputElement; await waitFor(() => expect(button).toBeInTheDocument()); userEvent.click(button); - const text = queryByText( - 'Create New Tags (separate multiple tags with Enter key) *', - ); - await waitFor(() => expect(text).toBeInTheDocument()); + const text = 'Create New Tags (separate multiple tags with Enter key) *'; + expect(await findByText(text)).toBeInTheDocument(); userEvent.click(getByTestId('CloseIcon') as HTMLInputElement); - await waitFor(() => expect(text).not.toBeInTheDocument()); + await waitFor(() => expect(queryByText(text)).not.toBeInTheDocument()); }); it('opens the more actions menu and clicks the edit fields action', async () => { - const { getByRole, queryByTestId, queryByText } = render( + const { getByRole, queryByTestId, findByTestId, queryByText } = render( , ); expect(queryByText('Edit Fields')).not.toBeInTheDocument(); @@ -88,14 +89,16 @@ describe('ContactsMassActionsDropdown', () => { const button = queryByText('Edit Fields') as HTMLInputElement; await waitFor(() => expect(button).toBeInTheDocument()); userEvent.click(button); - const modal = queryByTestId('EditFieldsModal') as HTMLInputElement; - await waitFor(() => expect(modal).toBeInTheDocument()); + const modalTestId = 'EditFieldsModal'; + expect(await findByTestId(modalTestId)).toBeInTheDocument(); userEvent.click(getByRole('button', { name: 'Close' })); - await waitFor(() => expect(modal).not.toBeInTheDocument()); + await waitFor(() => + expect(queryByTestId(modalTestId)).not.toBeInTheDocument(), + ); }); it('opens the more actions menu and clicks the add to appeal action', async () => { - const { getAllByTestId, queryByTestId, queryByText } = render( + const { getAllByTestId, queryByTestId, findByTestId, queryByText } = render( , ); expect(queryByText('Add to Appeal')).not.toBeInTheDocument(); @@ -103,15 +106,16 @@ describe('ContactsMassActionsDropdown', () => { const button = queryByText('Add to Appeal') as HTMLInputElement; await waitFor(() => expect(button).toBeInTheDocument()); userEvent.click(button); - const modal = queryByTestId('AddToAppealModal') as HTMLInputElement; - await waitFor(() => expect(modal).toBeInTheDocument()); + expect(await findByTestId('AddToAppealModal')).toBeInTheDocument(); userEvent.click(getAllByTestId('CloseIcon')[0] as HTMLInputElement); - await waitFor(() => expect(modal).not.toBeInTheDocument()); + await waitFor(() => + expect(queryByTestId('AddToAppealModal')).not.toBeInTheDocument(), + ); }); it('opens the more actions menu and clicks the add to new appeal action', async () => { - const { queryByTestId, queryByText, getByRole } = render( + const { queryByTestId, queryByText, findByTestId, getByRole } = render( , ); expect(queryByText('Add to New Appeal')).not.toBeInTheDocument(); @@ -119,8 +123,7 @@ describe('ContactsMassActionsDropdown', () => { const button = queryByText('Add to New Appeal') as HTMLInputElement; await waitFor(() => expect(button).toBeInTheDocument()); userEvent.click(button); - const modal = queryByTestId('CreateAppealModal') as HTMLInputElement; - await waitFor(() => expect(modal).toBeInTheDocument()); + expect(await findByTestId('CreateAppealModal')).toBeInTheDocument(); // Create Appeal userEvent.type(getByRole('textbox', { name: /appeal/i }), 'NewAppeal'); await waitFor(() => expect(queryByText('Save')).not.toBeDisabled()); @@ -130,7 +133,9 @@ describe('ContactsMassActionsDropdown', () => { variant: 'success', }), ); - await waitFor(() => expect(modal).not.toBeInTheDocument()); + await waitFor(() => + expect(queryByTestId('CreateAppealModal')).not.toBeInTheDocument(), + ); }); it('opens the more actions menu and clicks the hide contacts action', async () => { @@ -212,20 +217,15 @@ describe('ContactsMassActionsDropdown', () => { }); it('opens export contacts modal, then open Mail Merged Label modal', async () => { - const { getByText, queryByText, getByTestId, queryByTestId } = render( - , - ); + const { getByText, queryByText, getByTestId, queryByTestId, findByText } = + render(); expect(queryByText('Export')).not.toBeInTheDocument(); const actionsButton = getByText('Actions') as HTMLInputElement; userEvent.click(actionsButton); expect(getByText('Export')).toBeInTheDocument(); userEvent.click(getByText('Export')); - const pdfExport = getByText( - 'PDF of Mail Merged Labels', - ) as HTMLInputElement; - await waitFor(() => expect(pdfExport).toBeInTheDocument()); - userEvent.click(pdfExport); + userEvent.click(await findByText('PDF of Mail Merged Labels')); await waitFor(() => expect(getByTestId('MailMergedLabel')).toBeInTheDocument(), ); @@ -253,9 +253,9 @@ describe('ContactsMassActionsDropdown', () => { ); }); - it('opens merge contacts modal with multiple id selected', () => { + it('opens merge contacts modal with multiple id selected', async () => { const selectedIdsMerge = ['abc', 'def']; - const { getByTestId, getByText, queryByText } = render( + const { getByTestId, getByText, findByTestId, queryByText } = render( @@ -287,9 +287,8 @@ describe('ContactsMassActionsDropdown', () => { expect(queryByText('Merge')).not.toBeInTheDocument(); const actionsButton = getByText('Actions') as HTMLInputElement; userEvent.click(actionsButton); - expect(getByText('Merge')).toBeInTheDocument(); userEvent.click(getByText('Merge')); - expect(getByTestId('MergeModal')).toBeInTheDocument(); + expect(await findByTestId('MergeModal')).toBeInTheDocument(); userEvent.click(getByTestId('CloseIcon') as HTMLInputElement); }); diff --git a/src/components/Shared/MassActions/ContactsMassActionsDropdown.tsx b/src/components/Shared/MassActions/ContactsMassActionsDropdown.tsx index f75f606a6..580adabe9 100644 --- a/src/components/Shared/MassActions/ContactsMassActionsDropdown.tsx +++ b/src/components/Shared/MassActions/ContactsMassActionsDropdown.tsx @@ -4,21 +4,48 @@ import { Hidden, ListItemText, Menu, MenuItem } from '@mui/material'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import { ContactsDocument } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; -import { MassActionsAddTagsModal } from 'src/components/Contacts/MassActions/AddTags/MassActionsAddTagsModal'; -import { MassActionsAddToAppealModal } from 'src/components/Contacts/MassActions/AddToAppeal/MassActionsAddToAppealModal'; -import { MassActionsCreateAppealModal } from 'src/components/Contacts/MassActions/AddToAppeal/MassActionsCreateAppealModal'; -import { MassActionsEditFieldsModal } from 'src/components/Contacts/MassActions/EditFields/MassActionsEditFieldsModal'; -import { MassActionsExportEmailsModal } from 'src/components/Contacts/MassActions/Exports/Emails/MassActionsExportEmailsModal'; -import { ExportsModal } from 'src/components/Contacts/MassActions/Exports/ExportsModal'; -import { MailMergedLabelModal } from 'src/components/Contacts/MassActions/Exports/MailMergedLabelModal/MailMergedLabelModal'; +import { + DynamicMassActionsAddTagsModal, + preloadMassActionsAddTagsModal, +} from 'src/components/Contacts/MassActions/AddTags/DynamicMassActionsAddTagsModal'; +import { + DynamicMassActionsAddToAppealModal, + preloadMassActionsAddToAppealModal, +} from 'src/components/Contacts/MassActions/AddToAppeal/DynamicMassActionsAddToAppealModal'; +import { + DynamicMassActionsCreateAppealModal, + preloadMassActionsCreateAppealModal, +} from 'src/components/Contacts/MassActions/AddToAppeal/DynamicMassActionsCreateAppealModal'; +import { + DynamicMassActionsEditFieldsModal, + preloadMassActionsEditFieldsModal, +} from 'src/components/Contacts/MassActions/EditFields/DynamicMassActionsEditFieldsModal'; +import { + DynamicExportsModal, + preloadExportsModal, +} from 'src/components/Contacts/MassActions/Exports/DynamicExportsModal'; +import { + DynamicMassActionsExportEmailsModal, + preloadMassActionsExportEmailsModal, +} from 'src/components/Contacts/MassActions/Exports/Emails/DynamicMassActionsExportEmailsModal'; +import { DynamicMailMergedLabelModal } from 'src/components/Contacts/MassActions/Exports/MailMergedLabelModal/DynamicMailMergedLabelModal'; import { useMassActionsUpdateContactsMutation } from 'src/components/Contacts/MassActions/MassActionsUpdateContacts.generated'; -import { MassActionsMergeModal } from 'src/components/Contacts/MassActions/Merge/MassActionsMergeModal'; -import { MassActionsRemoveTagsModal } from 'src/components/Contacts/MassActions/RemoveTags/MassActionsRemoveTagsModal'; -import { HideContactsModal } from 'src/components/Shared/HideContactsModal/HideContactsModal'; +import { + DynamicMassActionsMergeModal, + preloadMassActionsMergeModal, +} from 'src/components/Contacts/MassActions/Merge/DynamicMassActionsMergeModal'; +import { + DynamicMassActionsRemoveTagsModal, + preloadMassActionsRemoveTagsModal, +} from 'src/components/Contacts/MassActions/RemoveTags/DynamicMassActionsRemoveTagsModal'; import { StatusEnum } from 'src/graphql/types.generated'; import useTaskModal from 'src/hooks/useTaskModal'; import { useAccountListId } from '../../../hooks/useAccountListId'; import { TableViewModeEnum } from '../Header/ListHeader'; +import { + DynamicHideContactsModal, + preloadHideContactsModal, +} from '../HideContactsModal/DynamicHideContactsModal'; import { MassActionsDropdown } from './MassActionsDropdown'; interface ContactsMassActionsDropdownProps { @@ -52,7 +79,7 @@ export const ContactsMassActionsDropdown: React.FC< setAnchorEl(null); }; - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const [openRemoveTagsModal, setOpenRemoveTagsModal] = useState(false); const [openAddTagsModal, setOpenAddTagsModal] = useState(false); @@ -121,6 +148,7 @@ export const ContactsMassActionsDropdown: React.FC< setExportsModalOpen(true); handleClose(); }} + onMouseEnter={preloadExportsModal} > {t('Export')} @@ -139,6 +167,7 @@ export const ContactsMassActionsDropdown: React.FC< } handleClose(); }} + onMouseEnter={preloadMassActionsMergeModal} > {t('Merge')} @@ -147,6 +176,7 @@ export const ContactsMassActionsDropdown: React.FC< setOpenAddTagsModal(true); handleClose(); }} + onMouseEnter={preloadMassActionsAddTagsModal} > {t('Add Tags')} @@ -156,6 +186,7 @@ export const ContactsMassActionsDropdown: React.FC< setOpenRemoveTagsModal(true); handleClose(); }} + onMouseEnter={preloadMassActionsRemoveTagsModal} > {t('Remove Tags')} @@ -167,6 +198,7 @@ export const ContactsMassActionsDropdown: React.FC< }); handleClose(); }} + onMouseEnter={() => preloadTaskModal('add')} > {t('Add Task')} @@ -179,6 +211,7 @@ export const ContactsMassActionsDropdown: React.FC< }); handleClose(); }} + onMouseEnter={() => preloadTaskModal('log')} > {t('Log Task')} @@ -188,6 +221,7 @@ export const ContactsMassActionsDropdown: React.FC< setEditFieldsModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsEditFieldsModal} > {t('Edit Fields')} @@ -196,6 +230,7 @@ export const ContactsMassActionsDropdown: React.FC< setHideContactsModalOpen(true); handleClose(); }} + onMouseEnter={preloadHideContactsModal} > {t('Hide Contacts')} @@ -205,6 +240,7 @@ export const ContactsMassActionsDropdown: React.FC< setAddToAppealModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsAddToAppealModal} > {t('Add to Appeal')} @@ -214,6 +250,7 @@ export const ContactsMassActionsDropdown: React.FC< setCreateAppealModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsCreateAppealModal} > {t('Add to New Appeal')} @@ -223,6 +260,7 @@ export const ContactsMassActionsDropdown: React.FC< setExportEmailsModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsExportEmailsModal} > {t('Export Emails')} @@ -235,42 +273,42 @@ export const ContactsMassActionsDropdown: React.FC< {buttonGroup} {openRemoveTagsModal && ( - setOpenRemoveTagsModal(false)} /> )} {openAddTagsModal && ( - setOpenAddTagsModal(false)} /> )} {addToAppealModalOpen && ( - setAddToAppealModalOpen(false)} /> )} {createAppealModalOpen && ( - setCreateAppealModalOpen(false)} /> )} {editFieldsModalOpen && ( - setEditFieldsModalOpen(false)} /> )} {hideContactsModalOpen && ( - )} {exportsModalOpen && ( - setExportsModalOpen(false)} @@ -286,21 +324,21 @@ export const ContactsMassActionsDropdown: React.FC< /> )} {labelModalOpen && ( - setLabelModalOpen(false)} /> )} {exportEmailsModalOpen && ( - setExportEmailsModalOpen(false)} /> )} {mergeModalOpen && ( - setMergeModalOpen(false)} diff --git a/src/components/Shared/MassActions/TasksMassActionsDropdown.test.tsx b/src/components/Shared/MassActions/TasksMassActionsDropdown.test.tsx index efba72104..9ae3832e0 100644 --- a/src/components/Shared/MassActions/TasksMassActionsDropdown.test.tsx +++ b/src/components/Shared/MassActions/TasksMassActionsDropdown.test.tsx @@ -5,9 +5,11 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { render, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; +import { I18nextProvider } from 'react-i18next'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { GetTasksForAddingTagsQuery } from 'src/components/Task/MassActions/AddTags/TasksAddTags.generated'; import { useAccountListId } from 'src/hooks/useAccountListId'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import i18n from 'src/lib/i18n'; import theme from '../../../theme'; import { TasksMassActionsDropdown } from './TasksMassActionsDropdown'; @@ -36,7 +38,7 @@ const mocks = { }, }; -jest.mock('../../../../src/hooks/useAccountListId'); +jest.mock('src/hooks/useAccountListId'); jest.mock('notistack', () => ({ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -50,17 +52,19 @@ jest.mock('notistack', () => ({ const TaskComponents = () => ( - - - - - - - + + + + + + + + + ); @@ -71,13 +75,15 @@ beforeEach(() => { describe('TasksMassActionsDropdown', () => { it('opens the more actions menu and clicks the complete tasks action', async () => { - const { getByRole, getByTestId, getByText, queryByTestId, queryByText } = + const { getByRole, getByText, findByTestId, queryByTestId, queryByText } = render(); expect(queryByText('Complete Tasks')).not.toBeInTheDocument(); userEvent.click(getByText('Actions')); userEvent.click(getByText('Complete Tasks')); - expect(getByTestId('CompleteAndDeleteTasksModal')).toBeInTheDocument(); + expect( + await findByTestId('CompleteAndDeleteTasksModal'), + ).toBeInTheDocument(); userEvent.click(getByRole('button', { name: 'Yes' })); await waitFor(() => @@ -91,17 +97,21 @@ describe('TasksMassActionsDropdown', () => { }); it('opens the more actions menu and clicks the edit tasks action', async () => { - const { queryByTestId, getByText, queryByText, getByLabelText, getByRole } = - render(); + const { + queryByTestId, + findByTestId, + getByText, + queryByText, + getByLabelText, + getByRole, + } = render(); expect(queryByText('Edit Tasks')).not.toBeInTheDocument(); const actionsButton = getByText('Actions') as HTMLInputElement; userEvent.click(actionsButton); expect(getByText('Edit Tasks')).toBeInTheDocument(); userEvent.click(getByText('Edit Tasks')); - await waitFor(() => - expect(queryByTestId('EditTasksModal')).toBeInTheDocument(), - ); + expect(await findByTestId('EditTasksModal')).toBeInTheDocument(); userEvent.click(getByLabelText('Action')); userEvent.click( within(getByRole('listbox', { hidden: true, name: 'Action' })).getByText( diff --git a/src/components/Shared/MassActions/TasksMassActionsDropdown.tsx b/src/components/Shared/MassActions/TasksMassActionsDropdown.tsx index fe36d8e71..b3c2cbf33 100644 --- a/src/components/Shared/MassActions/TasksMassActionsDropdown.tsx +++ b/src/components/Shared/MassActions/TasksMassActionsDropdown.tsx @@ -3,14 +3,26 @@ import { Hidden, ListItemText, Menu, MenuItem } from '@mui/material'; import { DateTime } from 'luxon'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; -import { MassActionsTasksAddTagsModal } from 'src/components/Task/MassActions/AddTags/MassActionsTasksAddTagsModal'; -import { MassActionsTasksConfirmationModal } from 'src/components/Task/MassActions/ConfirmationModal/MassActionsTasksConfirmationModal'; -import { MassActionsEditTasksModal } from 'src/components/Task/MassActions/EditTasks/MassActionsEditTasksModal'; +import { + DynamicMassActionsTasksAddTagsModal, + preloadMassActionsTasksAddTagsModal, +} from 'src/components/Task/MassActions/AddTags/DynamicMassActionsTasksAddTagsModal'; +import { + DynamicMassActionsTasksConfirmationModal, + preloadMassActionsTasksConfirmationModal, +} from 'src/components/Task/MassActions/ConfirmationModal/DynamicMassActionsTasksConfirmationModal'; +import { + DynamicMassActionsEditTasksModal, + preloadMassActionsEditTasksModal, +} from 'src/components/Task/MassActions/EditTasks/DynamicMassActionsEditTasksModal'; import { useMassActionsDeleteTasksMutation, useMassActionsUpdateTasksMutation, } from 'src/components/Task/MassActions/MassActionsUpdateTasks.generated'; -import { MassActionsTasksRemoveTagsModal } from 'src/components/Task/MassActions/RemoveTags/MassActionsTasksRemoveTagsModal'; +import { + DynamicMassActionsTasksRemoveTagsModal, + preloadMassActionsTasksRemoveTagsModal, +} from 'src/components/Task/MassActions/RemoveTags/DynamicMassActionsTasksRemoveTagsModal'; import { ResultEnum } from 'src/graphql/types.generated'; import { useUpdateTasksQueries } from 'src/hooks/useUpdateTasksQueries'; import { dispatch } from 'src/lib/analytics'; @@ -122,6 +134,7 @@ export const TasksMassActionsDropdown: React.FC< setCompleteTasksModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsTasksConfirmationModal} > {t('Complete Tasks')} @@ -132,6 +145,7 @@ export const TasksMassActionsDropdown: React.FC< setEditTasksModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsEditTasksModal} > {t('Edit Tasks')} @@ -140,6 +154,7 @@ export const TasksMassActionsDropdown: React.FC< setAddTagsModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsTasksAddTagsModal} > {t('Add Tag(s)')} @@ -150,6 +165,7 @@ export const TasksMassActionsDropdown: React.FC< setRemoveTagsModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsTasksRemoveTagsModal} > {t('Remove Tag(s)')} @@ -159,6 +175,7 @@ export const TasksMassActionsDropdown: React.FC< setDeleteTasksModalOpen(true); handleClose(); }} + onMouseEnter={preloadMassActionsTasksConfirmationModal} > {t('Delete Tasks')} @@ -168,7 +185,7 @@ export const TasksMassActionsDropdown: React.FC< {completeTasksModalOpen && ( - )} {addTagsModalOpen && ( - )} {deleteTasksModalOpen && ( - )} {editTasksModalOpen && ( - )} {removeTagsModalOpen && ( - ({ + color: theme.palette.cruGrayMedium.main, + marginRight: theme.spacing(1), +})); + +export const ContactTagInput = styled(TextField)(({ theme }) => ({ + '&& .MuiInput-underline:before ': { + borderBottom: `2px solid ${theme.palette.divider}`, + }, + '&& .MuiInput-underline:after ': { + borderBottom: `2px solid ${theme.palette.divider}`, + }, + '&& .MuiInputBase-input': { + minWidth: '200px', + }, + '& ::placeholder': { + color: theme.palette.info.main, + opacity: 1, + }, + '& :hover::placeholder': { + textDecoration: 'underline', + }, + '& :focus::placeholder': { + textDecoration: 'none', + color: theme.palette.cruGrayMedium.main, + }, + margin: theme.spacing(1), + marginLeft: '0', +})); diff --git a/src/components/Task/MassActions/AddTags/DynamicMassActionsTasksAddTagsModal.tsx b/src/components/Task/MassActions/AddTags/DynamicMassActionsTasksAddTagsModal.tsx new file mode 100644 index 000000000..9b0082679 --- /dev/null +++ b/src/components/Task/MassActions/AddTags/DynamicMassActionsTasksAddTagsModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsTasksAddTagsModal = () => + import( + /* webpackChunkName: "MassActionsTasksAddTagsModal" */ './MassActionsTasksAddTagsModal' + ).then(({ MassActionsTasksAddTagsModal }) => MassActionsTasksAddTagsModal); + +export const DynamicMassActionsTasksAddTagsModal = dynamic( + preloadMassActionsTasksAddTagsModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Task/MassActions/AddTags/MassActionsTasksAddTagsModal.tsx b/src/components/Task/MassActions/AddTags/MassActionsTasksAddTagsModal.tsx index 78d27dc7e..cae4f73f6 100644 --- a/src/components/Task/MassActions/AddTags/MassActionsTasksAddTagsModal.tsx +++ b/src/components/Task/MassActions/AddTags/MassActionsTasksAddTagsModal.tsx @@ -15,6 +15,7 @@ import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import * as yup from 'yup'; import { ContactsDocument } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; +import { ContactTagIcon, ContactTagInput } from 'src/components/Tags/Tags'; import { CancelButton, SubmitButton, @@ -23,10 +24,6 @@ import { ContactUpdateInput } from 'src/graphql/types.generated'; import { useFetchAllPages } from 'src/hooks/useFetchAllPages'; import { useUpdateTasksQueries } from 'src/hooks/useUpdateTasksQueries'; import theme from 'src/theme'; -import { - ContactTagIcon, - ContactTagInput, -} from '../../../Contacts/ContactDetails/ContactDetailsTab/Tags/ContactTags'; import Modal from '../../../common/Modal/Modal'; import { IncompleteWarning } from '../IncompleteWarning/IncompleteWarning'; import { diff --git a/src/components/Task/MassActions/ConfirmationModal/DynamicMassActionsTasksConfirmationModal.tsx b/src/components/Task/MassActions/ConfirmationModal/DynamicMassActionsTasksConfirmationModal.tsx new file mode 100644 index 000000000..f838481bb --- /dev/null +++ b/src/components/Task/MassActions/ConfirmationModal/DynamicMassActionsTasksConfirmationModal.tsx @@ -0,0 +1,15 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsTasksConfirmationModal = () => + import( + /* webpackChunkName: "MassActionsTasksConfirmationModal" */ './MassActionsTasksConfirmationModal' + ).then( + ({ MassActionsTasksConfirmationModal }) => + MassActionsTasksConfirmationModal, + ); + +export const DynamicMassActionsTasksConfirmationModal = dynamic( + preloadMassActionsTasksConfirmationModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Task/MassActions/EditTasks/DynamicMassActionsEditTasksModal.tsx b/src/components/Task/MassActions/EditTasks/DynamicMassActionsEditTasksModal.tsx new file mode 100644 index 000000000..ba608dccd --- /dev/null +++ b/src/components/Task/MassActions/EditTasks/DynamicMassActionsEditTasksModal.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsEditTasksModal = () => + import( + /* webpackChunkName: "MassActionsEditTasksModal" */ './MassActionsEditTasksModal' + ).then(({ MassActionsEditTasksModal }) => MassActionsEditTasksModal); + +export const DynamicMassActionsEditTasksModal = dynamic( + preloadMassActionsEditTasksModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Task/MassActions/RemoveTags/DynamicMassActionsTasksRemoveTagsModal.tsx b/src/components/Task/MassActions/RemoveTags/DynamicMassActionsTasksRemoveTagsModal.tsx new file mode 100644 index 000000000..9def958ed --- /dev/null +++ b/src/components/Task/MassActions/RemoveTags/DynamicMassActionsTasksRemoveTagsModal.tsx @@ -0,0 +1,14 @@ +import dynamic from 'next/dynamic'; +import { DynamicModalPlaceholder } from 'src/components/DynamicPlaceholders/DynamicModalPlaceholder'; + +export const preloadMassActionsTasksRemoveTagsModal = () => + import( + /* webpackChunkName: "MassActionsTasksRemoveTagsModal" */ './MassActionsTasksRemoveTagsModal' + ).then( + ({ MassActionsTasksRemoveTagsModal }) => MassActionsTasksRemoveTagsModal, + ); + +export const DynamicMassActionsTasksRemoveTagsModal = dynamic( + preloadMassActionsTasksRemoveTagsModal, + { loading: DynamicModalPlaceholder }, +); diff --git a/src/components/Task/Modal/Comments/DynamicTaskModalCommentsList.tsx b/src/components/Task/Modal/Comments/DynamicTaskModalCommentsList.tsx new file mode 100644 index 000000000..f429e9439 --- /dev/null +++ b/src/components/Task/Modal/Comments/DynamicTaskModalCommentsList.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadTaskModalCommentsList = () => + import( + /* webpackChunkName: "TaskModalCommentsList" */ './TaskModalCommentsList' + ).then(({ TaskModalCommentsList }) => TaskModalCommentsList); + +export const DynamicTaskModalCommentsList = dynamic( + preloadTaskModalCommentsList, + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Task/Modal/Comments/Item/TaskModalCommentListItem.tsx b/src/components/Task/Modal/Comments/Item/TaskModalCommentListItem.tsx index 549d5522d..8a21d8c45 100644 --- a/src/components/Task/Modal/Comments/Item/TaskModalCommentListItem.tsx +++ b/src/components/Task/Modal/Comments/Item/TaskModalCommentListItem.tsx @@ -15,7 +15,7 @@ import { } from 'src/components/common/Modal/ActionButtons/ActionButtons'; import { useAccountListId } from 'src/hooks/useAccountListId'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormat } from 'src/lib/intlFormat/intlFormat'; +import { dateFormat } from 'src/lib/intlFormat'; import theme from '../../../../../theme'; import { CommentSchemaAttributes, commentSchema } from '../Form/commentSchema'; import { diff --git a/src/components/Task/Modal/Form/Complete/DynamicTaskModalCompleteForm.tsx b/src/components/Task/Modal/Form/Complete/DynamicTaskModalCompleteForm.tsx new file mode 100644 index 000000000..975094e5b --- /dev/null +++ b/src/components/Task/Modal/Form/Complete/DynamicTaskModalCompleteForm.tsx @@ -0,0 +1,12 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadTaskModalCompleteForm = () => + import( + /* webpackChunkName: "TaskModalCompleteForm" */ './TaskModalCompleteForm' + ); + +export const DynamicTaskModalCompleteForm = dynamic( + preloadTaskModalCompleteForm, + { loading: DynamicComponentPlaceholder }, +); diff --git a/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx b/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx index b172ea5fc..8cc1296a5 100644 --- a/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx +++ b/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { render, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { DateTime } from 'luxon'; +import TestWrapper from '__tests__/util/TestWrapper'; import { ActivityTypeEnum, NotificationTimeUnitEnum, @@ -9,7 +10,6 @@ import { ResultEnum, } from 'src/graphql/types.generated'; import { dispatch } from 'src/lib/analytics'; -import TestWrapper from '../../../../../../__tests__/util/TestWrapper'; import useTaskModal from '../../../../../hooks/useTaskModal'; import { GetThisWeekDefaultMocks } from '../../../../Dashboard/ThisWeek/ThisWeek.mock'; import { CompleteTaskDocument } from './CompleteTask.generated'; @@ -27,6 +27,7 @@ const openTaskModal = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Task/Modal/Form/DynamicTaskModalForm.tsx b/src/components/Task/Modal/Form/DynamicTaskModalForm.tsx new file mode 100644 index 000000000..6ecead6fd --- /dev/null +++ b/src/components/Task/Modal/Form/DynamicTaskModalForm.tsx @@ -0,0 +1,9 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadTaskModalForm = () => + import(/* webpackChunkName: "TaskModalForm" */ './TaskModalForm'); + +export const DynamicTaskModalForm = dynamic(preloadTaskModalForm, { + loading: DynamicComponentPlaceholder, +}); diff --git a/src/components/Task/Modal/Form/LogForm/DynamicTaskModalLogForm.tsx b/src/components/Task/Modal/Form/LogForm/DynamicTaskModalLogForm.tsx new file mode 100644 index 000000000..df9a929d2 --- /dev/null +++ b/src/components/Task/Modal/Form/LogForm/DynamicTaskModalLogForm.tsx @@ -0,0 +1,9 @@ +import dynamic from 'next/dynamic'; +import { DynamicComponentPlaceholder } from 'src/components/DynamicPlaceholders/DynamicComponentPlaceholder'; + +export const preloadTaskModalLogForm = () => + import(/* webpackChunkName: "TaskModalLogForm" */ './TaskModalLogForm'); + +export const DynamicTaskModalLogForm = dynamic(preloadTaskModalLogForm, { + loading: DynamicComponentPlaceholder, +}); diff --git a/src/components/Task/Modal/Form/LogForm/TaskModalLogForm.test.tsx b/src/components/Task/Modal/Form/LogForm/TaskModalLogForm.test.tsx index 890811cb7..8d2b08eac 100644 --- a/src/components/Task/Modal/Form/LogForm/TaskModalLogForm.test.tsx +++ b/src/components/Task/Modal/Form/LogForm/TaskModalLogForm.test.tsx @@ -32,6 +32,7 @@ const router = { beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Task/Modal/Form/TaskModalForm.test.tsx b/src/components/Task/Modal/Form/TaskModalForm.test.tsx index ac0f95368..a9dc24af4 100644 --- a/src/components/Task/Modal/Form/TaskModalForm.test.tsx +++ b/src/components/Task/Modal/Form/TaskModalForm.test.tsx @@ -26,6 +26,7 @@ const openTaskModal = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Task/Modal/Form/TaskModalForm.tsx b/src/components/Task/Modal/Form/TaskModalForm.tsx index 6811073ff..62436ca62 100644 --- a/src/components/Task/Modal/Form/TaskModalForm.tsx +++ b/src/components/Task/Modal/Form/TaskModalForm.tsx @@ -20,7 +20,6 @@ import { Typography, } from '@mui/material'; import { Formik } from 'formik'; -import _ from 'lodash'; import { DateTime } from 'luxon'; import { useSession } from 'next-auth/react'; import { useSnackbar } from 'notistack'; diff --git a/src/components/Task/Modal/TaskModal.tsx b/src/components/Task/Modal/TaskModal.tsx index f41987ee0..fc5c8a5c0 100644 --- a/src/components/Task/Modal/TaskModal.tsx +++ b/src/components/Task/Modal/TaskModal.tsx @@ -5,10 +5,10 @@ import { TaskCreateInput, TaskUpdateInput } from 'src/graphql/types.generated'; import { useAccountListId } from '../../../hooks/useAccountListId'; import Loading from '../../Loading'; import Modal from '../../common/Modal/Modal'; -import { TaskModalCommentsList } from './Comments/TaskModalCommentsList'; -import TaskModalCompleteForm from './Form/Complete/TaskModalCompleteForm'; -import TaskModalLogForm from './Form/LogForm/TaskModalLogForm'; -import TaskModalForm from './Form/TaskModalForm'; +import { DynamicTaskModalCommentsList } from './Comments/DynamicTaskModalCommentsList'; +import { DynamicTaskModalCompleteForm } from './Form/Complete/DynamicTaskModalCompleteForm'; +import { DynamicTaskModalForm } from './Form/DynamicTaskModalForm'; +import { DynamicTaskModalLogForm } from './Form/LogForm/DynamicTaskModalLogForm'; import { useGetTaskForTaskModalQuery } from './TaskModalTask.generated'; export interface TaskModalProps { @@ -65,7 +65,7 @@ const TaskModal = ({ case 'complete': if (task) { return ( - ({ openTaskModal: () => undefined, + preloadTaskModal: () => undefined, taskModals: [], }); diff --git a/src/components/Task/Modal/TaskModalProvider.tsx b/src/components/Task/Modal/TaskModalProvider.tsx index fb005b366..82155a040 100644 --- a/src/components/Task/Modal/TaskModalProvider.tsx +++ b/src/components/Task/Modal/TaskModalProvider.tsx @@ -1,6 +1,10 @@ import { ReactElement, ReactNode, useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; import theme from 'src/theme'; +import { preloadTaskModalCommentsList } from './Comments/DynamicTaskModalCommentsList'; +import { preloadTaskModalCompleteForm } from './Form/Complete/DynamicTaskModalCompleteForm'; +import { preloadTaskModalForm } from './Form/DynamicTaskModalForm'; +import { preloadTaskModalLogForm } from './Form/LogForm/DynamicTaskModalLogForm'; import TaskModal, { TaskModalProps } from './TaskModal'; import TaskModalContext from './TaskModalContext'; @@ -10,6 +14,7 @@ interface Props { export interface TaskModalProviderContext { openTaskModal: (props: TaskModalProps) => void; + preloadTaskModal: (view: TaskModalProps['view']) => void; taskModals: TaskModalPropsWithId[]; } @@ -48,8 +53,20 @@ const TaskModalProvider = ({ children }: Props): ReactElement => { ]); } }; + const preloadTaskModal = (view: TaskModalProps['view']) => { + if (view === 'complete') { + preloadTaskModalCompleteForm(); + } else if (view === 'comments') { + preloadTaskModalCommentsList(); + } else if (view === 'log') { + preloadTaskModalLogForm(); + } else { + preloadTaskModalForm(); + } + }; const value: TaskModalProviderContext = { openTaskModal, + preloadTaskModal, taskModals, }; diff --git a/src/components/Task/Status/Status.test.tsx b/src/components/Task/Status/Status.test.tsx index 12739c904..90470979f 100644 --- a/src/components/Task/Status/Status.test.tsx +++ b/src/components/Task/Status/Status.test.tsx @@ -13,6 +13,7 @@ const openTaskModal = jest.fn(); beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Task/Status/Status.tsx b/src/components/Task/Status/Status.tsx index c6a6d6f09..b63929750 100644 --- a/src/components/Task/Status/Status.tsx +++ b/src/components/Task/Status/Status.tsx @@ -1,8 +1,7 @@ import React, { ReactElement } from 'react'; import AssignmentTurnedInIcon from '@mui/icons-material/AssignmentTurnedIn'; import Check from '@mui/icons-material/Check'; -import { Avatar, Theme, Tooltip } from '@mui/material'; -import IconButton from '@mui/material/IconButton'; +import { Avatar, IconButton, Theme, Tooltip } from '@mui/material'; import { styled } from '@mui/material/styles'; import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; @@ -103,7 +102,7 @@ const CompleteButton = ({ taskId: string; title?: string; }): ReactElement => { - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const handleClick = ( event: React.MouseEvent, @@ -112,7 +111,10 @@ const CompleteButton = ({ event.stopPropagation(); }; return ( - + preloadTaskModal('complete')} + > ); diff --git a/src/components/Task/TaskRow/TaskRow.stories.tsx b/src/components/Task/TaskRow/TaskRow.stories.tsx index f694d7ae7..d427d9739 100644 --- a/src/components/Task/TaskRow/TaskRow.stories.tsx +++ b/src/components/Task/TaskRow/TaskRow.stories.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; +import { gqlMock } from '__tests__/util/graphqlMocking'; import { ResultEnum } from 'src/graphql/types.generated'; -import { gqlMock } from '../../../../__tests__/util/graphqlMocking'; import { TaskRow } from './TaskRow'; import { TaskRowFragment, TaskRowFragmentDoc } from './TaskRow.generated'; diff --git a/src/components/Task/TaskRow/TaskRow.test.tsx b/src/components/Task/TaskRow/TaskRow.test.tsx index 33c7eb5c9..fee703d89 100644 --- a/src/components/Task/TaskRow/TaskRow.test.tsx +++ b/src/components/Task/TaskRow/TaskRow.test.tsx @@ -2,11 +2,8 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { GqlMockedProvider, gqlMock } from '__tests__/util/graphqlMocking'; import { ResultEnum } from 'src/graphql/types.generated'; -import { - GqlMockedProvider, - gqlMock, -} from '../../../../__tests__/util/graphqlMocking'; import useTaskModal from '../../../hooks/useTaskModal'; import theme from '../../../theme'; import { TaskRow } from './TaskRow'; @@ -38,6 +35,7 @@ jest.mock('notistack', () => ({ beforeEach(() => { (useTaskModal as jest.Mock).mockReturnValue({ openTaskModal, + preloadTaskModal: jest.fn(), }); }); diff --git a/src/components/Task/TaskRow/TaskRow.tsx b/src/components/Task/TaskRow/TaskRow.tsx index 65e5a56c3..f1c8b9bbc 100644 --- a/src/components/Task/TaskRow/TaskRow.tsx +++ b/src/components/Task/TaskRow/TaskRow.tsx @@ -96,7 +96,7 @@ export const TaskRow: React.FC = ({ marginTop: useTopMargin ? '20px' : '0', })); - const { openTaskModal } = useTaskModal(); + const { openTaskModal, preloadTaskModal } = useTaskModal(); const onClick = ( event: React.MouseEvent, contactId: string, @@ -176,6 +176,7 @@ export const TaskRow: React.FC = ({ preloadTaskModal('complete')} />
@@ -195,6 +196,7 @@ export const TaskRow: React.FC = ({ handleSubjectPressed(); e.stopPropagation(); }} + onMouseEnter={() => preloadTaskModal('edit')} > {activityType ? getLocalizedTaskType(t, activityType) : ''} @@ -243,6 +245,7 @@ export const TaskRow: React.FC = ({ isComplete={isComplete} numberOfComments={comments?.totalCount} onClick={handleCommentButtonPressed} + onMouseEnter={() => preloadTaskModal('comments')} /> @@ -254,6 +257,7 @@ export const TaskRow: React.FC = ({ isComplete={isComplete} numberOfComments={comments?.totalCount} onClick={handleCommentButtonPressed} + onMouseEnter={() => preloadTaskModal('comments')} small /> diff --git a/src/components/Tool/Appeal/AddAppealForm.tsx b/src/components/Tool/Appeal/AddAppealForm.tsx index e95ff746d..2affe52ed 100644 --- a/src/components/Tool/Appeal/AddAppealForm.tsx +++ b/src/components/Tool/Appeal/AddAppealForm.tsx @@ -21,8 +21,8 @@ import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import * as yup from 'yup'; +import { useContactFiltersQuery } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; import { MultiselectFilter } from 'src/graphql/types.generated'; -import { useContactFiltersQuery } from '../../../../pages/accountLists/[accountListId]/contacts/Contacts.generated'; import { useAccountListId } from '../../../hooks/useAccountListId'; import theme from '../../../theme'; import AnimatedCard from '../../AnimatedCard'; diff --git a/src/components/Tool/Appeal/Appeal.test.tsx b/src/components/Tool/Appeal/Appeal.test.tsx index 7bc077507..10a03494e 100644 --- a/src/components/Tool/Appeal/Appeal.test.tsx +++ b/src/components/Tool/Appeal/Appeal.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; +import TestWrapper from '__tests__/util/TestWrapper'; import theme from '../../../theme'; import Appeal from './Appeal'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsAsked.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsAsked.tsx index 0c5d4cfc1..fe86c4e3b 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsAsked.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsAsked.tsx @@ -5,7 +5,7 @@ import { Box, IconButton } from '@mui/material'; import { DataGrid, GridSelectionModel } from '@mui/x-data-grid'; import i18n from 'i18next'; import { makeStyles } from 'tss-react/mui'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import theme from '../../../../theme'; import { useAppealContext } from '../AppealContextProvider/AppealContextProvider'; import AppealDetailsNoData from './AppealDetailsNoData'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsCommitted.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsCommitted.tsx index cfefe12e4..bd9912e77 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsCommitted.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsCommitted.tsx @@ -5,7 +5,7 @@ import { Box, IconButton } from '@mui/material'; import { DataGrid, GridSelectionModel } from '@mui/x-data-grid'; import i18n from 'i18next'; import { makeStyles } from 'tss-react/mui'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import theme from '../../../../theme'; import { useAppealContext } from '../AppealContextProvider/AppealContextProvider'; import AppealDetailsNoData from './AppealDetailsNoData'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsExcluded.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsExcluded.tsx index 8ba5cb9ba..90d47ee01 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsExcluded.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsExcluded.tsx @@ -5,7 +5,7 @@ import { Box, IconButton } from '@mui/material'; import { DataGrid } from '@mui/x-data-grid'; import i18n from 'i18next'; import { makeStyles } from 'tss-react/mui'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import theme from '../../../../theme'; import AppealDetailsNoData from './AppealDetailsNoData'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsFlow.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsFlow.tsx index 37c3806b8..67a3a7b44 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsFlow.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsFlow.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; import { Box } from '@mui/material'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import theme from '../../../../theme'; import AppealDetailsFlowColumn from './AppealDetailsFlowColumn'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsFlowColumn.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsFlowColumn.tsx index ab2fda784..df8c1fead 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsFlowColumn.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsFlowColumn.tsx @@ -3,7 +3,7 @@ import { mdiDelete, mdiDotsVertical, mdiSquareEditOutline } from '@mdi/js'; import Icon from '@mdi/react'; import StarOutlineIcon from '@mui/icons-material/StarOutline'; import { Box, Grid, Typography } from '@mui/material'; -import { TestContact } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestContact } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import theme from '../../../../theme'; interface Props { diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsGiven.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsGiven.tsx index 138be43a2..d8b05112e 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsGiven.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsGiven.tsx @@ -5,7 +5,7 @@ import { Box, IconButton } from '@mui/material'; import { DataGrid, GridSelectionModel } from '@mui/x-data-grid'; import i18n from 'i18next'; import { makeStyles } from 'tss-react/mui'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import theme from '../../../../theme'; import { useAppealContext } from '../AppealContextProvider/AppealContextProvider'; import AppealDetailsNoData from './AppealDetailsNoData'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsHeader.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsHeader.tsx index 2b7df28b2..c224ddbe7 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsHeader.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsHeader.tsx @@ -8,7 +8,7 @@ import { Box, Button, ButtonGroup, Grid, TextField } from '@mui/material'; import clsx from 'clsx'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import { useAccountListId } from '../../../../hooks/useAccountListId'; import theme from '../../../../theme'; import { useAppealContext } from '../AppealContextProvider/AppealContextProvider'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsMain.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsMain.tsx index 7e14ad289..e01943a98 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsMain.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsMain.tsx @@ -1,5 +1,5 @@ import React, { ReactElement } from 'react'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import { useAppealContext } from '../AppealContextProvider/AppealContextProvider'; import AppealDetailsAsked from './AppealDetailsAsked'; import AppealDetailsCommitted from './AppealDetailsCommitted'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsNoData.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsNoData.tsx index 9435a33e9..4391300b6 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsNoData.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsNoData.tsx @@ -1,6 +1,5 @@ import React, { ReactElement } from 'react'; -import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; +import { Box, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useAppealContext } from '../AppealContextProvider/AppealContextProvider'; diff --git a/src/components/Tool/Appeal/AppealDetails/AppealDetailsReceived.tsx b/src/components/Tool/Appeal/AppealDetails/AppealDetailsReceived.tsx index 6f7d0272b..c411951a1 100644 --- a/src/components/Tool/Appeal/AppealDetails/AppealDetailsReceived.tsx +++ b/src/components/Tool/Appeal/AppealDetails/AppealDetailsReceived.tsx @@ -5,7 +5,7 @@ import { Box, IconButton } from '@mui/material'; import { DataGrid, GridSelectionModel } from '@mui/x-data-grid'; import i18n from 'i18next'; import { makeStyles } from 'tss-react/mui'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import theme from '../../../../theme'; import { useAppealContext } from '../AppealContextProvider/AppealContextProvider'; import AppealDetailsNoData from './AppealDetailsNoData'; diff --git a/src/components/Tool/Appeal/AppealDrawer/AppealDrawer.tsx b/src/components/Tool/Appeal/AppealDrawer/AppealDrawer.tsx index 09399caca..cdd59fa40 100644 --- a/src/components/Tool/Appeal/AppealDrawer/AppealDrawer.tsx +++ b/src/components/Tool/Appeal/AppealDrawer/AppealDrawer.tsx @@ -1,11 +1,10 @@ import React, { ReactElement } from 'react'; import { Drawer } from '@mui/material'; import { makeStyles } from 'tss-react/mui'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import theme from '../../../../theme'; import NavToolDrawerHandle from '../../NavToolList/NavToolDrawerHandle'; import AppealDrawerList from './AppealDrawerList'; -//import { useAppealId } from '../../../../src/hooks/useAppealId'; const useStyles = makeStyles()(() => ({ drawer: { diff --git a/src/components/Tool/Appeal/AppealDrawer/AppealDrawerList.tsx b/src/components/Tool/Appeal/AppealDrawer/AppealDrawerList.tsx index 4bd2e96d3..5b24106b2 100644 --- a/src/components/Tool/Appeal/AppealDrawer/AppealDrawerList.tsx +++ b/src/components/Tool/Appeal/AppealDrawer/AppealDrawerList.tsx @@ -11,7 +11,7 @@ import { } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; -import { TestAppeal } from '../../../../../pages/accountLists/[accountListId]/tools/appeals/testAppeal'; +import { TestAppeal } from 'pages/accountLists/[accountListId]/tools/appeals/testAppeal'; import { useAppealContext } from '../AppealContextProvider/AppealContextProvider'; import { AppealDrawerItem } from './Item/AppealDrawerItem'; import { AppealDrawerItemButton } from './Item/AppealDrawerItemButton'; diff --git a/src/components/Tool/Appeal/AppealDrawer/Item/AppealDrawerItem.tsx b/src/components/Tool/Appeal/AppealDrawer/Item/AppealDrawerItem.tsx index 6224f56b7..95f3a3d9a 100644 --- a/src/components/Tool/Appeal/AppealDrawer/Item/AppealDrawerItem.tsx +++ b/src/components/Tool/Appeal/AppealDrawer/Item/AppealDrawerItem.tsx @@ -1,8 +1,6 @@ import React, { ReactElement } from 'react'; import ArrowForwardIos from '@mui/icons-material/ArrowForwardIos'; -import Box from '@mui/material/Box'; -import ListItem from '@mui/material/ListItem'; -import ListItemText from '@mui/material/ListItemText'; +import { Box, ListItem, ListItemText } from '@mui/material'; import clsx from 'clsx'; import { makeStyles } from 'tss-react/mui'; import theme from '../../../../../theme'; diff --git a/src/components/Tool/Appeal/Appeals.test.tsx b/src/components/Tool/Appeal/Appeals.test.tsx index 396ff6c05..6ee9a2b9b 100644 --- a/src/components/Tool/Appeal/Appeals.test.tsx +++ b/src/components/Tool/Appeal/Appeals.test.tsx @@ -3,9 +3,9 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; -import { GetAppealsQuery } from '../../../../pages/accountLists/[accountListId]/tools/GetAppeals.generated'; +import TestRouter from '__tests__/util/TestRouter'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { GetAppealsQuery } from 'pages/accountLists/[accountListId]/tools/GetAppeals.generated'; import theme from '../../../theme'; import Appeals from './Appeals'; diff --git a/src/components/Tool/Appeal/Appeals.tsx b/src/components/Tool/Appeal/Appeals.tsx index 77a7d8e23..a5c665013 100644 --- a/src/components/Tool/Appeal/Appeals.tsx +++ b/src/components/Tool/Appeal/Appeals.tsx @@ -3,11 +3,11 @@ import { Box, CircularProgress, Divider, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; -import { useFetchAllPages } from 'src/hooks/useFetchAllPages'; import { GetAppealsDocument, useGetAppealsQuery, -} from '../../../../pages/accountLists/[accountListId]/tools/GetAppeals.generated'; +} from 'pages/accountLists/[accountListId]/tools/GetAppeals.generated'; +import { useFetchAllPages } from 'src/hooks/useFetchAllPages'; import Appeal from './Appeal'; import { useChangePrimaryAppealMutation } from './ChangePrimaryAppeal.generated'; import NoAppeals from './NoAppeals'; diff --git a/src/components/Tool/Appeal/NoAppeal.test.tsx b/src/components/Tool/Appeal/NoAppeal.test.tsx index 9fb4f1bd8..4bacd0bc1 100644 --- a/src/components/Tool/Appeal/NoAppeal.test.tsx +++ b/src/components/Tool/Appeal/NoAppeal.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; +import TestWrapper from '__tests__/util/TestWrapper'; import NoAppeals from './NoAppeals'; describe('NoAppeals', () => { diff --git a/src/components/Tool/ConfirmButtonIcon.tsx b/src/components/Tool/ConfirmButtonIcon.tsx new file mode 100644 index 000000000..6c1922714 --- /dev/null +++ b/src/components/Tool/ConfirmButtonIcon.tsx @@ -0,0 +1,11 @@ +import { mdiCheckboxMarkedCircle } from '@mdi/js'; +import Icon from '@mdi/react'; +import { styled } from '@mui/material/styles'; + +const StyledIcon = styled(Icon)(({ theme }) => ({ + marginRight: theme.spacing(1), +})); + +export const ConfirmButtonIcon: React.FC = () => ( + +); diff --git a/src/components/Tool/FixCommitmentInfo/Contact.test.tsx b/src/components/Tool/FixCommitmentInfo/Contact.test.tsx index f0d523959..d4b86024e 100644 --- a/src/components/Tool/FixCommitmentInfo/Contact.test.tsx +++ b/src/components/Tool/FixCommitmentInfo/Contact.test.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; -import { render } from '../../../../__tests__/util/testingLibraryReactMock'; +import TestRouter from '__tests__/util/TestRouter'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../theme'; import Contact from './Contact'; diff --git a/src/components/Tool/FixCommitmentInfo/Contact.tsx b/src/components/Tool/FixCommitmentInfo/Contact.tsx index c077ba304..a7bb55507 100644 --- a/src/components/Tool/FixCommitmentInfo/Contact.tsx +++ b/src/components/Tool/FixCommitmentInfo/Contact.tsx @@ -19,8 +19,8 @@ import { makeStyles } from 'tss-react/mui'; import { FilterOption } from 'src/graphql/types.generated'; import { useAccountListId } from 'src/hooks/useAccountListId'; import theme from '../../../theme'; +import { StyledInput } from '../StyledInput'; import { frequencies } from './InputOptions/Frequencies'; -import { StyledInput } from './StyledInput'; const useStyles = makeStyles()(() => ({ right: { diff --git a/src/components/Tool/FixCommitmentInfo/FixCommitmentInfo.tsx b/src/components/Tool/FixCommitmentInfo/FixCommitmentInfo.tsx index 7e7d41c1e..7a1910f63 100644 --- a/src/components/Tool/FixCommitmentInfo/FixCommitmentInfo.tsx +++ b/src/components/Tool/FixCommitmentInfo/FixCommitmentInfo.tsx @@ -11,6 +11,7 @@ import { import { useSnackbar } from 'notistack'; import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; +import { useContactFiltersQuery } from 'pages/accountLists/[accountListId]/contacts/Contacts.generated'; import { MultiselectFilter, PledgeFrequencyEnum, @@ -18,7 +19,6 @@ import { } from 'src/graphql/types.generated'; import useGetAppSettings from 'src/hooks/useGetAppSettings'; import { contactPartnershipStatus } from 'src/utils/contacts/contactPartnershipStatus'; -import { useContactFiltersQuery } from '../../../../pages/accountLists/[accountListId]/contacts/Contacts.generated'; import theme from '../../../theme'; import NoData from '../NoData'; import Contact from './Contact'; diff --git a/src/components/Tool/FixEmailAddresses/DeleteModal.test.tsx b/src/components/Tool/FixEmailAddresses/DeleteModal.test.tsx index 48a2216f0..9caf1caa8 100644 --- a/src/components/Tool/FixEmailAddresses/DeleteModal.test.tsx +++ b/src/components/Tool/FixEmailAddresses/DeleteModal.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; -import { render } from '../../../../__tests__/util/testingLibraryReactMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../theme'; import DeleteModal from './DeleteModal'; diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.test.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.test.tsx index 1912693d3..5131bc945 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.test.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.test.tsx @@ -2,8 +2,8 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; import { DateTime } from 'luxon'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; -import { render } from '../../../../__tests__/util/testingLibraryReactMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../theme'; import { FixEmailAddressPerson } from './FixEmailAddressPerson'; diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.tsx index f54ec0be2..2fe645b26 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddressPerson.tsx @@ -1,12 +1,5 @@ import React, { Fragment, useState } from 'react'; -import { - mdiCheckboxMarkedCircle, - mdiDelete, - mdiLock, - mdiPlus, - mdiStar, - mdiStarOutline, -} from '@mdi/js'; +import { mdiDelete, mdiLock, mdiPlus, mdiStar, mdiStarOutline } from '@mdi/js'; import { Icon } from '@mdi/react'; import { Avatar, @@ -24,9 +17,10 @@ import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { PersonEmailAddressInput } from 'src/graphql/types.generated'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormatShort } from 'src/lib/intlFormat/intlFormat'; +import { dateFormatShort } from 'src/lib/intlFormat'; import theme from '../../../theme'; -import { ConfirmButtonIcon, EmailAddressData } from './FixEmailAddresses'; +import { ConfirmButtonIcon } from '../ConfirmButtonIcon'; +import { EmailAddressData } from './FixEmailAddresses'; const PersonCard = styled(Box)(({ theme }) => ({ [theme.breakpoints.up('md')]: { @@ -308,7 +302,7 @@ export const FixEmailAddressPerson: React.FC = ({ > diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx index 489d7013b..c1ddb28a5 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx @@ -2,13 +2,10 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; import { ErgonoMockShape } from 'graphql-ergonomock'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; -import { - render, - waitFor, -} from '../../../../__tests__/util/testingLibraryReactMock'; +import TestRouter from '__tests__/util/TestRouter'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../theme'; import { FixEmailAddresses } from './FixEmailAddresses'; import { GetInvalidEmailAddressesQuery } from './GetInvalidEmailAddresses.generated'; diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx index 23eb11cc9..81301b808 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx @@ -1,6 +1,4 @@ import React, { useEffect, useState } from 'react'; -import { mdiCheckboxMarkedCircle } from '@mdi/js'; -import Icon from '@mdi/react'; import { Box, Button, @@ -14,8 +12,9 @@ import { styled } from '@mui/material/styles'; import { Trans, useTranslation } from 'react-i18next'; import { PersonEmailAddressInput } from 'src/graphql/types.generated'; import theme from '../../../theme'; -import { StyledInput } from '../FixCommitmentInfo/StyledInput'; +import { ConfirmButtonIcon } from '../ConfirmButtonIcon'; import NoData from '../NoData'; +import { StyledInput } from '../StyledInput'; import DeleteModal from './DeleteModal'; import { FixEmailAddressPerson } from './FixEmailAddressPerson'; import { useGetInvalidEmailAddressesQuery } from './GetInvalidEmailAddresses.generated'; @@ -69,10 +68,6 @@ const ConfirmButton = styled(Button)(({ theme }) => ({ }, })); -export const ConfirmButtonIcon = styled(Icon)(({ theme }) => ({ - marginRight: theme.spacing(1), -})); - const DefaultSourceWrapper = styled(Box)(({ theme }) => ({ display: 'flex', justifyContent: 'flex-start', @@ -274,10 +269,7 @@ export const FixEmailAddresses: React.FC = ({ - + {t('Confirm {{amount}} as {{source}}', { amount: data.people.nodes.length, source: defaultSource, diff --git a/src/components/Tool/FixMailingAddresses/AddressModal.tsx b/src/components/Tool/FixMailingAddresses/AddressModal.tsx index 559c06580..c62e7963b 100644 --- a/src/components/Tool/FixMailingAddresses/AddressModal.tsx +++ b/src/components/Tool/FixMailingAddresses/AddressModal.tsx @@ -23,8 +23,8 @@ import { SubmitButton, } from 'src/components/common/Modal/ActionButtons/ActionButtons'; import theme from '../../../theme'; +import { StyledInput } from '../StyledInput'; import { ContactAddressFragment } from './GetInvalidAddresses.generated'; -import { StyledInput } from './StyledInput'; const useStyles = makeStyles()(() => ({ modal: { diff --git a/src/components/Tool/FixMailingAddresses/Contact.tsx b/src/components/Tool/FixMailingAddresses/Contact.tsx index c620bddf9..9cff5d6a0 100644 --- a/src/components/Tool/FixMailingAddresses/Contact.tsx +++ b/src/components/Tool/FixMailingAddresses/Contact.tsx @@ -9,7 +9,7 @@ import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormatShort } from 'src/lib/intlFormat/intlFormat'; +import { dateFormatShort } from 'src/lib/intlFormat'; import theme from '../../../theme'; import { emptyAddress } from './FixMailingAddresses'; import { ContactAddressFragment } from './GetInvalidAddresses.generated'; diff --git a/src/components/Tool/FixMailingAddresses/FixMailingAddresses.tsx b/src/components/Tool/FixMailingAddresses/FixMailingAddresses.tsx index e62722635..43102d14a 100644 --- a/src/components/Tool/FixMailingAddresses/FixMailingAddresses.tsx +++ b/src/components/Tool/FixMailingAddresses/FixMailingAddresses.tsx @@ -13,8 +13,8 @@ import { import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import theme from '../../../theme'; -import { StyledInput } from '../FixCommitmentInfo/StyledInput'; import NoData from '../NoData'; +import { StyledInput } from '../StyledInput'; import AddressModal from './AddressModal'; import Contact from './Contact'; import { diff --git a/src/components/Tool/FixMailingAddresses/StyledInput.tsx b/src/components/Tool/FixMailingAddresses/StyledInput.tsx deleted file mode 100644 index e51ed24e3..000000000 --- a/src/components/Tool/FixMailingAddresses/StyledInput.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { InputBase, Theme } from '@mui/material'; -import { createStyles, withStyles } from '@mui/styles'; - -export const StyledInput = withStyles((theme: Theme) => - createStyles({ - root: { - 'label + &': { - marginTop: theme.spacing(3), - }, - }, - input: { - borderRadius: 4, - position: 'relative', - backgroundColor: theme.palette.background.paper, - border: '1px solid #ced4da', - fontSize: 16, - padding: '10px 26px 10px 12px', - transition: theme.transitions.create(['border-color', 'box-shadow']), - fontFamily: [ - '-apple-system', - 'BlinkMacSystemFont', - '"Segoe UI"', - 'Roboto', - '"Helvetica Neue"', - 'Arial', - 'sans-serif', - '"Apple Color Emoji"', - '"Segoe UI Emoji"', - '"Segoe UI Symbol"', - ].join(','), - '&:focus': { - borderRadius: 4, - borderColor: '#80bdff', - boxShadow: '0 0 0 0.2rem rgba(0,123,255,.25)', - }, - }, - }), -)(InputBase); diff --git a/src/components/Tool/FixPhoneNumbers/Contact.test.tsx b/src/components/Tool/FixPhoneNumbers/Contact.test.tsx index 21d7c4d3f..e5e355bdc 100644 --- a/src/components/Tool/FixPhoneNumbers/Contact.test.tsx +++ b/src/components/Tool/FixPhoneNumbers/Contact.test.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; -import { render } from '../../../../__tests__/util/testingLibraryReactMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../theme'; import Contact from './Contact'; diff --git a/src/components/Tool/FixPhoneNumbers/Contact.tsx b/src/components/Tool/FixPhoneNumbers/Contact.tsx index db7846e55..b52a3f877 100644 --- a/src/components/Tool/FixPhoneNumbers/Contact.tsx +++ b/src/components/Tool/FixPhoneNumbers/Contact.tsx @@ -19,7 +19,7 @@ import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { PersonPhoneNumberInput } from 'src/graphql/types.generated'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormatShort } from 'src/lib/intlFormat/intlFormat'; +import { dateFormatShort } from 'src/lib/intlFormat'; import theme from '../../../theme'; import { PhoneNumberData } from './FixPhoneNumbers'; diff --git a/src/components/Tool/FixPhoneNumbers/DeleteModal.test.tsx b/src/components/Tool/FixPhoneNumbers/DeleteModal.test.tsx index 25dc44a39..1c58e8a98 100644 --- a/src/components/Tool/FixPhoneNumbers/DeleteModal.test.tsx +++ b/src/components/Tool/FixPhoneNumbers/DeleteModal.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; -import { render } from '../../../../__tests__/util/testingLibraryReactMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../theme'; import DeleteModal from './DeleteModal'; diff --git a/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.test.tsx b/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.test.tsx index 579ed6220..e6bb9e260 100644 --- a/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.test.tsx +++ b/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.test.tsx @@ -2,13 +2,10 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import userEvent from '@testing-library/user-event'; import { ErgonoMockShape } from 'graphql-ergonomock'; -import TestRouter from '../../../../__tests__/util/TestRouter'; -import TestWrapper from '../../../../__tests__/util/TestWrapper'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; -import { - render, - waitFor, -} from '../../../../__tests__/util/testingLibraryReactMock'; +import TestRouter from '__tests__/util/TestRouter'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { render, waitFor } from '__tests__/util/testingLibraryReactMock'; import theme from '../../../theme'; import FixPhoneNumbers from './FixPhoneNumbers'; import { GetInvalidPhoneNumbersQuery } from './GetInvalidPhoneNumbers.generated'; diff --git a/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.tsx b/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.tsx index 4110d2a5f..95f425d73 100644 --- a/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.tsx +++ b/src/components/Tool/FixPhoneNumbers/FixPhoneNumbers.tsx @@ -14,8 +14,8 @@ import { Trans, useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { PersonPhoneNumberInput } from 'src/graphql/types.generated'; import theme from '../../../theme'; -import { StyledInput } from '../FixCommitmentInfo/StyledInput'; import NoData from '../NoData'; +import { StyledInput } from '../StyledInput'; import Contact from './Contact'; import DeleteModal from './DeleteModal'; import { useGetInvalidPhoneNumbersQuery } from './GetInvalidPhoneNumbers.generated'; diff --git a/src/components/Tool/FixSendNewsletter/Contact.tsx b/src/components/Tool/FixSendNewsletter/Contact.tsx index eccd1e41f..5eb49329c 100644 --- a/src/components/Tool/FixSendNewsletter/Contact.tsx +++ b/src/components/Tool/FixSendNewsletter/Contact.tsx @@ -12,11 +12,11 @@ import { import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import theme from '../../../theme'; +import { StyledInput } from '../StyledInput'; import { ContactPrimaryAddressFragment, ContactPrimaryPersonFragment, } from './GetInvalidNewsletter.generated'; -import { StyledInput } from './StyledInput'; const useStyles = makeStyles()(() => ({ left: { diff --git a/src/components/Tool/FixSendNewsletter/StyledInput.tsx b/src/components/Tool/FixSendNewsletter/StyledInput.tsx deleted file mode 100644 index e51ed24e3..000000000 --- a/src/components/Tool/FixSendNewsletter/StyledInput.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { InputBase, Theme } from '@mui/material'; -import { createStyles, withStyles } from '@mui/styles'; - -export const StyledInput = withStyles((theme: Theme) => - createStyles({ - root: { - 'label + &': { - marginTop: theme.spacing(3), - }, - }, - input: { - borderRadius: 4, - position: 'relative', - backgroundColor: theme.palette.background.paper, - border: '1px solid #ced4da', - fontSize: 16, - padding: '10px 26px 10px 12px', - transition: theme.transitions.create(['border-color', 'box-shadow']), - fontFamily: [ - '-apple-system', - 'BlinkMacSystemFont', - '"Segoe UI"', - 'Roboto', - '"Helvetica Neue"', - 'Arial', - 'sans-serif', - '"Apple Color Emoji"', - '"Segoe UI Emoji"', - '"Segoe UI Symbol"', - ].join(','), - '&:focus': { - borderRadius: 4, - borderColor: '#80bdff', - boxShadow: '0 0 0 0.2rem rgba(0,123,255,.25)', - }, - }, - }), -)(InputBase); diff --git a/src/components/Tool/Home/Home.test.tsx b/src/components/Tool/Home/Home.test.tsx index 137043d28..d470c7eb8 100644 --- a/src/components/Tool/Home/Home.test.tsx +++ b/src/components/Tool/Home/Home.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; -import TestRouter from '../../../../__tests__/util/TestRouter'; +import TestRouter from '__tests__/util/TestRouter'; import theme from '../../../theme'; import Home from './Home'; diff --git a/src/components/Tool/Home/Tool.test.tsx b/src/components/Tool/Home/Tool.test.tsx index fdbf7f10d..8624353a9 100644 --- a/src/components/Tool/Home/Tool.test.tsx +++ b/src/components/Tool/Home/Tool.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { mdiAlert } from '@mdi/js'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; -import TestRouter from '../../../../__tests__/util/TestRouter'; +import TestRouter from '__tests__/util/TestRouter'; import theme from '../../../theme'; import Tool from './Tool'; diff --git a/src/components/Tool/MergeContacts/Contact.tsx b/src/components/Tool/MergeContacts/Contact.tsx index af6445329..d758f2b02 100644 --- a/src/components/Tool/MergeContacts/Contact.tsx +++ b/src/components/Tool/MergeContacts/Contact.tsx @@ -19,7 +19,7 @@ import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormatShort } from 'src/lib/intlFormat/intlFormat'; +import { dateFormatShort } from 'src/lib/intlFormat'; import { contactPartnershipStatus } from 'src/utils/contacts/contactPartnershipStatus'; import theme from '../../../theme'; import { RecordInfoFragment } from './GetContactDuplicates.generated'; diff --git a/src/components/Tool/MergePeople/PersonDuplicates.tsx b/src/components/Tool/MergePeople/PersonDuplicates.tsx index 150f1f1e7..9abe4579e 100644 --- a/src/components/Tool/MergePeople/PersonDuplicates.tsx +++ b/src/components/Tool/MergePeople/PersonDuplicates.tsx @@ -19,7 +19,7 @@ import { DateTime } from 'luxon'; import { useTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; import { useLocale } from 'src/hooks/useLocale'; -import { dateFormatShort } from 'src/lib/intlFormat/intlFormat'; +import { dateFormatShort } from 'src/lib/intlFormat'; import theme from '../../../theme'; import { PersonInfoFragment } from './GetPersonDuplicates.generated'; diff --git a/src/components/Tool/NavToolList/Item/Item.test.tsx b/src/components/Tool/NavToolList/Item/Item.test.tsx index 8832c2a89..6e89242e5 100644 --- a/src/components/Tool/NavToolList/Item/Item.test.tsx +++ b/src/components/Tool/NavToolList/Item/Item.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import TestWrapper from '../../../../../__tests__/util/TestWrapper'; -import { render } from '../../../../../__tests__/util/testingLibraryReactMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render } from '__tests__/util/testingLibraryReactMock'; import { Item } from './Item'; const item = { diff --git a/src/components/Tool/NavToolList/Item/Item.tsx b/src/components/Tool/NavToolList/Item/Item.tsx index b2e69ccee..29d4700ee 100644 --- a/src/components/Tool/NavToolList/Item/Item.tsx +++ b/src/components/Tool/NavToolList/Item/Item.tsx @@ -1,8 +1,7 @@ import NextLink from 'next/link'; import React, { ReactElement } from 'react'; import ArrowForwardIos from '@mui/icons-material/ArrowForwardIos'; -import ListItem from '@mui/material/ListItem'; -import ListItemText from '@mui/material/ListItemText'; +import { ListItem, ListItemText } from '@mui/material'; import { makeStyles } from 'tss-react/mui'; import { useAccountListId } from 'src/hooks/useAccountListId'; import theme from '../../../../theme'; diff --git a/src/components/Tool/NavToolList/NavToolList.test.tsx b/src/components/Tool/NavToolList/NavToolList.test.tsx index d37ac792c..bf9e22a27 100644 --- a/src/components/Tool/NavToolList/NavToolList.test.tsx +++ b/src/components/Tool/NavToolList/NavToolList.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render } from '@testing-library/react'; -import TestRouter from '../../../../__tests__/util/TestRouter'; +import TestRouter from '__tests__/util/TestRouter'; import theme from '../../../theme'; import NavToolList from './NavToolList'; diff --git a/src/components/Tool/NoData.test.tsx b/src/components/Tool/NoData.test.tsx index 06ad2011d..baa330e57 100644 --- a/src/components/Tool/NoData.test.tsx +++ b/src/components/Tool/NoData.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; -import TestWrapper from '../../../__tests__/util/TestWrapper'; -import { render } from '../../../__tests__/util/testingLibraryReactMock'; +import TestWrapper from '__tests__/util/TestWrapper'; +import { render } from '__tests__/util/testingLibraryReactMock'; import theme from '../../theme'; import NoData from './NoData'; diff --git a/src/components/Tool/FixCommitmentInfo/StyledInput.tsx b/src/components/Tool/StyledInput.tsx similarity index 100% rename from src/components/Tool/FixCommitmentInfo/StyledInput.tsx rename to src/components/Tool/StyledInput.tsx diff --git a/src/components/common/DonorAccountAutocomplete/DonorAccountAutocomplete.test.tsx b/src/components/common/DonorAccountAutocomplete/DonorAccountAutocomplete.test.tsx index c7d31e163..84f030018 100644 --- a/src/components/common/DonorAccountAutocomplete/DonorAccountAutocomplete.test.tsx +++ b/src/components/common/DonorAccountAutocomplete/DonorAccountAutocomplete.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { GqlMockedProvider } from '../../../../__tests__/util/graphqlMocking'; +import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import theme from '../../../theme'; import { DonorAccountAutocomplete } from './DonorAccountAutocomplete'; import { GetDonorAccountsQuery } from './DonorAccountAutocomplete.generated'; diff --git a/src/components/common/EmptyDonationsTable/EmptyDonationsTable.test.tsx b/src/components/common/EmptyDonationsTable/EmptyDonationsTable.test.tsx index fea96b92c..dac7c1679 100644 --- a/src/components/common/EmptyDonationsTable/EmptyDonationsTable.test.tsx +++ b/src/components/common/EmptyDonationsTable/EmptyDonationsTable.test.tsx @@ -5,8 +5,10 @@ import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SnackbarProvider } from 'notistack'; +import { I18nextProvider } from 'react-i18next'; import TestRouter from '__tests__/util/TestRouter'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import i18n from 'src/lib/i18n'; import theme from '../../../theme'; import { EmptyDonationsTable } from './EmptyDonationsTable'; @@ -19,17 +21,19 @@ describe('EmptyDonationsTable', () => { it('renders', async () => { const { findByRole, getByRole, getByText, queryByRole } = render( - - - - - - - - - + + + + + + + + + + + , ); diff --git a/src/components/common/EmptyDonationsTable/EmptyDonationsTable.tsx b/src/components/common/EmptyDonationsTable/EmptyDonationsTable.tsx index 4de10b985..3eebbdf16 100644 --- a/src/components/common/EmptyDonationsTable/EmptyDonationsTable.tsx +++ b/src/components/common/EmptyDonationsTable/EmptyDonationsTable.tsx @@ -3,7 +3,10 @@ import LocalAtmIcon from '@mui/icons-material/LocalAtm'; import { Box, Button, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; -import { AddDonation } from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/AddDonation'; +import { + DynamicAddDonation, + preloadAddDonation, +} from 'src/components/Layouts/Primary/TopBar/Items/AddMenu/Items/AddDonation/DynamicAddDonation'; import { NextLinkComposed } from 'src/components/common/Links/NextLinkComposed'; import { useAccountListId } from 'src/hooks/useAccountListId'; import Modal from '../Modal/Modal'; @@ -58,6 +61,7 @@ export const EmptyDonationsTable: React.FC = ({ title }) => { variant="contained" color="primary" onClick={() => setAddDonationOpen(true)} + onMouseEnter={preloadAddDonation} > {t('Add New Donation')} @@ -69,7 +73,7 @@ export const EmptyDonationsTable: React.FC = ({ title }) => { fullWidth size="sm" > - diff --git a/src/components/common/Links/Facebook.tsx b/src/components/common/Links/Facebook.tsx index cebf8821a..cac45188f 100644 --- a/src/components/common/Links/Facebook.tsx +++ b/src/components/common/Links/Facebook.tsx @@ -1,10 +1,10 @@ import React from 'react'; import FacebookIcon from '@mui/icons-material/Facebook'; import { IconButton } from '@mui/material'; -import * as Types from 'src/graphql/types.generated'; +import { FacebookAccount } from 'src/graphql/types.generated'; interface Props { - username: Types.FacebookAccount['username']; + username: FacebookAccount['username']; } export const Facebook: React.FC = ({ username }) => { diff --git a/src/components/common/Links/LinkedIn.tsx b/src/components/common/Links/LinkedIn.tsx index 70bbaa48b..5d65b8286 100644 --- a/src/components/common/Links/LinkedIn.tsx +++ b/src/components/common/Links/LinkedIn.tsx @@ -1,10 +1,10 @@ import React from 'react'; import Icon from '@mui/icons-material/LinkedIn'; import { IconButton } from '@mui/material'; -import * as Types from 'src/graphql/types.generated'; +import { LinkedinAccount } from 'src/graphql/types.generated'; interface Props { - publicUrl: Types.LinkedinAccount['publicUrl']; + publicUrl: LinkedinAccount['publicUrl']; } export const LinkedIn: React.FC = ({ publicUrl }) => { diff --git a/src/components/common/Links/Twitter.tsx b/src/components/common/Links/Twitter.tsx index e62dbbd24..93ca58927 100644 --- a/src/components/common/Links/Twitter.tsx +++ b/src/components/common/Links/Twitter.tsx @@ -1,10 +1,10 @@ import React from 'react'; import Icon from '@mui/icons-material/Twitter'; import { IconButton } from '@mui/material'; -import * as Types from 'src/graphql/types.generated'; +import { TwitterAccount } from 'src/graphql/types.generated'; interface Props { - screenName: Types.TwitterAccount['screenName']; + screenName: TwitterAccount['screenName']; } export const Twitter: React.FC = ({ screenName }) => { diff --git a/src/components/common/Links/Website.tsx b/src/components/common/Links/Website.tsx index a6d414147..5db0fcaff 100644 --- a/src/components/common/Links/Website.tsx +++ b/src/components/common/Links/Website.tsx @@ -1,10 +1,10 @@ import React from 'react'; import Icon from '@mui/icons-material/Language'; import { IconButton } from '@mui/material'; -import * as Types from 'src/graphql/types.generated'; +import { Website as WebsiteType } from 'src/graphql/types.generated'; interface Props { - url: Types.Website['url']; + url: WebsiteType['url']; } export const Website: React.FC = ({ url }) => { diff --git a/src/components/common/SearchBox/SearchBox.tsx b/src/components/common/SearchBox/SearchBox.tsx index 0f105eed6..b03d333be 100644 --- a/src/components/common/SearchBox/SearchBox.tsx +++ b/src/components/common/SearchBox/SearchBox.tsx @@ -14,11 +14,7 @@ export interface SearchBoxProps { showContactSearchIcon: boolean; } -export const AccountSearchIcon = styled(Icon)(({ theme }) => ({ - color: theme.palette.text.secondary, -})); - -export const SearchInput = styled(TextField)(() => ({ +const SearchInput = styled(TextField)(() => ({ '& .MuiInputBase-root': { height: 48, }, diff --git a/src/lib/intlFormat/intlFormat.test.ts b/src/lib/intlFormat.test.ts similarity index 99% rename from src/lib/intlFormat/intlFormat.test.ts rename to src/lib/intlFormat.test.ts index 3fb68edc3..f204d96a5 100644 --- a/src/lib/intlFormat/intlFormat.test.ts +++ b/src/lib/intlFormat.test.ts @@ -1,17 +1,15 @@ import { DateTime } from 'luxon'; import { + currencyFormat, dateFormat, dateFormatWithoutYear, dateFromParts, dateTimeFormat, - monthYearFormat, -} from './intlFormat'; -import { - currencyFormat, dayMonthFormat, + monthYearFormat, numberFormat, percentageFormat, -} from '.'; +} from './intlFormat'; describe('intlFormat', () => { let languageMock: jest.SpyInstance; diff --git a/src/lib/intlFormat/intlFormat.ts b/src/lib/intlFormat.ts similarity index 100% rename from src/lib/intlFormat/intlFormat.ts rename to src/lib/intlFormat.ts diff --git a/src/lib/intlFormat/index.ts b/src/lib/intlFormat/index.ts deleted file mode 100644 index 4f2cbb691..000000000 --- a/src/lib/intlFormat/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { - currencyFormat, - dateFormat, - dateFormatShort, - dateFormatWithoutYear, - dayMonthFormat, - monthYearFormat, - numberFormat, - percentageFormat, -} from './intlFormat'; - -export { - numberFormat, - percentageFormat, - currencyFormat, - dayMonthFormat, - monthYearFormat, - dateFormat, - dateFormatShort, - dateFormatWithoutYear, -};