diff --git a/packages/component-invite/src/controllers/assignCollectionRole.js b/packages/component-invite/src/controllers/assignCollectionRole.js
index e810e941147c908584f9b5ec5daaf72aa9c2ad5a..cd855f6221ce59106910c090011d0eb1148f0882 100644
--- a/packages/component-invite/src/controllers/assignCollectionRole.js
+++ b/packages/component-invite/src/controllers/assignCollectionRole.js
@@ -18,14 +18,6 @@ module.exports = async (
   url,
   resend,
 ) => {
-  if (reqUser.admin) {
-    logger.error(`admin tried to invite a ${role} to a collection`)
-
-    return res.status(403).json({
-      error: `admin cannot invite an ${role} to a collection`,
-    })
-  }
-
   if (!configRoles.collection.includes(role)) {
     logger.error(`invitation has been attempted with invalid role: ${role}`)
     return res
@@ -33,11 +25,11 @@ module.exports = async (
       .json({ error: `Role ${role} cannot be set on collections` })
   }
 
-  if (!reqUser.editorInChief && reqUser.teams === undefined) {
+  if (!reqUser.editorInChief && reqUser.teams === undefined && !reqUser.admin) {
     return res
       .status(403)
       .json({ error: `User ${reqUser.username} is not part of any teams` })
-  } else if (reqUser.editorInChief === false) {
+  } else if (reqUser.editorInChief === false && reqUser.admin === false) {
     const matchingTeams = await teamHelper.getMatchingTeams(
       reqUser.teams,
       models.Team,
@@ -67,24 +59,13 @@ module.exports = async (
   try {
     let user = await models.User.findByEmail(email)
 
-    let team = await teamHelper.getTeamByGroupAndCollection(
+    const team = await teamHelper.setupManuscriptTeam(
+      models,
+      user,
       collectionId,
       role,
-      models.Team,
     )
-    if (team === undefined) {
-      team = await teamHelper.setupManuscriptTeam(
-        models,
-        user,
-        collectionId,
-        role,
-      )
-      user = await models.User.findByEmail(email)
-    } else {
-      user.teams = user.teams || []
-      user.teams.push(team.id)
-      user = await user.save()
-    }
+    user = await models.User.findByEmail(email)
 
     if (user.invitations === undefined) {
       user = await inviteHelper.setupInvitation(
diff --git a/packages/component-invite/src/helpers/Collection.js b/packages/component-invite/src/helpers/Collection.js
index d11dc8b7011c1fe50c5b9b7aae4d288a16eae402..da805647f2381691090bc339e83badde97c35073 100644
--- a/packages/component-invite/src/helpers/Collection.js
+++ b/packages/component-invite/src/helpers/Collection.js
@@ -19,4 +19,11 @@ module.exports = {
     collection.assignedPeople.push(assignedPerson)
     await collection.save()
   },
+  removeAssignedPeople: async (collection, email) => {
+    const assignedPeople = collection.assignedPeople.filter(
+      person => person.email !== email,
+    )
+    collection.assignedPeople = assignedPeople
+    await collection.save()
+  },
 }
diff --git a/packages/component-invite/src/helpers/Team.js b/packages/component-invite/src/helpers/Team.js
index 39bbca5152ab564cbc4e5ac53de18953a962de4a..9a9319e25d942c33b65c0a13053a1e0868871989 100644
--- a/packages/component-invite/src/helpers/Team.js
+++ b/packages/component-invite/src/helpers/Team.js
@@ -87,7 +87,7 @@ const setupManuscriptTeam = async (models, user, collectionId, role) => {
     team.members.push(user.id)
 
     try {
-      team = await team.updateProperties(team)
+      // team = await team.updateProperties(team)
       team = await team.save()
       user.teams.push(team.id)
       await user.save()
diff --git a/packages/component-invite/src/routes/deleteInvitation.js b/packages/component-invite/src/routes/deleteInvitation.js
index d8c77d72d2d0717ae32a44291a97f2e33aec5ca2..9062262829d0c6ff875bde722f6540feedb84758 100644
--- a/packages/component-invite/src/routes/deleteInvitation.js
+++ b/packages/component-invite/src/routes/deleteInvitation.js
@@ -4,6 +4,7 @@ const config = require('config')
 const inviteHelper = require('../helpers/Invitation')
 const mailService = require('pubsweet-component-mail-service')
 const logger = require('@pubsweet/logger')
+const collectionHelper = require('../helpers/Collection')
 
 const configRoles = config.get('roles')
 module.exports = models => async (req, res) => {
@@ -26,7 +27,7 @@ module.exports = models => async (req, res) => {
 
   const { collectionId, userId } = req.params
   try {
-    await models.Collection.find(collectionId)
+    const collection = await models.Collection.find(collectionId)
     let user = await models.User.find(userId)
     const team = await teamHelper.getTeamByGroupAndCollection(
       collectionId,
@@ -43,13 +44,14 @@ module.exports = models => async (req, res) => {
     await inviteHelper.revokeInvitation(user, collectionId, role)
     user = await models.User.find(userId)
     await teamHelper.removeTeamMember(team.id, userId, models.Team)
+    await collectionHelper.removeAssignedPeople(collection, user.email)
     try {
       await mailService.setupRevokeInvitationEmail(
         user.email,
         'revoke-handling-editor',
       )
 
-      return res.status(204).json()
+      return res.status(200).json({})
     } catch (e) {
       logger.error(e.message)
       return res.status(500).json({ error: 'Email could not be sent.' })
diff --git a/packages/component-invite/src/routes/postHandleInvitation.js b/packages/component-invite/src/routes/postHandleInvitation.js
index 85fd4151dcd1e929cc6f95b7cafd4435f958c482..5be9650861cc50aed18fffd6ed959da624936792 100644
--- a/packages/component-invite/src/routes/postHandleInvitation.js
+++ b/packages/component-invite/src/routes/postHandleInvitation.js
@@ -1,6 +1,7 @@
 const logger = require('@pubsweet/logger')
 const helpers = require('../helpers/helpers')
 const teamHelper = require('../helpers/Team')
+const mailService = require('pubsweet-component-mail-service')
 
 module.exports = models => async (req, res) => {
   const { type, accept } = req.body
@@ -11,7 +12,7 @@ module.exports = models => async (req, res) => {
     return
   }
 
-  const user = await models.User.find(req.user)
+  let user = await models.User.find(req.user)
   if (!user.invitations) {
     res.status(400).json({ error: 'The user has no invitation' })
     logger.error('The request user does not have any invitation')
@@ -20,13 +21,13 @@ module.exports = models => async (req, res) => {
   const { collectionId } = req.params
 
   try {
-    await models.Collection.find(collectionId)
-    const filteredInvitations = user.invitations.filter(
+    const collection = await models.Collection.find(collectionId)
+    const matchingInvitations = user.invitations.filter(
       invitation =>
         invitation.collectionId === collectionId && invitation.type === type,
     )
 
-    if (filteredInvitations.length === 0) {
+    if (matchingInvitations.length === 0) {
       res.status(400).json({
         error: `Request data does not match any user invitation`,
       })
@@ -36,20 +37,39 @@ module.exports = models => async (req, res) => {
       return
     }
 
-    const matchingInvitation = filteredInvitations[0]
+    const matchingInvitation = matchingInvitations[0]
     matchingInvitation.hasAnswer = true
     if (accept === true) {
       matchingInvitation.isAccepted = true
-      await user.save()
+      try {
+        const users = await models.User.all()
+
+        const eic = users.find(user => user.editorInChief === true)
+        await mailService.setupHandlingEditorAgreedEmail(
+          eic.email,
+          user,
+          'handling-editor-agreed',
+          `${req.protocol}://${req.get('host')}`,
+          collection.customId,
+        )
+      } catch (e) {
+        logger.error(e)
+        return res.status(500).json({ error: 'Mail could not be sent.' })
+      }
     } else {
+      matchingInvitation.isAccepted = false
       await teamHelper.removeTeamMember(
         matchingInvitation.teamId,
         user.id,
         models.Team,
       )
+      const { reason } = req.body
+      if (reason !== undefined) {
+        matchingInvitation.reason = reason
+      }
     }
-
-    res.status(204).json()
+    user = await user.save()
+    res.status(200).json(user)
     return
   } catch (e) {
     const notFoundError = await helpers.handleNotFoundError(e, 'collection')
diff --git a/packages/component-invite/src/tests/deleteInvitation.test.js b/packages/component-invite/src/tests/deleteInvitation.test.js
index 30e994b12abf5365195570f6d48892815709e6f7..e20a0773af872f4105b4aa171588124a2415ca1a 100644
--- a/packages/component-invite/src/tests/deleteInvitation.test.js
+++ b/packages/component-invite/src/tests/deleteInvitation.test.js
@@ -27,7 +27,7 @@ describe('Delete Invitation route handler', () => {
     const res = httpMocks.createResponse()
     const initialSize = handlingEditor.invitations.length
     await require(deleteInvitationPath)(models)(req, res)
-    expect(res.statusCode).toBe(204)
+    expect(res.statusCode).toBe(200)
     expect(heTeam.members).not.toContain(handlingEditor.id)
     expect(handlingEditor.invitations).toHaveLength(initialSize - 1)
   })
diff --git a/packages/component-invite/src/tests/fixtures/collections.js b/packages/component-invite/src/tests/fixtures/collections.js
index 210aa318228faea749cc790593ec29bb8a5088d4..09b4b6eb797d61b15e529b247b5e76161736859c 100644
--- a/packages/component-invite/src/tests/fixtures/collections.js
+++ b/packages/component-invite/src/tests/fixtures/collections.js
@@ -1,4 +1,5 @@
 const Chance = require('chance')
+const { handlingEditor } = require('./userData')
 
 const chance = new Chance()
 module.exports = {
@@ -9,6 +10,16 @@ module.exports = {
     fragments: [],
     owners: [],
     save: jest.fn(),
+    assignedPeople: [
+      {
+        id: handlingEditor.id,
+        name: `${handlingEditor.firstName} ${handlingEditor.lastName}`,
+        role: 'handlingEditor',
+        email: handlingEditor.email,
+        hasAnswer: false,
+        isAccepted: false,
+      },
+    ],
   },
   noTeamCollection: {
     id: chance.guid(),
diff --git a/packages/component-invite/src/tests/fixtures/userData.js b/packages/component-invite/src/tests/fixtures/userData.js
new file mode 100644
index 0000000000000000000000000000000000000000..a4a2327911e9969621d34315b0b4b0ad9176fdbf
--- /dev/null
+++ b/packages/component-invite/src/tests/fixtures/userData.js
@@ -0,0 +1,12 @@
+const Chance = require('chance')
+
+const chance = new Chance()
+
+module.exports = {
+  handlingEditor: {
+    id: chance.guid(),
+    email: chance.email(),
+    firstName: chance.first(),
+    lastName: chance.last(),
+  },
+}
diff --git a/packages/component-invite/src/tests/fixtures/users.js b/packages/component-invite/src/tests/fixtures/users.js
index 53e00485ec4413381309488acb126c2ccb4b2dfe..c1542563fd1b62c510a94705386cb06be944c341 100644
--- a/packages/component-invite/src/tests/fixtures/users.js
+++ b/packages/component-invite/src/tests/fixtures/users.js
@@ -1,5 +1,6 @@
 const { standardCollection } = require('./collections')
 const { heTeamID, reviewerTeamID } = require('./teamIDs')
+const { handlingEditor } = require('./userData')
 
 const users = {
   admin: {
@@ -29,12 +30,12 @@ const users = {
   handlingEditor: {
     type: 'user',
     username: 'handling',
-    email: 'handling@example.com',
+    email: handlingEditor.email,
     password: 'test',
     admin: false,
-    id: 'handling123',
-    firstName: 'Handling',
-    lastName: 'Editor',
+    id: handlingEditor.id,
+    firstName: handlingEditor.firstName,
+    lastName: handlingEditor.lastName,
     invitations: [
       {
         type: 'handlingEditor',
diff --git a/packages/component-invite/src/tests/helpers/Model.js b/packages/component-invite/src/tests/helpers/Model.js
index 7ff2e90b59f218c2e37967701d0ea8b70d78c73b..420cc704e1cfb10eaeb4e346648c192054f7b0dc 100644
--- a/packages/component-invite/src/tests/helpers/Model.js
+++ b/packages/component-invite/src/tests/helpers/Model.js
@@ -16,9 +16,8 @@ const build = () => {
     Team: {},
   }
   UserMock.find = jest.fn(id => findMock(id, 'users'))
-
   UserMock.findByEmail = jest.fn(email => findByEmailMock(email))
-
+  UserMock.all = jest.fn(() => Object.values(fixtures.users))
   TeamMock.find = jest.fn(id => findMock(id, 'teams'))
   TeamMock.updateProperties = jest.fn(team =>
     updatePropertiesMock(team, 'teams'),
diff --git a/packages/component-invite/src/tests/postHandleInvitation.test.js b/packages/component-invite/src/tests/postHandleInvitation.test.js
index ffa1215761d1b0a017f09a71f939dacb2d2a1c3c..68bec23c38908eec9f2bedf7755b730ea66b96d0 100644
--- a/packages/component-invite/src/tests/postHandleInvitation.test.js
+++ b/packages/component-invite/src/tests/postHandleInvitation.test.js
@@ -8,6 +8,7 @@ const Model = require('./helpers/Model')
 const models = Model.build()
 jest.mock('pubsweet-component-mail-service', () => ({
   setupAssignEmail: jest.fn(),
+  setupHandlingEditorAgreedEmail: jest.fn(),
 }))
 
 const notFoundError = new Error()
@@ -36,7 +37,7 @@ describe('Post handle invitation route handler', () => {
     req.params.collectionId = standardCollection.id
     const res = httpMocks.createResponse()
     await require(postInvitationPath)(models)(req, res)
-    expect(res.statusCode).toBe(204)
+    expect(res.statusCode).toBe(200)
     expect(handlingEditor.invitations[0].hasAnswer).toBeTruthy()
     expect(handlingEditor.invitations[0].isAccepted).toBeTruthy()
   })
@@ -53,7 +54,7 @@ describe('Post handle invitation route handler', () => {
     const res = httpMocks.createResponse()
     await require(postInvitationPath)(models)(req, res)
 
-    expect(res.statusCode).toBe(204)
+    expect(res.statusCode).toBe(200)
     expect(invitedHandlingEditor.invitations[0].hasAnswer).toBeTruthy()
     expect(invitedHandlingEditor.invitations[0].isAccepted).toBeFalsy()
   })
diff --git a/packages/component-invite/src/tests/postInvite.test.js b/packages/component-invite/src/tests/postInvite.test.js
index e350f5c33c485da065b6d4e029e9aa59fd06ad3c..fce9d62a45e5e41f4ccbfd1b7622ab6c9f3e61bf 100644
--- a/packages/component-invite/src/tests/postInvite.test.js
+++ b/packages/component-invite/src/tests/postInvite.test.js
@@ -39,6 +39,7 @@ const {
   invitedHandlingEditor,
 } = fixtures.users
 const { standardCollection } = fixtures.collections
+const { heTeam } = fixtures.teams
 const postInvitePath = '../routes/postInvite'
 describe('Post invite route handler', () => {
   it('should return success when the admin invites a global role', async () => {
@@ -55,36 +56,6 @@ describe('Post invite route handler', () => {
     expect(data.email).toEqual(body.email)
     expect(data.admin).toEqual(body.admin)
   })
-  it('should return an error when the admin invites a user on a collection', async () => {
-    const req = httpMocks.createRequest({
-      body,
-    })
-    req.user = admin.id
-    req.params.collectionId = '123'
-    const res = httpMocks.createResponse()
-    await require(postInvitePath)(models)(req, res)
-    expect(res.statusCode).toBe(403)
-    const data = JSON.parse(res._getData())
-    expect(data.error).toEqual(
-      `admin cannot invite an ${body.role} to a collection`,
-    )
-  })
-  it('should return an error when the admin invites a reviewer', async () => {
-    body.role = 'reviewer'
-    body.admin = false
-    const req = httpMocks.createRequest({
-      body,
-    })
-    req.user = admin.id
-    const res = httpMocks.createResponse()
-    await require(postInvitePath)(models)(req, res)
-    expect(res.statusCode).toBe(403)
-    const data = JSON.parse(res._getData())
-    expect(data.error).toEqual(
-      `admin tried to invite an invalid role: ${body.role}`,
-    )
-    body.role = globalRoles[random(0, globalRoles.length - 1)]
-  })
   it('should return an error params are missing', async () => {
     delete body.email
     const req = httpMocks.createRequest({
@@ -171,6 +142,7 @@ describe('Post invite route handler', () => {
       body,
     })
     req.user = editorInChief.id
+    const initialSize = standardCollection.assignedPeople.length
     req.params.collectionId = standardCollection.id
     const res = httpMocks.createResponse()
     await require(postInvitePath)(models)(req, res)
@@ -179,7 +151,11 @@ describe('Post invite route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.email).toEqual(body.email)
     expect(data.invitations[0].collectionId).toEqual(req.params.collectionId)
-    expect(standardCollection.assignedPeople).toHaveLength(1)
+    expect(standardCollection.assignedPeople.length).toBeGreaterThan(
+      initialSize,
+    )
+    expect(heTeam.members).toContain(author.id)
+    expect(author.teams).toContain(heTeam.id)
   })
   it('should return success when the handlingEditor invites a reviewer with a collection', async () => {
     const body = {
diff --git a/packages/component-mail-service/src/Mail.js b/packages/component-mail-service/src/Mail.js
index 11d1f29f20684c90abf2c8e8f0df3e2f3baeb2fc..f7f573102cce617530cb6732e5ae1c1b06aa6448 100644
--- a/packages/component-mail-service/src/Mail.js
+++ b/packages/component-mail-service/src/Mail.js
@@ -83,6 +83,27 @@ module.exports = {
     }
     return Email.send(mailData)
   },
+  setupHandlingEditorAgreedEmail: async (
+    toEmail,
+    user,
+    emailType,
+    url,
+    collectionId,
+  ) => {
+    const { htmlBody, textBody } = getEmailBody(emailType, {
+      url,
+      name: `${user.firstName} ${user.lastName}`,
+      collectionId,
+    })
+    const mailData = {
+      from: config.get('mailer.from'),
+      to: toEmail,
+      subject: 'Handling Editor Agreed',
+      text: textBody,
+      html: htmlBody,
+    }
+    return Email.send(mailData)
+  },
 }
 
 const getEmailBody = (emailType, replacements) => {
diff --git a/packages/component-mail-service/src/templates/handling-editor-agreed.html b/packages/component-mail-service/src/templates/handling-editor-agreed.html
new file mode 100644
index 0000000000000000000000000000000000000000..3f24b1f4216f3d8554def6a0bc63fc80fb4afa36
--- /dev/null
+++ b/packages/component-mail-service/src/templates/handling-editor-agreed.html
@@ -0,0 +1,232 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html data-editor-version="2" class="sg-campaigns" xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" />
+  <!--[if !mso]><!-->
+  <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+  <!--<![endif]-->
+  <!--[if (gte mso 9)|(IE)]>
+    <xml>
+    <o:OfficeDocumentSettings>
+    <o:AllowPNG/>
+    <o:PixelsPerInch>96</o:PixelsPerInch>
+    </o:OfficeDocumentSettings>
+    </xml>
+    <![endif]-->
+  <!--[if (gte mso 9)|(IE)]>
+    <style type="text/css">
+      body {width: 600px;margin: 0 auto;}
+      table {border-collapse: collapse;}
+      table, td {mso-table-lspace: 0pt;mso-table-rspace: 0pt;}
+      img {-ms-interpolation-mode: bicubic;}
+    </style>
+    <![endif]-->
+
+  <style type="text/css">
+    body,
+    p,
+    div {
+      font-family: helvetica, arial, sans-serif;
+      font-size: 14px;
+    }
+
+    body {
+      color: #626262;
+    }
+
+    body a {
+      color: #0D78F2;
+      text-decoration: none;
+    }
+
+    p {
+      margin: 0;
+      padding: 0;
+    }
+
+    table.wrapper {
+      width: 100% !important;
+      table-layout: fixed;
+      -webkit-font-smoothing: antialiased;
+      -webkit-text-size-adjust: 100%;
+      -moz-text-size-adjust: 100%;
+      -ms-text-size-adjust: 100%;
+    }
+
+    img.max-width {
+      max-width: 100% !important;
+    }
+
+    .column.of-2 {
+      width: 50%;
+    }
+
+    .column.of-3 {
+      width: 33.333%;
+    }
+
+    .column.of-4 {
+      width: 25%;
+    }
+
+    @media screen and (max-width:480px) {
+      .preheader .rightColumnContent,
+      .footer .rightColumnContent {
+        text-align: left !important;
+      }
+      .preheader .rightColumnContent div,
+      .preheader .rightColumnContent span,
+      .footer .rightColumnContent div,
+      .footer .rightColumnContent span {
+        text-align: left !important;
+      }
+      .preheader .rightColumnContent,
+      .preheader .leftColumnContent {
+        font-size: 80% !important;
+        padding: 5px 0;
+      }
+      table.wrapper-mobile {
+        width: 100% !important;
+        table-layout: fixed;
+      }
+      img.max-width {
+        height: auto !important;
+        max-width: 480px !important;
+      }
+      a.bulletproof-button {
+        display: block !important;
+        width: auto !important;
+        font-size: 80%;
+        padding-left: 0 !important;
+        padding-right: 0 !important;
+      }
+      .columns {
+        width: 100% !important;
+      }
+      .column {
+        display: block !important;
+        width: 100% !important;
+        padding-left: 0 !important;
+        padding-right: 0 !important;
+        margin-left: 0 !important;
+        margin-right: 0 !important;
+      }
+    }
+  </style>
+  <!--user entered Head Start-->
+
+  <!--End Head user entered-->
+</head>
+
+<body>
+  <center class="wrapper" data-link-color="#0D78F2" data-body-style="font-size: 14px; font-family: helvetica,arial,sans-serif; color: #626262; background-color: #F4F4F4;">
+    <div class="webkit">
+      <table cellpadding="0" cellspacing="0" border="0" width="100%" class="wrapper" bgcolor="#F4F4F4">
+        <tr>
+          <td valign="top" bgcolor="#F4F4F4" width="100%">
+            <table width="100%" role="content-container" class="outer" align="center" cellpadding="0" cellspacing="0" border="0">
+              <tr>
+                <td width="100%">
+                  <table width="100%" cellpadding="0" cellspacing="0" border="0">
+                    <tr>
+                      <td>
+                        <!--[if mso]>
+                          <center>
+                          <table><tr><td width="600">
+                          <![endif]-->
+                        <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width:600px;" align="center">
+                          <tr>
+                            <td role="modules-container" style="padding: 0px 0px 0px 0px; color: #626262; text-align: left;" bgcolor="#F4F4F4" width="100%"
+                              align="left">
+
+                              <table class="module preheader preheader-hide" role="module" data-type="preheader" border="0" cellpadding="0" cellspacing="0"
+                                width="100%" style="display: none !important; mso-hide: all; visibility: hidden; opacity: 0; color: transparent; height: 0; width: 0;">
+                                <tr>
+                                  <td role="module-content">
+                                    <p>handling editor agreed</p>
+                                  </td>
+                                </tr>
+                              </table>
+
+                              <table class="wrapper" role="module" data-type="image" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;">
+                                <tr>
+                                  <td style="font-size:6px;line-height:10px;padding:20px 0px 20px 0px;" valign="top" align="center">
+                                    <img class="max-width" border="0" style="display:block;color:#000000;text-decoration:none;font-family:Helvetica, arial, sans-serif;font-size:16px;max-width:10% !important;width:10%;height:auto !important;"
+                                      src="https://marketing-image-production.s3.amazonaws.com/uploads/bb39b20cf15e52c1c0933676e25f2b2402737c6560b8098c204ad6932b84eb2058804376dbc4db138c7a21dcaed9325bde36185648afac5bc97e3d73d4e12718.png"
+                                      alt="" width="60">
+                                  </td>
+                                </tr>
+                              </table>
+
+                              <table class="module" role="module" data-type="text" border="0" cellpadding="0" cellspacing="0" width="100%" style="table-layout: fixed;">
+                                <tr>
+                                  <td style="padding:30px 23px 0px 23px;background-color:#ffffff;" height="100%" valign="top" bgcolor="#ffffff">
+                                    <h1 style="text-align: center;">{{ name }} has agreed to be Handling Editor on manuscript {{ collectionId }}</h1>
+
+                                    <div style="text-align: center;">Please click on the link below to access your dashboard.</div>
+
+                                    <div style="text-align: center;">&nbsp;</div>
+
+                                    <div style="text-align: center;">&nbsp;</div>
+
+                                  </td>
+                                </tr>
+                              </table>
+                              <table border="0" cellPadding="0" cellSpacing="0" class="module" data-role="module-button" data-type="button" role="module"
+                                style="table-layout:fixed" width="100%">
+                                <tbody>
+                                  <tr>
+                                    <td align="center" bgcolor="#FFFFFF" class="outer-td" style="padding:0px 0px 30px 0px;background-color:#FFFFFF">
+                                      <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile"
+                                        style="text-align:center">
+                                        <tbody>
+                                          <tr>
+                                            <td align="center" bgcolor="#0d78f2" class="inner-td" style="border-radius:6px;font-size:16px;text-align:center;background-color:inherit">
+                                              <a href="{{ url }}" style="background-color:#0d78f2;border:1px solid #333333;border-color:#0d78f2;border-radius:0px;border-width:1px;color:#ffffff;display:inline-block;font-family:arial,helvetica,sans-serif;font-size:16px;font-weight:normal;letter-spacing:0px;line-height:16px;padding:12px 18px 12px 18px;text-align:center;text-decoration:none"
+                                                target="_blank">VIEW DASHBOARD</a>
+                                            </td>
+                                          </tr>
+                                        </tbody>
+                                      </table>
+                                    </td>
+                                  </tr>
+                                </tbody>
+                              </table>
+                              <div data-role="module-unsubscribe" class="module unsubscribe-css__unsubscribe___2CDlR" role="module"
+                                data-type="unsubscribe" style="color:#444444;font-size:12px;line-height:20px;padding:16px 16px 16px 16px;text-align:center">
+                                <div class="Unsubscribe--addressLine">
+                                  <p class="Unsubscribe--senderName" style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">Hindawi Publishing Corporation</p>
+                                  <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">
+                                    <span class="Unsubscribe--senderAddress">315 Madison Ave, Third Floor, Suite 3070</span>,
+                                    <span class="Unsubscribe--senderCity">NEW YORK</span>,
+                                    <span class="Unsubscribe--senderState">NY</span>
+                                    <span class="Unsubscribe--senderZip">10017</span>
+                                  </p>
+                                </div>
+                                <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">
+                                  <a class="Unsubscribe--unsubscribeLink" href="[Unsubscribe]">Unsubscribe</a>
+                                </p>
+                              </div>
+                            </td>
+                          </tr>
+                        </table>
+                        <!--[if mso]>
+                          </td></tr></table>
+                          </center>
+                          <![endif]-->
+                      </td>
+                    </tr>
+                  </table>
+                </td>
+              </tr>
+            </table>
+          </td>
+        </tr>
+      </table>
+    </div>
+  </center>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/packages/component-mail-service/src/templates/handling-editor-agreed.txt b/packages/component-mail-service/src/templates/handling-editor-agreed.txt
new file mode 100644
index 0000000000000000000000000000000000000000..550581b4489de9dca0da675eb4c3da2db498d815
--- /dev/null
+++ b/packages/component-mail-service/src/templates/handling-editor-agreed.txt
@@ -0,0 +1,6 @@
+{{ name }} has agreed to be Handling Editor on manuscript {{ collectionId }}
+Please click on the link below to access your dashboard
+{{ url }} VIEW DASHBOARD
+Hindawi Publishing Corporation
+315 Madison Ave, Third Floor, Suite 307
+New York, NY 10017
\ No newline at end of file
diff --git a/packages/component-modal/src/components/ConfirmationModal.js b/packages/component-modal/src/components/ConfirmationModal.js
index ddc1d30f39d44b94f2a287690cc768e33f804241..7d1b6664396f7396d6ecfa8cb17d19464f743660 100644
--- a/packages/component-modal/src/components/ConfirmationModal.js
+++ b/packages/component-modal/src/components/ConfirmationModal.js
@@ -1,5 +1,5 @@
 import React from 'react'
-import { Icon, Button } from '@pubsweet/ui'
+import { Icon, Button, th } from '@pubsweet/ui'
 import styled, { css, withTheme } from 'styled-components'
 
 const ConfirmationModal = ({
@@ -11,6 +11,7 @@ const ConfirmationModal = ({
   cancelText = 'Cancel',
   hideModal,
   theme,
+  modalError,
 }) => (
   <Root>
     <CloseIcon data-test="icon-modal-hide" onClick={hideModal}>
@@ -19,13 +20,18 @@ const ConfirmationModal = ({
     {title && <Title dangerouslySetInnerHTML={{ __html: title }} />}
     {subtitle && <Subtitle dangerouslySetInnerHTML={{ __html: subtitle }} />}
     {content && <Content dangerouslySetInnerHTML={{ __html: content }} />}
+
+    {modalError && <ErrorMessage>{modalError}</ErrorMessage>}
+
     <ButtonsContainer>
       <Button data-test="button-modal-hide" onClick={hideModal}>
         {cancelText}
       </Button>
-      <Button data-test="button-modal-confirm" onClick={onConfirm} primary>
-        {confirmText}
-      </Button>
+      {onConfirm && (
+        <Button data-test="button-modal-confirm" onClick={onConfirm} primary>
+          {confirmText}
+        </Button>
+      )}
     </ButtonsContainer>
   </Root>
 )
@@ -34,51 +40,59 @@ export default withTheme(ConfirmationModal)
 
 // #region styled-components
 const defaultText = css`
-  color: ${({ theme }) => theme.colorText};
-  font-family: ${({ theme }) => theme.fontReading};
-  font-size: ${({ theme }) => theme.fontSizeBaseSmall};
+  color: ${th('colorText')};
+  font-family: ${th('fontReading')};
+  font-size: ${th('fontSizeBaseSmall')};
 `
 
 const Root = styled.div`
-  background-color: ${({ theme }) => theme.backgroundColor};
-  padding: 50px 32px 32px 32px;
-  border: ${({ theme }) => theme.borderDefault};
+  background-color: ${th('backgroundColor')};
+  border: ${th('borderDefault')};
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  max-height: calc(${th('gridUnit')} * 20);
+  padding: calc(${th('gridUnit')} * 2);
   position: relative;
-  width: 600px;
-  max-height: 500px;
   overflow-y: scroll;
+  width: calc(${th('gridUnit')} * 25);
 `
 
 const Title = styled.div`
   ${defaultText};
-  font-size: ${({ theme }) => theme.fontSizeBase};
+  font-size: ${th('fontSizeHeading5')};
+  margin-bottom: ${th('gridUnit')};
   text-align: center;
-  margin-bottom: 20px;
 `
 
 const Subtitle = styled.div`
   ${defaultText};
-  font-weight: bold;
-  line-height: 1.57;
-  margin-bottom: 15px;
+  margin-bottom: calc(${th('subGridUnit')} * 6);
   text-align: center;
 `
 
 const Content = styled.div`
   ${defaultText};
-  line-height: 1.57;
-  margin-top: 10px;
+  margin-top: calc(${th('subGridUnit')} * 2);
   text-align: left;
 `
 const ButtonsContainer = styled.div`
   display: flex;
   justify-content: space-evenly;
-  margin: 30px auto 0;
+  margin: ${th('gridUnit')} auto 0;
+  width: 100%;
 `
 const CloseIcon = styled.div`
   cursor: pointer;
   position: absolute;
-  top: 5px;
-  right: 5px;
+  top: ${th('subGridUnit')};
+  right: ${th('subGridUnit')};
 `
+
+const ErrorMessage = styled.div`
+  color: ${th('colorError')};
+  margin: ${th('subGridUnit')};
+  text-align: center;
+`
+
 // #endregion
diff --git a/packages/component-modal/src/components/Modal.js b/packages/component-modal/src/components/Modal.js
index 4015782fef9d60d7ecde1e2d19efeb83628036d5..b16774202a19629f580e8fe050200b9c1fa2ba8c 100644
--- a/packages/component-modal/src/components/Modal.js
+++ b/packages/component-modal/src/components/Modal.js
@@ -40,5 +40,5 @@ const ModalRoot = styled.div`
   justify-content: center;
   background-color: ${({ overlayColor }) =>
     overlayColor || 'rgba(0, 0, 0, 0.8)'};
-  /* z-index: ${({ theme }) => theme.modalIndex}; */
+  z-index: ${({ theme }) => theme.modalIndex};
 `
diff --git a/packages/component-modal/src/components/SuccessModal.js b/packages/component-modal/src/components/SuccessModal.js
new file mode 100644
index 0000000000000000000000000000000000000000..676ba603e6cd5312967d6d6a9efa548fb85c1dc4
--- /dev/null
+++ b/packages/component-modal/src/components/SuccessModal.js
@@ -0,0 +1,51 @@
+import React from 'react'
+import { Button, th } from '@pubsweet/ui'
+import styled, { css, withTheme } from 'styled-components'
+
+const SuccessModal = ({ title, confirmText = 'OK', hideModal, theme }) => (
+  <Root>
+    {title && <Title dangerouslySetInnerHTML={{ __html: title }} />}
+    <ButtonsContainer>
+      <Button data-test="button-modal-confirm" onClick={hideModal} primary>
+        {confirmText}
+      </Button>
+    </ButtonsContainer>
+  </Root>
+)
+
+export default withTheme(SuccessModal)
+
+// #region styled-components
+const defaultText = css`
+  color: ${th('colorText')};
+  font-family: ${th('fontReading')};
+  font-size: ${th('fontSizeBaseSmall')};
+`
+
+const Root = styled.div`
+  background-color: ${th('backgroundColor')};
+  border: ${th('borderDefault')};
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  max-height: calc(${th('gridUnit')} * 20);
+  padding: calc(${th('gridUnit')} * 2);
+  position: relative;
+  overflow-y: scroll;
+  width: calc(${th('gridUnit')} * 25);
+`
+
+const Title = styled.div`
+  ${defaultText};
+  font-size: ${th('fontSizeHeading5')};
+  margin-bottom: ${th('gridUnit')};
+  text-align: center;
+`
+
+const ButtonsContainer = styled.div`
+  display: flex;
+  justify-content: space-evenly;
+  margin: ${th('gridUnit')} auto 0;
+  width: 100%;
+`
+// #endregion
diff --git a/packages/component-modal/src/components/index.js b/packages/component-modal/src/components/index.js
index 22f1e90fca99f0f6b8c1d66c3d91272730d9078d..724e8d8878f79f7754077b39dda7a1105632eebb 100644
--- a/packages/component-modal/src/components/index.js
+++ b/packages/component-modal/src/components/index.js
@@ -1,2 +1,3 @@
 export { default as withModal } from './withModal'
+export { default as SuccessModal } from './SuccessModal'
 export { default as ConfirmationModal } from './ConfirmationModal'
diff --git a/packages/component-modal/src/components/withModal.js b/packages/component-modal/src/components/withModal.js
index 1d5c786c7b6026264442f30a9ab52ecb59c0a7fa..84a7b51fd1a957730e963cde62d78db750082b87 100644
--- a/packages/component-modal/src/components/withModal.js
+++ b/packages/component-modal/src/components/withModal.js
@@ -3,16 +3,18 @@ import { omit } from 'lodash'
 import { connect } from 'react-redux'
 
 import Modal from './Modal'
-import { showModal, hideModal } from '../redux/modal'
+import { showModal, hideModal, setModalError } from '../redux/modal'
 
 const mapState = state => ({
   modalsVisibility: omit(state.modal, 'props'),
   modalProps: state.modal.props,
+  modalError: state.modal.error,
 })
 
 const mapDispatch = modalKey => (dispatch, propss) => ({
   hideModal: () => dispatch(hideModal()),
   showModal: (modalProps = {}) => dispatch(showModal(modalKey, modalProps)),
+  setModalError: errorMessage => dispatch(setModalError(errorMessage)),
 })
 
 const withModal = ({
@@ -21,13 +23,14 @@ const withModal = ({
   overlayColor,
 }) => WrappedComponent =>
   connect(mapState, mapDispatch(modalKey))(
-    ({ modalsVisibility, modalProps, hideModal, ...rest }) => (
+    ({ modalsVisibility, modalProps, modalError, hideModal, ...rest }) => (
       <React.Fragment>
         {modalsVisibility[modalKey] && (
           <Modal
             {...modalProps}
             component={Component}
             hideModal={hideModal}
+            modalError={modalError}
             overlayColor={overlayColor}
           />
         )}
diff --git a/packages/component-modal/src/redux/modal.js b/packages/component-modal/src/redux/modal.js
index cba9f707d60c3001c123abad56ced39270e1821e..06d5702bfafc89ef6732a95773a3504490eac45a 100644
--- a/packages/component-modal/src/redux/modal.js
+++ b/packages/component-modal/src/redux/modal.js
@@ -1,8 +1,10 @@
 const initialState = {
+  error: null,
   props: {},
 }
 
 const SHOW_MODAL = 'modal/SHOW_MODAL'
+const SET_MODAL_ERROR = 'modal/SET_MODAL_ERROR'
 const HIDE_MODAL = 'modal/HIDE_MODAL'
 
 export const showModal = (modalKey, props = {}) => ({
@@ -13,6 +15,13 @@ export const showModal = (modalKey, props = {}) => ({
   },
 })
 
+export const setModalError = error => ({
+  type: SET_MODAL_ERROR,
+  payload: {
+    error,
+  },
+})
+
 export const hideModal = () => ({
   type: HIDE_MODAL,
 })
@@ -24,8 +33,14 @@ export default (state = initialState, action = {}) => {
     case SHOW_MODAL:
       return {
         [action.payload.modalKey]: true,
+        error: null,
         props: action.payload.props,
       }
+    case SET_MODAL_ERROR:
+      return {
+        ...state,
+        error: action.payload.error,
+      }
     case HIDE_MODAL:
       return initialState
     default:
diff --git a/packages/component-wizard/src/components/WizardFormStep.js b/packages/component-wizard/src/components/WizardFormStep.js
index 3e8c0a020bc413beaf229c50ba36cabe3359d536..b50d4d3e408bc85af1d024e385aa8aa350fa8486 100644
--- a/packages/component-wizard/src/components/WizardFormStep.js
+++ b/packages/component-wizard/src/components/WizardFormStep.js
@@ -8,7 +8,6 @@ import { reduxForm, formValueSelector, SubmissionError } from 'redux-form'
 import WizardStep from './WizardStep'
 import { autosaveRequest } from '../redux/autosave'
 
-let cachedVersion = ''
 const wizardSelector = formValueSelector('wizard')
 
 const onChange = (
@@ -20,13 +19,11 @@ const onChange = (
   const prev = pick(prevValues, formSectionKeys)
   const newValues = pick(values, formSectionKeys)
   // TODO: fix this if it sucks down the road
-  if (!isEqual(prev, newValues) && cachedVersion !== version.rev) {
-    cachedVersion = version.rev
+  if (!isEqual(prev, newValues)) {
     dispatch(autosaveRequest())
     dispatch(
       actions.updateFragment(project, {
         id: version.id,
-        rev: version.rev,
         ...newValues,
       }),
     )
@@ -44,7 +41,6 @@ const submitManuscript = (
   dispatch(
     actions.updateFragment(project, {
       id: version.id,
-      rev: version.rev,
       submitted: new Date(),
       ...values,
     }),
@@ -53,7 +49,6 @@ const submitManuscript = (
       dispatch(
         actions.updateCollection({
           id: project.id,
-          rev: project.rev,
           status: 'submitted',
         }),
       ),
diff --git a/packages/components-faraday/src/components/Admin/AdminUsers.js b/packages/components-faraday/src/components/Admin/AdminUsers.js
index 4185c022c7a6c704fdacb35f20039c4d29690789..f81860a85cb51e8d8f51686a3ba3eb69192af4ad 100644
--- a/packages/components-faraday/src/components/Admin/AdminUsers.js
+++ b/packages/components-faraday/src/components/Admin/AdminUsers.js
@@ -24,6 +24,7 @@ const TableRow = ({
   affiliation,
   isConfirmed,
   editorInChief,
+  handlingEditor,
   admin,
   roleOptions,
 }) => (
@@ -36,8 +37,8 @@ const TableRow = ({
     <td>{affiliation}</td>
     <td>
       <Role>{`Author${isEqual(editorInChief, true) ? ', Editor in Chief' : ''}${
-        isEqual(admin, true) ? ', Admin' : ''
-      }`}</Role>
+        isEqual(handlingEditor, true) ? ', Handling Editor' : ''
+      }${isEqual(admin, true) ? ', Admin' : ''}`}</Role>
     </td>
     <td>
       <Tag>{isConfirmed ? 'Confirmed' : 'Invited'}</Tag>
diff --git a/packages/components-faraday/src/components/Admin/EditUserForm.js b/packages/components-faraday/src/components/Admin/EditUserForm.js
index ecbef0d9aff2bc5ad41ab4706a3da6cf313e5d95..afbe740a1a0b933dddbab781d39cb952753cb560 100644
--- a/packages/components-faraday/src/components/Admin/EditUserForm.js
+++ b/packages/components-faraday/src/components/Admin/EditUserForm.js
@@ -69,6 +69,17 @@ const EditUserForm = ({ roles, journal, user, error }) => (
           )}
           name="editorInChief"
         />
+        <ValidatedField
+          component={input => (
+            <Checkbox
+              checked={input.value}
+              type="checkbox"
+              {...input}
+              label="Handling Editor"
+            />
+          )}
+          name="handlingEditor"
+        />
         <ValidatedField
           component={input => (
             <Checkbox
diff --git a/packages/components-faraday/src/components/Admin/utils.js b/packages/components-faraday/src/components/Admin/utils.js
index 18d68678757f353480e592d49f094e0e98129b11..eb9b5cec9493be46809ba4bddafabf961eba5db9 100644
--- a/packages/components-faraday/src/components/Admin/utils.js
+++ b/packages/components-faraday/src/components/Admin/utils.js
@@ -24,6 +24,7 @@ export const parseUpdateUser = values => {
     'roles',
     'rev',
     'editorInChief',
+    'handlingEditor',
   ]
 
   return pick(values, valuesToSave)
diff --git a/packages/components-faraday/src/components/Dashboard/AssignEditor.js b/packages/components-faraday/src/components/Dashboard/AssignEditor.js
deleted file mode 100644
index 4fca2fe52927497f5f0d595dcc4c7a5ea37b77c0..0000000000000000000000000000000000000000
--- a/packages/components-faraday/src/components/Dashboard/AssignEditor.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react'
-import styled, { css } from 'styled-components'
-import { Button, th } from '@pubsweet/ui'
-import { compose, withHandlers } from 'recompose'
-import { withModal } from 'pubsweet-component-modal/src/components'
-
-import HEModal from './AssignHEModal'
-
-const AssignEditor = ({ assign }) => (
-  <ActionButtons onClick={assign}>ASSIGN</ActionButtons>
-)
-
-export default compose(
-  withModal({
-    modalKey: 'assignHEmodal',
-    modalComponent: HEModal,
-  }),
-  withHandlers({
-    assign: ({ showModal, collectionId }) => () => {
-      showModal({
-        collectionId,
-      })
-    },
-  }),
-)(AssignEditor)
-
-// #region styled-components
-const defaultText = css`
-  color: ${th('colorText')};
-  font-family: ${th('fontReading')};
-  font-size: ${th('fontSizeBaseSmall')};
-`
-
-const ActionButtons = styled(Button)`
-  ${defaultText};
-  align-items: center;
-  background-color: ${th('colorPrimary')};
-  color: ${th('colorTextReverse')};
-  text-align: center;
-  height: calc(${th('subGridUnit')}*5);
-`
-// #endregion
diff --git a/packages/components-faraday/src/components/Dashboard/AssignHEModal.js b/packages/components-faraday/src/components/Dashboard/AssignHEModal.js
index 86e6d1438c6334a18508077cd7bbcf56b1ff03f9..592a672532c297eee54a7935536514435bc2f17f 100644
--- a/packages/components-faraday/src/components/Dashboard/AssignHEModal.js
+++ b/packages/components-faraday/src/components/Dashboard/AssignHEModal.js
@@ -1,10 +1,12 @@
 /* eslint react/prefer-stateless-function: 0 */
 
 import React from 'react'
-import { th } from '@pubsweet/ui'
+import { get } from 'lodash'
 import { compose } from 'recompose'
 import { connect } from 'react-redux'
-import styled from 'styled-components'
+import { th, Icon } from '@pubsweet/ui'
+import { actions } from 'pubsweet-client'
+import styled, { withTheme } from 'styled-components'
 
 import { handlingEditors, assignHandlingEditor } from '../../redux/editors'
 
@@ -27,22 +29,54 @@ class AssignHEModal extends React.Component {
   }
 
   assignEditor = email => () => {
-    const { assignHandlingEditor, collectionId, hideModal } = this.props
-    assignHandlingEditor(email, collectionId).then(hideModal)
+    const {
+      assignHandlingEditor,
+      collectionId,
+      showModal,
+      hideModal,
+      setModalError,
+      updateCollection,
+      getCollections,
+    } = this.props
+    assignHandlingEditor(email, collectionId).then(
+      () => {
+        updateCollection({
+          id: collectionId,
+          status: 'he-invited',
+        }).then(() => {
+          getCollections()
+          hideModal()
+          showModal({
+            type: 'confirmation',
+            title: 'Assignation Sent',
+            cancelText: 'OK',
+          })
+        })
+      },
+      e => {
+        setModalError(
+          get(JSON.parse(e.response), 'error') || 'Oops! Something went wrong!',
+        )
+      },
+    )
   }
 
   render() {
     const { searchInput } = this.state
-    const { editors } = this.props
+    const { editors, hideModal, theme } = this.props
     const filteredEditors = this.filterEditors(editors)
     return (
       <RootModal>
-        <button onClick={this.props.hideModal}>CLOSE</button>
+        <CloseIcon data-test="icon-modal-hide" onClick={hideModal}>
+          <Icon color={theme.colorPrimary}>x</Icon>
+        </CloseIcon>
         <ModalTitle>Assign Handling Editor</ModalTitle>
         <ModalHeader>
           <span>HANDLING EDITORS</span>
           <SearchInput
+            data-test="he-search"
             onChange={this.changeInput}
+            placeholder="Search by name or email"
             type="text"
             value={searchInput}
           />
@@ -58,7 +92,10 @@ class AssignHEModal extends React.Component {
                   <span>{`${firstName} ${lastName}`}</span>
                   <span>{email}</span>
                 </EditorDetails>
-                <AssignButton onClick={this.assignEditor(email)}>
+                <AssignButton
+                  data-test={`assign-${email}`}
+                  onClick={this.assignEditor(email)}
+                >
                   ASSIGN
                 </AssignButton>
               </SuggestedEditor>
@@ -75,11 +112,23 @@ export default compose(
     state => ({
       editors: handlingEditors(state),
     }),
-    { assignHandlingEditor },
+    {
+      assignHandlingEditor,
+      updateCollection: actions.updateCollection,
+      getCollections: actions.getCollections,
+    },
   ),
+  withTheme,
 )(AssignHEModal)
 
 // #region styled-components
+const CloseIcon = styled.div`
+  cursor: pointer;
+  position: absolute;
+  top: 5px;
+  right: 5px;
+`
+
 const EditorDetails = styled.div`
   display: flex;
   flex-direction: column;
@@ -100,13 +149,16 @@ const SuggestedEditor = styled.div`
 
 const AssignButton = styled.button`
   align-items: center;
-  color: ${th('colorTextReverse')};
   background-color: ${th('colorPrimary')};
+  cursor: pointer;
+  color: ${th('colorTextReverse')};
   display: flex;
   justify-content: center;
+  font-size: ${th('fontSizeBaseSmall')};
+  font-family: ${th('fontReading')};
   height: ${th('gridUnit')};
-  width: calc(${th('gridUnit')} * 4);
   opacity: 0;
+  width: calc(${th('gridUnit')} * 4);
 
   ${SuggestedEditor}:hover & {
     opacity: 1;
@@ -121,6 +173,7 @@ const RootModal = styled.div`
   justify-content: flex-start;
   height: calc(${th('gridUnit')} * 18);
   padding: calc(${th('subGridUnit')} * 8) calc(${th('subGridUnit')} * 6);
+  position: relative;
   width: calc(${th('gridUnit')} * 24);
 `
 
@@ -139,6 +192,7 @@ const ModalHeader = styled.div`
   & span {
     color: ${th('colorPrimary')};
     font-size: ${th('fontSizeBase')};
+    font-family: ${th('fontReading')};
     margin-bottom: ${th('subGridUnit')};
   }
 `
@@ -147,6 +201,11 @@ const SearchInput = styled.input`
   border: 4px solid gray;
   height: calc(${th('subGridUnit')} * 5);
   padding: ${th('subGridUnit')};
+
+  &:focus,
+  &:active {
+    outline: none;
+  }
 `
 
 const ScrollContainer = styled.div`
diff --git a/packages/components-faraday/src/components/Dashboard/DashboardCard.js b/packages/components-faraday/src/components/Dashboard/DashboardCard.js
index 9401acd55ba87aac3e577ecc444865d973eb433d..5a0087a40ee4f16bf8489a2172ef8b5625de19c6 100644
--- a/packages/components-faraday/src/components/Dashboard/DashboardCard.js
+++ b/packages/components-faraday/src/components/Dashboard/DashboardCard.js
@@ -1,12 +1,16 @@
 import React from 'react'
 import { get } from 'lodash'
 import PropTypes from 'prop-types'
-import { compose, getContext } from 'recompose'
 import { Button, Icon, th } from '@pubsweet/ui'
 import styled, { css, withTheme } from 'styled-components'
+import { compose, getContext, withHandlers } from 'recompose'
+import {
+  withModal,
+  ConfirmationModal,
+} from 'pubsweet-component-modal/src/components'
 
 import ZipFiles from './ZipFiles'
-import { parseVersion, parseJournalIssue } from './utils'
+import { parseVersion, parseJournalIssue, mapStatusToLabel } from './utils'
 import HandlingEditorActions from './HandlingEditorActions'
 
 const DashboardCard = ({
@@ -16,7 +20,7 @@ const DashboardCard = ({
   version,
   showAbstractModal,
   journal,
-  cancelSubmission,
+  showConfirmationModal,
   theme,
   ...rest
 }) => {
@@ -66,11 +70,11 @@ const DashboardCard = ({
           </RightDetails>
         </Top>
         <Bottom>
-          <LeftDetails flex="2">
-            <Status>{status}</Status>
+          <LeftDetails flex="3">
+            <Status>{mapStatusToLabel(status)}</Status>
             <DateField>{submitted || ''}</DateField>
           </LeftDetails>
-          <RightDetails flex="5">
+          <RightDetails flex="4">
             <ManuscriptType title={manuscriptMeta}>
               {manuscriptMeta}
             </ManuscriptType>
@@ -89,9 +93,9 @@ const DashboardCard = ({
             ) : (
               <Details
                 data-test="button-cancel-submission"
-                onClick={cancelSubmission}
+                onClick={showConfirmationModal}
               >
-                Cancel submission
+                Delete
               </Details>
             )}
           </RightDetails>
@@ -139,9 +143,36 @@ const DashboardCard = ({
   ) : null
 }
 
-export default compose(getContext({ journal: PropTypes.object }), withTheme)(
-  DashboardCard,
-)
+export default compose(
+  getContext({ journal: PropTypes.object }),
+  withTheme,
+  withModal({
+    modalKey: 'cancelManuscript',
+    modalComponent: ConfirmationModal,
+  }),
+  withHandlers({
+    showConfirmationModal: ({
+      deleteProject,
+      showModal,
+      hideModal,
+      setModalError,
+      project,
+    }) => () => {
+      showModal({
+        title: 'Are you sure you want to delete this submission?',
+        confirmText: 'Delete',
+        onConfirm: () => {
+          deleteProject(project).then(hideModal, e => {
+            setModalError(
+              get(JSON.parse(e.response), 'error') ||
+                'Oops! Something went wrong!',
+            )
+          })
+        },
+      })
+    },
+  }),
+)(DashboardCard)
 
 // #region styled-components
 const defaultText = css`
diff --git a/packages/components-faraday/src/components/Dashboard/DashboardPage.js b/packages/components-faraday/src/components/Dashboard/DashboardPage.js
index 1e59c3c6684e7284307aeb139d0d7ee0f780971f..00a2fc968658af3bf5384f74a7f91a209b95ec43 100644
--- a/packages/components-faraday/src/components/Dashboard/DashboardPage.js
+++ b/packages/components-faraday/src/components/Dashboard/DashboardPage.js
@@ -10,16 +10,11 @@ import { newestFirst, selectCurrentUser } from 'xpub-selectors'
 import { createDraftSubmission } from 'pubsweet-component-wizard/src/redux/conversion'
 
 import Dashboard from './Dashboard'
-import { getHandlingEditors } from '../../redux/editors'
 import withFilters from './withFilters'
+import { getHandlingEditors } from '../../redux/editors'
 
 export default compose(
-  ConnectPage(() => [
-    actions.getCollections(),
-    actions.getTeams(),
-    actions.getUsers(),
-    getHandlingEditors(),
-  ]),
+  ConnectPage(() => [actions.getCollections()]),
   connect(
     state => {
       const { collections, conversion } = state
@@ -50,6 +45,12 @@ export default compose(
       createDraftSubmission: () => dispatch(createDraftSubmission(history)),
     }),
   ),
+  ConnectPage(
+    ({ currentUser }) =>
+      get(currentUser, 'admin') || get(currentUser, 'editorInChief')
+        ? [getHandlingEditors()]
+        : [],
+  ),
   withRouter,
   withJournal,
   withFilters({
diff --git a/packages/components-faraday/src/components/Dashboard/HandlingEditorActions.js b/packages/components-faraday/src/components/Dashboard/HandlingEditorActions.js
index c9a60e77aee3acdcdf1bd9ebbd390a808121c61b..33c9eb65b2cc952e6bb6a79b766f6a5793fd6382 100644
--- a/packages/components-faraday/src/components/Dashboard/HandlingEditorActions.js
+++ b/packages/components-faraday/src/components/Dashboard/HandlingEditorActions.js
@@ -1,11 +1,27 @@
 import React from 'react'
 import { get, head } from 'lodash'
-import { Icon, th } from '@pubsweet/ui'
-import styled, { css, withTheme } from 'styled-components'
+import { connect } from 'react-redux'
+import { actions } from 'pubsweet-client'
+import { Icon, Button, th } from '@pubsweet/ui'
 import { compose, withHandlers } from 'recompose'
-import AssignEditor from './AssignEditor'
+import styled, { css, withTheme } from 'styled-components'
+import {
+  withModal,
+  ConfirmationModal,
+  SuccessModal,
+} from 'pubsweet-component-modal/src/components'
+
+import { revokeHandlingEditor, assignHandlingEditor } from '../../redux/editors'
 
-const HandlingEditorActions = ({ project, theme, getHandlingEditor }) => {
+import HEModal from './AssignHEModal'
+
+const HandlingEditorActions = ({
+  project,
+  theme,
+  getHandlingEditor,
+  showConfirmModal,
+  showHEModal,
+}) => {
   const handlingEditor = getHandlingEditor()
   return (
     <Root>
@@ -15,21 +31,51 @@ const HandlingEditorActions = ({ project, theme, getHandlingEditor }) => {
             <HEName>{get(handlingEditor, 'name')}</HEName>
             {!handlingEditor.hasAnswer && (
               <HEActions>
-                <Icon color={theme.colorPrimary}>refresh-cw</Icon>
-                <Icon color={theme.colorPrimary}>x-circle</Icon>
+                <div onClick={showConfirmModal('resend')}>
+                  <Icon color={theme.colorPrimary}>refresh-cw</Icon>
+                </div>
+                <div onClick={showConfirmModal('cancel')}>
+                  <Icon color={theme.colorPrimary}>x-circle</Icon>
+                </div>
               </HEActions>
             )}
           </HEActions>
         ) : (
-          <AssignEditor collectionId={project.id} />
+          <AssignButton onClick={showHEModal}>Assign</AssignButton>
         )}
       </HEActions>
     </Root>
   )
 }
 
+const CardModal = ({ type, ...rest }) => {
+  switch (type) {
+    case 'confirmation':
+      return <ConfirmationModal {...rest} />
+    case 'success':
+      return <SuccessModal {...rest} />
+    case 'he-modal':
+    default:
+      return <HEModal {...rest} />
+  }
+}
+
+const handleError = fn => e => {
+  fn(get(JSON.parse(e.response), 'error') || 'Oops! Something went wrong!')
+}
+
 export default compose(
+  connect(null, {
+    revokeHandlingEditor,
+    assignHandlingEditor,
+    updateCollection: actions.updateCollection,
+    getCollections: actions.getCollections,
+  }),
   withTheme,
+  withModal({
+    modalKey: 'confirmHE',
+    modalComponent: CardModal,
+  }),
   withHandlers({
     getHandlingEditor: ({ project }) => () => {
       const assignedEditors = get(project, 'assignedPeople')
@@ -44,6 +90,64 @@ export default compose(
       return null
     },
   }),
+  withHandlers({
+    showConfirmModal: ({
+      showModal,
+      project,
+      revokeHandlingEditor,
+      assignHandlingEditor,
+      getHandlingEditor,
+      hideModal,
+      setModalError,
+      updateCollection,
+      getCollections,
+    }) => actionType => {
+      const editor = getHandlingEditor()
+      const resendConfig = {
+        title: 'Resend Invitation?',
+        subtitle: '',
+        confirmText: 'Resend',
+        onConfirm: () =>
+          assignHandlingEditor(get(editor, 'email'), project.id, true).then(
+            () => {
+              hideModal()
+              showModal({
+                type: 'success',
+                title: 'Invite resent',
+              })
+            },
+            handleError(setModalError),
+          ),
+      }
+      const revokeConfig = {
+        title: 'Revoke Handling Editor Assignation?',
+        subtitle: `Clicking 'Revoke' will allow you to invite a different person.`,
+        confirmText: 'Revoke invite',
+        onConfirm: () =>
+          revokeHandlingEditor(get(editor, 'id'), project.id).then(() => {
+            updateCollection({
+              id: project.id,
+              status: 'submitted',
+            }).then(() => {
+              getCollections()
+              hideModal()
+              showModal({
+                type: 'success',
+                title: 'Handling Editor Assignation Revoked',
+              })
+            })
+          }, handleError(setModalError)),
+      }
+
+      return () => {
+        const cfg = actionType === 'resend' ? resendConfig : revokeConfig
+        showModal({ ...cfg, type: 'confirmation' })
+      }
+    },
+    showHEModal: ({ showModal, project }) => () => {
+      showModal({ type: 'he-modal', collectionId: project.id, showModal })
+    },
+  }),
 )(HandlingEditorActions)
 
 // #region styled-components
@@ -75,4 +179,13 @@ const HEActions = styled.div`
     }
   }
 `
+
+const AssignButton = styled(Button)`
+  ${defaultText};
+  align-items: center;
+  background-color: ${th('colorPrimary')};
+  color: ${th('colorTextReverse')};
+  text-align: center;
+  height: calc(${th('subGridUnit')}*5);
+`
 // #endregion
diff --git a/packages/components-faraday/src/components/Dashboard/utils.js b/packages/components-faraday/src/components/Dashboard/utils.js
index de53b9268bf0cd284e2186f97ffdb0abdc974788..c3604010acb437e90aaeb9528b7826d8419b5586 100644
--- a/packages/components-faraday/src/components/Dashboard/utils.js
+++ b/packages/components-faraday/src/components/Dashboard/utils.js
@@ -74,3 +74,12 @@ export const parseVersion = version => ({
 
 export const parseJournalIssue = (journal, metadata) =>
   journal.issueTypes.find(t => t.value === get(metadata, 'issue'))
+
+export const mapStatusToLabel = status => {
+  switch (status) {
+    case 'he-invited':
+      return 'Handling Editor Invited'
+    default:
+      return 'Submitted'
+  }
+}
diff --git a/packages/components-faraday/src/redux/editors.js b/packages/components-faraday/src/redux/editors.js
index 77fee22d73b2f328a8e718a8a028d30b74ad3955..4203a858219f6261cb37f05a39e2109c64a7f90b 100644
--- a/packages/components-faraday/src/redux/editors.js
+++ b/packages/components-faraday/src/redux/editors.js
@@ -25,7 +25,7 @@ export const assignHandlingEditor = (
     resend,
   })
 
-export const revokeHandlingEditor = (collectionId, userId) => dispatch =>
+export const revokeHandlingEditor = (userId, collectionId) => dispatch =>
   remove(`/collections/${collectionId}/users/${userId}?role=handlingEditor`)
 
 const initialState = []