diff --git a/packages/component-faraday-selectors/src/index.js b/packages/component-faraday-selectors/src/index.js index 40e8640c8c2cc1b685b37ba1a927b34fbf020c6e..d51783f1446fedd11253274513411241b8fc01ad 100644 --- a/packages/component-faraday-selectors/src/index.js +++ b/packages/component-faraday-selectors/src/index.js @@ -115,6 +115,8 @@ export const authorCanViewReportsDetails = ( ) } +export const canInviteReviewersAsEiC = state => !currentUserIs(state, 'isEiC') + export const reviewersCanViewReviewerReports = ( state, collection = {}, diff --git a/packages/component-faraday-ui/src/ReviewersTable.js b/packages/component-faraday-ui/src/ReviewersTable.js index f9ba6708bc73a0ebbbced263fc9bc85176a3b279..1278bbf3199cec07cdbeba58842f0732021e817f 100644 --- a/packages/component-faraday-ui/src/ReviewersTable.js +++ b/packages/component-faraday-ui/src/ReviewersTable.js @@ -9,6 +9,7 @@ import { compose, shouldUpdate, withHandlers, withProps } from 'recompose' import { Label, PersonInvitation, Text } from './' const ReviewersTable = ({ + currentUser, invitations = [], getInvitationStatus, renderAcceptedLabel, @@ -71,13 +72,14 @@ const ReviewersTable = ({ </DateParser> </td> <HiddenCell> - {!invitation.hasAnswer && ( - <PersonInvitation - {...invitation} - onResend={onResendReviewerInvite} - onRevoke={onRevokeReviewerInvite} - /> - )} + {!invitation.hasAnswer && + get(currentUser, 'permissions.canInviteReviewersAsEiC') && ( + <PersonInvitation + {...invitation} + onResend={onResendReviewerInvite} + onRevoke={onRevokeReviewerInvite} + /> + )} </HiddenCell> </TableRow> ))} diff --git a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js index d8c5df524a74c5de294c3d9bb7611b4cc2875e95..98434bfa2ea4ddad76bc4fc0c563756d0a85e9e9 100644 --- a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js +++ b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js @@ -27,6 +27,7 @@ const ReviewerDetails = ({ reports = [], fragment, invitations, + currentUser, publonReviewers, isFetching, previewFile, @@ -42,6 +43,7 @@ const ReviewerDetails = ({ highlight, canViewReviewersDetails, authorCanViewReportsDetails, + canSeeReviewerSuggestionsTab, isLatestVersion, ...rest }) => ( @@ -66,7 +68,8 @@ const ReviewerDetails = ({ <H4>Reviewer Details</H4> </TabButton> {canInviteReviewers && - isLatestVersion && ( + isLatestVersion && + get(currentUser, 'permissions.canInviteReviewersAsEiC') && ( <TabButton data-test-id="reviewer-tab-suggestions" ml={1} @@ -92,7 +95,8 @@ const ReviewerDetails = ({ {selectedTab === 0 && ( <Fragment> {canInviteReviewers && - isLatestVersion && ( + isLatestVersion && + get(currentUser, 'permissions.canInviteReviewersAsEiC') && ( <InviteReviewers modalKey="invite-reviewers" onInvite={onInviteReviewer} @@ -100,6 +104,7 @@ const ReviewerDetails = ({ )} <ReviewersTable + currentUser={currentUser} invitations={invitations} onResendReviewerInvite={onResendReviewerInvite} onRevokeReviewerInvite={onRevokeReviewerInvite} @@ -107,7 +112,8 @@ const ReviewerDetails = ({ </Fragment> )} {selectedTab === 2 && - isLatestVersion && ( + isLatestVersion && + get(currentUser, 'permissions.canInviteReviewersAsEiC') && ( <PublonsTable onInvite={onInvitePublonReviewer} publonsError={fetchingError} diff --git a/packages/component-invite/src/tests/fragmentsInvitations/delete.test.js b/packages/component-invite/src/tests/fragmentsInvitations/delete.test.js index d7ee683a82165b31adf4b13eb53779be1c1d8b9c..c6e5c0fc9718533c793c610a05e47d2393464148 100644 --- a/packages/component-invite/src/tests/fragmentsInvitations/delete.test.js +++ b/packages/component-invite/src/tests/fragmentsInvitations/delete.test.js @@ -59,11 +59,11 @@ describe('Delete Fragments Invitations route handler', () => { ) }) it('should return an error when the invitation does not exist', async () => { - const { editorInChief } = testFixtures.users + const { handlingEditor } = testFixtures.users const { collection } = testFixtures.collections const { fragment } = testFixtures.fragments const res = await requests.sendRequest({ - userId: editorInChief.id, + userId: handlingEditor.id, route, models, path, @@ -78,11 +78,11 @@ describe('Delete Fragments Invitations route handler', () => { expect(data.error).toEqual('Invitation invalid-id not found') }) it('should return success when the collection and invitation exist', async () => { - const { editorInChief } = testFixtures.users + const { handlingEditor } = testFixtures.users const { collection } = testFixtures.collections const { fragment } = testFixtures.fragments const res = await requests.sendRequest({ - userId: editorInChief.id, + userId: handlingEditor.id, route, models, path, diff --git a/packages/component-invite/src/tests/fragmentsInvitations/post.test.js b/packages/component-invite/src/tests/fragmentsInvitations/post.test.js index cf4b990bb539ca664bb997a79bd136142908ac57..64a1efa019618bce9eaec3d1be17c41d1ce9192b 100644 --- a/packages/component-invite/src/tests/fragmentsInvitations/post.test.js +++ b/packages/component-invite/src/tests/fragmentsInvitations/post.test.js @@ -54,7 +54,7 @@ describe('Post fragments invitations route handler', () => { }) it('should return success when a reviewer is invited', async () => { - const { user, editorInChief } = testFixtures.users + const { user, handlingEditor } = testFixtures.users const { collection } = testFixtures.collections const { fragment } = testFixtures.fragments @@ -65,7 +65,7 @@ describe('Post fragments invitations route handler', () => { const res = await requests.sendRequest({ body, - userId: editorInChief.id, + userId: handlingEditor.id, route, models, path, @@ -81,7 +81,7 @@ describe('Post fragments invitations route handler', () => { }) it('should return success when resending an invitation to an existing reviewer', async () => { - const { editorInChief, reviewer } = testFixtures.users + const { handlingEditor, reviewer } = testFixtures.users const { collection } = testFixtures.collections const { fragment } = testFixtures.fragments @@ -93,7 +93,7 @@ describe('Post fragments invitations route handler', () => { const res = await requests.sendRequest({ body, - userId: editorInChief.id, + userId: handlingEditor.id, route, models, path, diff --git a/packages/component-manuscript/src/components/ManuscriptPage.js b/packages/component-manuscript/src/components/ManuscriptPage.js index 928d9077cc3d789097545716b34e5431ce9d0b14..ee40454d7d33d6901eea583c4d365d50a517f1fd 100644 --- a/packages/component-manuscript/src/components/ManuscriptPage.js +++ b/packages/component-manuscript/src/components/ManuscriptPage.js @@ -49,6 +49,7 @@ import { isFetchingFromAutosave, canMakeHERecommendation, canViewReviewersDetails, + canInviteReviewersAsEiC, canViewEditorialComments, pendingReviewerInvitation, canViewResponseFromAuthor, @@ -196,6 +197,7 @@ export default compose( canMakeDecision: canMakeDecision(state, collection), canEditManuscript: canEditManuscript(state, collection, fragment), canViewReviewersDetails: canViewReviewersDetails(state, collection), + canInviteReviewersAsEiC: canInviteReviewersAsEiC(state), authorCanViewReportsDetails: authorCanViewReportsDetails( state, collection, diff --git a/packages/xpub-faraday/config/authsome-mode.js b/packages/xpub-faraday/config/authsome-mode.js index c54dac097298841495a2289a5f4bebb986dd01ff..56c817fb19d725db835eaea7bd30f932d246dd5d 100644 --- a/packages/xpub-faraday/config/authsome-mode.js +++ b/packages/xpub-faraday/config/authsome-mode.js @@ -417,6 +417,20 @@ async function applyEditorInChiefPolicy(user, operation, object, context) { return false } } + if (operation === 'POST') { + if ( + get(object, 'path') === + '/api/collections/:collectionId/fragments/:fragmentId/invitations' + ) + return false + } + if (operation === 'DELETE') { + if ( + get(object, 'path') === + '/api/collections/:collectionId/fragments/:fragmentId/invitations/:invitationId' + ) + return false + } return true }