-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stark-ui): implementation of a session timeout warning
- Loading branch information
Showing
25 changed files
with
612 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Session Timeout Warning configuration | ||
|
||
Stark provides a nice feature when it comes to session expiration handling: in case the user's session is about to end due | ||
to inactivity (the user is idle for some time) and you want to warn him about this, a dialog will be displayed. | ||
|
||
This is what the `SessionTimeoutWarningDialogComponent` does and also asks the user if its session should be kept alive. | ||
|
||
This warning dialog is displayed by an NGRX Effect that triggers when a `StarkSessionActionTypes.SESSION_TIMEOUT_COUNTDOWN_START` action | ||
is dispatched (by the Session service when the user becomes idle). | ||
|
||
To use this feature, you'll have to modify the `app.module.ts` file of your application | ||
|
||
## app.module.ts | ||
|
||
You'll have to import the StarkSessionUiModule like follow: | ||
|
||
``` | ||
import {StarkSessionUiModule} from "@nationalbankbelgium/stark-ui"; | ||
@NgModule({ | ||
imports: [ | ||
StarkSessionUiModule.forRoot(), | ||
... | ||
] | ||
}) | ||
``` | ||
|
||
To indicate that you don't wish to display such warning dialog, just set `timeoutWarningDialogDisabled` value to true. | ||
This option is false by default. | ||
|
||
``` | ||
import {StarkSessionUiModule} from "@nationalbankbelgium/stark-ui"; | ||
@NgModule({ | ||
imports: [ | ||
StarkSessionUiModule.forRoot({ | ||
timeoutWarningDialogDisabled: true | ||
}), | ||
... | ||
] | ||
}) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
export * from "./session-ui/session-ui.module"; | ||
export * from "./session-ui/pages"; | ||
export * from "./session-ui/effects"; | ||
export * from "./session-ui/entities"; | ||
export * from "./session-ui/components"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./components/session-timeout-warning-dialog.component"; |
13 changes: 13 additions & 0 deletions
13
...stark-ui/src/modules/session-ui/components/_session-timeout-warning-dialog.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* ============================================================================== */ | ||
/* S t a r k S e s s i o n T i m e o u t W a r n i n g D i a l o g */ | ||
/* ============================================================================== */ | ||
/* stark-ui: src/modules/session-ui/components/_session-timeout-warning-dialog.component.scss */ | ||
|
||
.stark-timeout-warning-dialog { | ||
margin: 16px auto; | ||
box-sizing: border-box; | ||
border-radius: 8px; | ||
text-align: center; | ||
} | ||
|
||
/* END stark-ui: src/modules/session-ui/components/_session-timeout-warning-dialog.component.scss */ |
20 changes: 20 additions & 0 deletions
20
.../stark-ui/src/modules/session-ui/components/session-timeout-warning-dialog.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<div class="stark-timeout-warning-dialog" role="alertdialog" aria-busy="true" aria-live="assertive"> | ||
<h1 mat-dialog-title translate>STARK.SESSION_TIMEOUT.TITLE</h1> | ||
<div mat-dialog-content> | ||
<p> | ||
<span translate>STARK.SESSION_TIMEOUT.WILL_EXPIRE_IN</span><span> {{ countdown$|async }} </span> | ||
<span translate>STARK.SESSION_TIMEOUT.SECONDS</span> | ||
</p> | ||
<p translate>STARK.SESSION_TIMEOUT.WISH_STAY_CONNECTED</p> | ||
</div> | ||
<div mat-dialog-actions> | ||
<button mat-raised-button | ||
color="primary" | ||
(click)="keepSession()" | ||
aria-label="Close Dialog"> | ||
<span translate>STARK.SESSION_TIMEOUT.STAY_CONNECTED</span> | ||
</button> | ||
</div> | ||
</div> | ||
|
||
|
70 changes: 70 additions & 0 deletions
70
...ark-ui/src/modules/session-ui/components/session-timeout-warning-dialog.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/*tslint:disable:completed-docs*/ | ||
import { async, ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; | ||
import { CommonModule } from "@angular/common"; | ||
import { STARK_LOGGING_SERVICE } from "@nationalbankbelgium/stark-core"; | ||
import { MockStarkLoggingService } from "@nationalbankbelgium/stark-core/testing"; | ||
import { MatDialog, MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from "@angular/material/dialog"; | ||
import { StarkSessionTimeoutWarningDialogComponent } from "./session-timeout-warning-dialog.component"; | ||
|
||
import Spy = jasmine.Spy; | ||
import createSpyObj = jasmine.createSpyObj; | ||
import { Observer } from "rxjs"; | ||
|
||
describe("SessionTimeoutWarningDialogComponent", () => { | ||
let component: StarkSessionTimeoutWarningDialogComponent; | ||
let fixture: ComponentFixture<StarkSessionTimeoutWarningDialogComponent>; | ||
|
||
let mockDialogRef: MatDialogRef<any>; | ||
const mockLogger: MockStarkLoggingService = new MockStarkLoggingService(); | ||
|
||
beforeEach(async(() => { | ||
return TestBed.configureTestingModule({ | ||
declarations: [StarkSessionTimeoutWarningDialogComponent], | ||
imports: [CommonModule, MatDialogModule], | ||
providers: [ | ||
{ provide: STARK_LOGGING_SERVICE, useValue: mockLogger }, | ||
{ provide: MatDialog, useValue: MatDialog }, | ||
{ provide: MAT_DIALOG_DATA, useValue: 20 }, | ||
{ provide: MatDialogRef, useValue: createSpyObj("MatDialogRefSpy", ["close"]) } | ||
] | ||
}).compileComponents(); | ||
})); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(StarkSessionTimeoutWarningDialogComponent); | ||
mockDialogRef = TestBed.get(MatDialogRef); | ||
component = fixture.componentInstance; | ||
|
||
(<Spy>mockLogger.debug).calls.reset(); | ||
}); | ||
|
||
describe("ngOnInit", () => { | ||
it("should set the countdown and decrement it every second", fakeAsync(() => { | ||
const mockObserver: Observer<any> = createSpyObj<Observer<any>>("observerSpy", ["next", "error", "complete"]); | ||
|
||
component.ngOnInit(); | ||
component.countdown$.subscribe(mockObserver); | ||
|
||
expect(mockLogger.debug).toHaveBeenCalledTimes(1); | ||
|
||
tick(20000); | ||
|
||
expect(mockObserver.next).toHaveBeenCalledTimes(21); | ||
expect(mockObserver.error).not.toHaveBeenCalled(); | ||
expect(mockObserver.complete).toHaveBeenCalled(); | ||
|
||
expect(mockDialogRef.close).toHaveBeenCalledTimes(1); | ||
expect(mockDialogRef.close).toHaveBeenCalledWith("countdown-finished"); | ||
})); | ||
}); | ||
|
||
describe("keepSession", () => { | ||
it("should close the windows when the button is clicked", fakeAsync(() => { | ||
component.ngOnInit(); | ||
component.keepSession(); | ||
|
||
expect(mockDialogRef.close).toHaveBeenCalledTimes(1); | ||
expect(mockDialogRef.close).toHaveBeenCalledWith("keep-logged"); | ||
})); | ||
}); | ||
}); |
55 changes: 55 additions & 0 deletions
55
...es/stark-ui/src/modules/session-ui/components/session-timeout-warning-dialog.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { Component, Inject, OnInit, ViewEncapsulation } from "@angular/core"; | ||
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; | ||
import { Observable, interval } from "rxjs"; | ||
import { STARK_LOGGING_SERVICE, StarkLoggingService } from "@nationalbankbelgium/stark-core"; | ||
import { map, startWith, tap, take } from "rxjs/operators"; | ||
|
||
/** | ||
* The name of the component | ||
*/ | ||
const componentName: string = "stark-session-timeout-warning-dialog"; | ||
|
||
/** | ||
* Component to display a session timeout warning dialog | ||
*/ | ||
@Component({ | ||
selector: "session-timeout-warning-dialog", | ||
templateUrl: "./session-timeout-warning-dialog.component.html", | ||
encapsulation: ViewEncapsulation.None | ||
}) | ||
export class StarkSessionTimeoutWarningDialogComponent implements OnInit { | ||
/** | ||
* countdown Time in seconds before the current session expires. | ||
*/ | ||
public countdown$: Observable<number>; | ||
|
||
public constructor( | ||
@Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService, | ||
@Inject(MatDialogRef) private dialogRef: MatDialogRef<StarkSessionTimeoutWarningDialogComponent>, | ||
@Inject(MAT_DIALOG_DATA) private coutdown: number | ||
) {} | ||
|
||
/** | ||
* Component lifecycle hook | ||
*/ | ||
public ngOnInit(): void { | ||
this.logger.debug(componentName + ": controller initialized"); | ||
this.countdown$ = interval(1000).pipe( | ||
take(this.coutdown), | ||
startWith(-1), | ||
map((value: number) => this.coutdown - value - 1), // -1 due to the delay of the dialog animation | ||
tap((value: number) => { | ||
if (value === 0) { | ||
this.dialogRef.close("countdown-finished"); | ||
} | ||
}) | ||
); | ||
} | ||
|
||
/** | ||
* This methods is used to close the dialog and to send an answer indicating that the user should keep logged. | ||
*/ | ||
public keepSession(): void { | ||
this.dialogRef.close("keep-logged"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./effects/session-timeout-warning.effects"; |
Oops, something went wrong.