Skip to content

Commit d5321c5

Browse files
jekabs-karklinsjekabskarklins
authored andcommitted
feat: improve ProposalQuestionaryReview ui (#1295)
Co-authored-by: jekabskarklins <jekabs.karklins@ess.eu>
1 parent beaed5c commit d5321c5

10 files changed

Lines changed: 140 additions & 8 deletions

File tree

apps/backend/src/resolvers/types/Proposal.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,23 @@ export class ProposalResolver {
312312
}
313313

314314
@FieldResolver(() => ProposalAttachments, { nullable: true })
315-
attachments(@Root() proposal: Proposal, @Ctx() ctx: ResolverContext) {
315+
async attachments(@Root() proposal: Proposal, @Ctx() ctx: ResolverContext) {
316316
return ctx.queries.questionary.getProposalAttachments(
317317
ctx.user,
318318
proposal.primaryKey
319319
);
320320
}
321+
322+
@FieldResolver(() => [BasicUserDetails], { nullable: true })
323+
async dataAccessUsers(
324+
@Root() proposal: Proposal,
325+
@Ctx() context: ResolverContext
326+
): Promise<BasicUserDetails[]> {
327+
return await context.queries.dataAccessUsers.findByProposalPk(
328+
context.user,
329+
proposal.primaryKey
330+
);
331+
}
321332
}
322333

323334
export async function resolveProposalReference(

apps/e2e/cypress/e2e/proposals.cy.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ context('Proposal tests', () => {
192192
createdProposalId
193193
);
194194
cy.get('[data-cy="questionary-details-view"]').contains(newProposalTitle);
195+
cy.get('[data-cy="data-access-users-list"]').contains(
196+
initialDBData.users.user3.lastName
197+
);
195198
});
196199

197200
it('Copy to clipboard should work for Proposal ID', () => {

apps/frontend/src/components/proposal/ProposalCreate.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export function createProposalStub(
5353
samples: [],
5454
genericTemplates: [],
5555
call: call,
56+
dataAccessUsers: [],
5657
};
5758
}
5859

apps/frontend/src/components/review/ProposalQuestionaryReview.tsx

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
import { TableProps } from '@mui/material';
2-
import React, { FunctionComponent } from 'react';
2+
import React, { FunctionComponent, useContext } from 'react';
33

44
import UOLoader from 'components/common/UOLoader';
55
import ProposalQuestionaryDetails from 'components/proposal/ProposalQuestionaryDetails';
66
import { TableRowData } from 'components/questionary/QuestionaryDetails';
7-
import { BasicUserDetails } from 'generated/sdk';
7+
import UserList from 'components/user/UserList';
8+
import UserListItem from 'components/user/UserListItem';
9+
import { FeatureContext } from 'context/FeatureContextProvider';
10+
import { FeatureId } from 'generated/sdk';
811
import { ProposalWithQuestionary } from 'models/questionary/proposal/ProposalWithQuestionary';
9-
import { getFullUserNameWithBasicDetails } from 'utils/user';
1012

1113
export default function ProposalQuestionaryReview(
1214
props: {
1315
data: ProposalWithQuestionary;
1416
} & TableProps<FunctionComponent<unknown>>
1517
) {
1618
const { data, ...restProps } = props;
19+
const featureContext = useContext(FeatureContext);
20+
const isDataAccessUsersEnabled = featureContext.featuresMap.get(
21+
FeatureId.DATA_ACCESS_USERS
22+
)?.isEnabled;
1723

1824
if (!data.questionaryId) {
1925
return <UOLoader style={{ marginLeft: '50%', marginTop: '100px' }} />;
@@ -34,14 +40,25 @@ export default function ProposalQuestionaryReview(
3440
{ label: 'Abstract', value: data.abstract },
3541
{
3642
label: 'Principal Investigator',
37-
value: getFullUserNameWithBasicDetails(data.proposer),
43+
value: <UserListItem user={data.proposer} />,
3844
},
3945
{
4046
label: 'Co-Proposers',
41-
value: users
42-
.map((user: BasicUserDetails) => getFullUserNameWithBasicDetails(user))
43-
.join(', '),
47+
value: <UserList users={users} />,
4448
},
49+
...(isDataAccessUsersEnabled && data.dataAccessUsers
50+
? [
51+
{
52+
label: 'Data Access Users',
53+
value: (
54+
<UserList
55+
users={data.dataAccessUsers}
56+
data-cy="data-access-users-list"
57+
/>
58+
),
59+
},
60+
]
61+
: []),
4562
...(data.coProposerInvites?.length > 0
4663
? [
4764
{

apps/frontend/src/components/review/ReviewQuestionary.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export function createFapReviewStub(
101101
experiments: null,
102102
experimentSequence: null,
103103
fileId: null,
104+
dataAccessUsers: [],
104105
},
105106
};
106107
}

apps/frontend/src/components/review/TechnicalReviewQuestionary.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export function createTechnicalReviewStub(
114114
experiments: null,
115115
experimentSequence: null,
116116
fileId: null,
117+
dataAccessUsers: [],
117118
},
118119
};
119120
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { Button, Collapse, List, ListItem, styled } from '@mui/material';
2+
import React, { useState } from 'react';
3+
4+
import { BasicUserDetails } from 'generated/sdk';
5+
6+
import UserListItem from './UserListItem';
7+
8+
interface UserListProps {
9+
users: BasicUserDetails[];
10+
initVisibleItems?: number;
11+
'data-cy'?: string;
12+
}
13+
14+
const StyledList = styled(List)(() => ({
15+
padding: 0,
16+
'& .MuiListItem-root': {
17+
paddingLeft: 0,
18+
paddingRight: 0,
19+
paddingTop: 0,
20+
paddingBottom: 0,
21+
},
22+
}));
23+
24+
const UserList: React.FC<UserListProps> = ({
25+
users,
26+
initVisibleItems = 4,
27+
'data-cy': dataCy = 'user-list',
28+
}) => {
29+
const [showAll, setShowAll] = useState(false);
30+
31+
if (!users || users.length === 0) {
32+
return null;
33+
}
34+
35+
const initialUsers = users.slice(0, initVisibleItems);
36+
const hiddenUsers = users.slice(initVisibleItems);
37+
const hasMore = users.length > initVisibleItems;
38+
39+
return (
40+
<div data-cy={dataCy}>
41+
<StyledList>
42+
{initialUsers.map((user) => (
43+
<ListItem key={user.id} disableGutters>
44+
<UserListItem user={user} />
45+
</ListItem>
46+
))}
47+
</StyledList>
48+
<Collapse in={showAll}>
49+
<StyledList>
50+
{hiddenUsers.map((user) => (
51+
<ListItem key={user.id} disableGutters>
52+
<UserListItem user={user} />
53+
</ListItem>
54+
))}
55+
</StyledList>
56+
</Collapse>
57+
{hasMore && (
58+
<Button
59+
onClick={() => setShowAll(!showAll)}
60+
variant="text"
61+
size="small"
62+
data-cy={showAll ? 'show-less-users-btn' : 'show-more-users-btn'}
63+
sx={{ paddingLeft: 0, textTransform: 'none' }}
64+
>
65+
{showAll ? 'Show less...' : 'Show more...'}
66+
</Button>
67+
)}
68+
</div>
69+
);
70+
};
71+
72+
export default UserList;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { ListItemText } from '@mui/material';
2+
import React from 'react';
3+
4+
import { BasicUserDetails } from 'generated/sdk';
5+
import { getFullUserNameWithEmail } from 'utils/user';
6+
7+
interface UserListItemProps {
8+
user?: BasicUserDetails | null;
9+
}
10+
11+
const UserListItem: React.FC<UserListItemProps> = ({ user }) => {
12+
return (
13+
<ListItemText
14+
primary={getFullUserNameWithEmail(user)}
15+
secondary={user?.institution || ''}
16+
primaryTypographyProps={{ variant: 'body2' }}
17+
secondaryTypographyProps={{ variant: 'caption' }}
18+
/>
19+
);
20+
};
21+
22+
export default UserListItem;

apps/frontend/src/graphql/proposal/getProposal.graphql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ query getProposal($primaryKey: Int!) {
77
users {
88
...basicUserDetails
99
}
10+
dataAccessUsers {
11+
...basicUserDetails
12+
}
1013
questionary {
1114
...questionary
1215
isCompleted

apps/frontend/src/models/questionary/proposal/ProposalWithQuestionary.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type ProposalWithQuestionary = Pick<
1515
| 'questionary'
1616
| 'status'
1717
| 'users'
18+
| 'dataAccessUsers'
1819
| 'coProposerInvites'
1920
| 'title'
2021
| 'proposalId'

0 commit comments

Comments
 (0)