Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPDX-8479 HI Report Page & key #1228

Open
wants to merge 24 commits into
base: health-indicator
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3d157e1
Add config file for GraphQL language server
canac Dec 5, 2024
3c6d694
Extract typeguard into lib
canac Dec 5, 2024
d6ddc19
Refactor monthYearFormat to accept DateTime instances
canac Dec 5, 2024
ddc65d5
Create reusable LegendReferenceLine component
canac Dec 6, 2024
7d356c9
Create reusable BarChartSkeleton component
canac Dec 6, 2024
d179617
Unconditionally mock window.ResizeObserver
canac Dec 6, 2024
d1efb9f
Create HealthIndicatorGraph component
canac Dec 6, 2024
597e418
Remove Hi suffix from field names
canac Dec 9, 2024
165f36c
fixup! Create reusable BarChartSkeleton component
canac Dec 9, 2024
2e01206
Add graph colors to theme
canac Dec 9, 2024
e3940ad
fixup! Create reusable LegendReferenceLine component
canac Dec 9, 2024
94bc197
Fixing error: Required unplugged package missing from disk
dr-bizz Dec 11, 2024
f942c79
Create bare bones of the MPD Health Indicator report page
dr-bizz Dec 11, 2024
abf0f90
Adding Monthly goal and HI graphs to report page
dr-bizz Dec 11, 2024
a10fc85
Health Formula
dr-bizz Dec 11, 2024
e9b3578
Adding tooltip and data to HI formula
dr-bizz Dec 12, 2024
a8e572b
Show no data message if no HI data
dr-bizz Dec 16, 2024
7efc41d
Merge branch 'health-indicator' into 8479-hi-report-page
dr-bizz Dec 16, 2024
40f0514
fixup! Create bare bones of the MPD Health Indicator report page
dr-bizz Dec 16, 2024
938cc10
force codescene to review
dr-bizz Dec 17, 2024
260ab26
Adding codceScene rules json to see if it changes how codeScene revie…
dr-bizz Dec 17, 2024
bef08f2
Cleaning up PR and simplifying code
dr-bizz Dec 19, 2024
8ed6e96
fixup! Cleaning up PR and simplifying code
dr-bizz Dec 19, 2024
a45a032
fixup! Cleaning up PR and simplifying code
dr-bizz Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions __tests__/util/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ Object.defineProperty(window, 'location', {

window.HTMLElement.prototype.scrollIntoView = jest.fn();

window.ResizeObserver = jest.fn().mockReturnValue({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
});

window.URL.revokeObjectURL = jest.fn();

beforeEach(() => {
Expand Down
14 changes: 0 additions & 14 deletions __tests__/util/windowResizeObserver.ts

This file was deleted.

4 changes: 4 additions & 0 deletions graphql.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"schema": "src/graphql/schema.graphql",
"documents": "**/*.graphql"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { ThemeProvider } from '@mui/material/styles';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
import { render } 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 'src/theme';
import HealthIndicatorPage from './index.page';

const accountListId = 'account-list-1';
const router = {
query: { accountListId },
isReady: true,
};

const Components = () => (
<I18nextProvider i18n={i18n}>
<LocalizationProvider dateAdapter={AdapterLuxon}>
<SnackbarProvider>
<ThemeProvider theme={theme}>
<TestRouter router={router}>
<GqlMockedProvider>
<HealthIndicatorPage />
</GqlMockedProvider>
</TestRouter>
</ThemeProvider>
</SnackbarProvider>
</LocalizationProvider>
</I18nextProvider>
);

describe('MPD Health Indicator Page', () => {
it('should show initial financial accounts page', async () => {
const { findByText } = render(<Components />);

expect(await findByText('Overall Staff MPD Health')).toBeInTheDocument();
});

it('should open and close menu', async () => {
const { findByRole, getByRole, queryByRole } = render(<Components />);

userEvent.click(
await findByRole('button', { name: 'Toggle Navigation Panel' }),
);
expect(getByRole('heading', { name: 'Reports' })).toBeInTheDocument();
userEvent.click(getByRole('img', { name: 'Close' }));
expect(queryByRole('heading', { name: 'Reports' })).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Head from 'next/head';
import React, { useState } from 'react';
import { Box } from '@mui/material';
import { useTranslation } from 'react-i18next';
import { ensureSessionAndAccountList } from 'pages/api/utils/pagePropsHelpers';
import { SidePanelsLayout } from 'src/components/Layouts/SidePanelsLayout';
import Loading from 'src/components/Loading';
import { HealthIndicatorReport } from 'src/components/Reports/HealthIndicatorReport/HealthIndicatorReport';
import { headerHeight } from 'src/components/Shared/Header/ListHeader';
import {
MultiPageMenu,
NavTypeEnum,
} from 'src/components/Shared/MultiPageLayout/MultiPageMenu/MultiPageMenu';
import { useAccountListId } from 'src/hooks/useAccountListId';
import useGetAppSettings from 'src/hooks/useGetAppSettings';

const HealthIndicatorPage: React.FC = () => {
const { t } = useTranslation();
const accountListId = useAccountListId();
const { appName } = useGetAppSettings();
const [navListOpen, setNavListOpen] = useState(false);

const handleNavListToggle = () => {
setNavListOpen(!navListOpen);
};
return (
<>
<Head>
<title>{`${appName} | ${t('Reports - MPD Health')}`}</title>
</Head>

{accountListId ? (
<Box sx={{ background: 'common.white' }}>
<SidePanelsLayout
headerHeight={headerHeight}
isScrollBox={false}
leftOpen={navListOpen}
leftWidth="290px"
mainContent={
<HealthIndicatorReport
accountListId={accountListId}
isNavListOpen={navListOpen}
onNavListToggle={handleNavListToggle}
title={t('Overall Staff MPD Health')}
/>
}
leftPanel={
<MultiPageMenu
isOpen={navListOpen}
selectedId="healthIndicator"
onClose={handleNavListToggle}
navType={NavTypeEnum.Reports}
/>
}
/>
</Box>
) : (
<Loading loading />
)}
</>
);
};

export const getServerSideProps = ensureSessionAndAccountList;

export default HealthIndicatorPage;
7 changes: 3 additions & 4 deletions pages/api/Schema/CoachingAnswerSets/dataHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import {
CoachingAnswerSet,
CoachingQuestion,
} from 'src/graphql/types.generated';

const isNotNull = <T>(item: T | null): item is T => item !== null;
import { isNotNullish } from 'src/lib/typeGuards';

interface CoachingAnswerSetData {
id: string;
Expand Down Expand Up @@ -77,10 +76,10 @@ const parseCoachingAnswerSet = (
};
const answers = relationships.answers.data
.map(({ id }) => getIncludedAnswer(id, included))
.filter(isNotNull);
.filter(isNotNullish);
const questions = relationships.questions.data
.map(({ id }) => getIncludedQuestion(id, included))
.filter(isNotNull);
.filter(isNotNullish);

return {
id,
Expand Down
12 changes: 0 additions & 12 deletions src/components/Coaching/CoachingDetail/CoachingDetail.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import TestRouter from '__tests__/util/TestRouter';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import matchMediaMock from '__tests__/util/matchMediaMock';
import { render } from '__tests__/util/testingLibraryReactMock';
import {
afterTestResizeObserver,
beforeTestResizeObserver,
} from '__tests__/util/windowResizeObserver';
import theme from 'src/theme';
import { AccountListTypeEnum, CoachingDetail } from './CoachingDetail';
import { LevelOfEffortQuery } from './LevelOfEffort/LevelOfEffort.generated';
Expand Down Expand Up @@ -121,14 +117,6 @@ const TestComponent: React.FC<TestComponentProps> = ({

const accountListId = 'account-list-1';
describe('LoadCoachingDetail', () => {
beforeEach(() => {
beforeTestResizeObserver();
});

afterEach(() => {
afterTestResizeObserver();
});

describe.each([
{ type: AccountListTypeEnum.Coaching, name: 'coaching' },
{ type: AccountListTypeEnum.Own, name: 'own' },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { render } from '@testing-library/react';
import { DateTime } from 'luxon';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import {
afterTestResizeObserver,
beforeTestResizeObserver,
} from '__tests__/util/windowResizeObserver';
import { AccountListTypeEnum } from '../CoachingDetail';
import { MonthlyCommitment, MonthlyCommitmentProps } from './MonthlyCommitment';
import { GetReportsPledgeHistoriesQuery } from './MonthlyCommitment.generated';
Expand Down Expand Up @@ -60,14 +56,6 @@ const TestComponent: React.FC<TestComponentProps> = ({
);

describe('MonthlyCommitment', () => {
beforeEach(() => {
beforeTestResizeObserver();
});

afterEach(() => {
afterTestResizeObserver();
});

it('renders', async () => {
const { findByTestId } = render(<TestComponent missingData />);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import React from 'react';

Check notice on line 1 in src/components/Contacts/ContactDetails/ContactDonationsTab/DonationsGraph/DonationsGraph.test.tsx

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (health-indicator)

✅ No longer an issue: Code Duplication

The module no longer contains too many functions with similar structure
import { renderHook } from '@testing-library/react-hooks';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import { render } from '__tests__/util/testingLibraryReactMock';
import {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No longer an issue: Code Duplication
The module no longer contains too many functions with similar structure

afterTestResizeObserver,
beforeTestResizeObserver,
} from '__tests__/util/windowResizeObserver';
import { DonationsGraph } from './DonationsGraph';
import {
GetDonationsGraphQuery,
Expand All @@ -30,14 +26,6 @@
const currency = 'USD';

describe('Donations Graph', () => {
beforeEach(() => {
beforeTestResizeObserver();
});

afterEach(() => {
afterTestResizeObserver();
});

it('test renderer', async () => {
const { findByText } = render(
<GqlMockedProvider<{ GetDonationsGraph: GetDonationsGraphQuery }>
Expand Down
9 changes: 0 additions & 9 deletions src/components/Dashboard/Dashboard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import { ThemeProvider } from '@mui/material/styles';
import { render, waitFor } from '@testing-library/react';
import { SnackbarProvider } from 'notistack';
import matchMediaMock from '__tests__/util/matchMediaMock';
import {
afterTestResizeObserver,
beforeTestResizeObserver,
} from '__tests__/util/windowResizeObserver';
import { GetDashboardQuery } from 'pages/accountLists/GetDashboard.generated';
import useTaskModal from '../../hooks/useTaskModal';
import theme from '../../theme';
Expand Down Expand Up @@ -125,11 +121,6 @@ const data: GetDashboardQuery = {
describe('Dashboard', () => {
beforeEach(() => {
matchMediaMock({ width: '1024px' });
beforeTestResizeObserver();
});

afterEach(() => {
afterTestResizeObserver();
});

it('default', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import React from 'react';
import { render } from '@testing-library/react';
import TestRouter from '__tests__/util/TestRouter';
import {
afterTestResizeObserver,
beforeTestResizeObserver,
} from '__tests__/util/windowResizeObserver';
import DonationHistories from '.';

const setTime = jest.fn();
Expand All @@ -29,9 +25,7 @@ describe('DonationHistories', () => {
</TestRouter>,
);
expect(getByTestId('DonationHistoriesBoxEmpty')).toBeInTheDocument();
expect(
queryByTestId('DonationHistoriesGridLoading'),
).not.toBeInTheDocument();
expect(queryByTestId('BarChartSkeleton')).not.toBeInTheDocument();
});

it('empty periods', () => {
Expand Down Expand Up @@ -59,9 +53,7 @@ describe('DonationHistories', () => {
</TestRouter>,
);
expect(getByTestId('DonationHistoriesBoxEmpty')).toBeInTheDocument();
expect(
queryByTestId('DonationHistoriesGridLoading'),
).not.toBeInTheDocument();
expect(queryByTestId('BarChartSkeleton')).not.toBeInTheDocument();
});

it('loading', () => {
Expand All @@ -70,7 +62,7 @@ describe('DonationHistories', () => {
<DonationHistories setTime={setTime} loading={true} />
</TestRouter>,
);
expect(getByTestId('DonationHistoriesGridLoading')).toBeInTheDocument();
expect(getByTestId('BarChartSkeleton')).toBeInTheDocument();
expect(queryByTestId('DonationHistoriesBoxEmpty')).not.toBeInTheDocument();
});

Expand All @@ -91,11 +83,6 @@ describe('DonationHistories', () => {
],
averageIgnoreCurrent: 1000,
};
beforeTestResizeObserver();
});

afterEach(() => {
afterTestResizeObserver();
});

it('shows references', () => {
Expand Down
Loading
Loading