From aa55f7484977e7335760293018913c9646c5ecd4 Mon Sep 17 00:00:00 2001 From: Alexandru Munteanu <alexandru.munt@gmail.com> Date: Thu, 21 Jun 2018 14:45:25 +0300 Subject: [PATCH] feat(submit-revision): update authsome to get the correct version, create new version --- .../component-faraday-selectors/src/index.js | 11 +- .../src/components/SideBarActions.js | 41 ++++++- .../component-wizard/src/redux/conversion.js | 23 +++- .../src/components/Dashboard/DashboardCard.js | 106 +++++++++--------- .../xpub-faraday/config/authsome-helpers.js | 14 ++- packages/xpub-faraday/config/authsome-mode.js | 20 +++- 6 files changed, 153 insertions(+), 62 deletions(-) diff --git a/packages/component-faraday-selectors/src/index.js b/packages/component-faraday-selectors/src/index.js index 2ad7a635b..cde4ed57f 100644 --- a/packages/component-faraday-selectors/src/index.js +++ b/packages/component-faraday-selectors/src/index.js @@ -56,10 +56,11 @@ export const getHERecommendation = (state, collectionId, fragmentId) => { ) } +const cantMakeDecisionStatuses = ['rejected', 'published', 'draft'] export const canMakeDecision = (state, collection) => { const status = get(collection, 'status') - if (!status || status === 'rejected' || status === 'published') return false + if (!status || cantMakeDecisionStatuses.includes(status)) return false const isEIC = currentUserIs(state, 'adminEiC') return isEIC && status @@ -72,3 +73,11 @@ export const canSeeReviewersReports = (state, collectionId) => { } export const canSeeEditorialComments = canSeeReviewersReports + +export const canMakeRevision = (state, collection) => { + const currentUserId = get(state, 'currentUser.user.id') + return ( + collection.status === 'revisionRequested' && + collection.owners.map(o => o.id).includes(currentUserId) + ) +} diff --git a/packages/component-manuscript/src/components/SideBarActions.js b/packages/component-manuscript/src/components/SideBarActions.js index 01f60511f..c85422bad 100644 --- a/packages/component-manuscript/src/components/SideBarActions.js +++ b/packages/component-manuscript/src/components/SideBarActions.js @@ -2,13 +2,19 @@ import React from 'react' import { compose } from 'recompose' import { connect } from 'react-redux' import styled from 'styled-components' -import { th, Icon } from '@pubsweet/ui' +import { th } from '@pubsweet/ui-toolkit' +import { Icon, Button } from '@pubsweet/ui' +import { withRouter } from 'react-router-dom' import ZipFiles from 'pubsweet-components-faraday/src/components/Files/ZipFiles' import { Decision, Recommendation, } from 'pubsweet-components-faraday/src/components' + +import { createRevision } from 'pubsweet-component-wizard/src/redux/conversion' + import { + canMakeRevision, canMakeDecision, canMakeRecommendation, } from '../../../component-faraday-selectors' @@ -16,10 +22,15 @@ import { const SideBarActions = ({ project, version, + createRevision, + canMakeRevision, canMakeDecision, canMakeRecommendation, }) => ( <Root> + {canMakeRevision && ( + <DecisionButton onClick={createRevision}>Submit revision</DecisionButton> + )} {canMakeDecision && ( <Decision collectionId={project.id} @@ -48,10 +59,17 @@ const SideBarActions = ({ ) export default compose( - connect((state, { project }) => ({ - canMakeDecision: canMakeDecision(state, project), - canMakeRecommendation: canMakeRecommendation(state, project), - })), + withRouter, + connect( + (state, { project }) => ({ + canMakeDecision: canMakeDecision(state, project), + canMakeRevision: canMakeRevision(state, project), + canMakeRecommendation: canMakeRecommendation(state, project), + }), + (dispatch, { project, version, history }) => ({ + createRevision: () => dispatch(createRevision(project, version, history)), + }), + ), )(SideBarActions) // #region styled-components @@ -68,4 +86,17 @@ const ClickableIcon = styled.div` opacity: 0.7; } ` + +const DecisionButton = styled(Button)` + align-items: center; + background-color: ${th('colorPrimary')}; + color: ${th('colorTextReverse')}; + display: flex; + font-family: ${th('fontReading')}; + font-size: ${th('fontSizeBaseSmall')}; + height: calc(${th('subGridUnit')} * 5); + padding: calc(${th('subGridUnit')} / 2) ${th('subGridUnit')}; + text-align: center; + white-space: nowrap; +` // #endregion diff --git a/packages/component-wizard/src/redux/conversion.js b/packages/component-wizard/src/redux/conversion.js index 7b28e5644..87f5ac384 100644 --- a/packages/component-wizard/src/redux/conversion.js +++ b/packages/component-wizard/src/redux/conversion.js @@ -1,5 +1,5 @@ -import { pick } from 'lodash' import moment from 'moment' +import { pick } from 'lodash' import { actions } from 'pubsweet-client' import { create } from 'pubsweet-client/src/helpers/api' @@ -77,6 +77,27 @@ export const createDraftSubmission = history => (dispatch, getState) => { }) } +export const createRevision = ( + collection, + previousVersion, + history, +) => dispatch => { + const { id, submitted, ...prev } = previousVersion + return dispatch( + actions.createFragment(collection, { + ...prev, + created: new Date(), + version: previousVersion.version + 1, + }), + ).then(({ fragment }) => { + const route = `/projects/${collection.id}/versions/${fragment.id}/submit` + window.setTimeout(() => { + history.push(route) + }, 10) + return fragment + }) +} + /* reducer */ const initialState = { complete: undefined, diff --git a/packages/components-faraday/src/components/Dashboard/DashboardCard.js b/packages/components-faraday/src/components/Dashboard/DashboardCard.js index afa389aea..ae4c120f5 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardCard.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardCard.js @@ -85,18 +85,19 @@ const DashboardCard = ({ <Icon>download</Icon> </ClickableIcon> </ZipFiles> - {!project.status && ( - <ActionButtons - data-test="button-resume-submission" - onClick={() => - history.push( - `/projects/${project.id}/versions/${version.id}/submit`, - ) - } - > - RESUME SUBMISSION - </ActionButtons> - )} + {!project.status || + (project.status === 'draft' && ( + <ActionButtons + data-test="button-resume-submission" + onClick={() => + history.push( + `/projects/${project.id}/versions/${version.id}/submit`, + ) + } + > + RESUME SUBMISSION + </ActionButtons> + ))} </RightDetails> </LeftDetails> </Top> @@ -117,7 +118,7 @@ const DashboardCard = ({ <ManuscriptType title={manuscriptMeta}> {manuscriptMeta} </ManuscriptType> - {project.status ? ( + {project.status && project.status !== 'draft' ? ( <Details data-test="button-details" onClick={() => @@ -138,47 +139,48 @@ const DashboardCard = ({ </RightDetails> </Bottom> </ListView> - {project.status && ( - <DetailsView> - <Top> - <AuthorsWithTooltip authors={project.authors} /> - </Top> - <Bottom> - <LeftDetails flex={4}> - <HandlingEditorSection - currentUser={currentUser} - isHE={isHE} - project={project} - /> - </LeftDetails> - {canInviteReviewers && ( - <RightDetails flex={4}> - <ReviewerBreakdown - collectionId={project.id} - compact - versionId={version.id} - /> - <InviteReviewers - modalKey={`invite-reviewers-${project.id}`} - project={project} - version={version} - /> - </RightDetails> - )} - {invitation && ( - <RightDetails flex={4}> - <ReviewerText>Invited to review</ReviewerText> - <ReviewerDecision - invitation={invitation} - modalKey={`reviewer-decision-${project.id}`} + {project.status && + project.status !== 'draft' && ( + <DetailsView> + <Top> + <AuthorsWithTooltip authors={project.authors} /> + </Top> + <Bottom> + <LeftDetails flex={4}> + <HandlingEditorSection + currentUser={currentUser} + isHE={isHE} project={project} - version={version} /> - </RightDetails> - )} - </Bottom> - </DetailsView> - )} + </LeftDetails> + {canInviteReviewers && ( + <RightDetails flex={4}> + <ReviewerBreakdown + collectionId={project.id} + compact + versionId={version.id} + /> + <InviteReviewers + modalKey={`invite-reviewers-${project.id}`} + project={project} + version={version} + /> + </RightDetails> + )} + {invitation && ( + <RightDetails flex={4}> + <ReviewerText>Invited to review</ReviewerText> + <ReviewerDecision + invitation={invitation} + modalKey={`reviewer-decision-${project.id}`} + project={project} + version={version} + /> + </RightDetails> + )} + </Bottom> + </DetailsView> + )} </Card> ) : null } diff --git a/packages/xpub-faraday/config/authsome-helpers.js b/packages/xpub-faraday/config/authsome-helpers.js index 658f47bb6..ad75355dd 100644 --- a/packages/xpub-faraday/config/authsome-helpers.js +++ b/packages/xpub-faraday/config/authsome-helpers.js @@ -1,6 +1,6 @@ -const omit = require('lodash/omit') +const { omit, get, last } = require('lodash') + const config = require('config') -const get = require('lodash/get') const statuses = config.get('statuses') @@ -116,6 +116,14 @@ const hasPermissionForObject = async ({ user, object, Team, roles = [] }) => { const isHandlingEditor = ({ user, object }) => get(object, 'collection.handlingEditor.id') === user.id +const isInDraft = fragment => !get(fragment, 'submitted') + +const hasFragmentInDraft = async ({ object, Fragment }) => { + const lastFragmentId = last(get(object, 'fragments')) + const fragment = await Fragment.find(lastFragmentId) + return isInDraft(fragment) +} + module.exports = { filterObjectData, parseAuthorsData, @@ -127,4 +135,6 @@ module.exports = { getUserPermissions, heIsInvitedToFragment, hasPermissionForObject, + isInDraft, + hasFragmentInDraft, } diff --git a/packages/xpub-faraday/config/authsome-mode.js b/packages/xpub-faraday/config/authsome-mode.js index dae38b3e1..31cd3f415 100644 --- a/packages/xpub-faraday/config/authsome-mode.js +++ b/packages/xpub-faraday/config/authsome-mode.js @@ -91,6 +91,20 @@ async function authenticatedUser(user, operation, object, context) { if (get(object, 'type') === 'collection') { if (helpers.isOwner({ user, object })) { + if ( + await helpers.hasFragmentInDraft({ + object, + Fragment: context.models.Fragment, + }) + ) { + return { + filter: collection => ({ + ...collection, + status: 'draft', + visibleStatus: statuses.draft.public, + }), + } + } return true } return { @@ -124,6 +138,10 @@ async function authenticatedUser(user, operation, object, context) { return true } + if (helpers.isInDraft(object)) { + return false + } + const userPermissions = await helpers.getUserPermissions({ user, Team: context.models.Team, @@ -252,7 +270,7 @@ const authsomeMode = async (userId, operation, object, context) => { const user = await context.models.User.find(userId) // Admins and editor in chiefs can do anything - if (user && (user.admin || user.editorInChief)) return true + // if (user && (user.admin || user.editorInChief)) return true if (user) { return authenticatedUser(user, operation, object, context) -- GitLab