import { get, has, last, chain } from 'lodash' import { selectCurrentUser } from 'xpub-selectors' export const isHEToManuscript = (state, collectionId) => { 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) => { 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'))) return false const user = selectCurrentUser(state) const isAdmin = currentUserIs(state, 'isAdmin') const { isAccepted, id: heId } = get(collection, 'handlingEditor', {}) return isAccepted && (user.id === heId || isAdmin) } const cannotViewReviewersDetails = [ 'draft', 'technicalChecks', 'submitted', 'heInvited', ] export const canViewReviewersDetails = (state, collection = {}) => { if (cannotViewReviewersDetails.includes(get(collection, 'status', 'draft'))) { return false } return canViewReports(state, collection.id) } const canHeViewEditorialCommentsStatuses = [ 'revisionRequested', 'rejected', 'accepted', 'inQA', ] export const canHeViewEditorialComments = (state, collection = {}) => { const isHE = isHEToManuscript(state, collection.id) const status = get(collection, 'status', 'draft') return isHE && canHeViewEditorialCommentsStatuses.includes(status) } const canEICViewEditorialCommentsStatuses = ['rejected', 'accepted', 'inQA'] export const canEICViewEditorialComments = (state, collection = {}) => { const isEIC = currentUserIs(state, 'adminEiC') const status = get(collection, 'status', 'draft') return isEIC && canEICViewEditorialCommentsStatuses.includes(status) } export const canViewEditorialComments = ( state, collection = {}, fragmentId, ) => { const editorialRecommentations = getFragmentEditorialComments( state, fragmentId, ) return ( (canHeViewEditorialComments(state, collection) || canEICViewEditorialComments(state, collection)) && editorialRecommentations.length > 0 ) } 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() 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`, []) export const getFragmentReviewerRecommendations = (state, fragmentId) => getFragmentRecommendations(state, fragmentId).filter( r => r.recommendationType === 'review', ) 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'), ) .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