From d9237acb701491106acb6873e599d2adbd762e57 Mon Sep 17 00:00:00 2001 From: Rezart Vata Date: Fri, 24 Sep 2021 17:16:53 +0200 Subject: [PATCH] [CST-4634] Added custom validator and messages and show error message for not valid email, lint fixes & unit testing --- .../access-control/access-control.module.ts | 1 + .../eperson-form/eperson-form.component.ts | 14 +++++++++-- .../validators/email-taken.validator.ts | 23 +++++++++++++++++++ src/assets/i18n/en.json5 | 5 ++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/app/access-control/epeople-registry/eperson-form/validators/email-taken.validator.ts diff --git a/src/app/access-control/access-control.module.ts b/src/app/access-control/access-control.module.ts index 0e872458bd..6968bff63d 100644 --- a/src/app/access-control/access-control.module.ts +++ b/src/app/access-control/access-control.module.ts @@ -10,6 +10,7 @@ import { MembersListComponent } from './group-registry/group-form/members-list/m import { SubgroupsListComponent } from './group-registry/group-form/subgroup-list/subgroups-list.component'; import { GroupsRegistryComponent } from './group-registry/groups-registry.component'; + @NgModule({ imports: [ CommonModule, diff --git a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts index b1d0c5bed3..f4eeaf468a 100644 --- a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts +++ b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts @@ -1,5 +1,5 @@ import { Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core'; -import { FormGroup } from '@angular/forms'; +import { FormGroup, Validators } from '@angular/forms'; import { DynamicCheckboxModel, DynamicFormControlModel, @@ -33,6 +33,7 @@ import { RequestService } from '../../../core/data/request.service'; import { NoContent } from '../../../core/shared/NoContent.model'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { followLink } from '../../../shared/utils/follow-link-config.model'; +import { ValidateEmailNotTaken } from './validators/email-taken.validator'; @Component({ selector: 'ds-eperson-form', @@ -187,6 +188,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy { * This method will initialise the page */ initialisePage() { + observableCombineLatest( this.translateService.get(`${this.messagePrefix}.firstName`), this.translateService.get(`${this.messagePrefix}.lastName`), @@ -219,9 +221,13 @@ export class EPersonFormComponent implements OnInit, OnDestroy { name: 'email', validators: { required: null, - pattern: '^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$' + pattern: '^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$', }, required: true, + errorMessages: { + emailTaken: 'error.validation.emailTaken', + pattern: 'error.validation.NotValidEmail' + }, hint: emailHint }); this.canLogIn = new DynamicCheckboxModel( @@ -262,6 +268,10 @@ export class EPersonFormComponent implements OnInit, OnDestroy { }); })); + if (!!this.formGroup.controls.email) { + this.formGroup.controls.email.setAsyncValidators(ValidateEmailNotTaken.createValidator(this.epersonService)); + } + const activeEPerson$ = this.epersonService.getActiveEPerson(); this.groups = activeEPerson$.pipe( diff --git a/src/app/access-control/epeople-registry/eperson-form/validators/email-taken.validator.ts b/src/app/access-control/epeople-registry/eperson-form/validators/email-taken.validator.ts new file mode 100644 index 0000000000..8e5303c00c --- /dev/null +++ b/src/app/access-control/epeople-registry/eperson-form/validators/email-taken.validator.ts @@ -0,0 +1,23 @@ +import { AbstractControl, ValidationErrors } from '@angular/forms'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { EPersonDataService } from '../../../../core/eperson/eperson-data.service'; +import { getFirstSucceededRemoteData, } from '../../../../core/shared/operators'; + +export class ValidateEmailNotTaken { + + /** + * This method will create the validator with the ePersonDataService requested from component + * @param ePersonDataService the service with DI in the component that this validator is being utilized. + */ + static createValidator(ePersonDataService: EPersonDataService) { + return (control: AbstractControl): Promise | Observable => { + return ePersonDataService.getEPersonByEmail(control.value) + .pipe( + getFirstSucceededRemoteData(), + map(res => { return !!res.payload ? { emailTaken: true } : null; }) + ); + }; + } +} diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index aa76d2e422..373e25d2bd 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1260,6 +1260,11 @@ "error.validation.filerequired": "The file upload is mandatory", + "error.validation.required": "This field is required", + + "error.validation.NotValidEmail": "This E-mail is not a valid email", + + "error.validation.emailTaken": "This E-mail is already taken", "file-section.error.header": "Error obtaining files for this item",