diff --git a/packages/component-manuscript/src/components/ReviewsAndReports.js b/packages/component-manuscript/src/components/ReviewsAndReports.js index 2a5b22aafb647aac32ed6824a3ea0a75f1ee55c5..57e783f4f083cf6984834e69a5d8c83575116002 100644 --- a/packages/component-manuscript/src/components/ReviewsAndReports.js +++ b/packages/component-manuscript/src/components/ReviewsAndReports.js @@ -47,13 +47,14 @@ const getTabSections = (collectionId, reviewers, recommendations = []) => [ const ReviewsAndReports = ({ project, version, - report, - isReviewer, - review = {}, - currentUserIs, reviewers = [], recommendations = [], + isReviewer, + currentUserIs, + report, + review = {}, mappedRecommendations, + mappedReviewers, }) => ( <Fragment> {currentUserIs('staff') && ( @@ -61,7 +62,11 @@ const ReviewsAndReports = ({ <Expandable label="Reviewers & Reports" rightHTML={ - <ReviewerBreakdown type="reviewer" values={reviewers || []} /> + <ReviewerBreakdown + type="reviewer" + values={reviewers || []} + versionId={version.id} + /> } startExpanded > @@ -69,7 +74,7 @@ const ReviewsAndReports = ({ activeKey={1} sections={getTabSections( project.id, - reviewers, + mappedReviewers(), mappedRecommendations(), )} /> @@ -113,6 +118,11 @@ export default compose( ...r, user: reviewers.find(user => user.userId === r.userId), })), + mappedReviewers: ({ recommendations, reviewers }) => () => + reviewers.map(r => ({ + ...r, + review: recommendations.find(rec => rec.userId === r.userId), + })), }), withProps(({ recommendations = [] }) => ({ report: head(recommendations.filter(r => r.submittedOn)), diff --git a/packages/components-faraday/src/components/Dashboard/DashboardCard.js b/packages/components-faraday/src/components/Dashboard/DashboardCard.js index 200ce0f6c810cd1bc6b2fa7da2bb874a2f91bb78..a177280e3c4146808fac5898d35903c4db356d7d 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardCard.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardCard.js @@ -141,6 +141,7 @@ const DashboardCard = ({ <InviteReviewers modalKey={`invite-reviewers-${project.id}`} project={project} + version={version} /> </RightDetails> )} diff --git a/packages/components-faraday/src/components/Invitations/ReviewerBreakdown.js b/packages/components-faraday/src/components/Invitations/ReviewerBreakdown.js index aebc1000d766066fc1648a6a1f7df2e75c1387cb..0e62a38363dd0ebdf6fecad2261cdd379f5ad1b4 100644 --- a/packages/components-faraday/src/components/Invitations/ReviewerBreakdown.js +++ b/packages/components-faraday/src/components/Invitations/ReviewerBreakdown.js @@ -1,5 +1,7 @@ import React from 'react' import { th } from '@pubsweet/ui' +import { connect } from 'react-redux' +import { selectFragment } from 'xpub-selectors' import styled, { css } from 'styled-components' import { compose, withHandlers, withProps } from 'recompose' @@ -16,11 +18,14 @@ const BREAKDOWN_TYPES = { const reviewFilter = r => r.status === 'accepted' const invitationFilter = i => i.hasAnswer && i.isAccepted +const submittedFilter = r => + r.status === 'accepted' && r.review && r.review.submittedOn const roleFilter = role => i => i.role === role const reviewerReduce = (acc, r) => ({ ...acc, [r.status]: acc[r.status] + 1, + submitted: submittedFilter(r) ? acc.submitted + 1 : acc.submitted, }) const invitationReduce = (acc, i) => { @@ -35,6 +40,9 @@ const invitationReduce = (acc, i) => { } export default compose( + connect((state, { versionId }) => ({ + fragment: selectFragment(state, versionId), + })), withProps(({ values = [], type = BREAKDOWN_TYPES.invitation }) => ({ values: type === BREAKDOWN_TYPES.invitation @@ -57,13 +65,21 @@ export default compose( }, getExtendedReport: ({ values = [], + fragment = {}, + versionId, type = BREAKDOWN_TYPES.invitation, }) => () => { - const report = values.reduce( + const { recommendations = [] } = fragment + const mappedValues = values.map(r => ({ + ...r, + review: recommendations.find(rec => rec.userId === r.userId), + })) + const report = mappedValues.reduce( type === BREAKDOWN_TYPES.invitation ? invitationReduce : reviewerReduce, { accepted: 0, declined: 0, + submitted: 0, }, ) @@ -72,6 +88,7 @@ export default compose( <b>{values.length}</b> invited, <b> {report.accepted}</b> agreed, <b> {report.declined}</b> declined + <b> {report.submitted}</b> submitted </BreakdownText> ) }, diff --git a/packages/components-faraday/src/components/Reviewers/InviteReviewers.js b/packages/components-faraday/src/components/Reviewers/InviteReviewers.js index bd6dc66d48f04bfe823b91985e52472e79840fd9..1e857cd94c8e955c7dba75d59562e2ecd6760001 100644 --- a/packages/components-faraday/src/components/Reviewers/InviteReviewers.js +++ b/packages/components-faraday/src/components/Reviewers/InviteReviewers.js @@ -55,8 +55,9 @@ const InviteReviewersModal = compose( hideModal, onConfirm, showModal, - reviewers, - invitations, + reviewers = [], + invitations = [], + versionId, collectionId, getReviewers, reviewerError, @@ -83,7 +84,11 @@ const InviteReviewersModal = compose( {reviewers.length > 0 && ( <Fragment> <Subtitle>Reviewers Info</Subtitle> - <ReviewerBreakdown type="review" values={reviewers} /> + <ReviewerBreakdown + type="review" + values={reviewers} + versionId={versionId} + /> </Fragment> )} {fetchingReviewers && <Spinner size={3} />} @@ -92,6 +97,7 @@ const InviteReviewersModal = compose( collectionId={collectionId} reviewers={reviewers} showModal={showModal} + versionId={versionId} /> </Root> ), @@ -118,6 +124,7 @@ export default compose( withHandlers({ showInviteModal: ({ project, + version, hideModal, showModal, clearReviewersError, @@ -126,6 +133,7 @@ export default compose( showModal({ type: 'invite-reviewers', collectionId: project.id, + versionId: version.id, invitations: project.invitations, onConfirm: () => { hideModal() diff --git a/packages/components-faraday/src/components/Reviewers/ReviewersDetailsList.js b/packages/components-faraday/src/components/Reviewers/ReviewersDetailsList.js index 9fba420117bb6cec6b81ebf7e1866a91f1df501d..a3df9a1caa6c9d33165cf864b2d3912f1538830f 100644 --- a/packages/components-faraday/src/components/Reviewers/ReviewersDetailsList.js +++ b/packages/components-faraday/src/components/Reviewers/ReviewersDetailsList.js @@ -1,6 +1,6 @@ import React from 'react' import moment from 'moment' -import { pick } from 'lodash' +import { pick, get } from 'lodash' import { connect } from 'react-redux' import { th, Icon } from '@pubsweet/ui' import styled, { withTheme } from 'styled-components' @@ -40,33 +40,36 @@ const TR = ({ renderTimestamp, showConfirmResend, showConfirmRevoke, -}) => ( - <Row> - <td> - <ReviewerName>{r.name}</ReviewerName>{' '} - {r.status === 'accepted' && ( - <AcceptedReviewer>{renderAcceptedLabel(index)}</AcceptedReviewer> - )} - </td> - <td>{r.invitedOn ? renderTimestamp(r.invitedOn) : ''}</td> - <td> - <StatusText>{r.status === 'accepted' ? 'Agreed' : r.status}</StatusText> - <DateText> - {r.respondedOn ? `: ${renderTimestamp(r.respondedOn)}` : ''} - </DateText> - </td> - <td> {r.submittedOn ? `: ${renderTimestamp(r.submittedOn)}` : ''} </td> - <td width={100}> - {r.status === 'pending' && ( - <ResendRevoke - showConfirmResend={showConfirmResend(r)} - showConfirmRevoke={showConfirmRevoke(r.invitationId)} - status={r.status} - /> - )} - </td> - </Row> -) +}) => { + const submittedOn = get(r, 'review.submittedOn') + return ( + <Row> + <td> + <ReviewerName>{r.name}</ReviewerName>{' '} + {r.status === 'accepted' && ( + <AcceptedReviewer>{renderAcceptedLabel(index)}</AcceptedReviewer> + )} + </td> + <td>{r.invitedOn ? renderTimestamp(r.invitedOn) : ''}</td> + <td> + <StatusText>{r.status === 'accepted' ? 'Agreed' : r.status}</StatusText> + <DateText> + {r.respondedOn ? `: ${renderTimestamp(r.respondedOn)}` : ''} + </DateText> + </td> + <td>{submittedOn ? `${renderTimestamp(submittedOn)}` : ''}</td> + <td width={100}> + {r.status === 'pending' && ( + <ResendRevoke + showConfirmResend={showConfirmResend(r)} + showConfirmRevoke={showConfirmRevoke(r.invitationId)} + status={r.status} + /> + )} + </td> + </Row> + ) +} const ReviewersDetailsList = ({ renderAcceptedLabel, reviewers,