diff --git a/packages/component-faraday-selectors/src/index.js b/packages/component-faraday-selectors/src/index.js index af395e7147c405501a6457a8f46ba07de67f186d..ae7b54ace427f4e6af74297ad94dfcbefe76496a 100644 --- a/packages/component-faraday-selectors/src/index.js +++ b/packages/component-faraday-selectors/src/index.js @@ -185,17 +185,25 @@ const parseInvitedHE = (handlingEditor, state, collectionId) => ? 'Invited' : handlingEditor.name, } + const hideCustomIdStatuses = ['draft', 'technicalChecks'] -export const newestFirstParseDashboard = (state, items) => - chain(items) + +export const parseCollectionDetails = (state, collection) => ({ + ...collection, + customId: + !hideCustomIdStatuses.includes(get(collection, 'status', 'draft')) && + collection.customId, + handlingEditor: parseInvitedHE( + collection.handlingEditor, + state, + collection.id, + ), +}) + +export const newestFirstParseDashboard = (state = {}) => + chain(state.collections) .orderBy(['created'], ['desc']) - .map(item => ({ - ...item, - customId: - !hideCustomIdStatuses.includes(get(item, 'status', 'draft')) && - item.customId, - handlingEditor: parseInvitedHE(item.handlingEditor, state, item.id), - })) + .map(item => parseCollectionDetails(state, item)) .value() export const getInvitationsWithReviewersForFragment = (state, fragmentId) => diff --git a/packages/component-faraday-ui/src/ManuscriptCard.js b/packages/component-faraday-ui/src/ManuscriptCard.js index 20996f07bfb2a73604d543bd8ccd5a270aed740c..095e959e26d78489305ac9c569adf17342656e72 100644 --- a/packages/component-faraday-ui/src/ManuscriptCard.js +++ b/packages/component-faraday-ui/src/ManuscriptCard.js @@ -27,7 +27,7 @@ const ManuscriptCard = ({ onCardClick, fragment = {}, manuscriptType = {}, - collection: { visibleStatus = 'Draft', handlingEditor, customId }, + collection: { visibleStatus = 'Draft', handlingEditor, customId, id: collId }, }) => { const { authors = [], @@ -86,7 +86,7 @@ const ManuscriptCard = ({ <Item justify="flex-end" onClick={e => e.stopPropagation()}> <OpenModal confirmText="Delete" - modalKey={`delete-${customId}`} + modalKey={`delete-${collId}`} onConfirm={onDelete} title="Are you sure you want to delete this submission?" > diff --git a/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js b/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js index a4d5c432c355631b1c842b6e681dd19a0359e2ea..cc79766601a6e3bf1461efb6c0c1eaa294624d95 100644 --- a/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js +++ b/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js @@ -40,7 +40,7 @@ const ManuscriptHeader = ({ </Row> )} <Row alignItems="center" justify="flex-start" mb={1}> - <Text customId mr={1}>{`ID ${customId}`}</Text> + {customId && <Text customId mr={1}>{`ID ${customId}`}</Text>} {submitted && ( <DateParser durationThreshold={0} timestamp={submitted}> {timestamp => <Text mr={3}>Submitted on {timestamp}</Text>} diff --git a/packages/component-helper-service/src/services/Fragment.js b/packages/component-helper-service/src/services/Fragment.js index a0e8494bb014ebe42a81ee538f68351d5cfa53ca..bf7013772455b040774f5eb3eab97f3a468f8e22 100644 --- a/packages/component-helper-service/src/services/Fragment.js +++ b/packages/component-helper-service/src/services/Fragment.js @@ -76,7 +76,9 @@ class Fragment { ) const userHelper = new User({ UserModel }) - const activeAuthors = await userHelper.getActiveAuthors(authors) + const activeAuthors = await userHelper.getActiveAuthors({ + fragmentAuthors: authors, + }) return { activeAuthors, diff --git a/packages/component-helper-service/src/services/User.js b/packages/component-helper-service/src/services/User.js index e37a835dce2cc83b7541bae9f22a808bf86eb908..83c8809d2f4076bc5992731557f97cf49fb21499 100644 --- a/packages/component-helper-service/src/services/User.js +++ b/packages/component-helper-service/src/services/User.js @@ -62,15 +62,25 @@ class User { user.save() } - async getActiveAuthors(authors) { - const activeUsers = (await Promise.all( - authors.map(author => this.UserModel.find(author.id)), + async getActiveAuthors({ fragmentAuthors }) { + const userData = (await Promise.all( + fragmentAuthors.map(author => this.UserModel.find(author.id)), )) - .filter(user => user.isActive) - .filter(user => get(user, 'notifications.email.user')) - .map(user => user.id) + .filter(user => user.isActive && get(user, 'notifications.email.user')) + .map(user => ({ id: user.id, accessTokens: user.accessTokens })) - return authors.filter(author => activeUsers.includes(author.id)) + return fragmentAuthors + .map(fAuthor => { + const matchingAuthor = userData.find(user => user.id === fAuthor.id) + if (matchingAuthor) { + return { + ...fAuthor, + accessTokens: matchingAuthor.accessTokens, + } + } + return false + }) + .filter(Boolean) } async getEiCName() { diff --git a/packages/component-helper-service/src/services/email/Email.js b/packages/component-helper-service/src/services/email/Email.js index 0a7c2028bc6dde1ba7259459136a48a541eae620..5fdd6b42cb2f6705b092a6123e1270952561440f 100644 --- a/packages/component-helper-service/src/services/email/Email.js +++ b/packages/component-helper-service/src/services/email/Email.js @@ -85,9 +85,7 @@ class Email { logger.info( `EMAIL: Sent email from ${from} to ${to} with subject '${subject}'`, ) - logger.debug( - `EMAIL: Sent email from ${from} to ${to} with subject '${subject}'`, - ) + SendEmail.send(mailData) } } diff --git a/packages/component-manuscript-manager/src/routes/fragments/post.js b/packages/component-manuscript-manager/src/routes/fragments/post.js index 2ec4ab94af0427c9014609b1927f0db01e40a498..7b541025809ee4dea338b7f5cd6f2136e47dd034 100644 --- a/packages/component-manuscript-manager/src/routes/fragments/post.js +++ b/packages/component-manuscript-manager/src/routes/fragments/post.js @@ -8,9 +8,25 @@ const { const notifications = require('./notifications/notifications') -const s3Config = get(config, 'pubsweet-component-aws-s3', {}) -const mtsConfig = get(config, 'mts-service', {}) -const MTSService = require('pubsweet-component-mts-package') +const { features = {} } = config + +const sendMTSPackage = async (collection, fragment) => { + const s3Config = get(config, 'pubsweet-component-aws-s3', {}) + const mtsConfig = get(config, 'mts-service', {}) + const MTSService = require('pubsweet-component-mts-package') + + const { journal, xmlParser, ftp } = mtsConfig + const MTS = new MTSService(journal, xmlParser, s3Config, ftp) + const packageFragment = { + ...fragment, + metadata: { + ...fragment.metadata, + customId: collection.customId, + }, + } + + await MTS.sendPackage({ fragment: packageFragment }) +} module.exports = models => async (req, res) => { const { collectionId, fragmentId } = req.params @@ -42,18 +58,10 @@ module.exports = models => async (req, res) => { set(collection, 'technicalChecks.token', v4()) await collection.save() - const { journal, xmlParser, ftp } = mtsConfig - const MTS = new MTSService(journal, xmlParser, s3Config, ftp) - const packageFragment = { - ...fragment, - metadata: { - ...fragment.metadata, - customId: collection.customId, - }, + if (features.mts) { + await sendMTSPackage(collection, fragment) } - await MTS.sendPackage({ fragment: packageFragment }) - notifications.sendNotifications({ fragment, collection, 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 c2f6338979e4940494b69798b30c2bbf1adce1c8..fbb64a10ee122ab134c26e6941a54c20eb381f63 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/emailCopy.js @@ -109,6 +109,12 @@ const getEmailCopy = ({ paragraph = `${titleText} has been accepted for publication by ${eicName}. <br/><br/> Please complete QA screening so that manuscript can be sent to production.` break + case 'authors-manuscript-rejected-before-review': + paragraph = `I regret to inform you that your manuscript has been rejected for publication in ${journalName} for the following reason:<br/><br/> + ${comments}<br/><br/> + Thank you for your submission, and please do consider submitting again in the future.` + hasLink = false + break default: throw new Error(`The ${emailType} email type is not defined.`) } diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/helpers.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/helpers.js index ffeb610de4b8dc4921ba7b0a89b4a186c89eddff..3dc8b8d7741c96ffa742617b424673b1a0b31e03 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/helpers.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/helpers.js @@ -378,14 +378,19 @@ module.exports = { return email }, - getEmailTypeByRecommendationForAuthors: ({ recommendation }) => { + getEmailTypeByRecommendationForAuthors: ({ + recommendation, + hasPeerReview, + }) => { let emailType switch (recommendation) { case 'publish': emailType = 'author-manuscript-published' break case 'reject': - emailType = 'author-manuscript-rejected' + emailType = hasPeerReview + ? 'author-manuscript-rejected' + : 'authors-manuscript-rejected-before-review' break default: throw new Error(`Undefined recommendation: ${recommendation}`) 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 9f6c43f5ea5f30885ad0fa99dc01e372abba8d00..c930744e70e8db6829fb9423a52f78066b133b71 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/notifications/notifications.js @@ -68,8 +68,7 @@ module.exports = { }) } - const hasPeerReview = (collection = {}) => - !isEmpty(collection.handlingEditor) + const hasPeerReview = !isEmpty(collection.handlingEditor) const { customId } = collection const collHelper = new Collection({ collection }) @@ -77,7 +76,7 @@ module.exports = { // or when the EiC makes a recommendation after peer review if ( (isEditorInChief || recommendationType === 'review') && - hasPeerReview(collection) && + hasPeerReview && (recommendation !== 'publish' || hasEQA) ) { const handlingEditor = get(collection, 'handlingEditor', {}) @@ -118,10 +117,18 @@ module.exports = { // send all authors email const emailType = helpers.getEmailTypeByRecommendationForAuthors({ recommendation, + hasPeerReview, }) - const comments = helpers.getHEComments({ - heRecommendation: parsedFragment.heRecommendation, - }) + + let comments + if (hasPeerReview) { + comments = helpers.getHEComments({ + heRecommendation: parsedFragment.heRecommendation, + }) + } else { + comments = newRecommendation.comments[0].content + } + const authors = helpers.getAllAuthors({ comments, emailType, @@ -156,7 +163,7 @@ module.exports = { helpers.sendSubmittingAuthorEmail({ email, author, baseUrl }) } - if (!hasPeerReview(collection)) { + if (!hasPeerReview) { return } diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js index 6b2ccae9ccf2e8c4eb5e65974c37f105ae66221a..ee36ebb094a75bd91e694ad027c0d7b6c6bac745 100644 --- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js +++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/post.js @@ -9,9 +9,25 @@ const { Collection, } = require('pubsweet-component-helper-service') -const s3Config = get(config, 'pubsweet-component-aws-s3', {}) -const mtsConfig = get(config, 'mts-service', {}) -const MTSService = require('pubsweet-component-mts-package') +const { features = {} } = config + +const sendMTSPackage = async (collection, fragment) => { + const s3Config = get(config, 'pubsweet-component-aws-s3', {}) + const mtsConfig = get(config, 'mts-service', {}) + const MTSService = require('pubsweet-component-mts-package') + + const { journal, xmlParser, ftp } = mtsConfig + const MTS = new MTSService(journal, xmlParser, s3Config, ftp) + const packageFragment = { + ...fragment, + metadata: { + ...fragment.metadata, + customId: collection.customId, + }, + } + + await MTS.sendPackage({ fragment: packageFragment }) +} const notifications = require('./notifications/notifications') @@ -80,18 +96,10 @@ module.exports = models => async (req, res) => { const hasEQA = has(technicalChecks, 'eqa') // the manuscript has not yet passed through the EQA process so we need to upload it to the FTP server if (isEditorInChief && recommendation === 'publish' && !hasEQA) { - const { journal, xmlParser, ftp } = mtsConfig - const MTS = new MTSService(journal, xmlParser, s3Config, ftp) - const packageFragment = { - ...fragment, - metadata: { - ...fragment.metadata, - customId: collection.customId, - }, + if (features.mts) { + await sendMTSPackage(collection, fragment) } - await MTS.sendPackage({ fragment: packageFragment, isEQA: true }) - collection.status = 'inQA' set(collection, 'technicalChecks.token', v4()) set(collection, 'technicalChecks.eqa', false) diff --git a/packages/component-manuscript/src/components/ManuscriptPage.js b/packages/component-manuscript/src/components/ManuscriptPage.js index ed5bab6a31ab79490630375ad50106c68cfc848a..b928e99ebce45ed1993264ed16394029992f3f6b 100644 --- a/packages/component-manuscript/src/components/ManuscriptPage.js +++ b/packages/component-manuscript/src/components/ManuscriptPage.js @@ -42,6 +42,7 @@ import { pendingHEInvitation, currentUserIsReviewer, canMakeRecommendation, + parseCollectionDetails, canOverrideTechnicalChecks, getInvitationsWithReviewersForFragment, } from 'pubsweet-component-faraday-selectors' @@ -79,7 +80,10 @@ export default compose( handlingEditors: selectHandlingEditors(state), hasManuscriptFailure: hasManuscriptFailure(state), fragment: selectFragment(state, match.params.version), - collection: selectCollection(state, match.params.project), + collection: parseCollectionDetails( + state, + selectCollection(state, match.params.project), + ), pendingHEInvitation: pendingHEInvitation(state, match.params.project), editorialRecommendations: selectEditorialRecommendations( state, diff --git a/packages/component-user-manager/src/routes/fragmentsUsers/get.js b/packages/component-user-manager/src/routes/fragmentsUsers/get.js index 6798a5f55d82666a88d4e1adc8bdc2c732e9114a..1931adfbe7245d082502f8a0cf545019817f2b27 100644 --- a/packages/component-user-manager/src/routes/fragmentsUsers/get.js +++ b/packages/component-user-manager/src/routes/fragmentsUsers/get.js @@ -13,7 +13,9 @@ module.exports = models => async (req, res) => { const { authors = [] } = await models.Fragment.find(fragmentId) const userHelper = new User({ UserModel: models.User }) - const activeAuthors = await userHelper.getActiveAuthors(authors) + const activeAuthors = await userHelper.getActiveAuthors({ + fragmentAuthors: authors, + }) return res.status(200).json(activeAuthors) } catch (e) { diff --git a/packages/components-faraday/src/components/Dashboard/DashboardPage.js b/packages/components-faraday/src/components/Dashboard/DashboardPage.js index 646720b8ab16883694bfd66caae03cf779b786ba..eda5819b44ca04a7b91afc876a6cec42bba2569c 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardPage.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardPage.js @@ -21,7 +21,7 @@ export default compose( state => { const { collections, conversion } = state const currentUser = selectCurrentUser(state) - const dashboard = newestFirstParseDashboard(state, collections) + const dashboard = newestFirstParseDashboard(state) const userPermissions = getUserPermissions(state) return { diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js index 4fc862bd584106b2ab78792fb97e4bdfffd42e6e..b00ae42cad1a21a1a71f724f8b07ec43b5d35e03 100644 --- a/packages/xpub-faraday/config/default.js +++ b/packages/xpub-faraday/config/default.js @@ -124,4 +124,7 @@ module.exports = { name: get(journalConfig, 'metadata.nameText'), staffEmail: get(journalConfig, 'metadata.email'), }, + features: { + mts: JSON.parse(get(process, 'env.FEATURE_MTS', true)), + }, }