Newer
Older
import { selectCurrentUser } from 'xpub-selectors'
// eslint-disable-next-line no-unused-vars
import { get, has, last, chain, some, isEmpty, flatten } from 'lodash'
export const isHEToManuscript = (state, collectionId = '') => {
const { id = '', isAccepted = false } = chain(state)
.get('collections', [])
.find(c => c.id === collectionId)

Tania Fecheta
committed
.get('handlingEditor', '')
.value()
return isAccepted && id === get(state, 'currentUser.user.id')
}
export const currentUserIs = ({ currentUser: { user } }, role) => {
const isAdmin = get(user, 'admin')
const isEic = get(user, 'editorInChief')
const isHe = get(user, 'handlingEditor')
switch (role) {
case 'isHE':
return isHe
case 'staff':
return isAdmin || isEic || isHe
case 'isEiC':
return isEic
case 'isAdmin':
return isAdmin
case 'adminEiC':
return isAdmin || isEic
default:
return false
}
}
const canInviteReviewersStatuses = [
'heAssigned',
'reviewersInvited',
'underReview',
'reviewCompleted',
]
export const canInviteReviewers = (state, collection = {}) => {
if (!canInviteReviewersStatuses.includes(get(collection, 'status', 'draft')))

Alexandru Munteanu
committed
return false

Alexandru Munteanu
committed
const { id: userId } = selectCurrentUser(state)
const isAdminEiC = currentUserIs(state, 'adminEiC')

Alexandru Munteanu
committed
const { isAccepted, id: heId } = get(collection, 'handlingEditor', {})
return isAccepted && (userId === heId || isAdminEiC)
}
const cannotViewReviewersDetails = [
'draft',
'technicalChecks',
'submitted',
'heInvited',
]

