diff --git a/assets/js/actions/guest.js b/assets/js/actions/guest.js
index 2e50efcac..a26317d47 100644
--- a/assets/js/actions/guest.js
+++ b/assets/js/actions/guest.js
@@ -4,9 +4,10 @@ export const SET_CODE = "SET_CODE"
export const GENERATE_CODE = "GENERATE_CODE"
export const CLEAR = "CLEAR"
-export const changeEmail = (email) => ({
+export const changeEmail = (email, collaborators = []) => ({
type: CHANGE_EMAIL,
email,
+ collaborators,
})
export const changeLevel = (level) => ({
diff --git a/assets/js/components/collaborators/CollaboratorIndex.jsx b/assets/js/components/collaborators/CollaboratorIndex.jsx
index 9dcfb5bfe..4ffa7d6af 100644
--- a/assets/js/components/collaborators/CollaboratorIndex.jsx
+++ b/assets/js/components/collaborators/CollaboratorIndex.jsx
@@ -24,16 +24,6 @@ class CollaboratorIndex extends Component {
$("#addCollaborator").modal("open")
}
- loadCollaboratorToEdit(event, collaborator) {
- event.preventDefault()
- if (collaborator.invited) {
- this.props.guestActions.changeEmail(collaborator.email)
- this.props.guestActions.changeLevel(collaborator.role)
- this.props.guestActions.setCode(collaborator.code)
- $("#addCollaborator").modal("open")
- }
- }
-
levelChanged(e, collaborator) {
const { projectId, inviteActions, actions, t } = this.props
const level = e.target.value
@@ -143,9 +133,8 @@ class CollaboratorIndex extends Component {
modalId="addCollaborator"
modalText={t("The access of project collaborators will be managed through roles")}
header={t("Invite collaborators")}
- confirmationText={t("Accept")}
- onConfirm={(event) => event.preventDefault()}
style={{ maxWidth: "800px" }}
+ collaborators={collaborators}
/>
diff --git a/assets/js/components/collaborators/InviteModal.jsx b/assets/js/components/collaborators/InviteModal.jsx
index 8ee7d2d4b..fe2eed667 100644
--- a/assets/js/components/collaborators/InviteModal.jsx
+++ b/assets/js/components/collaborators/InviteModal.jsx
@@ -32,7 +32,7 @@ export class InviteModal extends Component {
}
emailOnChange(e) {
- this.props.guestActions.changeEmail(e.target.value)
+ this.props.guestActions.changeEmail(e.target.value, this.props.collaborators)
}
emailOnBlur(e) {
@@ -42,7 +42,7 @@ export class InviteModal extends Component {
return
}
if (newEmail != config.user) {
- Promise.resolve(this.props.guestActions.changeEmail(newEmail)).then(() => {
+ Promise.resolve(this.props.guestActions.changeEmail(newEmail, this.props.collaborators)).then(() => {
Promise.resolve(
this.props.actions.getInviteByEmailAndProject(projectId, guest.data.email)
).then((dbGuest) => {
@@ -97,10 +97,10 @@ export class InviteModal extends Component {
)
- const validEmail = guest.data.email && !guest.errors.email
+ const emailError = this.getEmailError(guest);
const sendButton =
- guest.data.code && validEmail ? (
+ guest.data.code && !emailError ? (
- {!validEmail ? (
+ {emailError ? (
- {t("Please enter a valid email")}
+ {t(emailError)}
) : (
@@ -189,6 +189,23 @@ export class InviteModal extends Component {
)
}
+
+ getEmailError(guest) {
+ let errorCode = "invalid-email";
+ if (guest.data.email) {
+ errorCode = guest.errors.email
+ }
+
+ switch (errorCode) {
+ case null:
+ return null;
+ case "existing-email":
+ return "Email already in project";
+ case "invalid-email":
+ default:
+ return "Please enter a valid email";
+ }
+ }
}
InviteModal.propTypes = {
@@ -202,12 +219,11 @@ InviteModal.propTypes = {
linkText: PropTypes.string,
header: PropTypes.string.isRequired,
modalText: PropTypes.string.isRequired,
- confirmationText: PropTypes.string.isRequired,
- onConfirm: PropTypes.func.isRequired,
modalId: PropTypes.string.isRequired,
projectId: PropTypes.number,
style: PropTypes.object,
userLevel: PropTypes.string,
+ collaborators: PropTypes.array,
}
const mapDispatchToProps = (dispatch) => ({
@@ -220,6 +236,7 @@ const mapStateToProps = (state) => ({
projectId: state.project.data.id,
userLevel: state.project.data.level,
guest: state.guest,
+ collaborators: state.collaborators.items,
})
export default translate()(connect(mapStateToProps, mapDispatchToProps)(InviteModal))
diff --git a/assets/js/reducers/guest.js b/assets/js/reducers/guest.js
index 718f5f563..e4eef8a04 100644
--- a/assets/js/reducers/guest.js
+++ b/assets/js/reducers/guest.js
@@ -34,6 +34,16 @@ const validEmail = (email) => {
}
const changeEmail = (state, action) => {
+ const { email, collaborators } = action;
+ let emailError = null;
+ if (!validEmail(email)) {
+ emailError = "invalid-email";
+ } else {
+ const collaborator = collaborators.find((c) => c.email === email);
+ if (collaborator) {
+ emailError = "existing-email";
+ }
+ }
return {
...state,
data: {
@@ -41,8 +51,8 @@ const changeEmail = (state, action) => {
email: action.email,
},
errors: {
- ...state.errors,
- email: !validEmail(action.email),
+ ...state.errors,
+ email: emailError,
},
}
}
diff --git a/test/ask_web/controllers/invite_controller_test.exs b/test/ask_web/controllers/invite_controller_test.exs
index 863bd10a6..9b450bef1 100644
--- a/test/ask_web/controllers/invite_controller_test.exs
+++ b/test/ask_web/controllers/invite_controller_test.exs
@@ -1095,7 +1095,7 @@ defmodule AskWeb.InviteControllerTest do
end
test "send invite to existing user", %{conn: conn, user: user} do
- Process.register self(), :mail_target
+ Process.register(self(), :mail_target)
project = create_project_for_user(user)
code = "ABC1234"
level = "reader"