From 9e0cf2560ac8bac6ab131b28422876a284030acf Mon Sep 17 00:00:00 2001 From: Bogdan Cochior <bogdan.cochior@thinslices.com> Date: Tue, 21 Aug 2018 14:04:40 +0300 Subject: [PATCH] feat(theme): add Reviewers Reports breakdown --- .../src/ManuscriptCard.js | 15 ++- .../src/ReviewerBreakdown.js | 67 ++++++++++++++ .../src/ReviewerBreakdown.md | 92 +++++++++++++++++++ packages/component-faraday-ui/src/index.js | 3 + .../component-faraday-ui/src/styledHelpers.js | 4 + .../hindawi-theme/src/elements/Heading.js | 6 ++ 6 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 packages/component-faraday-ui/src/ReviewerBreakdown.js create mode 100644 packages/component-faraday-ui/src/ReviewerBreakdown.md diff --git a/packages/component-faraday-ui/src/ManuscriptCard.js b/packages/component-faraday-ui/src/ManuscriptCard.js index cc85137e4..9f0f816d0 100644 --- a/packages/component-faraday-ui/src/ManuscriptCard.js +++ b/packages/component-faraday-ui/src/ManuscriptCard.js @@ -6,11 +6,19 @@ import styled from 'styled-components' import { th } from '@pubsweet/ui-toolkit' import { compose, withHandlers, setDisplayName, withProps } from 'recompose' -import { Tag, Text, Row, IconButton, AuthorTagList } from './' +import { + Tag, + Text, + Row, + IconButton, + AuthorTagList, + ReviewerBreakdown, +} from './' const ManuscriptCard = ({ onCardClick, submitDate, + fragment, fragment: { authors = [], id: fragmentId, @@ -46,10 +54,7 @@ const ManuscriptCard = ({ <Text ml={1} mr={3}> {get(handlingEditor, 'name', 'Unassigned')} </Text> - <H4>Reviewer Reports</H4> - <Text ml={1} secondary> - 0 invited - </Text> + <ReviewerBreakdown fragment={fragment} label="Reviewer Reports" /> </Row> </MainContainer> <SideNavigation> diff --git a/packages/component-faraday-ui/src/ReviewerBreakdown.js b/packages/component-faraday-ui/src/ReviewerBreakdown.js new file mode 100644 index 000000000..5c0d5a9e5 --- /dev/null +++ b/packages/component-faraday-ui/src/ReviewerBreakdown.js @@ -0,0 +1,67 @@ +import React, { Fragment } from 'react' +import { get } from 'lodash' +import { H4 } from '@pubsweet/ui' +import styled from 'styled-components' +import { th } from '@pubsweet/ui-toolkit' +import { compose, withHandlers, withProps } from 'recompose' + +import { Text } from './' + +const ReviewerBreakdown = ({ getReportBreakdown }) => getReportBreakdown() + +const roleFilter = role => i => i.role === role +const submittedFilter = r => r.review && r.review.submittedOn +const acceptedFilter = i => i.hasAnswer && i.isAccepted +const declinedFilter = i => i.hasAnswer && !i.isAccepted +const reviewerReduce = (acc, r) => ({ + ...acc, + accepted: acceptedFilter(r) ? acc.accepted + 1 : acc.accepted, + declined: declinedFilter(r) ? acc.declined + 1 : acc.declined, + submitted: submittedFilter(r) ? acc.submitted + 1 : acc.submitted, +}) + +export default compose( + withProps(({ fragment }) => ({ + invitations: get(fragment, 'invitations', []), + recommendations: get(fragment, 'recommendations', []), + })), + withHandlers({ + getReportBreakdown: ({ + invitations, + recommendations, + label = '', + }) => () => { + const reviewerInvitations = invitations.filter(roleFilter('reviewer')) + const invitationsWithRecommendations = reviewerInvitations.map(r => ({ + ...r, + review: recommendations.find(rec => rec.userId === r.userId), + })) + const report = invitationsWithRecommendations.reduce(reviewerReduce, { + accepted: 0, + declined: 0, + submitted: 0, + }) + return ( + <Fragment> + {!!label && <Label>{label}</Label>} + {reviewerInvitations.length ? ( + <Text secondary> + {`${reviewerInvitations.length} invited, ${ + report.accepted + } agreed, ${report.declined} declined, ${ + report.submitted + } submitted`} + </Text> + ) : ( + <Text secondary> {`${reviewerInvitations.length} invited`}</Text> + )} + </Fragment> + ) + }, + }), +)(ReviewerBreakdown) + +const Label = styled(H4)` + display: inline-block; + margin-right: ${th('gridUnit')}; +` diff --git a/packages/component-faraday-ui/src/ReviewerBreakdown.md b/packages/component-faraday-ui/src/ReviewerBreakdown.md new file mode 100644 index 000000000..d14eaaf2c --- /dev/null +++ b/packages/component-faraday-ui/src/ReviewerBreakdown.md @@ -0,0 +1,92 @@ +Reviewer Breakdown Component + +```js +const fragment = { + invitations: [ + { + id: 'a69c1273-4073-4529-9e65-5424ad8034ea', + role: 'reviewer', + type: 'invitation', + userId: '9c79c3bf-ccba-4540-aad8-ce4609325826', + hasAnswer: false, + invitedOn: 1534506511008, + isAccepted: false, + respondedOn: null, + }, + { + id: 'ca1c08bb-4da6-4cb4-972d-d16e3b66b884', + role: 'reviewer', + type: 'invitation', + userId: 'd3ab9a0b-d8e8-41e5-ab3b-72b13f84fba1', + hasAnswer: true, + invitedOn: 1534506542522, + isAccepted: true, + respondedOn: 1534506569565, + }, + ], + recommendations: [ + { + id: '87fb2c45-2685-47cc-9952-d58435ff8f3a', + userId: 'd3ab9a0b-d8e8-41e5-ab3b-72b13f84fba1', + comments: [ + { + files: [], + public: true, + content: 'This is a great manuscript', + }, + ], + createdOn: 1534506583815, + updatedOn: 1534506592527, + submittedOn: 1534506591684, + recommendation: 'publish', + recommendationType: 'review', + }, + { + id: '9853453f-1049-4369-8543-1b812930430d', + userId: 'ede6770d-8dbf-4bf9-bbe2-98facfd0a114', + comments: [ + { + public: true, + content: 'nice job', + }, + { + public: false, + content: 'please publish this', + }, + ], + createdOn: 1534506624583, + updatedOn: 1534506624583, + recommendation: 'publish', + recommendationType: 'editorRecommendation', + }, + { + id: '64c5b596-fbfc-485c-9068-f3a58306efd7', + userId: '5b53da0d-3f88-4e94-b8f9-7eae6a754168', + createdOn: 1534506644873, + updatedOn: 1534506644873, + recommendation: 'publish', + recommendationType: 'editorRecommendation', + }, + { + id: '3d43ff74-9a20-479d-a218-23bf8eac0b6a', + userId: '5b53da0d-3f88-4e94-b8f9-7eae6a754168', + createdOn: 1534506813446, + updatedOn: 1534506813446, + recommendation: 'publish', + recommendationType: 'editorRecommendation', + }, + ], +} +; +<ReviewerBreakdown fragment={fragment} /> +``` + +Without invitations +```js +<ReviewerBreakdown fragment={{}} /> +``` + +With label +```js +<ReviewerBreakdown fragment={{}} label='Reviewer Reports' /> +``` diff --git a/packages/component-faraday-ui/src/index.js b/packages/component-faraday-ui/src/index.js index 0dd450ad6..f9c3b50f4 100644 --- a/packages/component-faraday-ui/src/index.js +++ b/packages/component-faraday-ui/src/index.js @@ -12,11 +12,14 @@ export { default as IconButton } from './IconButton' export { default as Label } from './Label' export { default as Logo } from './Logo' export { default as ManuscriptCard } from './ManuscriptCard' +export { default as ReviewerBreakdown } from './ReviewerBreakdown' export { default as PersonInfo } from './PersonInfo' export { default as SortableList } from './SortableList' export { default as Tag } from './Tag' export { default as Text } from './Text' +export * from './styledHelpers' + // modals export * from './modals' export * from './gridItems' diff --git a/packages/component-faraday-ui/src/styledHelpers.js b/packages/component-faraday-ui/src/styledHelpers.js index 2bdd97529..5d1f75bbc 100644 --- a/packages/component-faraday-ui/src/styledHelpers.js +++ b/packages/component-faraday-ui/src/styledHelpers.js @@ -61,6 +61,10 @@ export const positionHelper = css` has(props, 'right') ? `${get(props, 'right')}px` : 'unset'}; ` +export const displayHelper = css` + display: ${({ display }) => display || 'initial'}; +` + export const radiusHelpers = props => { const borderTop = props.isFirst ? css` diff --git a/packages/hindawi-theme/src/elements/Heading.js b/packages/hindawi-theme/src/elements/Heading.js index ec5cf96c3..1d93c1651 100644 --- a/packages/hindawi-theme/src/elements/Heading.js +++ b/packages/hindawi-theme/src/elements/Heading.js @@ -1,17 +1,23 @@ import { css } from 'styled-components' import { th } from '@pubsweet/ui-toolkit' +import { marginHelper, displayHelper } from 'pubsweet-component-faraday-ui' export default { H1: css` color: ${th('heading.h1Color')}; + ${marginHelper}; `, H2: css` color: ${th('heading.h2Color')}; + ${marginHelper}; `, H3: css` color: ${th('heading.h3Color')}; + ${marginHelper}; `, H4: css` color: ${th('heading.h4Color')}; + ${marginHelper}; + ${displayHelper}; `, } -- GitLab