diff --git a/packages/components-faraday/src/components/Dashboard/AssignHEModal.js b/packages/components-faraday/src/components/Dashboard/AssignHEModal.js
index 37ab14727ea3048cc87c3deb39f45cc9e083fe65..813ee6cea52ef51bc2838b9a776b4d83d240a1ad 100644
--- a/packages/components-faraday/src/components/Dashboard/AssignHEModal.js
+++ b/packages/components-faraday/src/components/Dashboard/AssignHEModal.js
@@ -4,11 +4,15 @@ import React from 'react'
 import { get } from 'lodash'
 import { compose } from 'recompose'
 import { connect } from 'react-redux'
-import { th, Icon } from '@pubsweet/ui'
 import { actions } from 'pubsweet-client'
+import { th, Icon, Spinner } from '@pubsweet/ui'
 import styled, { withTheme } from 'styled-components'
 
-import { handlingEditors, assignHandlingEditor } from '../../redux/editors'
+import {
+  selectHandlingEditors,
+  selectFetching,
+  assignHandlingEditor,
+} from '../../redux/editors'
 
 class AssignHEModal extends React.Component {
   state = {
@@ -57,7 +61,7 @@ class AssignHEModal extends React.Component {
 
   render() {
     const { searchInput } = this.state
-    const { editors, hideModal, theme } = this.props
+    const { editors, hideModal, theme, isFetching } = this.props
     const filteredEditors = this.filterEditors(editors)
     return (
       <RootModal>
@@ -66,7 +70,10 @@ class AssignHEModal extends React.Component {
         </CloseIcon>
         <ModalTitle>Assign Handling Editor</ModalTitle>
         <ModalHeader>
-          <span>HANDLING EDITORS</span>
+          <SubtitleRow>
+            <span>HANDLING EDITORS</span>
+            {isFetching && <Spinner size={3} />}
+          </SubtitleRow>
           <SearchInput
             data-test="he-search"
             onChange={this.changeInput}
@@ -86,12 +93,14 @@ class AssignHEModal extends React.Component {
                   <span>{`${firstName} ${lastName}`}</span>
                   <span>{email}</span>
                 </EditorDetails>
-                <AssignButton
-                  data-test={`assign-${email}`}
-                  onClick={this.assignEditor(email)}
-                >
-                  ASSIGN
-                </AssignButton>
+                {!isFetching && (
+                  <AssignButton
+                    data-test={`assign-${email}`}
+                    onClick={this.assignEditor(email)}
+                  >
+                    ASSIGN
+                  </AssignButton>
+                )}
               </SuggestedEditor>
             ))}
           </ModalContent>
@@ -104,7 +113,8 @@ class AssignHEModal extends React.Component {
 export default compose(
   connect(
     state => ({
-      editors: handlingEditors(state),
+      isFetching: selectFetching(state),
+      editors: selectHandlingEditors(state),
     }),
     {
       assignHandlingEditor,
@@ -116,6 +126,18 @@ export default compose(
 )(AssignHEModal)
 
 // #region styled-components
+const SubtitleRow = styled.div`
+  display: flex;
+  justify-content: space-between;
+
+  & span {
+    color: ${th('colorPrimary')};
+    font-size: ${th('fontSizeBase')};
+    font-family: ${th('fontReading')};
+    margin-bottom: ${th('subGridUnit')};
+  }
+`
+
 const CloseIcon = styled.div`
   cursor: pointer;
   position: absolute;
@@ -182,13 +204,6 @@ const ModalHeader = styled.div`
   align-self: stretch;
   display: flex;
   flex-direction: column;
-
-  & span {
-    color: ${th('colorPrimary')};
-    font-size: ${th('fontSizeBase')};
-    font-family: ${th('fontReading')};
-    margin-bottom: ${th('subGridUnit')};
-  }
 `
 
 const SearchInput = styled.input`
diff --git a/packages/components-faraday/src/components/Dashboard/EditorInChiefActions.js b/packages/components-faraday/src/components/Dashboard/EditorInChiefActions.js
index 74d43be7981a96341f71e2527dffd463a76bf39c..6858e83d774b36b4b419de5bb1031b88cea06b2a 100644
--- a/packages/components-faraday/src/components/Dashboard/EditorInChiefActions.js
+++ b/packages/components-faraday/src/components/Dashboard/EditorInChiefActions.js
@@ -12,7 +12,11 @@ import {
 } from 'pubsweet-component-modal/src/components'
 
 import { handleError } from './../utils'
-import { revokeHandlingEditor, assignHandlingEditor } from '../../redux/editors'
+import {
+  revokeHandlingEditor,
+  assignHandlingEditor,
+  selectFetching,
+} from '../../redux/editors'
 
 import HEModal from './AssignHEModal'
 
@@ -49,17 +53,19 @@ const EditorInChiefActions = ({
   )
 }
 
-const CardModal = ({ type, ...rest }) => {
+const CardModal = connect(state => ({
+  isFetching: selectFetching(state),
+}))(({ type, isFetching, ...rest }) => {
   switch (type) {
     case 'confirmation':
-      return <ConfirmationModal {...rest} />
+      return <ConfirmationModal {...rest} isFetching={isFetching} />
     case 'success':
       return <SuccessModal {...rest} />
     case 'he-modal':
     default:
       return <HEModal {...rest} />
   }
-}
+})
 
 export default compose(
   connect(null, {
diff --git a/packages/components-faraday/src/redux/editors.js b/packages/components-faraday/src/redux/editors.js
index 282c89000790bf24a2c090d46240309bbcd8692e..63cb3b837d2b43150e4487bcc0cb65fd60327e9d 100644
--- a/packages/components-faraday/src/redux/editors.js
+++ b/packages/components-faraday/src/redux/editors.js
@@ -1,27 +1,66 @@
-import { get, create, remove, update } from 'pubsweet-client/src/helpers/api'
+import { get } from 'lodash'
+import {
+  get as apiGet,
+  create,
+  remove,
+  update,
+} from 'pubsweet-client/src/helpers/api'
 
+const EDITORS_REQUEST = 'EDITORS_REQUEST'
+const EDITORS_DONE = 'EDITORS_DONE'
 const SET_HANDLING_EDITORS = 'SET_HANDLING_EDITORS'
 
 const setHandlingEditors = editors => ({
   type: SET_HANDLING_EDITORS,
-  editors,
+  payload: { editors },
 })
 
-export const handlingEditors = state => state.editors
+export const selectFetching = state => get(state, 'editors.isFetching')
+export const selectHandlingEditors = state => get(state, 'editors.editors')
+
+const editorsRequest = () => ({ type: EDITORS_REQUEST })
+const editorsDone = () => ({ type: EDITORS_DONE })
 
 export const getHandlingEditors = () => dispatch =>
-  get(`/users?handlingEditor=true`).then(res => {
-    dispatch(setHandlingEditors(res.users))
-  })
+  apiGet(`/users?handlingEditor=true`).then(res =>
+    dispatch(setHandlingEditors(res.users)),
+  )
 
-export const assignHandlingEditor = (email, collectionId) => dispatch =>
-  create(`/collections/${collectionId}/invitations`, {
+export const assignHandlingEditor = (email, collectionId) => dispatch => {
+  dispatch(editorsRequest())
+  return create(`/collections/${collectionId}/invitations`, {
     email,
     role: 'handlingEditor',
-  })
+  }).then(
+    res => {
+      dispatch(editorsDone())
+      return res
+    },
+    err => {
+      dispatch(editorsDone())
+      return err
+    },
+  )
+}
 
-export const revokeHandlingEditor = (invitationId, collectionId) => dispatch =>
-  remove(`/collections/${collectionId}/invitations/${invitationId}`)
+export const revokeHandlingEditor = (
+  invitationId,
+  collectionId,
+) => dispatch => {
+  dispatch(editorsRequest())
+  return remove(
+    `/collections/${collectionId}/invitations/${invitationId}`,
+  ).then(
+    res => {
+      dispatch(editorsDone())
+      return res
+    },
+    err => {
+      dispatch(editorsDone())
+      return err
+    },
+  )
+}
 
 export const handlingEditorDecision = (
   invitationId,
@@ -34,11 +73,28 @@ export const handlingEditorDecision = (
     reason,
   })
 
-const initialState = []
+const initialState = {
+  isFetching: false,
+  editors: [],
+}
+
 export default (state = initialState, action = {}) => {
   switch (action.type) {
+    case EDITORS_REQUEST:
+      return {
+        ...state,
+        isFetching: true,
+      }
+    case EDITORS_DONE:
+      return {
+        ...state,
+        isFetching: false,
+      }
     case SET_HANDLING_EDITORS:
-      return action.editors
+      return {
+        ...state,
+        editors: action.payload.editors,
+      }
     default:
       return state
   }