Skip to content

Commit

Permalink
[ASAP-565] - add compliance dashboard (#4458)
Browse files Browse the repository at this point in the history
* add compliance dashboard

* add tests

* add ComplianceTable test

* minor fix

* update test

* update compliance tab condition

* Update apps/crn-frontend/src/network/teams/__tests__/TeamProfile.test.tsx

Co-authored-by: Gabriela Ueno <gabiayako@gmail.com>

---------

Co-authored-by: Gabriela Ueno <gabiayako@gmail.com>
  • Loading branch information
AkosuaA and gabiayako authored Dec 12, 2024
1 parent f82babd commit eb9c86c
Show file tree
Hide file tree
Showing 17 changed files with 767 additions and 6 deletions.
16 changes: 15 additions & 1 deletion apps/crn-frontend/src/network/ProfileSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ const loadEventsList = () =>
const EventsList = lazy(loadEventsList);

type RequiredPaths = 'about' | 'upcoming' | 'past';
type OptionalPaths = 'calendar' | 'outputs' | 'workspace' | 'draftOutputs';
type OptionalPaths =
| 'calendar'
| 'outputs'
| 'workspace'
| 'draftOutputs'
| 'compliance';

type ProfileSwitchProps = {
About: FC;
Expand All @@ -27,6 +32,7 @@ type ProfileSwitchProps = {
paths: Record<RequiredPaths, string> & Partial<Record<OptionalPaths, string>>;
type: ComponentProps<typeof NoEvents>['type'];
Workspace?: FC;
Compliance?: FC;
};

const ProfileSwitch: FC<ProfileSwitchProps> = ({
Expand All @@ -41,6 +47,7 @@ const ProfileSwitch: FC<ProfileSwitchProps> = ({
type,
Workspace,
DraftOutputs,
Compliance,
}) => (
<Frame title={displayName}>
<Switch>
Expand Down Expand Up @@ -71,6 +78,13 @@ const ProfileSwitch: FC<ProfileSwitchProps> = ({
</Frame>
</Route>
)}
{Compliance && (
<Route path={paths.compliance}>
<Frame title="Compliance">
<Compliance />
</Frame>
</Route>
)}
{isActive && (
<Route path={paths.upcoming}>
<Frame title="Upcoming Events">
Expand Down
56 changes: 56 additions & 0 deletions apps/crn-frontend/src/network/teams/Compliance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useState } from 'react';
import { SearchField, ComplianceDashboard } from '@asap-hub/react-components';
import {
complianceInitialSortingDirection,
ComplianceSortingDirection,
SortCompliance,
} from '@asap-hub/model';

import { SearchFrame } from '@asap-hub/frontend-utils';
import { useManuscripts } from './state';

import { usePagination, usePaginationParams, useSearch } from '../../hooks';

const Compliance: React.FC = () => {
const { currentPage, pageSize } = usePaginationParams();
const { filters, searchQuery, setSearchQuery } = useSearch();
const result = useManuscripts({
searchQuery,
currentPage,
pageSize,
filters,
});
const { numberOfPages, renderPageHref } = usePagination(
result.total,
pageSize,
);

const [sort, setSort] = useState<SortCompliance>('team_asc');

const [sortingDirection, setSortingDirection] =
useState<ComplianceSortingDirection>(complianceInitialSortingDirection);

return (
<article>
<SearchField
placeholder="Enter team name, ID, assigned users..."
value={searchQuery}
onChange={setSearchQuery}
/>
<SearchFrame title="">
<ComplianceDashboard
data={result.items}
setSort={setSort}
setSortingDirection={setSortingDirection}
sort={sort}
sortingDirection={sortingDirection}
currentPageIndex={currentPage}
numberOfPages={numberOfPages}
renderPageHref={renderPageHref}
/>
</SearchFrame>
</article>
);
};

export default Compliance;
24 changes: 22 additions & 2 deletions apps/crn-frontend/src/network/teams/TeamProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { useUpcomingAndPastEvents } from '../events';
import ProfileSwitch from '../ProfileSwitch';

import { ManuscriptToastProvider } from './ManuscriptToastProvider';
import { useIsComplianceReviewer, useTeamById } from './state';
import { useIsComplianceReviewer, useManuscripts, useTeamById } from './state';
import TeamManuscript from './TeamManuscript';
import { EligibilityReasonProvider } from './EligibilityReasonProvider';
import TeamComplianceReport from './TeamComplianceReport';
Expand All @@ -33,6 +33,8 @@ const loadOutputs = () =>
import(/* webpackChunkName: "network-team-outputs" */ './Outputs');
const loadWorkspace = () =>
import(/* webpackChunkName: "network-team-workspace" */ './Workspace');
const loadCompliance = () =>
import(/* webpackChunkName: "network-team-compliance" */ './Compliance');
const loadTeamOutput = () =>
import(/* webpackChunkName: "network-team-team-output" */ './TeamOutput');
const loadEventsList = () =>
Expand All @@ -41,6 +43,7 @@ const loadEventsList = () =>
const About = lazy(loadAbout);
const Outputs = lazy(loadOutputs);
const Workspace = lazy(loadWorkspace);
const Compliance = lazy(loadCompliance);
const TeamOutput = lazy(loadTeamOutput);

type TeamProfileProps = {
Expand Down Expand Up @@ -76,15 +79,18 @@ const TeamProfile: FC<TeamProfileProps> = ({ currentTime }) => {
const team = useTeamById(teamId);
const user = useCurrentUserCRN();
const isStaff = user?.role === 'Staff';
const isAsapTeam = team?.displayName === 'ASAP';
const canDisplayCompliancePage = isStaff && isAsapTeam;

useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
loadAbout()
.then(team?.tools || isStaff ? loadWorkspace : undefined)
.then(canDisplayCompliancePage ? loadCompliance : undefined)
.then(loadOutputs)
.then(loadTeamOutput)
.then(loadEventsList);
}, [team, isStaff]);
}, [team, isStaff, canDisplayCompliancePage]);

const canShareResearchOutput = useCanShareResearchOutput(
'teams',
Expand Down Expand Up @@ -118,9 +124,17 @@ const TeamProfile: FC<TeamProfileProps> = ({ currentTime }) => {
teamId,
});

const manuscriptCount = useManuscripts({
searchQuery: '',
currentPage: 0,
pageSize,
filters: new Set(),
});

if (team) {
const {
about,
compliance,
createOutput,
duplicateOutput,
outputs,
Expand All @@ -133,6 +147,7 @@ const TeamProfile: FC<TeamProfileProps> = ({ currentTime }) => {
});
const paths = {
about: path + about.template,
compliance: path + compliance.template,
outputs: path + outputs.template,
past: path + past.template,
upcoming: path + upcoming.template,
Expand Down Expand Up @@ -199,13 +214,15 @@ const TeamProfile: FC<TeamProfileProps> = ({ currentTime }) => {
<TeamProfilePage
{...team}
isStaff={isStaff}
isAsapTeam={isAsapTeam}
teamListElementId={teamListElementId}
upcomingEventsCount={upcomingEvents?.total || 0}
pastEventsCount={pastEvents?.total || 0}
teamOutputsCount={teamOutputsResult.total}
teamDraftOutputsCount={
canShareResearchOutput ? outputDraftResults.total : undefined
}
manuscriptsCount={manuscriptCount.total || 0}
>
<ProfileSwitch
About={() => (
Expand Down Expand Up @@ -233,6 +250,9 @@ const TeamProfile: FC<TeamProfileProps> = ({ currentTime }) => {
Workspace={() => (
<Workspace team={{ ...team, tools: team.tools ?? [] }} />
)}
{...(canDisplayCompliancePage
? { Compliance: () => <Compliance /> }
: {})}
/>
</TeamProfilePage>
</Switch>
Expand Down
65 changes: 65 additions & 0 deletions apps/crn-frontend/src/network/teams/__tests__/TeamProfile.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -815,3 +815,68 @@ describe('The draft output tab', () => {
expect(screen.getByText('Draft Outputs (0)')).toBeVisible();
});
});

describe('The compliance tab', () => {
it('does not show compliance tab if not on Team ASAP', async () => {
enable('DISPLAY_MANUSCRIPTS');
await renderPage({
...createTeamResponse(),
displayName: 'Test',
});

expect(
screen.queryByText(/Compliance/i, { selector: 'nav *' }),
).not.toBeInTheDocument();
});

it('does not show compliance tab if on Team ASAP but not Staff', async () => {
enable('DISPLAY_MANUSCRIPTS');
await renderPage(
{
...createTeamResponse(),
displayName: 'ASAP',
},
{},
{ role: 'Grantee' },
);

expect(
screen.queryByText(/Compliance/i, { selector: 'nav *' }),
).not.toBeInTheDocument();
});

it('shows compliance tab on Team ASAP page if user is Staff', async () => {
enable('DISPLAY_MANUSCRIPTS');
await renderPage(
{
...createTeamResponse(),
displayName: 'ASAP',
},
{},
{
role: 'Staff',
},
);

expect(
screen.getByText(/Compliance/i, { selector: 'nav *' }),
).toBeVisible();
});

it('renders compliance dashboard on Team ASAP page', async () => {
enable('DISPLAY_MANUSCRIPTS');
await renderPage(
{
...createTeamResponse(),
displayName: 'ASAP',
},
{},
{
role: 'Staff',
},
);

userEvent.click(screen.getByText(/Compliance/i, { selector: 'nav *' }));
expect(await screen.findByText(/No manuscripts available/i)).toBeVisible();
});
});
8 changes: 8 additions & 0 deletions apps/crn-frontend/src/network/teams/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ManuscriptPutRequest,
DiscussionPatchRequest,
DiscussionResponse,
ListPartialManuscriptResponse,
} from '@asap-hub/model';
import { useCurrentUserCRN } from '@asap-hub/react-context';
import { useCallback } from 'react';
Expand Down Expand Up @@ -310,3 +311,10 @@ export const useReplyToDiscussion = () => {
setDiscussion(discussion);
};
};

export const useManuscripts = (
options: GetListOptions,
): ListPartialManuscriptResponse => ({
total: 0,
items: [],
});
4 changes: 2 additions & 2 deletions packages/model/src/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ export type LeadershipAndMembershipFields =

export type SortingDirection = 'asc' | 'desc';

const ascending: SortingDirection = 'asc';
const descending: SortingDirection = 'desc';
export const ascending: SortingDirection = 'asc';
export const descending: SortingDirection = 'desc';

export const initialSortingDirection = {
team: ascending,
Expand Down
49 changes: 49 additions & 0 deletions packages/model/src/manuscript.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { JSONSchemaType } from 'ajv';
import { ascending, descending, SortingDirection } from './analytics';
import { AuthorAlgoliaResponse, AuthorResponse } from './authors';
import { ListResponse } from './common';
import { ComplianceReportDataObject } from './compliance-report';
import { DiscussionDataObject } from './discussion';
import { UserResponse } from './user';
Expand Down Expand Up @@ -783,3 +785,50 @@ export const asapFundingReasons = [
'The manuscript is a thought leadership piece (review, communication, letter) pertaining to knowledge gaps in the field that the ASAP-funded proposal was addressing.',
},
];

export type SortComplianceFields =
| 'team'
| 'id'
| 'lastUpdated'
| 'status'
| 'apcCoverage';

export type ComplianceSortingDirection = {
[key in SortComplianceFields]: SortingDirection;
};

export type SortCompliance =
| 'team_asc'
| 'team_desc'
| 'id_asc'
| 'id_desc'
| 'last_updated_asc'
| 'last_updated_desc'
| 'status_asc'
| 'status_desc'
| 'apc_coverage_asc'
| 'apc_coverage_desc';

export const complianceInitialSortingDirection = {
team: ascending,
id: descending,
lastUpdated: descending,
status: ascending,
apcCoverage: ascending,
};

export type PartialManuscriptResponse = Pick<
ManuscriptVersion,
'id' | 'requestingApcCoverage'
> &
Pick<ManuscriptResponse, 'status'> & {
lastUpdated: string;
team: { id: string; displayName: string };
assignedUsers: Pick<
UserResponse,
'id' | 'firstName' | 'lastName' | 'avatarUrl'
>[];
};

export type ListPartialManuscriptResponse =
ListResponse<PartialManuscriptResponse>;
1 change: 1 addition & 0 deletions packages/react-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ export {
AnalyticsPageHeader,
BasicLayout,
BiographyModal,
ComplianceDashboard,
ComplianceReportForm,
ContactInfoModal,
ContentPage,
Expand Down
Loading

0 comments on commit eb9c86c

Please sign in to comment.