diff --git a/packages/component-faraday-selectors/src/index.js b/packages/component-faraday-selectors/src/index.js index 25da3448f2c3c38451f7d48b94ec880977a2f21c..925aac7a881fce50bf971f765a560042755bf468 100644 --- a/packages/component-faraday-selectors/src/index.js +++ b/packages/component-faraday-selectors/src/index.js @@ -2,10 +2,12 @@ import { get, has, last, chain } from 'lodash' import { selectCurrentUser } from 'xpub-selectors' export const isHEToManuscript = (state, collectionId) => { - const currentUserId = get(state, 'currentUser.user.id', '') - const collections = get(state, 'collections', []) - const collection = collections.find(c => c.id === collectionId) || {} - return get(collection, 'handlingEditor.id') === currentUserId + const { id = '', isAccepted = false } = chain(state) + .get('collections', []) + .find(c => c.id === collectionId) + .get('handlingEditor', '') + .value() + return isAccepted && id === get(state, 'currentUser.user.id') } export const currentUserIs = ({ currentUser: { user } }, role) => { @@ -233,6 +235,17 @@ export const getInvitationsWithReviewersForFragment = (state, fragmentId) => })) .value() +export const canMakeHERecommendation = (state, { collection, statuses }) => { + const validHE = isHEToManuscript(state, get(collection, 'id', '')) + const statusImportance = get( + statuses, + `${get(collection, 'status', 'draft')}.importance`, + 1, + ) + + return statusImportance > 1 && statusImportance < 9 && validHE +} + // #region Editorial and reviewer recommendations export const getFragmentRecommendations = (state, fragmentId) => get(state, `fragments.${fragmentId}.recommendations`, []) diff --git a/packages/component-faraday-ui/src/EditorialReportCard.js b/packages/component-faraday-ui/src/EditorialReportCard.js index d23b06d23b4561eec995de328a4afd99b2175a09..a294c039795914fe5e5333e95b395f938ee4f187 100644 --- a/packages/component-faraday-ui/src/EditorialReportCard.js +++ b/packages/component-faraday-ui/src/EditorialReportCard.js @@ -15,7 +15,7 @@ const EditorialReportCard = ({ recommendation, reviewerName, reviewerRole, - report: { submittedOn, reviewer }, + report: { createdOn, reviewer }, }) => ( <Root> <Row justify="space-between" mb={2}> @@ -31,7 +31,7 @@ const EditorialReportCard = ({ <Tag mr={2}>{reviewerRole}</Tag> </Fragment> )} - <DateParser timestamp={submittedOn}> + <DateParser timestamp={createdOn}> {date => <Text>{date}</Text>} </DateParser> </Item> diff --git a/packages/component-faraday-ui/src/RemoteOpener.md b/packages/component-faraday-ui/src/RemoteOpener.md index 283c505e2379663a157b285e46908f68f86553aa..173a86f0449ae555362dee9eed4d1a2caab8ad53 100644 --- a/packages/component-faraday-ui/src/RemoteOpener.md +++ b/packages/component-faraday-ui/src/RemoteOpener.md @@ -2,7 +2,7 @@ Toggle a boolean flag and pass it around in your React components tree. ```js <RemoteOpener> - {(expanded, toggle) => ( + {({ expanded, toggle }) => ( <div> <button onClick={toggle}>Toggle</button> <span>{expanded ? 'Collapse me!' : 'Expand me!'}</span> diff --git a/packages/component-faraday-ui/src/ReviewersTable.js b/packages/component-faraday-ui/src/ReviewersTable.js index 9dc2a45f11c5a6d5d9f96eb37bb611d0ca73e83e..901e657ebefcad468a49c2801c0485c6a7de8def 100644 --- a/packages/component-faraday-ui/src/ReviewersTable.js +++ b/packages/component-faraday-ui/src/ReviewersTable.js @@ -14,7 +14,7 @@ const ReviewersTable = ({ onResendReviewerInvite, onRevokeReviewerInvite, }) => - invitations.length > 0 && ( + invitations.length > 0 ? ( <Table> <thead> <tr> @@ -82,6 +82,8 @@ const ReviewersTable = ({ ))} </tbody> </Table> + ) : ( + <Text align="center">No reviewers invited yet.</Text> ) const orderInvitations = i => { diff --git a/packages/component-faraday-ui/src/contextualBoxes/HERecommendation.js b/packages/component-faraday-ui/src/contextualBoxes/HERecommendation.js new file mode 100644 index 0000000000000000000000000000000000000000..b6184d7fbde2515fdf7cc4808626b309129c2f21 --- /dev/null +++ b/packages/component-faraday-ui/src/contextualBoxes/HERecommendation.js @@ -0,0 +1,161 @@ +import React from 'react' +import { get, tail } from 'lodash' +import { reduxForm } from 'redux-form' +import styled from 'styled-components' +import { th } from '@pubsweet/ui-toolkit' +import { required } from 'xpub-validators' +import { compose, withProps } from 'recompose' +import { Button, Menu, ValidatedField } from '@pubsweet/ui' +import { withModal } from 'pubsweet-component-modal/src/components' + +import { + Row, + Text, + Label, + Textarea, + MultiAction, + ContextualBox, + ItemOverrideAlert, + withFetching, +} from 'pubsweet-component-faraday-ui/src' + +const options = [ + { value: 'publish', label: 'Publish' }, + { value: 'reject', label: 'Reject' }, + { value: 'minor', label: 'Request Minor Revision' }, + { value: 'major', label: 'Request Major Revision' }, +] + +const parseFormValues = ({ recommendation, ...rest }) => { + const comments = Object.entries(rest).map(([key, value]) => ({ + content: value, + public: key === 'public', + files: [], + })) + + return { + comments, + recommendation, + recommendationType: 'editorRecommendation', + } +} + +const HERecommendation = ({ + formValues, + handleSubmit, + hasReviewerReports, + highlight, +}) => ( + <ContextualBox + highlight={highlight} + label="Your Editorial Recommendation" + mb={2} + > + <Root> + <Row justify="flex-start"> + <ItemOverrideAlert flex={0} vertical> + <Label required>Recommendation</Label> + <ValidatedField + component={input => ( + <Menu + options={hasReviewerReports ? options : tail(options)} + {...input} + /> + )} + name="recommendation" + validate={[required]} + /> + </ItemOverrideAlert> + </Row> + + {get(formValues, 'recommendation') === 'publish' || + get(formValues, 'recommendation') === 'reject' ? ( + <Row mt={2}> + <ItemOverrideAlert vertical> + <Label required>Message for Author</Label> + <ValidatedField + component={Textarea} + name="public" + validate={[required]} + /> + </ItemOverrideAlert> + </Row> + ) : ( + <ResponsiveRow mt={2}> + <ResponsiveItem mr={1} vertical> + <Label> + Message for Author <Text secondary>Optional</Text> + </Label> + <ValidatedField component={Textarea} name="public" /> + </ResponsiveItem> + + <ResponsiveItem ml={1} vertical> + <Label> + Message for Editor in Chief <Text secondary>Optional</Text> + </Label> + <ValidatedField component={Textarea} name="private" /> + </ResponsiveItem> + </ResponsiveRow> + )} + + <Row justify="flex-end" mt={2}> + <Button onClick={handleSubmit} primary size="medium"> + Submit recommendation + </Button> + </Row> + </Root> + </ContextualBox> +) + +export default compose( + withFetching, + withModal(({ isFetching }) => ({ + isFetching, + modalComponent: MultiAction, + })), + withProps(({ formValues }) => ({ + modalTitle: options.find( + o => o.value === get(formValues, 'recommendation', 'publish'), + ).label, + })), + reduxForm({ + form: 'HERecommendation', + onSubmit: ( + values, + dispatch, + { onRecommendationSubmit, showModal, setFetching, modalTitle }, + ) => { + showModal({ + title: `${modalTitle}?`, + onConfirm: props => { + onRecommendationSubmit(parseFormValues(values), { + ...props, + setFetching, + }) + }, + }) + }, + }), +)(HERecommendation) + +// #region styles +const Root = styled.div` + display: flex; + flex-direction: column; + padding: ${th('gridUnit')}; +` + +const ResponsiveRow = styled(Row)` + @media (max-width: 800px) { + flex-direction: column; + } +` + +const ResponsiveItem = styled(ItemOverrideAlert)` + @media (max-width: 800px) { + margin-right: 0; + margin-left: 0; + width: 100%; + } +` +// #endregion diff --git a/packages/component-faraday-ui/src/contextualBoxes/HERecommendation.md b/packages/component-faraday-ui/src/contextualBoxes/HERecommendation.md new file mode 100644 index 0000000000000000000000000000000000000000..004abbffa36093806b1433ed149095634be108e6 --- /dev/null +++ b/packages/component-faraday-ui/src/contextualBoxes/HERecommendation.md @@ -0,0 +1,15 @@ +HE recommendation. + +```js +const formValues = { + recommendation: 'minor-revision', +} +;<HERecommendation + formValues={formValues} + modalKey="heRecommendation" + onRecommendationSubmit={(values, props) => { + console.log('se face surmit la', values) + props.setFetching(true) + }} +/> +``` diff --git a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js index 7362a5e07a6823c998dea778aec95737e8e37986..48126901139102f39cc8bee06828e9647fd50b10 100644 --- a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js +++ b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js @@ -30,15 +30,22 @@ const ReviewerDetails = ({ onInviteReviewer, onResendReviewerInvite, onRevokeReviewerInvite, + toggle, + expanded, + highlight, canViewReviewersDetails, + ...rest }) => canViewReviewersDetails ? ( <ContextualBox + expanded={expanded} + highlight={highlight} label="Reviewer Details & Reports" rightChildren={ <ReviewerBreakdown fitContent fragment={fragment} mr={1} /> } - startExpanded + toggle={toggle} + {...rest} > <Tabs> {({ selectedTab, changeTab }) => ( diff --git a/packages/component-faraday-ui/src/contextualBoxes/index.js b/packages/component-faraday-ui/src/contextualBoxes/index.js index 54a8bdd97d9e793d6924a90a81da41d0fd0020ba..9cca1b83bdf9aeaafc4fa12a8073b487ae590d88 100644 --- a/packages/component-faraday-ui/src/contextualBoxes/index.js +++ b/packages/component-faraday-ui/src/contextualBoxes/index.js @@ -1,3 +1,4 @@ export { default as AssignHE } from './AssignHE' export { default as ReviewerDetails } from './ReviewerDetails' +export { default as HERecommendation } from './HERecommendation' export { default as ReviewerReportForm } from './ReviewerReportForm' diff --git a/packages/component-faraday-ui/src/helpers/withFetching.js b/packages/component-faraday-ui/src/helpers/withFetching.js index 717a5f95b9257e38cae9bdad68d910192a896860..753c265e6b62deb9df24574fc9cab31572cd9386 100644 --- a/packages/component-faraday-ui/src/helpers/withFetching.js +++ b/packages/component-faraday-ui/src/helpers/withFetching.js @@ -2,12 +2,12 @@ import { withStateHandlers } from 'recompose' export default withStateHandlers( { - isFetchingg: false, + isFetching: false, fetchingError: '', }, { - setFetching: ({ isFetchingg }) => value => ({ - isFetchingg: value, + setFetching: ({ isFetching }) => value => ({ + isFetching: value, }), toggleFetching: ({ isFetching }) => () => ({ isFetching: !isFetching, diff --git a/packages/component-fixture-manager/src/fixtures/collectionIDs.js b/packages/component-fixture-manager/src/fixtures/collectionIDs.js index 0633f816e39359721e73dd32252279f05bcdff5e..d4d27580eba01b480a3de9ec5650fc7a0dcc8b01 100644 --- a/packages/component-fixture-manager/src/fixtures/collectionIDs.js +++ b/packages/component-fixture-manager/src/fixtures/collectionIDs.js @@ -1,8 +1,8 @@ const Chance = require('chance') const chance = new Chance() -const collId = chance.guid() module.exports = { - standardCollID: collId, + standardCollID: chance.guid(), + collectionReviewCompletedID: chance.guid(), } diff --git a/packages/component-fixture-manager/src/fixtures/collections.js b/packages/component-fixture-manager/src/fixtures/collections.js index fd83ed23b1d978e33a686785f14d08b64ea8d34c..4984c9f078027f840f262f68a5fd22b914b87cbf 100644 --- a/packages/component-fixture-manager/src/fixtures/collections.js +++ b/packages/component-fixture-manager/src/fixtures/collections.js @@ -1,7 +1,10 @@ const Chance = require('chance') const { user, handlingEditor, answerHE } = require('./userData') const { fragment, reviewCompletedFragment } = require('./fragments') -const { standardCollID } = require('./collectionIDs') +const { + standardCollID, + collectionReviewCompletedID, +} = require('./collectionIDs') const chance = new Chance() const collections = { @@ -90,6 +93,7 @@ const collections = { status: 'pendingApproval', }, collectionReviewCompleted: { + id: collectionReviewCompletedID, type: 'collection', owners: [user.id], status: 'reviewCompleted', diff --git a/packages/component-fixture-manager/src/fixtures/fragments.js b/packages/component-fixture-manager/src/fixtures/fragments.js index 719d65b46ac17088cd5932d6610fda53d6cdd8ef..3f149caf0e0a148bf47b04fae1076dd58323e36d 100644 --- a/packages/component-fixture-manager/src/fixtures/fragments.js +++ b/packages/component-fixture-manager/src/fixtures/fragments.js @@ -8,7 +8,10 @@ const { admin, inactiveReviewer, } = require('./userData') -const { standardCollID } = require('./collectionIDs') +const { + standardCollID, + collectionReviewCompletedID, +} = require('./collectionIDs') const { user } = require('./userData') const chance = new Chance() @@ -38,9 +41,10 @@ const fragments = { }, ], id: chance.guid(), - userId: recReviewer.id, + userId: answerReviewer.id, createdOn: chance.timestamp(), updatedOn: chance.timestamp(), + submittedOn: chance.timestamp(), }, { recommendation: 'minor', @@ -213,7 +217,7 @@ const fragments = { hasConflicts: 'no', hasDataAvailability: 'yes', }, - submitted: 1539000486993, + submitted: chance.timestamp(), invitations: [ { id: chance.guid(), @@ -246,7 +250,7 @@ const fragments = { respondedOn: chance.timestamp(), }, ], - collectionId: standardCollID, + collectionId: collectionReviewCompletedID, declarations: { agree: true, }, diff --git a/packages/component-fixture-manager/src/fixtures/teamIDs.js b/packages/component-fixture-manager/src/fixtures/teamIDs.js index 83ce3a556417bc4650efdc9ff478b8bad64a9f13..5528425bf62570b86f0c98472c1001698ab72732 100644 --- a/packages/component-fixture-manager/src/fixtures/teamIDs.js +++ b/packages/component-fixture-manager/src/fixtures/teamIDs.js @@ -1,12 +1,10 @@ const Chance = require('chance') const chance = new Chance() -const heID = chance.guid() -const revId = chance.guid() -const authorID = chance.guid() module.exports = { - heTeamID: heID, - revTeamID: revId, - authorTeamID: authorID, + heTeamID: chance.guid(), + revTeamID: chance.guid(), + authorTeamID: chance.guid(), + revRecommendationTeamID: chance.guid(), } diff --git a/packages/component-fixture-manager/src/fixtures/teams.js b/packages/component-fixture-manager/src/fixtures/teams.js index acd600dc743f9290eff5bb98920caad1f401d9c0..5191421c22e3cd9f0f4c5256c18becd8c6d89166 100644 --- a/packages/component-fixture-manager/src/fixtures/teams.js +++ b/packages/component-fixture-manager/src/fixtures/teams.js @@ -2,12 +2,23 @@ const users = require('./users') const collections = require('./collections') const fragments = require('./fragments') -const { heTeamID, revTeamID, authorTeamID } = require('./teamIDs') +const { + heTeamID, + revTeamID, + authorTeamID, + revRecommendationTeamID, +} = require('./teamIDs') const { submittingAuthor } = require('./userData') const { collection } = collections -const { fragment } = fragments -const { handlingEditor, reviewer, inactiveReviewer } = users +const { fragment, reviewCompletedFragment } = fragments +const { + handlingEditor, + reviewer, + inactiveReviewer, + answerReviewer, + recReviewer, +} = users const teams = { heTeam: { teamType: { @@ -36,11 +47,27 @@ const teams = { type: 'fragment', id: fragment.id, }, - members: [reviewer.id, inactiveReviewer.id], + members: [reviewer.id, inactiveReviewer.id, answerReviewer.id], save: jest.fn(() => teams.revTeam), updateProperties: jest.fn(() => teams.revTeam), id: revTeamID, }, + revRecommendationTeam: { + teamType: { + name: 'reviewer', + permissions: 'reviewer', + }, + group: 'reviewer', + name: 'reviewer', + object: { + type: 'fragment', + id: reviewCompletedFragment.id, + }, + members: [reviewer.id, answerReviewer.id, recReviewer.id], + save: jest.fn(() => teams.revRecommendationTeam), + updateProperties: jest.fn(() => teams.revRecommendationTeam), + id: revRecommendationTeamID, + }, authorTeam: { teamType: { name: 'author', diff --git a/packages/component-fixture-manager/src/fixtures/users.js b/packages/component-fixture-manager/src/fixtures/users.js index a315e0e1b720d98a1de3fabcb478d2f428b34ad2..e5ee9ae59e761d936dce39f1a263fa42f70dcf33 100644 --- a/packages/component-fixture-manager/src/fixtures/users.js +++ b/packages/component-fixture-manager/src/fixtures/users.js @@ -2,7 +2,12 @@ const Chance = require('chance') const usersData = require('./userData') const chance = new Chance() -const { heTeamID, revTeamID, authorTeamID } = require('./teamIDs') +const { + heTeamID, + revTeamID, + authorTeamID, + revRecommendationTeamID, +} = require('./teamIDs') const keys = Object.keys(usersData) let users = {} @@ -17,12 +22,12 @@ users = keys.reduce((obj, item) => { if (item === 'author') { teams = [authorTeamID] } - if ( - ['reviewer', 'answerReviewer', 'recReviewer', 'inactiveReviewer'].includes( - item, - ) - ) { - teams = [revTeamID] + if (['reviewer', 'inactiveReviewer', 'answerReviewer'].includes(item)) { + teams.push(revTeamID) + } + + if (['reviewer', 'answerReviewer', 'recReviewer'].includes(item)) { + teams.push(revRecommendationTeamID) } obj[item] = { diff --git a/packages/component-helper-service/config/authsome-mode.js b/packages/component-helper-service/config/authsome-mode.js new file mode 100644 index 0000000000000000000000000000000000000000..9c663beae1962d9fc13141f8439dc0a84214ae08 --- /dev/null +++ b/packages/component-helper-service/config/authsome-mode.js @@ -0,0 +1,3 @@ +const authsomeMode = require('xpub-faraday/config/authsome-mode') + +module.exports = authsomeMode diff --git a/packages/component-helper-service/config/default.js b/packages/component-helper-service/config/default.js new file mode 100644 index 0000000000000000000000000000000000000000..9950c9b354fa8710a4f043a07ac2b86a3cf6bd2f --- /dev/null +++ b/packages/component-helper-service/config/default.js @@ -0,0 +1,3 @@ +const defaultConfig = require('xpub-faraday/config/default') + +module.exports = defaultConfig diff --git a/packages/component-helper-service/config/test.js b/packages/component-helper-service/config/test.js new file mode 100644 index 0000000000000000000000000000000000000000..9950c9b354fa8710a4f043a07ac2b86a3cf6bd2f --- /dev/null +++ b/packages/component-helper-service/config/test.js @@ -0,0 +1,3 @@ +const defaultConfig = require('xpub-faraday/config/default') + +module.exports = defaultConfig diff --git a/packages/component-helper-service/package.json b/packages/component-helper-service/package.json index 5764bac137e9af7f48e1736f819e2497d3bd8d62..6c707d470181361319f2e2ead30675bc8967562d 100644 --- a/packages/component-helper-service/package.json +++ b/packages/component-helper-service/package.json @@ -22,5 +22,12 @@ }, "publishConfig": { "access": "public" + }, + "scripts": { + "test": "jest" + }, + "jest": { + "verbose": true, + "testRegex": "/src/.*.test.js$" } } diff --git a/packages/component-helper-service/src/Helper.js b/packages/component-helper-service/src/Helper.js index b47dc41778f2baec3e50de9a08d72f1b5b4ffc4b..44d3ef6c44ee6711e0b384f08329e85535c59251 100644 --- a/packages/component-helper-service/src/Helper.js +++ b/packages/component-helper-service/src/Helper.js @@ -1,4 +1,3 @@ -const Email = require('./services/email/Email') const Collection = require('./services/Collection') const Fragment = require('./services/Fragment') const services = require('./services/services') @@ -8,7 +7,6 @@ const Team = require('./services/Team') const Invitation = require('./services/Invitation') module.exports = { - Email, Collection, Fragment, services, diff --git a/packages/component-helper-service/src/services/Fragment.js b/packages/component-helper-service/src/services/Fragment.js index 0c1c05973d5a5540523e0acc76bc1e40eacedf10..db1ae899ea6226d5214c63326d693f9d31b4bb5d 100644 --- a/packages/component-helper-service/src/services/Fragment.js +++ b/packages/component-helper-service/src/services/Fragment.js @@ -143,6 +143,13 @@ class Fragment { .filter(rev => rev.isActive) .filter(rev => get(rev, 'notifications.email.user')) } + + hasReviewReport() { + const { fragment: { recommendations = [] } } = this + return recommendations.find( + rec => rec.recommendationType === 'review' && rec.submittedOn, + ) + } } module.exports = Fragment diff --git a/packages/component-helper-service/src/services/email/Email.js b/packages/component-helper-service/src/services/email/Email.js deleted file mode 100644 index 5b422bd5a7718a7bd5b898b3497803877f78c38c..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/Email.js +++ /dev/null @@ -1,95 +0,0 @@ -const config = require('config') - -const helpers = require('./helpers') -const SendEmail = require('@pubsweet/component-send-email') -const logger = require('@pubsweet/logger') - -const mainFromEmail = config.get('journal.staffEmail') -class Email { - constructor({ - type = 'system', - fromEmail = mainFromEmail, - toUser = { - id: '', - email: '', - name: '', - }, - content = { - subject: '', - ctaLink: '', - ctaText: '', - signatureName: '', - unsubscribeLink: '', - signatureJournal: '', - }, - }) { - this.type = type - this.toUser = toUser - this.content = content - this.fromEmail = fromEmail - } - - set _toUser(newToUser) { - this.toUser = newToUser - } - - set _subject(newSubject) { - this.subject = newSubject - } - - set _content(newContent) { - this.content = newContent - } - - getBody({ body = {}, isReviewerInvitation = false }) { - if (isReviewerInvitation) { - return { - html: helpers.getInvitationBody({ - replacements: { - ...body, - ...this.content, - toEmail: this.toUser.email, - toUserName: this.toUser.name, - }, - }), - text: `${this.content.signatureName}`, - } - } - - return { - html: helpers.getNotificationBody({ - replacements: { - ...body, - ...this.content, - toEmail: this.toUser.email, - toUserName: this.toUser.name, - }, - }), - text: `${body.paragraph} ${this.content.ctaLink} ${ - this.content.ctaText - } ${this.content.signatureName}`, - } - } - - sendEmail({ text, html }) { - const { fromEmail: from } = this - const { email: to } = this.toUser - const { subject } = this.content - - const mailData = { - to, - text, - html, - from, - subject, - } - - logger.info( - `EMAIL: Sent email from ${from} to ${to} with subject '${subject}'`, - ) - - SendEmail.send(mailData) - } -} - -module.exports = Email diff --git a/packages/component-helper-service/src/services/email/helpers.js b/packages/component-helper-service/src/services/email/helpers.js deleted file mode 100644 index f704b8d6656364b5069e9f99481dafc5045927ea..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/helpers.js +++ /dev/null @@ -1,53 +0,0 @@ -const fs = require('fs') -const handlebars = require('handlebars') - -const getNotificationBody = ({ replacements }) => { - handlePartial('header', replacements) - if (replacements.hasIntro) handlePartial('intro', replacements) - handlePartial('footer', replacements) - if (replacements.hasSignature) handlePartial('signature', replacements) - if (replacements.hasLink) handlePartial('button', replacements) - handlePartial('body', replacements) - - return getMainTemplate({ fileName: 'notification', context: replacements }) -} - -const getInvitationBody = ({ replacements }) => { - handlePartial('invHeader', replacements) - handlePartial('footer', replacements) - handlePartial('invUpperContent', replacements) - handlePartial('invButtons', replacements) - handlePartial('invManuscriptData', replacements) - handlePartial('signature', replacements) - handlePartial('invLowerContent', replacements) - - return getMainTemplate({ fileName: 'invitation', context: replacements }) -} - -const readFile = path => - fs.readFileSync(path, { encoding: 'utf-8' }, (err, file) => { - if (err) { - throw err - } else { - return file - } - }) - -const handlePartial = (partialName = 'signature', context = {}) => { - let partial = readFile(`${__dirname}/templates/partials/${partialName}.hbs`) - const template = handlebars.compile(partial) - partial = template(context) - handlebars.registerPartial(partialName, partial) -} - -const getMainTemplate = ({ fileName, context }) => { - const htmlFile = readFile(`${__dirname}/templates/${fileName}.html`) - const htmlTemplate = handlebars.compile(htmlFile) - const htmlBody = htmlTemplate(context) - return htmlBody -} - -module.exports = { - getNotificationBody, - getInvitationBody, -} diff --git a/packages/component-helper-service/src/services/email/templates/invitation.html b/packages/component-helper-service/src/services/email/templates/invitation.html deleted file mode 100644 index f9d5ed18cfa96454ba3454e9555e6144a6411467..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/invitation.html +++ /dev/null @@ -1,5 +0,0 @@ -{{> invHeader }} -{{> invUpperContent }} -{{> invButtons }} -{{> invLowerContent }} -{{> footer }} \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/notification.html b/packages/component-helper-service/src/services/email/templates/notification.html deleted file mode 100644 index 02cbf2a6e9c1b383534faf9358c0df3cd078c534..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/notification.html +++ /dev/null @@ -1,3 +0,0 @@ -{{> header }} -{{> body }} -{{> footer}} \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/body.hbs b/packages/component-helper-service/src/services/email/templates/partials/body.hbs deleted file mode 100644 index 59e1230635ab84764ca255052c0952cebf6df56e..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/body.hbs +++ /dev/null @@ -1,25 +0,0 @@ -<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> - <div> - {{#if hasIntro}} - {{> intro}} - {{/if}} - <p> </p> - <p> - {{{paragraph}}} - </p> - <p> </p> - <p> - {{#if hasLink }} - {{> button }} - {{/if}} - </p> - {{#if hasSignature }} - {{> signature}} - {{/if}} - <p> </p> - </div> - </td> - </tr> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/button.hbs b/packages/component-helper-service/src/services/email/templates/partials/button.hbs deleted file mode 100644 index 5b8b0493173d905c8a8a98322e4da5b0173a7302..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/button.hbs +++ /dev/null @@ -1,19 +0,0 @@ -<table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" - style="table-layout:fixed" width="100%"> - <tbody> - <tr> - <td align="center" bgcolor="#FFFFFF" class="outer-td" style="padding:0px 0px 30px 0px;background-color:#FFFFFF"> - <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> - <tbody> - <tr> - <td align="center" bgcolor="#63a945" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> - <a href="{{ ctaLink }}" style="background-color:#63a945;border:1px solid #333333;border-color:#63a945;border-radius:0px;border-width:1px;color:#ffffff;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" - target="_blank">{{ ctaText }}</a> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </tbody> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/footer.hbs b/packages/component-helper-service/src/services/email/templates/partials/footer.hbs deleted file mode 100644 index 5a98112919505d7caf577129073b5f5e72585921..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/footer.hbs +++ /dev/null @@ -1,40 +0,0 @@ -<div data-role="module-unsubscribe" class="module unsubscribe-css__unsubscribe___2CDlR" role="module" data-type="unsubscribe" - style="color:#444444;font-size:12px;line-height:20px;padding:16px 16px 16px 16px;text-align:center"> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:20px;text-align:left"> - This email was sent to {{toEmail}}. You have received this email in regards to the account creation, submission, or peer review process of a paper submitted to a journal published by Hindawi Limited. - </p> - <div class="Unsubscribe--addressLine"> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:20px;text-align:left"> - Hindawi Limited, 3rd Floor, Adam House, 1 Fitzroy Square, London, W1T 5HF, United Kingdom - </p> - </div> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:20px;text-align:left"> - </p> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:11px;line-height:20px;text-align:left"> - Hindawi respects your right to privacy. Please see our <a href="https://www.hindawi.com/privacy/">privacy policy</a> for information on how we store, process, and safeguard your data. - </p> - <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px"> - <a class="Unsubscribe--unsubscribeLink" href="{{ unsubscribeLink }}">Unsubscribe</a> - </p> -</div> -</td> -</tr> -</table> -<!--[if mso]> - </td></tr></table> - </center> - <![endif]--> -</td> -</tr> -</table> -</td> -</tr> -</table> -</td> -</tr> -</table> -</div> -</center> -</body> - -</html> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/header.hbs b/packages/component-helper-service/src/services/email/templates/partials/header.hbs deleted file mode 100644 index aef79db924cb4ea509dda88e4bcf63e2c02e4f75..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/header.hbs +++ /dev/null @@ -1,163 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml"> - -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> - <!--[if !mso]><!--> - <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> - <!--<![endif]--> - <!--[if (gte mso 9)|(IE)]> - <xml> - <o:OfficeDocumentSettings> - <o:AllowPNG/> - <o:PixelsPerInch>96</o:PixelsPerInch> - </o:OfficeDocumentSettings> - </xml> - <![endif]--> - <!--[if (gte mso 9)|(IE)]> - <style type="text/css"> - body {width: 600px;margin: 0 auto;} - table {border-collapse: collapse;} - table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;} - img {-ms-interpolation-mode: bicubic;} - </style> - <![endif]--> - - <style type="text/css"> - body, - p, - div { - font-family: helvetica, arial, sans-serif; - font-size: 14px; - } - - body { - color: #626262; - } - - body a { - color: #0D78F2; - text-decoration: none; - } - - p { - margin: 0; - padding: 0; - } - - table.wrapper { - width: 100% !important; - table-layout: fixed; - -webkit-font-smoothing: antialiased; - -webkit-text-size-adjust: 100%; - -moz-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - } - - img.max-width { - max-width: 100% !important; - } - - .column.of-2 { - width: 50%; - } - - .column.of-3 { - width: 33.333%; - } - - .column.of-4 { - width: 25%; - } - - @media screen and (max-width:480px) { - .preheader .rightColumnContent, - .footer .rightColumnContent { - text-align: left !important; - } - .preheader .rightColumnContent div, - .preheader .rightColumnContent span, - .footer .rightColumnContent div, - .footer .rightColumnContent span { - text-align: left !important; - } - .preheader .rightColumnContent, - .preheader .leftColumnContent { - font-size: 80% !important; - padding: 5px 0; - } - table.wrapper-mobile { - width: 100% !important; - table-layout: fixed; - } - img.max-width { - height: auto !important; - max-width: 480px !important; - } - a.bulletproof-button { - display: block !important; - width: auto !important; - font-size: 80%; - padding-left: 0 !important; - padding-right: 0 !important; - } - .columns { - width: 100% !important; - } - .column { - display: block !important; - width: 100% !important; - padding-left: 0 !important; - padding-right: 0 !important; - margin-left: 0 !important; - margin-right: 0 !important; - } - } - </style> - <!--user entered Head Start--> - - <!--End Head user entered--> -</head> - -<body> - <center class="wrapper" data-link-color="#0D78F2" data-body-style="font-size: 14px; font-family: helvetica,arial,sans-serif; color: #626262; background-color: #F4F4F4;"> - <div class="webkit"> - <table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#F4F4F4"> - <tr> - <td valign="top" bgcolor="#F4F4F4" width="100%"> - <table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td width="100%"> - <table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td> - <!--[if mso]> - <center> - <table><tr><td width="600"> - <![endif]--> - <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width:600px;" align="center"> - <tr> - <td role="modules-container" style="padding: 0px 0px 0px 0px; color: #626262; text-align: left;" bgcolor="#F4F4F4" width="100%" - align="left"> - - <table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0" - width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;"> - <tr> - <td role="module-content"> - <p>you have a new notification</p> - </td> - </tr> - </table> - - <table class="wrapper" role="module" data-type="image" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="font-size:6px;line-height:10px;padding:20px 0px 20px 0px;" valign="top" align="center"> - <a href="https://hindawi.com"> - <img class="max-width" border="0" style="display:block;color:#000000;text-decoration:none;font-family:Helvetica, arial, sans-serif;font-size:16px;max-width:10% !important;width:10%;height:auto !important;" - src="https://marketing-image-production.s3.amazonaws.com/uploads/bb39b20cf15e52c1c0933676e25f2b2402737c6560b8098c204ad6932b84eb2058804376dbc4db138c7a21dcaed9325bde36185648afac5bc97e3d73d4e12718.png" - alt="" width="60"> - </a> - </td> - </tr> - </table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/intro.hbs b/packages/component-helper-service/src/services/email/templates/partials/intro.hbs deleted file mode 100644 index 0ce780b6d9e09ac62aecd9ec48ef287f92184e30..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/intro.hbs +++ /dev/null @@ -1 +0,0 @@ -<p data-pm-slice="1 1 []">Dear Dr. {{toUserName}},</p> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invButtons.hbs b/packages/component-helper-service/src/services/email/templates/partials/invButtons.hbs deleted file mode 100644 index 5c5041dec3a973c019e5743106826fa11137c14e..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invButtons.hbs +++ /dev/null @@ -1,88 +0,0 @@ -<table border="0" cellpadding="0" cellspacing="0" align="center" width="100%" role="module" data-type="columns" data-version="2" - style="padding:20px 0px 20px 0px;background-color:#ffffff;box-sizing:border-box;" bgcolor="#ffffff"> - <tr role='module-content'> - <td height="100%" valign="top"> - <!--[if (gte mso 9)|(IE)]> - <center> - <table cellpadding="0" cellspacing="0" border="0" width="100%" style="border-spacing:0;border-collapse:collapse;table-layout: fixed;" > - <tr> - <![endif]--> - - <!--[if (gte mso 9)|(IE)]> - <td width="300.000px" valign="top" style="padding: 0px 0px 0px 0px;border-collapse: collapse;" > - <![endif]--> - - <table width="300.000" style="width:300.000px;border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;" cellpadding="0" - cellspacing="0" align="left" border="0" bgcolor="#ffffff" class="column column-0 of-2 - empty"> - <tr> - <td style="padding:0px;margin:0px;border-spacing:0;"> - <table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" - style="table-layout:fixed" width="100%"> - <tbody> - <tr> - <td align="center" class="outer-td" style="padding:0px 0px 0px 0px"> - <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> - <tbody> - <tr> - <td align="center" bgcolor="#0d78f2" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> - <a style="background-color:#0d78f2;border:1px solid #333333;border-color:#0d78f2;border-radius:0px;border-width:1px;color:#ffffff;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" - href="{{ agreeLink }}" target="_blank">AGREE</a> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </table> - - <!--[if (gte mso 9)|(IE)]> - </td> - <![endif]--> - <!--[if (gte mso 9)|(IE)]> - <td width="300.000px" valign="top" style="padding: 0px 0px 0px 0px;border-collapse: collapse;" > - <![endif]--> - - <table width="300.000" style="width:300.000px;border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;" cellpadding="0" - cellspacing="0" align="left" border="0" bgcolor="#ffffff" class="column column-1 of-2 - empty"> - <tr> - <td style="padding:0px;margin:0px;border-spacing:0;"> - <table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module" - style="table-layout:fixed" width="100%"> - <tbody> - <tr> - <td align="center" class="outer-td" style="padding:0px 0px 0px 0px"> - <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile" style="text-align:center"> - <tbody> - <tr> - <td align="center" bgcolor="#e4dfdf" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit"> - <a style="background-color:#e4dfdf;border:1px solid #333333;border-color:#E4DFDF;border-radius:0px;border-width:1px;color:#302e2e;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none" - href="{{ declineLink }}" target="_blank">DECLINE</a> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </tbody> - </table> - </td> - </tr> - </table> - - <!--[if (gte mso 9)|(IE)]> - </td> - <![endif]--> - <!--[if (gte mso 9)|(IE)]> - <tr> - </table> - </center> - <![endif]--> - </td> - </tr> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invHeader.hbs b/packages/component-helper-service/src/services/email/templates/partials/invHeader.hbs deleted file mode 100644 index a8390f81f0389272c8824e79e17fda96b444748d..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invHeader.hbs +++ /dev/null @@ -1,161 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml"> - -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> - <!--[if !mso]><!--> - <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> - <!--<![endif]--> - <!--[if (gte mso 9)|(IE)]> - <xml> - <o:OfficeDocumentSettings> - <o:AllowPNG/> - <o:PixelsPerInch>96</o:PixelsPerInch> - </o:OfficeDocumentSettings> - </xml> - <![endif]--> - <!--[if (gte mso 9)|(IE)]> - <style type="text/css"> - body {width: 600px;margin: 0 auto;} - table {border-collapse: collapse;} - table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;} - img {-ms-interpolation-mode: bicubic;} - </style> - <![endif]--> - - <style type="text/css"> - body, - p, - div { - font-family: helvetica, arial, sans-serif; - font-size: 14px; - } - - body { - color: #626262; - } - - body a { - color: #0D78F2; - text-decoration: none; - } - - p { - margin: 0; - padding: 0; - } - - table.wrapper { - width: 100% !important; - table-layout: fixed; - -webkit-font-smoothing: antialiased; - -webkit-text-size-adjust: 100%; - -moz-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - } - - img.max-width { - max-width: 100% !important; - } - - .column.of-2 { - width: 50%; - } - - .column.of-3 { - width: 33.333%; - } - - .column.of-4 { - width: 25%; - } - - @media screen and (max-width:480px) { - .preheader .rightColumnContent, - .footer .rightColumnContent { - text-align: left !important; - } - .preheader .rightColumnContent div, - .preheader .rightColumnContent span, - .footer .rightColumnContent div, - .footer .rightColumnContent span { - text-align: left !important; - } - .preheader .rightColumnContent, - .preheader .leftColumnContent { - font-size: 80% !important; - padding: 5px 0; - } - table.wrapper-mobile { - width: 100% !important; - table-layout: fixed; - } - img.max-width { - height: auto !important; - max-width: 480px !important; - } - a.bulletproof-button { - display: block !important; - width: auto !important; - font-size: 80%; - padding-left: 0 !important; - padding-right: 0 !important; - } - .columns { - width: 100% !important; - } - .column { - display: block !important; - width: 100% !important; - padding-left: 0 !important; - padding-right: 0 !important; - margin-left: 0 !important; - margin-right: 0 !important; - } - } - </style> - <!--user entered Head Start--> - - <!--End Head user entered--> -</head> - -<body> - <center class="wrapper" data-link-color="#0D78F2" data-body-style="font-size: 14px; font-family: helvetica,arial,sans-serif; color: #626262; background-color: #F4F4F4;"> - <div class="webkit"> - <table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#F4F4F4"> - <tr> - <td valign="top" bgcolor="#F4F4F4" width="100%"> - <table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td width="100%"> - <table width="100%" cellpadding="0" cellspacing="0" border="0"> - <tr> - <td> - <!--[if mso]> - <center> - <table><tr><td width="600"> - <![endif]--> - <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width:600px;" align="center"> - <tr> - <td role="modules-container" style="padding: 0px 0px 0px 0px; color: #626262; text-align: left;" bgcolor="#F4F4F4" width="100%" - align="left"> - - <table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0" - width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;"> - <tr> - <td role="module-content"> - <p>new invitation</p> - </td> - </tr> - </table> - - <table class="wrapper" role="module" data-type="image" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="font-size:6px;line-height:10px;padding:20px 0px 20px 0px;" valign="top" align="center"> - <img class="max-width" border="0" style="display:block;color:#000000;text-decoration:none;font-family:Helvetica, arial, sans-serif;font-size:16px;max-width:10% !important;width:10%;height:auto !important;" - src="https://marketing-image-production.s3.amazonaws.com/uploads/bb39b20cf15e52c1c0933676e25f2b2402737c6560b8098c204ad6932b84eb2058804376dbc4db138c7a21dcaed9325bde36185648afac5bc97e3d73d4e12718.png" - alt="" width="60"> - </td> - </tr> - </table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invLowerContent.hbs b/packages/component-helper-service/src/services/email/templates/partials/invLowerContent.hbs deleted file mode 100644 index 2e391bc6b161adfc49bee25dd7db227001cab266..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invLowerContent.hbs +++ /dev/null @@ -1,20 +0,0 @@ -<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> - <p data-pm-slice="1 1 []"> - <a href="{{ detailsLink }}">See more information</a> - </p> - - <p data-pm-slice="1 1 []"> </p> - - {{#unless resend }} - {{> invManuscriptData }} - {{/unless}} - <p data-pm-slice="1 1 []">{{{ lowerContent }}}</p> - - <p> </p> - {{> signature }} - <div style="text-align: center;"> </div> - </td> - </tr> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invManuscriptData.hbs b/packages/component-helper-service/src/services/email/templates/partials/invManuscriptData.hbs deleted file mode 100644 index 36d60dbe2943b37e8ef7ba15031256728b8f409b..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invManuscriptData.hbs +++ /dev/null @@ -1,15 +0,0 @@ -<p data-pm-slice="1 1 []">{{ manuscriptText }}</p> -<p> </p> -<h2>{{ title }}</h2> -<p> </p> -<h4> - <span style="font-family:arial,helvetica,sans-serif;">{{ authorsList }}</span> -</h4> -<p> - <br /> - <em> - <span style="font-family:arial,helvetica,sans-serif;">{{{abstract}}}</span> - </em> -</p> - -<p> </p> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/invUpperContent.hbs b/packages/component-helper-service/src/services/email/templates/partials/invUpperContent.hbs deleted file mode 100644 index 2b9dc858cbc000c6aff38dc4905fe8eb40474101..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/invUpperContent.hbs +++ /dev/null @@ -1,13 +0,0 @@ -<table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;"> - <tr> - <td style="padding:30px 23px 20px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff"> - <div> - <p data-pm-slice="1 1 []">Dear Dr. {{ toUserName }},</p> - - <p> </p> - <p>{{{ upperContent }}}</p> - </div> - - </td> - </tr> -</table> \ No newline at end of file diff --git a/packages/component-helper-service/src/services/email/templates/partials/signature.hbs b/packages/component-helper-service/src/services/email/templates/partials/signature.hbs deleted file mode 100644 index eec0831b8cdc1d3835c9852b1d79c04a8dcce891..0000000000000000000000000000000000000000 --- a/packages/component-helper-service/src/services/email/templates/partials/signature.hbs +++ /dev/null @@ -1,4 +0,0 @@ -<p>Kind regards, - <br /> {{ signatureName }} - <br /> {{ signatureJournal }} -</p> \ No newline at end of file diff --git a/packages/component-helper-service/src/tests/fragment.test.js b/packages/component-helper-service/src/tests/fragment.test.js new file mode 100644 index 0000000000000000000000000000000000000000..3b5875eaf284e315ce1e3dd8a8792769e545e9c4 --- /dev/null +++ b/packages/component-helper-service/src/tests/fragment.test.js @@ -0,0 +1,29 @@ +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' +process.env.SUPPRESS_NO_CONFIG_WARNING = true + +const { cloneDeep } = require('lodash') +const fixturesService = require('pubsweet-component-fixture-service') + +const { fixtures } = fixturesService +const { Fragment } = require('../Helper') + +describe('Fragment helper', () => { + let testFixtures = {} + beforeEach(() => { + testFixtures = cloneDeep(fixtures) + }) + + it('hasReviewReport - should return true if the fragment has a review report', () => { + const { fragment } = testFixtures.fragments + const fragmentHelper = new Fragment({ fragment }) + + expect(fragmentHelper.hasReviewReport()).toBeTruthy() + }) + it('hasReviewReport - should return false if the fragment does not have a review report', () => { + const { fragment } = testFixtures.fragments + fragment.recommendations = [] + const fragmentHelper = new Fragment({ fragment }) + + expect(fragmentHelper.hasReviewReport()).toBeFalsy() + }) +}) diff --git a/packages/component-invite/src/tests/fragmentsInvitations/get.test.js b/packages/component-invite/src/tests/fragmentsInvitations/get.test.js index d30877398cfcf319effc69b265f9f7a7025c295e..4a33e93aae65403fb14eb6b1161c3c093f442330 100644 --- a/packages/component-invite/src/tests/fragmentsInvitations/get.test.js +++ b/packages/component-invite/src/tests/fragmentsInvitations/get.test.js @@ -44,7 +44,7 @@ describe('Get fragment invitations route handler', () => { expect(res.statusCode).toBe(200) const data = JSON.parse(res._getData()) - expect(data).toHaveLength(2) + expect(data).toHaveLength(3) }) it('should return an error when parameters are missing', async () => { const { handlingEditor } = testFixtures.users diff --git a/packages/component-invite/src/tests/fragmentsInvitations/patch.test.js b/packages/component-invite/src/tests/fragmentsInvitations/patch.test.js index 15d6f7a45edb01cde39e137b57121fd8520a5168..0342f906ad6f1ea8b52f41dbff39c7236712b82b 100644 --- a/packages/component-invite/src/tests/fragmentsInvitations/patch.test.js +++ b/packages/component-invite/src/tests/fragmentsInvitations/patch.test.js @@ -62,7 +62,7 @@ describe('Patch fragments invitations route handler', () => { await require(patchPath)(models)(req, res) expect(res.statusCode).toBe(200) - expect(reviewer.teams).toHaveLength(0) + expect(reviewer.teams).toHaveLength(1) }) it('should return an error if the collection does not exist', async () => { const { handlingEditor } = testFixtures.users diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js index fbb64a10ee122ab134c26e6941a54c20eb381f63..8fadac625272f7f5a3d200d11da0af3e5a1d1270 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js @@ -87,8 +87,8 @@ const getEmailCopy = ({ case 'eic-recommend-to-reject-from-he': hasIntro = false hasSignature = false - paragraph = `Dr. ${targetUserName} has recommended rejecting ${titleText}.<br/> - ${comments}<br/> + paragraph = `Dr. ${targetUserName} has recommended rejecting ${titleText}.<br/><br/> + ${comments}<br/><br/> To review this decision, please visit the manuscript details page.` break case 'eic-request-revision-from-he': diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js index c24b1e0f6c70bcbaf6899015cc92e87b0a85c630..eee5ba2fc9ee4eb1206172c29b7d6c298dfeeabd 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js @@ -29,12 +29,15 @@ module.exports = { const parsedFragment = await fragmentHelper.getFragmentData({ handlingEditor: collection.handlingEditor, }) - const fragmentAuthors = await fragmentHelper.getAuthorData({ UserModel }) + const { + activeAuthors, + submittingAuthor, + } = await fragmentHelper.getAuthorData({ UserModel }) const subjectBaseText = `${collection.customId}: Manuscript` const titleText = `The manuscript titled "${parsedFragment.title}" by ${ - fragmentAuthors.submittingAuthor.firstName - } ${fragmentAuthors.submittingAuthor.lastName}` + submittingAuthor.firstName + } ${submittingAuthor.lastName}` const userHelper = new User({ UserModel }) const eicName = await userHelper.getEiCName() @@ -135,7 +138,7 @@ module.exports = { comments, emailType, title: parsedFragment.title, - fragmentAuthors: fragmentAuthors.activeAuthors, + fragmentAuthors: activeAuthors, }) email = helpers.updateEmailContentForAllAuthors({ email, @@ -151,10 +154,10 @@ module.exports = { newRecommendation, }) const author = helpers.getSubmittingAuthor({ - authorNoteText, journalName, + authorNoteText, + submittingAuthor, title: parsedFragment.title, - submittingAuthor: fragmentAuthors.submittingAuthor, }) email = helpers.updateEmailContentForSA({ email, @@ -203,10 +206,12 @@ module.exports = { email, baseUrl, customId, - titleText, userHelper, recommendation: newRecommendation, targetUserName: collHelper.getHELastName(), + titleText: `the submission "${parsedFragment.title}" by ${ + submittingAuthor.firstName + } ${submittingAuthor.lastName}`, }) } diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js index ee36ebb094a75bd91e694ad027c0d7b6c6bac745..4cbdb582680e110dc4d067474dfa4cc3e0c3e913 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js @@ -5,11 +5,12 @@ const { v4 } = require('uuid') const { services, - authsome: authsomeHelper, + Fragment, Collection, + authsome: authsomeHelper, } = require('pubsweet-component-helper-service') -const { features = {} } = config +const { features = {}, recommendations } = config const sendMTSPackage = async (collection, fragment) => { const s3Config = get(config, 'pubsweet-component-aws-s3', {}) @@ -68,6 +69,20 @@ module.exports = models => async (req, res) => { error: 'Unauthorized.', }) + if ( + recommendation === recommendations.publish && + recommendationType === recommendations.type.editor && + collection.handlingEditor && + collection.handlingEditor.id === req.user + ) { + const fragmentHelper = new Fragment({ fragment }) + if (!fragmentHelper.hasReviewReport()) { + return res + .status(400) + .json({ error: 'Cannot publish without at least one reviewer report.' }) + } + } + fragment.recommendations = fragment.recommendations || [] const newRecommendation = { id: uuid.v4(), diff --git a/packages/component-manuscript-manager/src/tests/collections/get.test.js b/packages/component-manuscript-manager/src/tests/collections/get.test.js index f072e2693638e8f954d1d061e446a15b7f1cd8d3..0862779b60d66f4d415632ce421f90fda6290010 100644 --- a/packages/component-manuscript-manager/src/tests/collections/get.test.js +++ b/packages/component-manuscript-manager/src/tests/collections/get.test.js @@ -44,10 +44,10 @@ describe('Get collections route handler', () => { }) it('should return collections with the latest fragments if the request user is reviewer', async () => { - const { recReviewer } = testFixtures.users + const { answerReviewer } = testFixtures.users const res = await requests.sendRequest({ - userId: recReviewer.id, + userId: answerReviewer.id, route, models, path, @@ -56,7 +56,7 @@ describe('Get collections route handler', () => { expect(res.statusCode).toBe(200) const data = JSON.parse(res._getData()) - expect(data).toHaveLength(1) + expect(data).toHaveLength(2) expect(data[0].type).toEqual('collection') expect(data[0].currentVersion.recommendations).toHaveLength(1) expect(data[0].currentVersion.authors[0]).not.toHaveProperty('email') diff --git a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/patch.test.js b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/patch.test.js index d67ae0ea44921e1a0781968f53949dcd67c7df98..05c6e8271c46b85a5f1278df341304cc4f4b49f1 100644 --- a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/patch.test.js +++ b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/patch.test.js @@ -45,13 +45,13 @@ describe('Patch fragments recommendations route handler', () => { models = Model.build(testFixtures) }) it('should return success when the parameters are correct', async () => { - const { recReviewer } = testFixtures.users + const { answerReviewer } = testFixtures.users const { collection } = testFixtures.collections const { fragment } = testFixtures.fragments const recommendation = fragment.recommendations[0] const res = await requests.sendRequest({ body, - userId: recReviewer.id, + userId: answerReviewer.id, models, route, path, @@ -64,7 +64,7 @@ describe('Patch fragments recommendations route handler', () => { expect(res.statusCode).toBe(200) const data = JSON.parse(res._getData()) - expect(data.userId).toEqual(recReviewer.id) + expect(data.userId).toEqual(answerReviewer.id) }) it('should return an error when the fragmentId does not match the collectionId', async () => { const { reviewer } = testFixtures.users diff --git a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js index 5489b35a75f8d70fba86992ab2369029248cd2e7..e86097c9abb9defbad77862f1826360d5edef8fa 100644 --- a/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js +++ b/packages/component-manuscript-manager/src/tests/fragmentsRecommendations/post.test.js @@ -332,4 +332,31 @@ describe('Post fragments recommendations route handler', () => { expect(data.userId).toEqual(editorInChief.id) expect(data.recommendation).toBe('return-to-handling-editor') }) + it('should return an error when a HE recommends to publish without a reviewer report', async () => { + const { handlingEditor } = testFixtures.users + const { collection } = testFixtures.collections + const { fragment } = testFixtures.fragments + body.recommendation = 'publish' + body.recommendationType = 'editorRecommendation' + fragment.recommendations = [] + + const res = await requests.sendRequest({ + body, + userId: handlingEditor.id, + models, + route, + path, + params: { + collectionId: collection.id, + fragmentId: fragment.id, + }, + }) + + expect(res.statusCode).toBe(400) + const data = JSON.parse(res._getData()) + + expect(data.error).toEqual( + 'Cannot publish without at least one reviewer report.', + ) + }) }) diff --git a/packages/component-manuscript/src/components/ManuscriptLayout.js b/packages/component-manuscript/src/components/ManuscriptLayout.js index 75d345cf6b92d84218658513f42450763fb85578..2450088dfa1d23f29cd9070bd21735f3a1f5d440 100644 --- a/packages/component-manuscript/src/components/ManuscriptLayout.js +++ b/packages/component-manuscript/src/components/ManuscriptLayout.js @@ -5,12 +5,13 @@ import { Text, paddingHelper, ReviewerDetails, + HERecommendation, ManuscriptHeader, ManuscriptAssignHE, ManuscriptMetadata, ManuscriptDetailsTop, - ManuscriptEicDecision, ResponseToInvitation, + ManuscriptEicDecision, } from 'pubsweet-component-faraday-ui' import ReviewerReportCard from './ReviewReportCard' @@ -62,7 +63,12 @@ const ManuscriptLayout = ({ reviewerRecommendationExpanded, shouldReview, submittedOwnRecommendation, + heAccepted, reviewerReports, + onEditorialRecommendation, + reviewerRecommendations, + toggleReviewerDetails, + reviewerDetailsExpanded, }) => ( <Root pb={30}> {!isEmpty(collection) && !isEmpty(fragment) ? ( @@ -156,31 +162,46 @@ const ManuscriptLayout = ({ toggle={toggleAssignHE} /> - {get(currentUser, 'permissions.canMakeDecision', false) && ( - <ManuscriptEicDecision - formValues={get(formValues, 'eicDecision')} - messagesLabel={messagesLabel} - mt={2} - options={ - get(collection, 'status', 'submitted') === 'submitted' - ? [last(eicDecisions)] - : eicDecisions - } - submitDecision={createRecommendation} - /> - )} - {get(currentUser, 'permissions.canViewReviewersDetails', false) && ( <ReviewerDetails currentUser={currentUser} + expanded={reviewerDetailsExpanded} fragment={fragment} getSignedUrl={getSignedUrl} + highlight={reviewerReports.length === 0} invitations={invitationsWithReviewers} journal={journal} + mb={2} onInviteReviewer={onInviteReviewer} onResendReviewerInvite={onResendReviewerInvite} onRevokeReviewerInvite={onRevokeReviewerInvite} reviewerReports={reviewerReports} + scrollIntoView + toggle={toggleReviewerDetails} + /> + )} + + {get(currentUser, 'permissions.canMakeHERecommendation', false) && ( + <HERecommendation + formValues={get(formValues, 'editorialRecommendation', {})} + hasReviewerReports={reviewerRecommendations.length > 0} + highlight={reviewerRecommendations.length > 0} + modalKey="heRecommendation" + onRecommendationSubmit={onEditorialRecommendation} + /> + )} + + {get(currentUser, 'permissions.canMakeDecision', false) && ( + <ManuscriptEicDecision + formValues={get(formValues, 'eicDecision')} + messagesLabel={messagesLabel} + mt={2} + options={ + get(collection, 'status', 'submitted') === 'submitted' + ? [last(eicDecisions)] + : eicDecisions + } + submitDecision={createRecommendation} /> )} </Fragment> diff --git a/packages/component-manuscript/src/components/ManuscriptPage.js b/packages/component-manuscript/src/components/ManuscriptPage.js index 31faec409b713b9f61f7a644db03e968cb4b4416..aa69fb6d10850f9150dc2c078216f437074dfe2d 100644 --- a/packages/component-manuscript/src/components/ManuscriptPage.js +++ b/packages/component-manuscript/src/components/ManuscriptPage.js @@ -41,11 +41,13 @@ import { canViewReports, canMakeRevision, canMakeDecision, + isHEToManuscript, canEditManuscript, canInviteReviewers, pendingHEInvitation, currentUserIsReviewer, parseCollectionDetails, + canMakeHERecommendation, canViewReviewersDetails, pendingReviewerInvitation, canOverrideTechnicalChecks, @@ -127,6 +129,7 @@ export default compose( state, { match, + journal, fragment, collection, currentUser, @@ -140,10 +143,15 @@ export default compose( token: getUserToken(state), isHE: currentUserIs(state, 'isHE'), isEIC: currentUserIs(state, 'adminEiC'), - isReviewer: currentUserIsReviewer(state, get(fragment, 'id', '')), isInvitedHE: !isUndefined(pendingHEInvitation), isInvitedToReview: !isUndefined(pendingReviewerInvitation), + isReviewer: currentUserIsReviewer(state, get(fragment, 'id', '')), + isHEToManuscript: isHEToManuscript(state, get(collection, 'id', '')), permissions: { + canMakeHERecommendation: canMakeHERecommendation(state, { + collection, + statuses: get(journal, 'statuses', {}), + }), canAssignHE: canAssignHE(state, match.params.project), canViewReports: canViewReports(state, match.params.project), canInviteReviewers: canInviteReviewers(state, collection), @@ -162,6 +170,9 @@ export default compose( eicDecision: getFormValues('eic-decision')(state), reviewerReport: getFormValues('reviewerReport')(state), responseToInvitation: getFormValues('answer-invitation')(state), + editorialRecommendation: getFormValues('editorialRecommendation')( + state, + ), }, invitationsWithReviewers: getInvitationsWithReviewersForFragment( state, @@ -372,6 +383,27 @@ export default compose( handleError(setModalError)(err) }) }, + onEditorialRecommendation: ({ + fragment, + collection, + fetchUpdatedCollection, + }) => (recommendation, { hideModal, setFetching, setModalError }) => { + setFetching(true) + createRecommendation({ + recommendation, + fragmentId: fragment.id, + collectionId: collection.id, + }) + .then(r => { + setFetching(false) + hideModal() + fetchUpdatedCollection() + }) + .catch(e => { + setFetching(false) + handleError(setModalError)(e) + }) + }, }), fromRenderProps(RemoteOpener, ({ toggle, expanded }) => ({ toggleAssignHE: toggle, @@ -389,7 +421,11 @@ export default compose( toggleReviewerRecommendations: toggle, reviewerRecommendationExpanded: expanded, })), - withProps(({ currentUser, submittedOwnRecommendation }) => ({ + fromRenderProps(RemoteOpener, ({ toggle, expanded }) => ({ + toggleReviewerDetails: toggle, + reviewerDetailsExpanded: expanded, + })), + withProps(({ currentUser, collection, submittedOwnRecommendation }) => ({ getSignedUrl, shouldReview: get(currentUser, 'isReviewer', false) && @@ -402,11 +438,12 @@ export default compose( history, location, shouldReview, + reviewerReports, setEditorInChief, clearCustomError, hasManuscriptFailure, fetchUpdatedCollection, - currentUser: { isInvitedHE, isInvitedToReview }, + currentUser: { isInvitedHE, isInvitedToReview, isHEToManuscript }, } = this.props if (hasManuscriptFailure) { history.push('/not-found') @@ -438,6 +475,10 @@ export default compose( if (shouldReview) { this.props.toggleReviewerRecommendations() } + + if (isHEToManuscript && !!reviewerReports.length) { + this.props.toggleReviewerDetails() + } }, }), )(ManuscriptLayout) diff --git a/packages/component-manuscript/src/redux/recommendations.js b/packages/component-manuscript/src/redux/recommendations.js index 320a8bec80edccce574d6fcbb7b47cd6ca990272..2d40db4a29ae1d53a7c05b870f97c3ca8a57eca2 100644 --- a/packages/component-manuscript/src/redux/recommendations.js +++ b/packages/component-manuscript/src/redux/recommendations.js @@ -21,7 +21,6 @@ export const selectReviewRecommendations = (state, fragmentId) => // #endregion // #region Actions -// error handling and fetching is handled by the autosave reducer export const createRecommendation = ({ fragmentId, collectionId, diff --git a/packages/components-faraday/src/redux/recommendations.js b/packages/components-faraday/src/redux/recommendations.js index 26e9ad321a8e2cf9434b9d23196ac25d5f2c69fc..ea1df6c5e97c81f983f539077f648629967cadb9 100644 --- a/packages/components-faraday/src/redux/recommendations.js +++ b/packages/components-faraday/src/redux/recommendations.js @@ -4,6 +4,7 @@ import { create, update } from 'pubsweet-client/src/helpers/api' // #region Selectors export const selectRecommendations = (state, fragmentId) => get(state, `fragments.${fragmentId}.recommendations`, []) + export const selectEditorialRecommendations = (state, fragmentId) => selectRecommendations(state, fragmentId) .filter(r => r.recommendationType === 'editorRecommendation' && r.comments) diff --git a/packages/hindawi-theme/src/elements/Radio.js b/packages/hindawi-theme/src/elements/Radio.js index 124dbf44596a4ac8aa6cd35ea9ba63a2b1f429a2..2dfb3ec071b1c2d1759b59d7e334be917cddad52 100644 --- a/packages/hindawi-theme/src/elements/Radio.js +++ b/packages/hindawi-theme/src/elements/Radio.js @@ -13,14 +13,14 @@ export default { &::before { display: none; } - + input:checked + span::before { border-color: ${th('colorPrimary')}; background: url('data:image/svg+xml;utf8,${encodeURIComponent( checkIcon, )}') center no-repeat; } - `, + `, Input: css` opacity: 0; margin-left: calc(${th('gridUnit')} * -2); @@ -35,9 +35,10 @@ export default { background: transparent; border: 1px solid #939393; border-radius: 50%; - display: inline-block; + display: inline-flex; margin-right: ${th('gridUnit')}; - vertical-align: middle; + vertical-align: text-bottom; + align-items: center; height: calc(${th('gridUnit')} * 2); width: calc(${th('gridUnit')} * 2); diff --git a/packages/hindawi-theme/src/index.js b/packages/hindawi-theme/src/index.js index d63931498ffdcf1b4a5d451b0b3fb5d1fd56e41e..09be373c770356d258fedd31dc9f3cbd3f582631 100644 --- a/packages/hindawi-theme/src/index.js +++ b/packages/hindawi-theme/src/index.js @@ -158,7 +158,7 @@ const hindawiTheme = { lineHeightHeading1: '37px', lineHeightHeading2: '29px', - lineHeightHeading3: '19px', + lineHeightHeading3: '20px', lineHeightHeading4: '18px', lineHeightHeading5: '18px', lineHeightHeading6: '18px', diff --git a/packages/xpub-faraday/config/authsome-helpers.js b/packages/xpub-faraday/config/authsome-helpers.js index 2960282ae2215eb31b8d8374e9abe052f2b51ae4..f44cf22496e43c2a4428dfa51e2ee4acf99c0d91 100644 --- a/packages/xpub-faraday/config/authsome-helpers.js +++ b/packages/xpub-faraday/config/authsome-helpers.js @@ -239,7 +239,19 @@ const getCollections = async ({ user, models }) => { role: up.role, }) - return stripedColl.coll + const role = get(up, 'role', 'author') + + let visibleStatus = get(statuses, `${status}.${role}.label`) + + if (role === 'reviewer' && status !== 'reviewersInvited') { + visibleStatus = await updateReviewerVisibleStatusByInvitation({ + collection, + FragmentModel: models.Fragment, + user, + }) + } + + return { ...stripedColl.coll, visibleStatus } }), )).filter(Boolean) } diff --git a/packages/xpub-faraday/config/authsome-mode.js b/packages/xpub-faraday/config/authsome-mode.js index 89c0caf14801a234d20013a8d2e16ec10fdeceb6..bf1c2ed4786f543a3777af550122385b83bb21c7 100644 --- a/packages/xpub-faraday/config/authsome-mode.js +++ b/packages/xpub-faraday/config/authsome-mode.js @@ -60,32 +60,6 @@ const createPaths = ['/collections', '/collections/:collectionId/fragments'] async function applyAuthenticatedUserPolicy(user, operation, object, context) { if (operation === 'GET') { - if (get(object, 'path') === '/collections') { - return { - filter: async collections => { - const userPermissions = await helpers.getUserPermissions({ - user, - Team: context.models.Team, - }) - return collections.filter(collection => { - if (collection.owners.includes(user.id)) { - return true - } - const collectionPermission = userPermissions.find( - p => p.objectId === collection.id, - ) - if (collectionPermission) { - return true - } - - return userPermissions.find(p => - collection.fragments.includes(p.objectId), - ) - }) - }, - } - } - if (get(object, 'path') === '/api/users') { return helpers.getUsersList({ UserModel: context.models.User, user }) } diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js index 737efe3bd3b91372aff2a608b6a712f30a25dbda..7cd9de3dbaab836663730ca2ed9942712d2d237b 100644 --- a/packages/xpub-faraday/config/default.js +++ b/packages/xpub-faraday/config/default.js @@ -129,4 +129,14 @@ module.exports = { features: { mts: JSON.parse(get(process, 'env.FEATURE_MTS', true)), }, + recommendations: { + minor: 'minor', + major: 'major', + reject: 'reject', + publish: 'publish', + type: { + review: 'review', + editor: 'editorRecommendation', + }, + }, }