Implement community feedback

Remove other registration references
Enabled enter submit in registration form
Fixed create-profile password validation to be on debounce
Fixed register page title
This commit is contained in:
Yana De Pauw
2020-06-10 10:15:06 +02:00
parent 8fc2309d48
commit ca7a76b80f
9 changed files with 37 additions and 110 deletions

View File

@@ -3,7 +3,6 @@ import { Action } from '@ngrx/store';
// import type function // import type function
import { type } from '../../shared/ngrx/type'; import { type } from '../../shared/ngrx/type';
// import models // import models
import { EPerson } from '../eperson/models/eperson.model';
import { AuthTokenInfo } from './models/auth-token-info.model'; import { AuthTokenInfo } from './models/auth-token-info.model';
import { AuthMethod } from './models/auth.method'; import { AuthMethod } from './models/auth.method';
import { AuthStatus } from './models/auth-status.model'; import { AuthStatus } from './models/auth-status.model';
@@ -31,9 +30,6 @@ export const AuthActionTypes = {
LOG_OUT: type('dspace/auth/LOG_OUT'), LOG_OUT: type('dspace/auth/LOG_OUT'),
LOG_OUT_ERROR: type('dspace/auth/LOG_OUT_ERROR'), LOG_OUT_ERROR: type('dspace/auth/LOG_OUT_ERROR'),
LOG_OUT_SUCCESS: type('dspace/auth/LOG_OUT_SUCCESS'), LOG_OUT_SUCCESS: type('dspace/auth/LOG_OUT_SUCCESS'),
REGISTRATION: type('dspace/auth/REGISTRATION'),
REGISTRATION_ERROR: type('dspace/auth/REGISTRATION_ERROR'),
REGISTRATION_SUCCESS: type('dspace/auth/REGISTRATION_SUCCESS'),
SET_REDIRECT_URL: type('dspace/auth/SET_REDIRECT_URL'), SET_REDIRECT_URL: type('dspace/auth/SET_REDIRECT_URL'),
RETRIEVE_AUTHENTICATED_EPERSON: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON'), RETRIEVE_AUTHENTICATED_EPERSON: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON'),
RETRIEVE_AUTHENTICATED_EPERSON_SUCCESS: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON_SUCCESS'), RETRIEVE_AUTHENTICATED_EPERSON_SUCCESS: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON_SUCCESS'),
@@ -263,48 +259,6 @@ export class RetrieveTokenAction implements Action {
public type: string = AuthActionTypes.RETRIEVE_TOKEN; public type: string = AuthActionTypes.RETRIEVE_TOKEN;
} }
/**
* Sign up.
* @class RegistrationAction
* @implements {Action}
*/
export class RegistrationAction implements Action {
public type: string = AuthActionTypes.REGISTRATION;
payload: EPerson;
constructor(user: EPerson) {
this.payload = user;
}
}
/**
* Sign up error.
* @class RegistrationErrorAction
* @implements {Action}
*/
export class RegistrationErrorAction implements Action {
public type: string = AuthActionTypes.REGISTRATION_ERROR;
payload: Error;
constructor(payload: Error) {
this.payload = payload;
}
}
/**
* Sign up success.
* @class RegistrationSuccessAction
* @implements {Action}
*/
export class RegistrationSuccessAction implements Action {
public type: string = AuthActionTypes.REGISTRATION_SUCCESS;
payload: EPerson;
constructor(user: EPerson) {
this.payload = user;
}
}
/** /**
* Add uthentication message. * Add uthentication message.
* @class AddAuthenticationMessageAction * @class AddAuthenticationMessageAction
@@ -439,9 +393,6 @@ export type AuthActions
| CheckAuthenticationTokenCookieAction | CheckAuthenticationTokenCookieAction
| RedirectWhenAuthenticationIsRequiredAction | RedirectWhenAuthenticationIsRequiredAction
| RedirectWhenTokenExpiredAction | RedirectWhenTokenExpiredAction
| RegistrationAction
| RegistrationErrorAction
| RegistrationSuccessAction
| AddAuthenticationMessageAction | AddAuthenticationMessageAction
| RefreshTokenAction | RefreshTokenAction
| RefreshTokenErrorAction | RefreshTokenErrorAction

View File

@@ -32,9 +32,6 @@ import {
RefreshTokenAction, RefreshTokenAction,
RefreshTokenErrorAction, RefreshTokenErrorAction,
RefreshTokenSuccessAction, RefreshTokenSuccessAction,
RegistrationAction,
RegistrationErrorAction,
RegistrationSuccessAction,
RetrieveAuthenticatedEpersonAction, RetrieveAuthenticatedEpersonAction,
RetrieveAuthenticatedEpersonErrorAction, RetrieveAuthenticatedEpersonErrorAction,
RetrieveAuthenticatedEpersonSuccessAction, RetrieveAuthenticatedEpersonSuccessAction,
@@ -138,18 +135,6 @@ export class AuthEffects {
}) })
); );
@Effect()
public createUser$: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.REGISTRATION),
debounceTime(500), // to remove when functionality is implemented
switchMap((action: RegistrationAction) => {
return this.authService.create(action.payload).pipe(
map((user: EPerson) => new RegistrationSuccessAction(user)),
catchError((error) => observableOf(new RegistrationErrorAction(error)))
);
})
);
@Effect() @Effect()
public retrieveToken$: Observable<Action> = this.actions$.pipe( public retrieveToken$: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.RETRIEVE_TOKEN), ofType(AuthActionTypes.RETRIEVE_TOKEN),

View File

@@ -115,7 +115,6 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
}); });
case AuthActionTypes.AUTHENTICATE_ERROR: case AuthActionTypes.AUTHENTICATE_ERROR:
case AuthActionTypes.REGISTRATION_ERROR:
return Object.assign({}, state, { return Object.assign({}, state, {
authenticated: false, authenticated: false,
authToken: undefined, authToken: undefined,
@@ -157,18 +156,6 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
userId: undefined userId: undefined
}); });
case AuthActionTypes.REGISTRATION:
return Object.assign({}, state, {
authenticated: false,
authToken: undefined,
error: undefined,
loading: true,
info: undefined
});
case AuthActionTypes.REGISTRATION_SUCCESS:
return state;
case AuthActionTypes.REFRESH_TOKEN: case AuthActionTypes.REFRESH_TOKEN:
return Object.assign({}, state, { return Object.assign({}, state, {
refreshing: true, refreshing: true,

View File

@@ -270,18 +270,6 @@ export class AuthService {
return observableOf(authMethods); return observableOf(authMethods);
} }
/**
* Create a new user
* @returns {User}
*/
public create(user: EPerson): Observable<EPerson> {
// Normally you would do an HTTP request to POST the user
// details and then return the new user object
// but, let's just return the new user for this example.
// this._authenticated = true;
return observableOf(user);
}
/** /**
* End session * End session
* @returns {Observable<boolean>} * @returns {Observable<boolean>}

View File

@@ -7,7 +7,7 @@
for="email">{{'register-page.create-profile.identification.email' | translate}}</label> for="email">{{'register-page.create-profile.identification.email' | translate}}</label>
<span id="email">{{(registration$ |async).email}}</span></div> <span id="email">{{(registration$ |async).email}}</span></div>
</div> </div>
<form [class]="'ng-invalid'" [formGroup]="userInfoForm"> <form [class]="'ng-invalid'" [formGroup]="userInfoForm" (ngSubmit)="submitEperson()">
<div class="form-group"> <div class="form-group">
<div class="row"> <div class="row">
@@ -64,13 +64,13 @@
<h4>{{'register-page.create-profile.security.header' | translate}}</h4> <h4>{{'register-page.create-profile.security.header' | translate}}</h4>
<p>{{'register-page.create-profile.security.info' | translate}}</p> <p>{{'register-page.create-profile.security.info' | translate}}</p>
<form class="form-horizontal" [formGroup]="passwordForm"> <form class="form-horizontal" [formGroup]="passwordForm" (ngSubmit)="submitEperson()">
<div class="form-group"> <div class="form-group">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<label class="font-weight-bold" for="password">{{'register-page.create-profile.security.password' |translate}}</label> <label class="font-weight-bold" for="password">{{'register-page.create-profile.security.password' |translate}}</label>
<input [type]="'password'" <input [type]="'password'"
[className]="(passwordForm.invalid) && (password.dirty || password.touched) && (confirmPassword.dirty || confirmPassword.touched) ? 'form-control is-invalid' :'form-control'" [className]="(!(isValidPassWord$|async)) && (password.dirty || password.touched) && (confirmPassword.dirty || confirmPassword.touched) ? 'form-control is-invalid' :'form-control'"
type="text" id="password" formControlName="password"/> type="text" id="password" formControlName="password"/>
</div> </div>
</div> </div>
@@ -78,9 +78,9 @@
<div class="col-12"> <div class="col-12">
<label class="font-weight-bold" for="confirmPassword">{{'register-page.create-profile.security.confirm-password' |translate}}</label> <label class="font-weight-bold" for="confirmPassword">{{'register-page.create-profile.security.confirm-password' |translate}}</label>
<input [type]="'password'" <input [type]="'password'"
[className]="(passwordForm.invalid) && (password.dirty || password.touched) && (confirmPassword.dirty || confirmPassword.touched) ? 'form-control is-invalid' :'form-control'" [className]="(!(isValidPassWord$|async)) && (password.dirty || password.touched) && (confirmPassword.dirty || confirmPassword.touched) ? 'form-control is-invalid' :'form-control'"
id="confirmPassword" formControlName="confirmPassword"> id="confirmPassword" formControlName="confirmPassword">
<div *ngIf="passwordForm.invalid && (password.dirty || password.touched) && (confirmPassword.dirty || confirmPassword.touched)" <div *ngIf="!(isValidPassWord$|async) && (password.dirty || password.touched) && (confirmPassword.dirty || confirmPassword.touched)"
class="invalid-feedback show-feedback"> class="invalid-feedback show-feedback">
{{ 'register-page.create-profile.security.password.error' | translate }} {{ 'register-page.create-profile.security.password.error' | translate }}
</div> </div>
@@ -92,7 +92,7 @@
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<button <button
[disabled]="passwordForm.invalid || userInfoForm.invalid" [disabled]=" !(isValidPassWord$|async) || userInfoForm.invalid"
class="btn btn-default btn-primary" (click)="submitEperson()">{{'register-page.create-profile.submit' | translate}}</button> class="btn btn-default btn-primary" (click)="submitEperson()">{{'register-page.create-profile.submit' | translate}}</button>
</div> </div>
</div> </div>

View File

@@ -1,6 +1,6 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { map } from 'rxjs/operators'; import { debounceTime, map } from 'rxjs/operators';
import { Registration } from '../../core/shared/registration.model'; import { Registration } from '../../core/shared/registration.model';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
@@ -32,6 +32,8 @@ export class CreateProfileComponent implements OnInit {
passwordForm: FormGroup; passwordForm: FormGroup;
activeLangs: LangConfig[]; activeLangs: LangConfig[];
isValidPassWord$: Observable<boolean>;
constructor( constructor(
private translateService: TranslateService, private translateService: TranslateService,
private ePersonDataService: EPersonDataService, private ePersonDataService: EPersonDataService,
@@ -68,15 +70,26 @@ export class CreateProfileComponent implements OnInit {
this.passwordForm = this.formBuilder.group({ this.passwordForm = this.formBuilder.group({
password: new FormControl('', { password: new FormControl('', {
validators: [Validators.required, Validators.minLength(6)], validators: [Validators.required, Validators.minLength(6)],
updateOn: 'blur' updateOn: 'change'
}), }),
confirmPassword: new FormControl('', { confirmPassword: new FormControl('', {
validators: [Validators.required], validators: [Validators.required],
updateOn: 'blur' updateOn: 'change'
}) })
}, { }, {
validator: ConfirmedValidator('password', 'confirmPassword') validator: ConfirmedValidator('password', 'confirmPassword')
}); });
this.isValidPassWord$ = this.passwordForm.statusChanges.pipe(
debounceTime(300),
map((status: string) => {
if (status === 'VALID') {
return true;
} else {
return false;
}
})
);
} }
get firstName() { get firstName() {

View File

@@ -2,7 +2,7 @@
<h2>{{'register-page.registration.header'|translate}}</h2> <h2>{{'register-page.registration.header'|translate}}</h2>
<p>{{'register-page.registration.info' | translate}}</p> <p>{{'register-page.registration.info' | translate}}</p>
<form [class]="'ng-invalid'" [formGroup]="form"> <form [class]="'ng-invalid'" [formGroup]="form" (ngSubmit)="register()">
<div class="form-group"> <div class="form-group">
<div class="row"> <div class="row">

View File

@@ -42,17 +42,19 @@ export class RegisterEmailComponent implements OnInit {
* Register an email address * Register an email address
*/ */
register() { register() {
this.epersonRegistrationService.registerEmail(this.email.value).subscribe((response: RestResponse) => { if (!this.form.invalid) {
if (response.isSuccessful) { this.epersonRegistrationService.registerEmail(this.email.value).subscribe((response: RestResponse) => {
this.notificationService.success(this.translateService.get('register-page.registration.success.head'), if (response.isSuccessful) {
this.translateService.get('register-page.registration.success.content', {email: this.email.value})); this.notificationService.success(this.translateService.get('register-page.registration.success.head'),
this.router.navigate(['/home']); this.translateService.get('register-page.registration.success.content', {email: this.email.value}));
} else { this.router.navigate(['/home']);
this.notificationService.error(this.translateService.get('register-page.registration.error.head'), } else {
this.translateService.get('register-page.registration.error.content', {email: this.email.value})); this.notificationService.error(this.translateService.get('register-page.registration.error.head'),
this.translateService.get('register-page.registration.error.content', {email: this.email.value}));
}
} }
} );
); }
} }
get email() { get email() {

View File

@@ -2037,6 +2037,7 @@
"publication.search.title": "DSpace Angular :: Publication Search", "publication.search.title": "DSpace Angular :: Publication Search",
"register-email.title": "New user registration",
"register-page.create-profile.header": "Create Profile", "register-page.create-profile.header": "Create Profile",