From b21d1ba1ed8206ce8bd2a137899404c268ff83bd Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Thu, 23 Jun 2022 10:46:31 -0400 Subject: [PATCH] LP1840773 SCKO Angular Signed-off-by: Bill Erickson --- Open-ILS/src/eg2/src/app/scko/scko.component.html | 9 ++++ Open-ILS/src/eg2/src/app/scko/scko.component.ts | 21 +++++++- Open-ILS/src/eg2/src/app/scko/scko.service.ts | 60 +++++++++++++++++++++- .../src/app/share/dialog/confirm.component.html | 12 +++-- .../eg2/src/app/share/dialog/confirm.component.ts | 3 ++ 5 files changed, 98 insertions(+), 7 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/scko/scko.component.html b/Open-ILS/src/eg2/src/app/scko/scko.component.html index 45df3e90b0..ebec821fbf 100644 --- a/Open-ILS/src/eg2/src/app/scko/scko.component.html +++ b/Open-ILS/src/eg2/src/app/scko/scko.component.html @@ -10,6 +10,15 @@
+ + + diff --git a/Open-ILS/src/eg2/src/app/scko/scko.component.ts b/Open-ILS/src/eg2/src/app/scko/scko.component.ts index 31a5bf8f47..4e21ebb5aa 100644 --- a/Open-ILS/src/eg2/src/app/scko/scko.component.ts +++ b/Open-ILS/src/eg2/src/app/scko/scko.component.ts @@ -1,8 +1,10 @@ -import {Component, OnInit, ViewEncapsulation} from '@angular/core'; +import {Component, OnInit, AfterViewInit, ViewChild, ViewEncapsulation} from '@angular/core'; import {Router, ActivatedRoute, NavigationEnd} from '@angular/router'; import {AuthService} from '@eg/core/auth.service'; +import {NetService} from '@eg/core/net.service'; import {SckoService} from './scko.service'; import {ServerStoreService} from '@eg/core/server-store.service'; +import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; @Component({ templateUrl: 'scko.component.html', @@ -10,16 +12,31 @@ import {ServerStoreService} from '@eg/core/server-store.service'; encapsulation: ViewEncapsulation.None }) -export class SckoComponent implements OnInit { +export class SckoComponent implements OnInit, AfterViewInit { + + @ViewChild('logoutDialog') logoutDialog: ConfirmDialogComponent; constructor( private router: Router, private route: ActivatedRoute, + private net: NetService, + private auth: AuthService, public scko: SckoService ) {} ngOnInit() { + this.net.authExpired$.subscribe(how => { + console.debug("SCKO auth expired with info", how); + this.scko.resetPatron(); + this.auth.logout(); + this.router.navigate(['/scko']); + }); + this.scko.load(); } + + ngAfterViewInit() { + this.scko.logoutDialog = this.logoutDialog; + } } diff --git a/Open-ILS/src/eg2/src/app/scko/scko.service.ts b/Open-ILS/src/eg2/src/app/scko/scko.service.ts index e1b6c3a236..03b156fec3 100644 --- a/Open-ILS/src/eg2/src/app/scko/scko.service.ts +++ b/Open-ILS/src/eg2/src/app/scko/scko.service.ts @@ -7,6 +7,7 @@ import {EventService, EgEvent} from '@eg/core/event.service'; import {IdlService, IdlObject} from '@eg/core/idl.service'; import {StoreService} from '@eg/core/store.service'; import {PatronService, PatronSummary, PatronStats} from '@eg/staff/share/patron/patron.service'; +import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; @Injectable({providedIn: 'root'}) export class SckoService { @@ -15,10 +16,18 @@ export class SckoService { patronSummary: PatronSummary; barcodeRegex: RegExp; patronPasswordRequired = false; + patronIdleTimeout: number; + patronTimeoutId: number; + logoutWarningTimeout = 20; + logoutWarningTimerId: number; sessionCheckouts: any[] = []; + // We get this from the main scko component. + logoutDialog: ConfirmDialogComponent; + constructor( + private router: Router, private route: ActivatedRoute, private org: OrgService, private net: NetService, @@ -60,6 +69,12 @@ export class SckoService { this.patronPasswordRequired = sets['circ.selfcheck.patron_password_required']; + this.patronIdleTimeout = + Number(sets['circ.selfcheck.patron_login_timeout'] || 160); + + // Compensate for the warning dialog + this.patronIdleTimeout -= this.logoutWarningTimeout; + // Load a patron by barcode via URL params. // Useful for development. const username = this.route.snapshot.queryParamMap.get('patron'); @@ -119,7 +134,50 @@ export class SckoService { }) .then(patron => this.patronSummary = new PatronSummary(patron)) .then(_ => this.patrons.getVitalStats(this.patronSummary.patron)) - .then(stats => this.patronSummary.stats = stats); + .then(stats => this.patronSummary.stats = stats) + .then(_ => this.startPatronTimer()); + } + + resetPatronTimeout() { + if (this.patronTimeoutId) { + clearTimeout(this.patronTimeoutId); + } + this.startPatronTimer(); + } + + startPatronTimer() { + console.debug('Starting patron timeout counter', this.patronIdleTimeout); + + this.patronTimeoutId = setTimeout( + () => this.showPatronLogoutWarning(), + this.patronIdleTimeout * 1000 + ); + } + + showPatronLogoutWarning() { + console.debug('Session timing out. Show warning dialog'); + + this.logoutDialog.open().subscribe(remain => { + if (remain) { + clearTimeout(this.logoutWarningTimerId); + this.logoutWarningTimerId = null; + this.resetPatronTimeout(); + } else { + this.resetPatron(); + this.router.navigate(['/scko']); + } + }); + + // Force the session to end if no action is taken on the + // logout warning dialog. + this.logoutWarningTimerId = setTimeout( + () => { + console.debug('Clearing patron on warning dialog timeout'); + this.resetPatron(); + this.router.navigate(['/scko']); + }, + this.logoutWarningTimeout * 1000 + ); } sessionTotalCheckouts(): number { diff --git a/Open-ILS/src/eg2/src/app/share/dialog/confirm.component.html b/Open-ILS/src/eg2/src/app/share/dialog/confirm.component.html index 05cf562123..c82440162e 100644 --- a/Open-ILS/src/eg2/src/app/share/dialog/confirm.component.html +++ b/Open-ILS/src/eg2/src/app/share/dialog/confirm.component.html @@ -15,9 +15,13 @@ diff --git a/Open-ILS/src/eg2/src/app/share/dialog/confirm.component.ts b/Open-ILS/src/eg2/src/app/share/dialog/confirm.component.ts index f195f32094..3b6be8b208 100644 --- a/Open-ILS/src/eg2/src/app/share/dialog/confirm.component.ts +++ b/Open-ILS/src/eg2/src/app/share/dialog/confirm.component.ts @@ -13,6 +13,9 @@ export class ConfirmDialogComponent extends DialogComponent { // What question are we asking? @Input() public dialogBody: string; @Input() public dialogBodyTemplate: TemplateRef; + + @Input() confirmButtonText: string; + @Input() cancelButtonText: string; } -- 2.11.0