-
Taniaf26 authored95657e86
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
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
}
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 cannotInviteReviewersStatuses = ['draft', 'rejected', 'published']
export const canInviteReviewers = (state, collection) => {
if (
cannotInviteReviewersStatuses.includes(get(collection, 'status', 'draft'))
)
return false
const user = selectCurrentUser(state)
const isStaff = currentUserIs(state, 'isAdmin')
const { isAccepted, id: heId } = get(collection, 'handlingEditor', {})
return isAccepted && (user.id === heId || isStaff)
}
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', '')
.value()
return (
chain(state)
.get(`fragments.${fragmentId}.recommendations`, [])
.find(r => r.rec === 'editorRecommendation' && r.userId === heId)
.value() || {}
)
}
const canMakeDecisionStatuses = ['submitted', 'pendingApproval']
export const canMakeDecision = (state, collection, fragment = {}) => {
if (fragment.id !== last(get(collection, 'fragments', []))) return false
const status = get(collection, 'status', 'draft')
const isEIC = currentUserIs(state, 'adminEiC')
return isEIC && canMakeDecisionStatuses.includes(status)
}
const canEditManuscriptStatuses = ['draft', 'technicalChecks', 'inQA']
export const canEditManuscript = (state, collection, fragment = {}) => {
const isAdmin = currentUserIs(state, 'isAdmin')
if (!isAdmin || fragment.id !== last(get(collection, 'fragments', [])))
return false
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) => {
const currentUserId = get(state, 'currentUser.user.id')
return (
get(fragment, 'revision') &&
collection.status === 'revisionRequested' &&
fragment.owners.map(o => o.id).includes(currentUserId)
)
}
export const currentUserIsAuthor = (state, id) => {
const permissions = getUserPermissions(state)
return permissions
.filter(f => f.role === 'author')
.map(p => p.objectId)
.includes(id)
}
export const getUserPermissions = ({ currentUser }) =>
get(currentUser, 'user.teams', []).map(t => ({
objectId: t.object.id,
objectType: t.object.type,
role: t.teamType.permissions,
}))
export const userNotConfirmed = ({ currentUser }) =>
get(currentUser, 'isAuthenticated') &&
!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,
)
.value()
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'])
.map(item => parseCollectionDetails(state, item))
.value()
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()
// #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',
)
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'),
)
.value()
export const getOwnSubmittedRecommendation = (state, fragmentId) =>
chain(getOwnRecommendations(state, fragmentId))
.find(
r =>
r.userId === get(state, 'currentUser.user.id', '') &&
has(r, 'submittedOn'),
)
.value()
const canMakeRecommendationStatuses = [
'heAssigned',
'underReview',
'reviewCompleted',
]
export const canMakeRecommendation = (state, collection, fragment = {}) => {
if (fragment.id !== last(get(collection, 'fragments', []))) return false
const isHE = isHEToManuscript(state, get(collection, 'id', ''))
const status = get(collection, 'status', 'draft')
return isHE && canMakeRecommendationStatuses.includes(status)
}
// #endregion