Skip to content

Commit

Permalink
conditional rules on edit manuscript (#4444)
Browse files Browse the repository at this point in the history
* conditional rules on edit manuscript

* linting

* fix tests

* linting

* remove manuscript lab pi condition

* update test

* disable fields on edit

* fixes

* update test

* add teamId prop

---------

Co-authored-by: AkosuaA <nattuah@gmail.com>
  • Loading branch information
lctrt and AkosuaA authored Nov 21, 2024
1 parent 52d7f58 commit 9af3313
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 59 deletions.
3 changes: 3 additions & 0 deletions apps/crn-server/test/fixtures/manuscript.fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ export const getContentfulGraphqlManuscriptVersions: () => NonNullable<
{
sys: { id: 'lab-1' },
name: 'Lab 1',
linkedFrom: {
usersCollection: { items: [] },
},
},
],
},
Expand Down
10 changes: 8 additions & 2 deletions apps/crn-server/test/fixtures/teams.fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,14 @@ export const getContentfulGraphqlTeamMembers = () => ({
export const getContentfulGraphqlTeamMemberLabs = () => ({
total: 2,
items: [
{ sys: { id: 'cd7be4902' }, name: 'Brighton' },
{ sys: { id: 'cd7be4903' }, name: 'Liverpool' },
{
sys: { id: 'cd7be4902' },
name: 'Brighton',
},
{
sys: { id: 'cd7be4903' },
name: 'Liverpool',
},
],
});

Expand Down
2 changes: 1 addition & 1 deletion packages/react-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"react-router-dom": "5.3.4"
},
"dependencies": {
"@asap-hub/auth": "workspace:*",
"@asap-hub/algolia": "workspace:*",
"@asap-hub/flags": "workspace:*",
"@asap-hub/model": "workspace:*",
Expand Down Expand Up @@ -70,7 +71,6 @@
"uuid": "8.3.2"
},
"devDependencies": {
"@asap-hub/auth": "workspace:*",
"@asap-hub/dom-test-utils": "workspace:*",
"@asap-hub/eslint-config-asap-hub": "workspace:*",
"@asap-hub/fixtures": "workspace:*",
Expand Down
8 changes: 7 additions & 1 deletion packages/react-components/src/atoms/Tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ const Tag: React.FC<TagProps> = ({
>
<Ellipsis>{children}</Ellipsis>
{!!onRemove && enabled && (
<button css={iconStyles} onClick={onRemove}>
<button
css={iconStyles}
onClick={(event) => {
event.preventDefault();
onRemove();
}}
>
{crossSmallIcon}
</button>
)}
Expand Down
7 changes: 6 additions & 1 deletion packages/react-components/src/molecules/LabeledFileField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type LabeledFileFieldProps = {
readonly customValidation?: (file: File) => boolean;
readonly handleFileUpload: (file: File) => Promise<void>;
readonly accept?: string;
readonly tagEnabled?: boolean;
} & Pick<ComponentProps<typeof Button>, 'enabled'>;

const LabeledFileField: React.FC<LabeledFileFieldProps> = ({
Expand All @@ -77,6 +78,7 @@ const LabeledFileField: React.FC<LabeledFileFieldProps> = ({
enabled,
customValidationMessage,
handleFileUpload,
tagEnabled = true,
}) => {
const fileInputRef = useRef<HTMLInputElement>(null);

Expand Down Expand Up @@ -115,7 +117,10 @@ const LabeledFileField: React.FC<LabeledFileFieldProps> = ({
{currentFiles &&
currentFiles.map((file) => (
<div css={uploadedButtonTagStyles} key={file.id}>
<Tag onRemove={() => handleRemove(file.id)}>
<Tag
onRemove={() => handleRemove(file.id)}
enabled={tagEnabled}
>
{file.filename}
</Tag>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,41 @@ it('restricts allowed files when accept prop is provided', async () => {
expect(uploadInput).toHaveAttribute('accept', 'application/pdf');
});

it('tagEnabled prop removes cross icon on file tag when false', async () => {
const { getByRole, queryByRole, rerender } = render(
<LabeledFileField
title="Title"
subtitle="Subtitle"
handleFileUpload={handleFileUploadMock}
enabled
tagEnabled={true}
currentFiles={[
{
filename: 'file.txt',
url: 'http://example.com/file.txt',
id: '123',
},
]}
/>,
);

expect(getByRole('button', { name: /cross/i })).toBeVisible();

rerender(
<LabeledFileField
title="Title"
subtitle="Subtitle"
handleFileUpload={handleFileUploadMock}
enabled
tagEnabled={false}
placeholder="Upload Manuscript File"
accept="application/pdf"
/>,
);

expect(queryByRole('button', { name: /cross/i })).not.toBeInTheDocument();
});

it('does not restrict allowed files when accept prop is not provided', async () => {
render(
<LabeledFileField
Expand Down
7 changes: 6 additions & 1 deletion packages/react-components/src/organisms/ManuscriptCard.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { User } from '@asap-hub/auth';
import {
ManuscriptPutRequest,
ManuscriptResponse,
Expand Down Expand Up @@ -31,6 +32,7 @@ type ManuscriptCardProps = Pick<
ComponentProps<typeof ManuscriptVersionCard>,
'onReplyToDiscussion' | 'getDiscussion'
> & {
user: User | null;
teamId: string;
teamIdCode: string;
grantId: string;
Expand Down Expand Up @@ -99,6 +101,7 @@ const ManuscriptCard: React.FC<ManuscriptCardProps> = ({
onUpdateManuscript,
getDiscussion,
onReplyToDiscussion,
user,
}) => {
const [displayConfirmStatusChangeModal, setDisplayConfirmStatusChangeModal] =
useState(false);
Expand Down Expand Up @@ -230,10 +233,12 @@ const ManuscriptCard: React.FC<ManuscriptCardProps> = ({
getDiscussion={getDiscussion}
key={index}
version={version}
teamId={teamIdCode}
teamId={teamId}
teamIdCode={teamIdCode}
grantId={grantId}
manuscriptCount={count}
manuscriptId={id}
user={user}
/>
))}
</div>
Expand Down
89 changes: 69 additions & 20 deletions packages/react-components/src/organisms/ManuscriptVersionCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { User } from '@asap-hub/auth';
import {
AuthorResponse,
ManuscriptLifecycle,
ManuscriptVersion,
Message,
Expand Down Expand Up @@ -35,9 +37,11 @@ import { mobileScreen, perRem, rem } from '../pixels';
import ComplianceReportCard from './ComplianceReportCard';

type ManuscriptVersionCardProps = {
user: User | null;
version: ManuscriptVersion;
grantId: string;
teamId: string;
teamIdCode: string;
manuscriptCount: number;
manuscriptId: string;
} & Pick<ComponentProps<typeof QuickCheckReplyModal>, 'onReplyToDiscussion'> &
Expand Down Expand Up @@ -197,15 +201,57 @@ export const getLifecycleCode = ({
}
};

export type VersionUserProps = {
version: Pick<
ManuscriptVersion,
| 'teams'
| 'firstAuthors'
| 'correspondingAuthor'
| 'additionalAuthors'
| 'labs'
>;
user: User | null;
};

export const isManuscriptLead = ({ version, user }: VersionUserProps) =>
user &&
user.teams.find((team) =>
version.teams.find(
(versionTeam) =>
versionTeam.id === team.id &&
(team.role === 'Lead PI (Core Leadership)' ||
team.role === 'Project Manager'),
),
);

export const isManuscriptAuthor = ({
authors,
user,
}: {
authors: AuthorResponse[];
user: User | null;
}) => user && authors.find((author) => author.id === user.id);

export const canEditManuscript = ({ version, user }: VersionUserProps) =>
isManuscriptLead({ version, user }) ||
isManuscriptAuthor({
authors: [
...version.firstAuthors,
...version.correspondingAuthor,
...version.additionalAuthors,
],
user,
});

export const getManuscriptVersionUID = ({
version,
teamId,
teamIdCode,
grantId,
manuscriptCount,
manuscriptVersionCount,
}: {
version: Pick<ManuscriptVersion, 'type' | 'lifecycle'>;
teamId: string;
teamIdCode: string;
grantId: string;
manuscriptCount: number;
manuscriptVersionCount: number;
Expand All @@ -214,22 +260,25 @@ export const getManuscriptVersionUID = ({
version.type === 'Original Research' ? 'org' : 'rev';

const lifecycleCode = getLifecycleCode(version);
return `${teamId}-${grantId}-${String(manuscriptCount).padStart(
return `${teamIdCode}-${grantId}-${String(manuscriptCount).padStart(
3,
'0',
)}-${manuscriptTypeCode}-${lifecycleCode}-${manuscriptVersionCount}`;
};

const ManuscriptVersionCard: React.FC<ManuscriptVersionCardProps> = ({
user,
version,
teamId,
teamIdCode,
grantId,
manuscriptCount,
onReplyToDiscussion,
getDiscussion,
manuscriptId,
}) => {
const history = useHistory();

const [expanded, setExpanded] = useState(false);

const quickCheckDetails = quickCheckQuestions.filter(
Expand Down Expand Up @@ -267,13 +316,11 @@ const ManuscriptVersionCard: React.FC<ManuscriptVersionCardProps> = ({

const updatedByData = getUpdatedByData();

const editManuscriptRoute =
version.createdBy?.teams[0]?.id &&
network({})
.teams({})
.team({ teamId: version.createdBy.teams[0].id })
.workspace({})
.editManuscript({ manuscriptId }).$;
const editManuscriptRoute = network({})
.teams({})
.team({ teamId })
.workspace({})
.editManuscript({ manuscriptId }).$;

const handleEditManuscript = () => {
if (editManuscriptRoute) {
Expand Down Expand Up @@ -318,15 +365,17 @@ const ManuscriptVersionCard: React.FC<ManuscriptVersionCardProps> = ({
</span>
</div>
</Caption>
<Button
aria-label="Edit"
small
noMargin
onClick={handleEditManuscript}
overrideStyles={editIconStyles}
>
<PencilIcon />
</Button>
{canEditManuscript({ version, user }) && (
<Button
aria-label="Edit"
small
noMargin
onClick={handleEditManuscript}
overrideStyles={editIconStyles}
>
<PencilIcon />
</Button>
)}
</div>
</div>
</span>
Expand All @@ -343,7 +392,7 @@ const ManuscriptVersionCard: React.FC<ManuscriptVersionCardProps> = ({
<Pill accent="blue">
{getManuscriptVersionUID({
version,
teamId,
teamIdCode,
grantId,
manuscriptCount,
manuscriptVersionCount: 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { createManuscriptResponse } from '@asap-hub/fixtures';
import {
createManuscriptResponse,
createUserResponse,
} from '@asap-hub/fixtures';
import { act, render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ComponentProps } from 'react';
Expand All @@ -8,6 +11,7 @@ import ManuscriptCard from '../ManuscriptCard';

const props: ComponentProps<typeof ManuscriptCard> = {
...createManuscriptResponse(),
user: { ...createUserResponse({}, 1), algoliaApiKey: 'algolia-mock-key' },
teamIdCode: 'TI1',
grantId: '000123',
isComplianceReviewer: false,
Expand Down
Loading

0 comments on commit 9af3313

Please sign in to comment.