Skip to content
Snippets Groups Projects
Commit d0d81db5 authored by Alexandru Munteanu's avatar Alexandru Munteanu
Browse files

fix(assign-he): add error handling and fetching

parent 815a4eb9
No related branches found
No related tags found
1 merge request!43Sprint #19
Showing
with 75 additions and 52 deletions
......@@ -2,7 +2,7 @@ import React from 'react'
import styled from 'styled-components'
import { groupBy, get } from 'lodash'
import { th } from '@pubsweet/ui-toolkit'
import { compose, withState, withHandlers, withProps } from 'recompose'
import { compose, withProps, withStateHandlers } from 'recompose'
import {
Row,
......@@ -59,15 +59,12 @@ const AuthorTagList = ({
)}
{withAffiliations && (
<Item ml={1}>
{showAffiliation ? (
<ActionLink icon="minus" onClick={toggleAffiliation(false)}>
Hide Affiliations
</ActionLink>
) : (
<ActionLink icon="plus" onClick={toggleAffiliation(true)}>
Show Affiliations
</ActionLink>
)}
<ActionLink
icon={showAffiliation ? 'minus' : 'plus'}
onClick={toggleAffiliation}
>
{showAffiliation ? 'Hide Affiliations' : 'Show Affiliations'}
</ActionLink>
</Item>
)}
......@@ -85,7 +82,14 @@ const AuthorTagList = ({
</Root>
)
export default compose(
withState('showAffiliation', 'setAffiliation', false),
withStateHandlers(
{ showAffiliation: false },
{
toggleAffiliation: ({ showAffiliation }) => () => ({
showAffiliation: !showAffiliation,
}),
},
),
withProps(({ authors = [], withAffiliations }) => ({
authors: withAffiliations
? get(parseAffiliationGroup(authors), 'list', [])
......@@ -94,10 +98,6 @@ export default compose(
withAffiliations &&
get(parseAffiliationGroup(authors), 'affiliationList', []),
})),
withHandlers({
toggleAffiliation: ({ setAffiliation }) => value => () =>
setAffiliation(value),
}),
)(AuthorTagList)
// #region styles
......
......@@ -6,6 +6,7 @@ import { Text, OpenModal, IconButton, marginHelper } from './'
const PersonInvitation = ({
hasAnswer,
isFetching,
person: { name },
revokeInvitation,
resendInvitation,
......@@ -16,6 +17,7 @@ const PersonInvitation = ({
{!hasAnswer && (
<Fragment>
<OpenModal
isFetching={isFetching}
onConfirm={resendInvitation}
title="Are you sure you want to resend the invitation?"
>
......@@ -31,6 +33,7 @@ const PersonInvitation = ({
</OpenModal>
<OpenModal
confirmText="Remove invite"
isFetching={isFetching}
onConfirm={revokeInvitation}
subtitle="Clicking ‘Remove’ will allow you to invite a different Handling Editor"
title="Remove invitation to Handling Editor?"
......@@ -59,11 +62,11 @@ export default compose(
onResend: id => {},
}),
withHandlers({
revokeInvitation: ({ id, onRevoke }) => () => {
typeof onRevoke === 'function' && onRevoke(id)
revokeInvitation: ({ id, onRevoke }) => props => {
typeof onRevoke === 'function' && onRevoke(id, props)
},
resendInvitation: ({ id, onResend, person: { email } }) => () => {
typeof onResend === 'function' && onResend(email)
resendInvitation: ({ id, onResend, person: { email } }) => props => {
typeof onResend === 'function' && onResend(email, props)
},
}),
setDisplayName('PersonInvitation'),
......
......@@ -22,6 +22,7 @@ import {
} from '../'
const AssignHE = ({
isFetching,
clearSearch,
searchValue,
changeSearch,
......@@ -70,6 +71,7 @@ const AssignHE = ({
</Item>
<Item flex={1}>
<OpenModal
isFetching={isFetching}
onConfirm={inviteHandlingEditor(he)}
subtitle={he.name}
title="Are you sure you want to invite Handling Editor?"
......@@ -118,9 +120,10 @@ export default compose(
withHandlers({
inviteHandlingEditor: ({ inviteHandlingEditor }) => ({
email = '',
}) => () => {
inviteHandlingEditor(email)
},
}) => props =>
inviteHandlingEditor(email, props).catch(() => {
props.setModalError('Oops! Something went wrong.')
}),
}),
setDisplayName('AssignHandlingEditor'),
)(AssignHE)
......
......@@ -5,6 +5,7 @@ const ManuscriptAssignHE = ({
toggle,
assignHE,
expanded,
isFetching,
currentUser,
handlingEditors = [],
}) =>
......@@ -18,6 +19,7 @@ const ManuscriptAssignHE = ({
<AssignHE
handlingEditors={handlingEditors}
inviteHandlingEditor={assignHE}
isFetching={isFetching}
/>
</ContextualBox>
) : null
......
......@@ -96,17 +96,16 @@ export default compose(
}),
),
withHandlers({
resendInvitation: ({ resendInvitation }) => id => {
resendInvitation(id)
},
revokeInvitation: ({ revokeInvitation }) => id => {
revokeInvitation(id)
},
resendInvitation: ({ resendInvitation }) => (email, props) =>
resendInvitation(email, props),
revokeInvitation: ({ revokeInvitation }) => (id, props) =>
revokeInvitation(id, props),
}),
withHandlers({
renderHE: ({
inviteHE,
revokeHE,
isFetching,
heInvitation,
resendInvitation,
revokeInvitation,
......@@ -123,6 +122,7 @@ export default compose(
return (
<PersonInvitation
isFetching={isFetching}
ml={1}
{...pendingInvitation}
onResend={resendInvitation}
......
import React, { Fragment } from 'react'
import styled from 'styled-components'
import { th } from '@pubsweet/ui-toolkit'
import { H2, Button, Spinner, ErrorText } from '@pubsweet/ui'
import { H2, Button, Spinner } from '@pubsweet/ui'
import { compose, setDisplayName, withHandlers } from 'recompose'
import { IconButton, Text } from '../'
......@@ -22,7 +22,11 @@ const MultiAction = ({
<H2>{title}</H2>
{subtitle && <Text secondary>{subtitle}</Text>}
{renderContent()}
{modalError && <ErrorText>{modalError}</ErrorText>}
{modalError && (
<Text error mt={1}>
{modalError}
</Text>
)}
<Buttons isFetching={isFetching}>
{isFetching ? (
<Spinner size={3} />
......@@ -40,17 +44,16 @@ const MultiAction = ({
export default compose(
withHandlers({
onConfirm: ({ onConfirm, hideModal }) => () => {
onConfirm: ({ onConfirm, ...props }) => () => {
if (onConfirm && typeof onConfirm === 'function') {
onConfirm()
onConfirm(props)
}
hideModal()
},
onClose: ({ onCancel, hideModal }) => () => {
onClose: ({ onCancel, ...props }) => () => {
if (onCancel && typeof onCancel === 'function') {
onCancel()
onCancel(props)
}
hideModal()
props.hideModal()
},
renderContent: ({ content }) => () => {
if (!content) return null
......
......@@ -6,7 +6,8 @@ import { MultiAction, SingleActionModal } from './'
const OpenModal = ({ showModal, children }) => children(showModal)
export default compose(
withModal(({ single }) => ({
withModal(({ single, isFetching }) => ({
isFetching,
modalComponent: single ? SingleActionModal : MultiAction,
})),
withHandlers({
......
......@@ -2,6 +2,7 @@
/* eslint-disable react/prefer-stateless-function */
import React from 'react'
import { get } from 'lodash'
import PropTypes from 'prop-types'
import { Icon } from '@pubsweet/ui'
import styled from 'styled-components'
......@@ -21,8 +22,11 @@ const HeaderComponent = ({ icon, label, toggle, expanded, ...props }) => (
)
class Accordion extends React.Component {
state = {
expanded: false,
constructor(props) {
super(props)
this.state = {
expanded: get(props, 'startExpanded', false),
}
}
componentDidUpdate(prevProps) {
......@@ -78,7 +82,6 @@ export default Accordion
// #region styles
const Root = styled.div`
cursor: pointer;
display: flex;
flex-direction: column;
transition: all ${th('transitionDuration')};
......
......@@ -48,7 +48,6 @@ export default ControlledAccordion
// #region styles
const Root = styled.div`
cursor: pointer;
display: flex;
flex-direction: column;
transition: all ${th('transitionDuration')};
......
......@@ -24,6 +24,7 @@ const ManuscriptLayout = ({
collection = {},
fragment = {},
permissions,
isFetching,
}) => (
<Root>
{!isEmpty(collection) && !isEmpty(fragment) ? (
......@@ -45,6 +46,7 @@ const ManuscriptLayout = ({
fragment={fragment}
handlingEditors={handlingEditors}
inviteHE={toggle}
isFetching={isFetching.editorsFetching}
journal={journal}
resendInvitation={assignHE}
revokeInvitation={revokeHE}
......@@ -61,6 +63,7 @@ const ManuscriptLayout = ({
currentUser={currentUser}
expanded={expanded}
handlingEditors={handlingEditors}
isFetching={isFetching.editorsFetching}
toggle={toggle}
/>
</Fragment>
......
......@@ -18,7 +18,6 @@ import {
withProps,
withHandlers,
setDisplayName,
toClass,
} from 'recompose'
import { getSignedUrl } from 'pubsweet-components-faraday/src/redux/files'
import { reviewerDecision } from 'pubsweet-components-faraday/src/redux/reviewers'
......@@ -42,6 +41,7 @@ import ManuscriptLayout from './ManuscriptLayout'
import { parseSearchParams, redirectToError } from './utils'
import {
canAssignHE,
selectFetching,
getHandlingEditors,
assignHandlingEditor,
revokeHandlingEditor,
......@@ -49,7 +49,6 @@ import {
} from '../redux/editors'
export default compose(
toClass,
setDisplayName('ManuscriptPage'),
withJournal,
withRouter,
......@@ -90,6 +89,9 @@ export default compose(
isReviewer: currentUserIsReviewer(state),
canAssignHE: canAssignHE(state, match.params.project),
},
isFetching: {
editorsFetching: selectFetching(state),
},
permissions: {
canMakeRevision: canMakeRevision(state, collection, fragment),
canMakeDecision: canMakeDecision(state, collection, fragment),
......@@ -123,27 +125,31 @@ export default compose(
getCollection,
assignHandlingEditor,
collection: { id: collectionId },
}) => email => {
}) => (email, modalProps) =>
assignHandlingEditor({
email,
collectionId,
}).then(() => {
getCollection({ id: collectionId })
getFragment(collection, fragment)
})
},
.then(() => {
getCollection({ id: collectionId })
getFragment(collection, fragment)
modalProps.hideModal()
})
.catch(() => modalProps.setModalError('Oops! Something went wrong.')),
revokeHE: ({
getCollection,
revokeHandlingEditor,
collection: { id: collectionId },
}) => invitationId => {
}) => (invitationId, modalProps) =>
revokeHandlingEditor({
invitationId,
collectionId,
}).then(() => {
getCollection({ id: collectionId })
})
},
.then(() => {
getCollection({ id: collectionId })
modalProps.hideModal()
})
.catch(() => modalProps.setModalError('Oops! Something went wrong.')),
}),
lifecycle({
componentDidMount() {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment