-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create Analytics page and Leadership tab (#4181)
* Everything minus tests * linting * add flag * add some basic tests * add more tests * add menu icon and pagination * fix tests * fix test * adjust styles * remove comments
- Loading branch information
Showing
27 changed files
with
672 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { FC, useState } from 'react'; | ||
import { AnalyticsPageBody } from '@asap-hub/react-components'; | ||
import { useMemberships } from './state'; | ||
import { usePagination, usePaginationParams } from '../hooks'; | ||
|
||
type MetricResponse = { | ||
id: string; | ||
displayName: string; | ||
workingGroupLeadershipRoleCount: number; | ||
workingGroupPreviousLeadershipRoleCount: number; | ||
workingGroupMemberCount: number; | ||
workingGroupPreviousMemberCount: number; | ||
|
||
interestGroupLeadershipRoleCount: number; | ||
interestGroupPreviousLeadershipRoleCount: number; | ||
interestGroupMemberCount: number; | ||
interestGroupPreviousMemberCount: number; | ||
}; | ||
|
||
const getDataForMetric = ( | ||
data: MetricResponse[], | ||
metric: 'workingGroup' | 'interestGroup', | ||
) => { | ||
if (metric === 'workingGroup') { | ||
return data.map((row) => ({ | ||
id: row.id, | ||
name: row.displayName, | ||
leadershipRoleCount: row.workingGroupLeadershipRoleCount, | ||
previousLeadershipRoleCount: row.workingGroupPreviousLeadershipRoleCount, | ||
memberCount: row.workingGroupMemberCount, | ||
previousMemberCount: row.workingGroupPreviousMemberCount, | ||
})); | ||
} | ||
return data.map((row) => ({ | ||
id: row.id, | ||
name: row.displayName, | ||
leadershipRoleCount: row.interestGroupLeadershipRoleCount, | ||
previousLeadershipRoleCount: row.interestGroupPreviousLeadershipRoleCount, | ||
memberCount: row.interestGroupMemberCount, | ||
previousMemberCount: row.interestGroupPreviousMemberCount, | ||
})); | ||
}; | ||
|
||
const About: FC<Record<string, never>> = () => { | ||
const [metric, setMetric] = useState<'workingGroup' | 'interestGroup'>( | ||
'workingGroup', | ||
); | ||
const { data } = useMemberships(); | ||
const { currentPage, pageSize } = usePaginationParams(); | ||
const { numberOfPages, renderPageHref } = usePagination( | ||
data.length, | ||
pageSize, | ||
); | ||
|
||
return ( | ||
<AnalyticsPageBody | ||
metric={metric} | ||
setMetric={setMetric} | ||
data={getDataForMetric(data, metric)} | ||
currentPageIndex={currentPage} | ||
numberOfPages={numberOfPages} | ||
renderPageHref={renderPageHref} | ||
/> | ||
); | ||
}; | ||
|
||
export default About; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { SkeletonBodyFrame as Frame } from '@asap-hub/frontend-utils'; | ||
import { AnalyticsPage } from '@asap-hub/react-components'; | ||
import { FC, lazy, useEffect } from 'react'; | ||
import { Route, Switch, useRouteMatch } from 'react-router-dom'; | ||
|
||
const loadAnalytics = () => | ||
import(/* webpackChunkName: "analytics" */ './Analytics'); | ||
|
||
const AnalyticsBody = lazy(loadAnalytics); | ||
|
||
const About: FC<Record<string, never>> = () => { | ||
useEffect(() => { | ||
// eslint-disable-next-line @typescript-eslint/no-floating-promises | ||
loadAnalytics(); | ||
}, []); | ||
|
||
const { path } = useRouteMatch(); | ||
|
||
return ( | ||
<Switch> | ||
<Route exact path={path}> | ||
<AnalyticsPage> | ||
<Frame title="Analytics"> | ||
<AnalyticsBody /> | ||
</Frame> | ||
</AnalyticsPage> | ||
</Route> | ||
</Switch> | ||
); | ||
}; | ||
|
||
export default About; |
73 changes: 73 additions & 0 deletions
73
apps/crn-frontend/src/analytics/__tests__/Analytics.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { render, screen } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { MemoryRouter } from 'react-router-dom'; | ||
|
||
import Analytics from '../Analytics'; | ||
import { getMemberships } from '../api'; | ||
|
||
jest.mock('../api'); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
const mockGetMemberships = getMemberships as jest.MockedFunction< | ||
typeof getMemberships | ||
>; | ||
|
||
const data = [ | ||
{ | ||
id: '1', | ||
displayName: 'Team 1', | ||
workingGroupLeadershipRoleCount: 1, | ||
workingGroupPreviousLeadershipRoleCount: 2, | ||
workingGroupMemberCount: 3, | ||
workingGroupPreviousMemberCount: 4, | ||
interestGroupLeadershipRoleCount: 5, | ||
interestGroupPreviousLeadershipRoleCount: 6, | ||
interestGroupMemberCount: 7, | ||
interestGroupPreviousMemberCount: 8, | ||
}, | ||
{ | ||
id: '2', | ||
displayName: 'Team 2', | ||
workingGroupLeadershipRoleCount: 2, | ||
workingGroupPreviousLeadershipRoleCount: 3, | ||
workingGroupMemberCount: 4, | ||
workingGroupPreviousMemberCount: 5, | ||
interestGroupLeadershipRoleCount: 4, | ||
interestGroupPreviousLeadershipRoleCount: 3, | ||
interestGroupMemberCount: 2, | ||
interestGroupPreviousMemberCount: 1, | ||
}, | ||
]; | ||
|
||
const renderPage = async () => { | ||
render( | ||
<MemoryRouter initialEntries={['/analytics']}> | ||
<Analytics /> | ||
</MemoryRouter>, | ||
); | ||
}; | ||
|
||
it('renders with working group data', async () => { | ||
mockGetMemberships.mockReturnValue(data); | ||
|
||
await renderPage(); | ||
expect( | ||
screen.getAllByText('Working Group Leadership & Membership').length, | ||
).toBe(2); | ||
}); | ||
|
||
it('renders with interest group data', async () => { | ||
mockGetMemberships.mockReturnValue(data); | ||
const label = 'Interest Group Leadership & Membership'; | ||
|
||
await renderPage(); | ||
const input = screen.getByRole('textbox', { hidden: false }); | ||
|
||
userEvent.click(input); | ||
userEvent.click(screen.getByText(label)); | ||
|
||
expect(screen.getAllByText(label).length).toBe(2); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { render, screen } from '@testing-library/react'; | ||
import { mockConsoleError } from '@asap-hub/dom-test-utils'; | ||
import { MemoryRouter, Route } from 'react-router-dom'; | ||
import { analytics } from '@asap-hub/routing'; | ||
|
||
import About from '../Routes'; | ||
import { getMemberships } from '../api'; | ||
|
||
jest.mock('../api'); | ||
mockConsoleError(); | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
const mockGetMemberships = getMemberships as jest.MockedFunction< | ||
typeof getMemberships | ||
>; | ||
|
||
const renderPage = async () => { | ||
render( | ||
<MemoryRouter initialEntries={['/analytics']}> | ||
<Route path={analytics.template}> | ||
<About /> | ||
</Route> | ||
</MemoryRouter>, | ||
); | ||
}; | ||
|
||
describe('Analytics page', () => { | ||
it('renders the Analytics Page successfully', async () => { | ||
mockGetMemberships.mockReturnValue([]); | ||
|
||
await renderPage(); | ||
expect( | ||
await screen.findByText(/Analytics/i, { | ||
selector: 'h1', | ||
}), | ||
).toBeVisible(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { getMemberships } from '../api'; | ||
|
||
describe('getMemberships', () => { | ||
it('returns data', () => { | ||
expect(getMemberships().length).toBe(2); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
export const getMemberships = () => { | ||
const fakeData = [ | ||
{ | ||
id: '1', | ||
displayName: 'Team 1', | ||
workingGroupLeadershipRoleCount: 1, | ||
workingGroupPreviousLeadershipRoleCount: 2, | ||
workingGroupMemberCount: 3, | ||
workingGroupPreviousMemberCount: 4, | ||
interestGroupLeadershipRoleCount: 5, | ||
interestGroupPreviousLeadershipRoleCount: 6, | ||
interestGroupMemberCount: 7, | ||
interestGroupPreviousMemberCount: 8, | ||
}, | ||
{ | ||
id: '2', | ||
displayName: 'Team 2', | ||
workingGroupLeadershipRoleCount: 2, | ||
workingGroupPreviousLeadershipRoleCount: 3, | ||
workingGroupMemberCount: 4, | ||
workingGroupPreviousMemberCount: 5, | ||
interestGroupLeadershipRoleCount: 4, | ||
interestGroupPreviousLeadershipRoleCount: 3, | ||
interestGroupMemberCount: 2, | ||
interestGroupPreviousMemberCount: 1, | ||
}, | ||
]; | ||
return fakeData; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { getMemberships } from './api'; | ||
|
||
export const useMemberships = () => ({ | ||
data: getMemberships(), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* istanbul ignore file */ | ||
|
||
const analytics = ( | ||
<svg | ||
width="24" | ||
height="24" | ||
viewBox="0 0 48 48" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<title>Analytics</title> | ||
<path | ||
d="M6.78571 4H4V40.2143C4 40.9531 4.29349 41.6617 4.81592 42.1841C5.33834 42.7065 6.0469 43 6.78571 43H43V40.2143H6.78571V4Z" | ||
fill="#4D646B" | ||
/> | ||
<path | ||
d="M42.9999 13.75H33.2499V16.5357H38.2502L27.6784 27.1075L21.7031 21.1182C21.5736 20.9877 21.4195 20.884 21.2498 20.8133C21.0801 20.7426 20.898 20.7062 20.7141 20.7062C20.5303 20.7062 20.3482 20.7426 20.1785 20.8133C20.0088 20.884 19.8547 20.9877 19.7252 21.1182L9.57129 31.2861L11.5352 33.25L20.7141 24.0711L26.6895 30.0604C26.819 30.1909 26.973 30.2945 27.1428 30.3652C27.3125 30.436 27.4946 30.4724 27.6784 30.4724C27.8623 30.4724 28.0444 30.436 28.2141 30.3652C28.3838 30.2945 28.5379 30.1909 28.6674 30.0604L40.2141 18.4996V23.5H42.9999V13.75Z" | ||
fill="#4D646B" | ||
/> | ||
</svg> | ||
); | ||
|
||
export default analytics; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* istanbul ignore file */ | ||
|
||
import { FC } from 'react'; | ||
|
||
interface LeadershipIconProps { | ||
readonly color?: string; | ||
readonly size?: number; | ||
} | ||
const Leadership: FC<LeadershipIconProps> = ({ | ||
color = '#4D646B', | ||
size = 24, | ||
}) => ( | ||
<svg | ||
width={size} | ||
height={size} | ||
viewBox="0 0 24 24" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<title>Leadership</title> | ||
<path | ||
d="M7.50903 14.8129L3.24464 7.44625C3.06076 7.12841 2.97428 6.76357 2.99594 6.39701C3.0176 6.03045 3.14645 5.67833 3.36648 5.38435L4.87542 3.37869C5.05002 3.14589 5.27642 2.95694 5.5367 2.8268C5.79698 2.69666 6.08398 2.62891 6.37498 2.62891H17.6217C17.9127 2.62891 18.1997 2.69666 18.46 2.8268C18.7203 2.95694 18.9467 3.14589 19.1213 3.37869L20.6208 5.38435C20.8423 5.67738 20.9728 6.02902 20.9962 6.39559C21.0195 6.76217 20.9346 7.12752 20.752 7.44625L16.4877 14.8129M11.0611 12.0012L5.55022 2.81635M12.9356 12.0012L18.4465 2.81635M8.24944 7.31504H15.7473" | ||
stroke={color} | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
/> | ||
<path | ||
d="M12.0006 21.3723C14.5887 21.3723 16.6867 19.2742 16.6867 16.6861C16.6867 14.0981 14.5887 12 12.0006 12C9.41251 12 7.31445 14.0981 7.31445 16.6861C7.31445 19.2742 9.41251 21.3723 12.0006 21.3723Z" | ||
stroke={color} | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
/> | ||
<path | ||
d="M11.9969 17.6245V15.75H11.5283" | ||
stroke={color} | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
/> | ||
</svg> | ||
); | ||
|
||
export default Leadership; |
Oops, something went wrong.