Anca Ursachi
committed
export const canViewReviewersDetails = (state, collection = {}) => {
const isHeAssigned = !!get(collection, 'handlingEditor', false)
if (
cannotViewReviewersDetails.includes(get(collection, 'status', 'draft')) ||
!isHeAssigned
) {
return canViewReports(state, get(collection, 'id', ''))

Tania Fecheta
committed
const authorAndReviewersCanViewReportsDetailsStatuses = [
'underReview',

Tania Fecheta
committed
'reviewCompleted',

Tania Fecheta
committed
]

Tania Fecheta
committed
state,
collection = {},
fragmentId,
) => {
const isAuthor = currentUserIsAuthor(state, fragmentId)

Tania Fecheta
committed
return (

Tania Fecheta
committed
authorAndReviewersCanViewReportsDetailsStatuses.includes(

Tania Fecheta
committed
get(collection, 'status', 'draft'),

Tania Fecheta
committed
)
}

Tania Fecheta
committed
export const reviewersCanViewReviewerReports = (
state,
collection = {},
fragmentId,
) => {
const isReviewer = currentUserIsReviewer(state, fragmentId)
const reviewerReports = getFragmentReviewerRecommendations(state, fragmentId)
return (
isReviewer &&
authorAndReviewersCanViewReportsDetailsStatuses.includes(
get(collection, 'status', 'draft'),
) &&
reviewerReports.length > 0
)
}

Anca Ursachi
committed
const canHeViewEditorialCommentsStatuses = [
'revisionRequested',
'rejected',
'accepted',
'inQA',

Tania Fecheta
committed
'reviewCompleted',

Anca Ursachi
committed
'underReview',

Anca Ursachi
committed
]

Anca Ursachi
committed
export const canHeViewEditorialComments = (state, collection = {}) => {
const isHE = isHEToManuscript(state, get(collection, 'id', ''))

Anca Ursachi
committed
const status = get(collection, 'status', 'draft')
return isHE && canHeViewEditorialCommentsStatuses.includes(status)
}

Anca Ursachi
committed
const canEICViewEditorialCommentsStatuses = [
'rejected',
'accepted',
'inQA',
'pendingApproval',

Tania Fecheta
committed
'reviewCompleted',

Anca Ursachi
committed
'revisionRequested',
'underReview',

Anca Ursachi
committed
]

Anca Ursachi
committed
export const canEICViewEditorialComments = (state, collection = {}) => {
const isEIC = currentUserIs(state, 'adminEiC')
const status = get(collection, 'status', 'draft')
return isEIC && canEICViewEditorialCommentsStatuses.includes(status)
}
const decisionTakenStatuses = ['rejected', 'accepted', 'inQA']
const canReviewerViewEditorialCommentsStatuses = [
'underReview',
'reviewCompleted',
'pendingApproval',

Mihail Hagiu
committed
'revisionRequested',
]
export const canReviewerViewEditorialComments = (
state,
collection = {},
fragment = {},
) => {
const status = get(collection, 'status', 'draft')
const isReviewer = currentUserIsReviewer(state, get(fragment, 'id', ''))
const hasDecision = decisionTakenStatuses.includes(status)
const hasSubmission = some(state.fragments, f => f.version > fragment.version)
return (
isReviewer &&
(hasDecision ||
(hasSubmission &&
canReviewerViewEditorialCommentsStatuses.includes(status)))
const cannotAuthorViewEditorialCommentsStatuses = [
'draft',
'technicalChecks',
'submitted',
'heInvited',
'heAssigned',
'reviewersInvited',
]
export const canAuthorViewEditorialComments = (
state,
collection = {},
fragmentId,
) => {
const isAuthor = currentUserIsAuthor(state, fragmentId)
return (
isAuthor &&
!cannotAuthorViewEditorialCommentsStatuses.includes(
get(collection, 'status', 'draft'),
)
)
}

Anca Ursachi
committed
export const canViewEditorialComments = (
state,
collection = {},

Anca Ursachi
committed
) => {
const fragmentId = get(fragment, 'id', '')

Anca Ursachi
committed
const editorialRecommentations = getFragmentEditorialComments(
state,
fragmentId,

Anca Ursachi
committed
)
return (
(canHeViewEditorialComments(state, collection) ||

Tania Fecheta
committed
canEICViewEditorialComments(state, collection) ||
canReviewerViewEditorialComments(state, collection, fragment) ||
canAuthorViewEditorialComments(state, collection, fragmentId)) &&

Anca Ursachi
committed
editorialRecommentations.length > 0
)

Anca Ursachi
committed
}

Tania Fecheta
committed
const cannotViewResponseFromAuthorStatuses = ['reviewersInvited']
export const canViewResponseFromAuthor = (state, collection, fragmentId) => {
const authorResponseToRevisonRequest = getFragmentAuthorResponse(
state,
fragmentId,
)
return (
!isEmpty(authorResponseToRevisonRequest) &&
!cannotViewResponseFromAuthorStatuses.includes(
get(collection, 'status', 'draft'),
)
)
}
export const getUserToken = ({ currentUser }) =>
get(currentUser, 'user.token', '')
export const getHERecommendation = (state, collectionId, fragmentId) => {
const heId = chain(state)
.get('collections', [])
.find(c => c.id === collectionId)
.get('handlingEditor.id', '')
return (
chain(state)
.get(`fragments.${fragmentId}.recommendations`, [])
.find(r => r.rec === 'editorRecommendation' && r.userId === heId)
.value() || {}
const canMakeDecisionStatuses = [
'submitted',
'pendingApproval',
'underReview',
'reviewCompleted',
]

Anca Ursachi
committed
export const canMakeDecision = (state, collection = {}) => {
const status = get(collection, 'status', 'draft')

Alexandru Munteanu
committed
const isEIC = currentUserIs(state, 'adminEiC')
return isEIC && canMakeDecisionStatuses.includes(status)
const collectionReviewerReports = state =>
chain(state)
.get('fragments', {})
.map(r => get(r, 'recommendations', []))
.flatten()
.find(r => r.recommendationType === 'review' && r.submittedOn)
.value()

Anca Ursachi
committed
const cannotHEMakeRecommendationToPublishStatuses = ['heInvited']
export const canHEMakeRecommendationToPublish = (state, collection = {}) => {
const status = get(collection, 'status', 'draft')
return (
!!collectionReviewerReports(state) ||

Anca Ursachi
committed
cannotHEMakeRecommendationToPublishStatuses.includes(status)
)
}
const canHEOnlyRejectStatuses = [
'reviewersInvited',
'underReview',
'revisionRequested',
]
export const canHEOnlyReject = (collection = {}) => {
const { status } = collection
return canHEOnlyRejectStatuses.includes(status)
}
const canEditManuscriptStatuses = ['draft', 'technicalChecks', 'inQA']
export const canEditManuscript = (state, collection = {}, fragment = {}) => {
const isAdmin = currentUserIs(state, 'isAdmin')
if (
!isAdmin ||
get(fragment, 'id', '') !== last(get(collection, 'fragments', []))
)
const status = get(collection, 'status', 'draft')
return canEditManuscriptStatuses.includes(status)
}
const canOverrideTechnicalChecksStatuses = ['technicalChecks', 'inQA']
export const canOverrideTechnicalChecks = (state, collection = {}) => {
const isAdmin = currentUserIs(state, 'isAdmin')
if (!isAdmin) return false
const status = get(collection, 'status', 'draft')
return canOverrideTechnicalChecksStatuses.includes(status)
export const canViewReports = (state, collectionId) => {
const isHE = isHEToManuscript(state, collectionId)
const isEiC = currentUserIs(state, 'adminEiC')
return isHE || isEiC
}
export const canMakeRevision = (state, collection = {}, fragment = {}) => {

Alexandru Munteanu
committed
const currentUserId = get(state, 'currentUser.user.id')
return (
get(fragment, 'revision') &&
get(collection, 'status', 'draft') === 'revisionRequested' &&
get(fragment, 'owners', [])
.map(o => o.id)
.includes(currentUserId)

Alexandru Munteanu
committed
)
}

Tania Fecheta
committed
export const currentUserIsAuthor = (state, fragmentId) => {
const { id: userId } = selectCurrentUser(state)
const authors = get(state, `fragments.${fragmentId}.authors`, [])
return !!authors.find(a => a.id === userId)
Andrei Cioromila
committed
export const getUserPermissions = ({ teams = [] }) =>
teams.map(t => ({
objectId: get(t, 'object.id', ''),
objectType: get(t, 'object.type', ''),
role: get(t, 'teamType.permissions', ''),

Alexandru Munteanu
committed
export const userNotConfirmed = ({ currentUser }) =>
get(currentUser, 'isAuthenticated') &&

Alexandru Munteanu
committed
!currentUserIs({ currentUser }, 'staff') &&
!get(currentUser, 'user.isConfirmed')
export const pendingReviewerInvitation = (state, fragmentId) =>
chain(state)
.get(`fragments.${fragmentId}.invitations`, [])
.find(
inv =>
inv.userId === get(state, 'currentUser.user.id', '') &&
!inv.hasAnswer &&
inv.role === 'reviewer',
)
.value()
export const currentUserIsReviewer = (state, fragmentId) => {
const currentUser = selectCurrentUser(state)
const invitations = get(state, `fragments.${fragmentId}.invitations`, [])
return !!invitations.find(
i =>
i.userId === currentUser.id &&
i.role === 'reviewer' &&
i.hasAnswer &&
i.isAccepted,
)
}
export const getAdminUsers = state =>
chain(state)
.get('users.users')
.map(u => {
let sortValue = -1
if (u.isActive) sortValue = 1
if (!u.isConfirmed) sortValue = 0
return {
user: u,
sortValue,
}
})
.sortBy('sortValue')
.map(s => s.user)
.reverse()
.value()
export const pendingHEInvitation = (state, collectionId) =>
chain(state)
.get('collections', [])
.find(c => c.id === collectionId)
.get('invitations', [])
.find(
i =>
i.userId === get(state, 'currentUser.user.id', '') &&
i.role === 'handlingEditor' &&
!i.hasAnswer,
)
const parseInvitedHE = (handlingEditor, state, collectionId) =>
handlingEditor && {
...handlingEditor,
name: pendingHEInvitation(state, collectionId)
? 'Invited'
: handlingEditor.name,
}
const hideCustomIdStatuses = ['draft', 'technicalChecks']
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'])
.value()

Alexandru Munteanu
committed
export const getInvitationsWithReviewersForFragment = (state, fragmentId) =>
chain(state)
.get(`fragments.${fragmentId}.invitations`, [])
.filter(invitation => invitation.role === 'reviewer')
.map(invitation => ({
...invitation,
person: get(state, 'users.users', []).find(
reviewer => reviewer.id === invitation.userId,
),
}))
.value()
export const canMakeHERecommendation = (state, { collection, statuses }) => {

Tania Fecheta
committed
const validHE = isHEToManuscript(state, get(collection, 'id', ''))
const statusImportance = get(
statuses,
`${get(collection, 'status', 'draft')}.importance`,
1,
)
if (!(statusImportance > 1 && statusImportance < 10)) return false

Alexandru Munteanu
committed
return true
export const getFragmentAuthorResponse = (state, fragmentId) =>
get(state, `fragments.${fragmentId}.responseToReviewers`, {})
// #region Editorial and reviewer recommendations
export const getFragmentRecommendations = (state, fragmentId) =>
get(state, `fragments.${fragmentId}.recommendations`, [])
export const getFragmentReviewerRecommendations = (state, fragmentId) =>
getFragmentRecommendations(state, fragmentId).filter(
r => r.recommendationType === 'review',
)

Anca Ursachi
committed
const getFragmentEditorialComments = (state, fragmentId) =>
getFragmentRecommendations(state, fragmentId).filter(
r => r.recommendationType === 'editorRecommendation',
)
const getOwnRecommendations = (state, fragmentId) =>
chain(state)
.get(`fragments.${fragmentId}.recommendations`, [])
.filter(r => r.userId === get(state, 'currentUser.user.id', ''))
.value()
export const getOwnPendingRecommendation = (state, fragmentId) =>
chain(getOwnRecommendations(state, fragmentId))
.find(
r =>
r.userId === get(state, 'currentUser.user.id', '') &&
!has(r, 'submittedOn'),
)
export const getOwnSubmittedRecommendation = (state, fragmentId) =>
chain(getOwnRecommendations(state, fragmentId))
.find(
r =>
r.userId === get(state, 'currentUser.user.id', '') &&
has(r, 'submittedOn'),
)
.value()
export const canSubmitRevision = (state, fragment = {}) => {
const userId = get(state, 'currentUser.user.id')
const fragmentAuthors = chain(fragment)
.get('authors', [])
.map(a => a.id)
.value()
return get(fragment, 'revision', null) && fragmentAuthors.includes(userId)
export const getVersionOptions = (state, collection = {}) => {
const fragments = get(state, 'fragments', {})
return chain(collection)
.get('fragments', [])
.reduce(
(acc, el) => [
...acc,
{
value: el,
label: `Version ${get(fragments, `${el}.version`)}`,
},
],
[],
)
.reverse()
.value()
}

Alexandru Munteanu
committed
export const canReview = (state, collection = {}, fragment = {}) => {
const fragmentId = get(fragment, 'id', false)
if (!fragmentId) return false
const isReviewer = currentUserIsReviewer(state, fragmentId)
if (!isReviewer) return false
return get(collection, 'status', 'draft') === 'underReview'
}