From 644d616ef8bdc225a5c00d5ace03462fa3606239 Mon Sep 17 00:00:00 2001 From: apapachristou Date: Tue, 17 Nov 2020 19:57:39 +0200 Subject: [PATCH] Add notification messages on click save of user profile --- .../user-profile/user-profile.component.html | 17 ++-- .../ui/user-profile/user-profile.component.ts | 94 ++++++++++++++++--- .../ui/user-profile/user-profile.module.ts | 4 +- 3 files changed, 94 insertions(+), 21 deletions(-) diff --git a/dmp-frontend/src/app/ui/user-profile/user-profile.component.html b/dmp-frontend/src/app/ui/user-profile/user-profile.component.html index 1ad39ba46..75b6c9743 100644 --- a/dmp-frontend/src/app/ui/user-profile/user-profile.component.html +++ b/dmp-frontend/src/app/ui/user-profile/user-profile.component.html @@ -20,14 +20,14 @@
-
{{'USER-PROFILE.SETTINGS.NAME' | translate}}
+
{{'USER-PROFILE.SETTINGS.NAME' | translate}} *
- - + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
@@ -124,7 +124,7 @@
-
{{'USER-PROFILE.SETTINGS.TIMEZONE' | translate}}
+
{{'USER-PROFILE.SETTINGS.TIMEZONE' | translate}} *
@@ -135,6 +135,7 @@ {{ timezone | timezoneInfoDisplay }} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
@@ -144,7 +145,7 @@
-
{{'USER-PROFILE.SETTINGS.CULTURE' | translate}}
+
{{'USER-PROFILE.SETTINGS.CULTURE' | translate}} *
@@ -155,6 +156,7 @@ {{ culture.displayName }} - {{ culture.nativeName }} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
@@ -164,7 +166,7 @@
-
{{'USER-PROFILE.SETTINGS.LANGUAGE' | translate}}
+
{{'USER-PROFILE.SETTINGS.LANGUAGE' | translate}} *
@@ -174,6 +176,7 @@ {{ language.label | translate }} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
diff --git a/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts b/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts index 727bada0e..86f815057 100644 --- a/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts +++ b/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { CultureInfo } from '@app/core/model/culture-info'; import { DmpModel } from '@app/core/model/dmp/dmp'; @@ -27,6 +27,8 @@ import { MatDialog } from '@angular/material'; import { UserCredentialModel } from '@app/core/model/user/user-credential'; import { AuthProvider } from '@app/core/common/enum/auth-provider'; import { MergeEmailConfirmationService } from '@app/core/services/merge-email-confirmation/merge-email-confirmation.service'; +import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; const availableLanguages: any[] = require('../../../assets/resources/language.json'); @@ -50,6 +52,9 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes roleOrganizationEnum = RoleOrganizationType; authProviderEnum = AuthProvider; private oauthLock: boolean; + errorMessages = []; + nestedCount = []; + nestedIndex = 0; organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = { filterFn: this.filterOrganisations.bind(this), @@ -72,6 +77,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes private languageService: LanguageService, private configurationService: ConfigurationService, private oauth2DialogService: Oauth2DialogService, + private uiNotificationService: UiNotificationService, private dialog: MatDialog, public enumUtils: EnumUtils, private mergeEmailConfirmation: MergeEmailConfirmationService @@ -98,20 +104,20 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes //this.formGroup.get('language').valueChanges.pipe(takeUntil(this._destroyed)).subscribe(x => { if (x) this.translate.use(x.value) }) this.formGroup.get('timezone').valueChanges - .pipe(takeUntil(this._destroyed)) - .subscribe(x => { if (x) { this.timezones = this._filterTimezone(x); } }); + .pipe(takeUntil(this._destroyed)) + .subscribe(x => { if (x) { this.timezones = this._filterTimezone(x); } }); this.formGroup.get('culture').valueChanges - .pipe(takeUntil(this._destroyed)) - .subscribe(x => { if (x) { this.cultures = this._filterCulture(x); } }); + .pipe(takeUntil(this._destroyed)) + .subscribe(x => { if (x) { this.cultures = this._filterCulture(x); } }); // this.initializeDisabledFormGroup(); this.unlock(); return result; })); this.userService.getEmails(userId).pipe(takeUntil(this._destroyed)) - .subscribe(result => { - this.userCredentials = result; - }); + .subscribe(result => { + this.userCredentials = result; + }); }); } @@ -166,7 +172,14 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes } save() { - if (!this.formGroup.valid) { return; } + if (!this.formGroup.valid) { + this.printErrors(this.formGroup); + this.showValidationErrorsDialog(); + this.nestedCount = []; + this.nestedIndex = 0; + this.errorMessages = []; + return; + } this.userService.updateUserSettings(this.formGroup.value) .pipe(takeUntil(this._destroyed)) .subscribe( @@ -176,7 +189,10 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes this.authService.current().culture = this.formGroup.value.culture.name; this.authService.me() .pipe(takeUntil(this._destroyed)) - .subscribe(result => this.router.navigate(['/profile'])); + .subscribe(result => { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/profile']); + }); // .subscribe(result => window.location.reload()); }, error => { @@ -213,6 +229,18 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes }); } + private showValidationErrorsDialog(projectOnly?: boolean) { + const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { + disableClose: true, + autoFocus: false, + restoreFocus: false, + data: { + errorMessages: this.errorMessages, + projectOnly: projectOnly + }, + }); + } + public applyFallbackAvatar(ev: Event) { (ev.target as HTMLImageElement).src = 'assets/images/profile-placeholder.png'; } @@ -253,8 +281,8 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes public RemoveZenodo() { this.userService.deleteDOIToken() - .pipe(takeUntil(this._destroyed)) - .subscribe(() => this.router.navigate(['/reload']).then(() => this.router.navigate(['/profile']))); + .pipe(takeUntil(this._destroyed)) + .subscribe(() => this.router.navigate(['/reload']).then(() => this.router.navigate(['/profile']))); } public removeAccount() { @@ -272,9 +300,49 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result) { this.mergeEmailConfirmation.sendConfirmationEmail(result).pipe(takeUntil(this._destroyed)) - .subscribe(res => {}, err => {}); + .subscribe(res => { }, err => { }); } }); } + printErrors(rootform: FormGroup) { + if (!rootform.valid) { + Object.keys(rootform.controls).forEach(key => { + const errors = rootform.get(key).errors; + if (errors !== null) { + let numbering: string = ''; + for (let j = 0; j < this.nestedCount.length; j++) { + numbering += this.nestedCount[j]; + if (j < this.nestedIndex) { + numbering += '.'; + } else { + break; + } + } + Object.keys(errors).forEach(keyError => { + if (typeof errors[keyError] === 'boolean') { + this.errorMessages.push(numbering + ' ' + key + ' is ' + keyError); + } else { + this.errorMessages.push(numbering + ' ' + key + ': ' + keyError + ': ' + JSON.stringify(errors[keyError])); + } + }); + } else { + if (rootform.get(key) instanceof FormGroup) { + this.printErrors(rootform.get(key)); + } else if (rootform.get(key) instanceof FormArray) { + this.nestedIndex++; + this.nestedCount[this.nestedIndex] = 0; + for (let childForm of (rootform.get(key)).controls) { + this.nestedCount[this.nestedIndex]++; + this.printErrors(childForm); + } + this.nestedCount[this.nestedIndex] = 0; + this.nestedIndex--; + + } + } + }); + } + } + } diff --git a/dmp-frontend/src/app/ui/user-profile/user-profile.module.ts b/dmp-frontend/src/app/ui/user-profile/user-profile.module.ts index bdbce2b15..c5efaeb7c 100644 --- a/dmp-frontend/src/app/ui/user-profile/user-profile.module.ts +++ b/dmp-frontend/src/app/ui/user-profile/user-profile.module.ts @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core'; import { FormattingModule } from '@app/core/formatting.module'; import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { FormValidationErrorsDialogModule } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; import { LoginComponent } from '../auth/login/login.component'; import { LoginModule } from '../auth/login/login.module'; @@ -17,7 +18,8 @@ import { UserProfileRoutingModule } from './user-profile.routing'; FormattingModule, UserProfileRoutingModule, AutoCompleteModule, - AddAccountDialogModule + AddAccountDialogModule, + FormValidationErrorsDialogModule ], declarations: [ UserProfileComponent