diff --git a/smp-angular/src/app/app.component.ts b/smp-angular/src/app/app.component.ts index 9a0c6b9de14ed0fcbe2cd921ba1f98391262f3bf..e41958b4fb6543d15b216fcecaaea4e4e42921f5 100644 --- a/smp-angular/src/app/app.component.ts +++ b/smp-angular/src/app/app.component.ts @@ -10,7 +10,6 @@ import {HttpClient} from "@angular/common/http"; import {SidenavComponent} from "./window/sidenav/sidenav.component"; import {ToolbarComponent} from "./window/toolbar/toolbar.component"; import {ThemeService} from "./common/theme-service/theme.service"; -import {AlertMessageComponent} from "./common/alert-message/alert-message.component"; import 'codemirror/mode/javascript/javascript'; import 'codemirror/mode/markdown/markdown'; import 'codemirror/mode/xml/xml'; @@ -24,8 +23,6 @@ import 'codemirror/mode/properties/properties'; }) export class AppComponent { - @ViewChild('alertMessage') alertMessage: AlertMessageComponent; - @ViewChild('sidenav') sidenav: SidenavComponent; @ViewChild('windowToolbar') windowToolbar: ToolbarComponent; @@ -44,10 +41,9 @@ export class AppComponent { private themeService: ThemeService, ) { this.userController = new UserController(this.http, this.lookups, this.dialog); - themeService.updateThemeFromLocalStorage(); + this.themeService.updateThemeFromLocalStorage(); } - isCurrentUserSystemAdmin(): boolean { return this.securityService.isCurrentUserInRole([Authority.SYSTEM_ADMIN]); } @@ -60,7 +56,6 @@ export class AppComponent { return this.securityService.isCurrentUserInRole([Authority.SERVICE_GROUP_ADMIN]); } - get currentUser(): string { let user = this.securityService.getCurrentUser(); return user ? user.username : ""; @@ -108,7 +103,7 @@ export class AppComponent { onDrawerContentScroll(scrollEvent: any){ let scrollTop = scrollEvent.srcElement.scrollTop; - this.alertMessage.setSticky(scrollTop > 0) + this.alertService.setSticky(scrollTop > 0) } } diff --git a/smp-angular/src/app/common/alert-message/alert-message.component.css b/smp-angular/src/app/common/alert-message/alert-message.component.css index 73bcf37109960d8eadcbae543e363347114dd661..753bf8fae750771408edb5528e7c0e24ace0358b 100644 --- a/smp-angular/src/app/common/alert-message/alert-message.component.css +++ b/smp-angular/src/app/common/alert-message/alert-message.component.css @@ -12,14 +12,6 @@ z-index: 2000; } -.stickyError { - position: fixed; - z-index: 1000; - top: 0; - right: 0; - left: 180px; -} - .closebtn { margin-left: 15px; color: white; diff --git a/smp-angular/src/app/common/alert-message/alert-message.component.html b/smp-angular/src/app/common/alert-message/alert-message.component.html index 9494a75e64e4ef03903911bc57680945a37d4b82..f16cb684cf8c90f2f19e10def611fd26cadae4b0 100644 --- a/smp-angular/src/app/common/alert-message/alert-message.component.html +++ b/smp-angular/src/app/common/alert-message/alert-message.component.html @@ -2,9 +2,7 @@ *ngIf="message" [ngClass]="{ 'alert-message': message, 'alert-success': message.type === 'success', 'alert-error': message.type === 'error'}" - id="alertmessage_id" - - > - <span class="closebtn" (click)="clearAlert()">×</span> - {{messageText}} + id="alertmessage_id"> + <span class="closebtn" (click)="clearAlert(true)">×</span> + {{ message.text }} </div> diff --git a/smp-angular/src/app/common/alert-message/alert-message.component.ts b/smp-angular/src/app/common/alert-message/alert-message.component.ts index ffe5042199f9f818945d10d944ba47e1f8945313..6fcb73d72e6b62f1e39313e4dab5f26b0bc9de7a 100644 --- a/smp-angular/src/app/common/alert-message/alert-message.component.ts +++ b/smp-angular/src/app/common/alert-message/alert-message.component.ts @@ -1,5 +1,7 @@ -import {Component, OnInit, ViewChild} from '@angular/core'; +import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {AlertMessageService} from './alert-message.service'; +import {AlertComponent} from "../../alert/alert.component"; +import {Subscription} from "rxjs"; @Component({ selector: 'alert', @@ -7,41 +9,35 @@ import {AlertMessageService} from './alert-message.service'; styleUrls: ['./alert-message.component.css'] }) -export class AlertMessageComponent implements OnInit { - @ViewChild('alertMessage') alertMessage; - showSticky:boolean = false; - message: any=null; +export class AlertMessageComponent implements OnInit, OnDestroy { readonly successTimeout: number = 3000; + message: any; - constructor(private alertService: AlertMessageService) { } + private subscription: Subscription; - ngOnInit() { - this.alertService.getMessage().subscribe(message => { this.showMessage(message); }); + constructor(private alertService: AlertMessageService) { } - clearAlert():void { - this.alertService.clearAlert(); + ngOnInit() { + this.subscription = this.alertService.getMessage().subscribe(message => { this.showMessage(message); }); } - setSticky(sticky: boolean):void { - this.showSticky = sticky; + ngOnDestroy(): void { + this.subscription.unsubscribe(); } - get messageText(){ - if (!!this.message){ - return this.message.text; - } + clearAlert(force = false):void { + this.alertService.clearAlert(force); } showMessage(message: any) { this.message = message; - if (message?.type==='success') { + if (message && message.type && message.type === 'success') { setTimeout(() => { this.clearAlert(); }, this.successTimeout); } - } } diff --git a/smp-angular/src/app/common/alert-message/alert-message.service.ts b/smp-angular/src/app/common/alert-message/alert-message.service.ts index 7b3472c989ec7644577c7102fdd1fc084f7caef4..335493add72145eaabc22c5d01ccd4ac5628d629 100644 --- a/smp-angular/src/app/common/alert-message/alert-message.service.ts +++ b/smp-angular/src/app/common/alert-message/alert-message.service.ts @@ -5,52 +5,75 @@ import {Observable, Subject} from 'rxjs'; @Injectable() export class AlertMessageService { private subject = new Subject<any>(); - private previousRoute: string; + private previousRoute = ''; + + private sticky = false; + + private message: { type: string, text: string }; //TODO move the logic in the ngInit block constructor (private router: Router) { - this.previousRoute = ''; // clear alert message on route change router.events.subscribe(event => { if (event instanceof NavigationStart) { if (this.isRouteChanged(event.url)) { this.clearAlert(); } else { - console.log('Alert kept when navigating from [' + this.previousRoute + '] to [' + event.url + ']'); + console.log('Alert after when navigating from [' + this.previousRoute + '] to [' + event.url + ']'); } } else if (event instanceof NavigationEnd) { this.previousRoute = event.url; + if (this.sticky) { + this.displayCurrentMessage(); + this.reset(); + } } }); } + private reset () { + this.sticky = false; + this.message = null; + } + getPath (url: string): string { - var parser = document.createElement('a'); + const parser = document.createElement('a'); parser.href = url; return parser.pathname; } isRouteChanged (currentRoute: string): boolean { - let result = false; let previousRoutePath = this.getPath(this.previousRoute); let currentRoutePath = this.getPath(currentRoute); - if (previousRoutePath !== currentRoutePath) { - result = true; - } - return result; + return previousRoutePath !== currentRoutePath; } - clearAlert (): void { + clearAlert (force = false): void { + if (!force && this.sticky) { + return; + } this.subject.next(null); } + setSticky (sticky: boolean) { + this.sticky = sticky; + } + + displayCurrentMessage () { + this.subject.next(this.message); + } + success (message: string, keepAfterNavigationChange = false) { - this.subject.next({type: 'success', text: message}); + this.setSticky(keepAfterNavigationChange); + this.message = {type: 'success', text: message}; + this.displayCurrentMessage(); } error (message: string, keepAfterNavigationChange = false) { - this.subject.next({type: 'error', text: message}); + this.setSticky(keepAfterNavigationChange); + this.message = {type: 'error', text: message}; + this.displayCurrentMessage(); } exception (message: string, error: any, keepAfterNavigationChange = false): void { diff --git a/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.ts b/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.ts index 1881fc5f1bb8c8937d46b23e2dff52d57924a763..a033124181af0e83a98a277f2245ec7a69aa5ae1 100644 --- a/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.ts +++ b/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.ts @@ -128,19 +128,15 @@ export class PasswordChangeDialogComponent { } } - showPassChangeDialog() { - this.dialog.open(InformationDialogComponent, { - data: { - title: "Password set/changed", - description: "Password has been successfully set/changed." + - (!this.adminUser ? " Login again to the application with the new password!" : "") - } - }).afterClosed().subscribe(result => { - if (!this.adminUser) { - // logout if changed for itself - this.securityService.finalizeLogout(result); - } - }) + async showPassChangeDialog() { + this.alertService.success("Password has been successfully set/changed." + + (!this.adminUser ? " Login again to the application with the new password!" : ""), true); + + + if (!this.adminUser) { + // logout if changed for itself + this.securityService.finalizeLogout({}); + } } showSuccessMessage(value: string) { diff --git a/smp-angular/src/app/login/login.component.html b/smp-angular/src/app/login/login.component.html index 0f96e24f200a87de1d47bfe86def7b78f4607bf1..632241d25f489baf026fb09449fde8c045feaaee 100644 --- a/smp-angular/src/app/login/login.component.html +++ b/smp-angular/src/app/login/login.component.html @@ -4,7 +4,7 @@ <mat-card-title class="title-panel" >SSO Login: {{lookups.cachedApplicationInfo.ssoAuthenticationLabel}}</mat-card-title> <mat-card-content style="align-items: center;justify-content: center;display: flex;height: 200px;"> <a mat-raised-button color="primary" href="{{lookups.cachedApplicationInfo.ssoAuthenticationURI}}" - [style]="'width=150px'"> + [style]="'width:150px'"> <mat-icon>input</mat-icon> <span> SSO Login</span> </a> diff --git a/smp-angular/src/app/security/security.service.ts b/smp-angular/src/app/security/security.service.ts index 2130d93d436c67fbe71ead8bdcbdf89a47f5ab2b..e96b7d035082c4cd563ea8bc3a865f4e2c13c115 100644 --- a/smp-angular/src/app/security/security.service.ts +++ b/smp-angular/src/app/security/security.service.ts @@ -2,27 +2,26 @@ import {Observable, ReplaySubject} from 'rxjs'; import {User} from './user.model'; import {SecurityEventService} from './security-event.service'; -import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http'; +import {HttpClient, HttpHeaders} from '@angular/common/http'; import {SmpConstants} from "../smp.constants"; import {Authority} from "./authority.model"; import {AlertMessageService} from "../common/alert-message/alert-message.service"; import {PasswordChangeDialogComponent} from "../common/dialogs/password-change-dialog/password-change-dialog.component"; import {MatDialog} from "@angular/material/dialog"; +import {Router} from "@angular/router"; @Injectable() export class SecurityService { readonly LOCAL_STORAGE_KEY_CURRENT_USER = 'currentUser'; - - constructor( private http: HttpClient, private alertService: AlertMessageService, private securityEventService: SecurityEventService, private dialog: MatDialog, - ) { - this.securityEventService.onLogoutSuccessEvent().subscribe(() => window.location.reload()); + private router: Router) { + this.securityEventService.onLogoutSuccessEvent().subscribe(() => { this.dialog.closeAll(); this.router.navigateByUrl('/'); }); this.securityEventService.onLogoutErrorEvent().subscribe((error) => this.alertService.error(error)); }