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"