From bd77bb1b02c8d9d1a65f75958b22894c2954bd99 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Tue, 21 Nov 2017 11:38:49 -0500 Subject: [PATCH] LP#626157 Ang2 experiments Signed-off-by: Bill Erickson --- .../webby-src/src/app/base-resolver.service.ts | 23 ++++ Open-ILS/webby-src/src/app/base-routing.module.ts | 12 +- Open-ILS/webby-src/src/app/base.module.ts | 8 +- Open-ILS/webby-src/src/app/core/README | 4 +- Open-ILS/webby-src/src/app/core/auth.service.ts | 122 +++++++++++++++++++++ Open-ILS/webby-src/src/app/core/eg-auth.service.ts | 85 -------------- .../core/{eg-event.service.ts => event.service.ts} | 0 .../app/core/{eg-idl.service.ts => idl.service.ts} | 0 .../app/core/{eg-net.service.ts => net.service.ts} | 2 +- Open-ILS/webby-src/src/app/core/store.service.ts | 94 ++++++++++++++++ .../circ/patron/bcsearch/bcsearch.component.ts | 27 +---- .../staff/circ/patron/bcsearch/bcsearch.module.ts | 2 +- .../webby-src/src/app/staff/login.component.html | 6 +- .../webby-src/src/app/staff/login.component.ts | 7 +- .../src/app/staff/staff-resolver.service.ts | 8 +- .../src/app/staff/staff-routing.module.ts | 2 - 16 files changed, 272 insertions(+), 130 deletions(-) create mode 100644 Open-ILS/webby-src/src/app/base-resolver.service.ts create mode 100644 Open-ILS/webby-src/src/app/core/auth.service.ts delete mode 100644 Open-ILS/webby-src/src/app/core/eg-auth.service.ts rename Open-ILS/webby-src/src/app/core/{eg-event.service.ts => event.service.ts} (100%) rename Open-ILS/webby-src/src/app/core/{eg-idl.service.ts => idl.service.ts} (100%) rename Open-ILS/webby-src/src/app/core/{eg-net.service.ts => net.service.ts} (98%) create mode 100644 Open-ILS/webby-src/src/app/core/store.service.ts diff --git a/Open-ILS/webby-src/src/app/base-resolver.service.ts b/Open-ILS/webby-src/src/app/base-resolver.service.ts new file mode 100644 index 0000000000..e1e8b731e4 --- /dev/null +++ b/Open-ILS/webby-src/src/app/base-resolver.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { Router, Resolve, RouterStateSnapshot, + ActivatedRouteSnapshot } from '@angular/router'; + +import { EgIdlService } from '@eg/core/idl.service'; + +@Injectable() +export class EgBaseResolver implements Resolve { + + constructor(private router: Router, private egIdl: EgIdlService) {} + + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable { + + console.debug('EgBaseResolver:resolve()'); + + this.egIdl.parseIdl(); + + return Observable.empty(); // Nothing to report. + } +} diff --git a/Open-ILS/webby-src/src/app/base-routing.module.ts b/Open-ILS/webby-src/src/app/base-routing.module.ts index 08b9c48eaf..7280e37f9e 100644 --- a/Open-ILS/webby-src/src/app/base-routing.module.ts +++ b/Open-ILS/webby-src/src/app/base-routing.module.ts @@ -1,5 +1,6 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { EgBaseResolver } from './base-resolver.service'; import { WelcomeComponent } from './welcome.component'; /** @@ -7,17 +8,20 @@ import { WelcomeComponent } from './welcome.component'; * When lazy loading, no module references should be directly imported. * The refs are encoded in the loadChildren attribute of each route. */ - const routes: Routes = [ - { path: '', component: WelcomeComponent }, - { path: 'staff', + { path: '', + component: WelcomeComponent + }, { + path: 'staff', + resolve : {startup : EgBaseResolver}, loadChildren: './staff/staff.module#EgStaffModule' } ]; @NgModule({ imports: [ RouterModule.forRoot(routes) ], - exports: [ RouterModule ] + exports: [ RouterModule ], + providers: [ EgBaseResolver ] }) export class EgBaseRoutingModule {} diff --git a/Open-ILS/webby-src/src/app/base.module.ts b/Open-ILS/webby-src/src/app/base.module.ts index ecb4d28662..1fbb2fafb0 100644 --- a/Open-ILS/webby-src/src/app/base.module.ts +++ b/Open-ILS/webby-src/src/app/base.module.ts @@ -13,10 +13,10 @@ import { EgBaseRoutingModule } from './base-routing.module'; import { WelcomeComponent } from './welcome.component'; // Import and 'provide' globally required services. -import { EgEventService } from '@eg/core/eg-event.service'; -import { EgIdlService } from '@eg/core/eg-idl.service'; -import { EgNetService } from '@eg/core/eg-net.service'; -import { EgAuthService } from '@eg/core/eg-auth.service'; +import { EgEventService } from '@eg/core/event.service'; +import { EgIdlService } from '@eg/core/idl.service'; +import { EgNetService } from '@eg/core/net.service'; +import { EgAuthService } from '@eg/core/auth.service'; @NgModule({ declarations: [ diff --git a/Open-ILS/webby-src/src/app/core/README b/Open-ILS/webby-src/src/app/core/README index 217411dc7b..68dff847e9 100644 --- a/Open-ILS/webby-src/src/app/core/README +++ b/Open-ILS/webby-src/src/app/core/README @@ -1,5 +1,5 @@ Core types (classes) and Angular services used by all modules. -Class files are named $classname.ts +NOTES: -Service files are named $servicename.service.ts +* Avoid path navigation in the core services as paths will vary by application. diff --git a/Open-ILS/webby-src/src/app/core/auth.service.ts b/Open-ILS/webby-src/src/app/core/auth.service.ts new file mode 100644 index 0000000000..dfb101e2a9 --- /dev/null +++ b/Open-ILS/webby-src/src/app/core/auth.service.ts @@ -0,0 +1,122 @@ +/** + * + */ +import { Injectable, EventEmitter } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; +import { EgNetService } from './net.service'; +import { EgEventService, EgEvent } from './event.service'; +import { EgIdlService, EgIdlObject } from './idl.service'; +import { EgStoreService } from './store.service'; + +// Models a login instance. +class EgAuthUser { + user: EgIdlObject; + workstation: String; // workstation name + token: String; + authtime: Number; + + constructor(token: String, authtime: Number, workstation: String) { + this.token = token; + this.workstation = workstation; + this.authtime = authtime; + } +} + +// Params required for calling the login() method. +interface EgAuthLoginArgs { + username: String, + password: String, + workstation: String, + type: String // staff, persist, etc. +} + +@Injectable() +export class EgAuthService { + + private activeUser: EgAuthUser; + + // opChangeUser refers to the user that has been superseded during + // an op-change event. This use will become the activeUser once + // again, when the op-change cycle has completed. + private opChangeUser: EgAuthUser; + + constructor( + private egEvt: EgEventService, + private egNet: EgNetService, + private egStore: EgStoreService + ) {} + + // - Accessor functions alway refer to the active user. + + user(): EgIdlObject { + return this.activeUser.user + }; + + // Workstation name. + workstation(): String { + return this.activeUser.workstation + }; + + token(): String { + return this.activeUser.token + }; + + authtime(): Number { + return this.activeUser.authtime + }; + + login(args: EgAuthLoginArgs, ops?: Object): Promise { + if (!ops) ops = {}; + + return new Promise((resolve, reject) => { + this.egNet.request('open-ils.auth', 'open-ils.auth.login', args) + .subscribe(res => { + let evt = this.egEvt.parse(res); + if (evt) { + if (evt.textcode == 'SUCCESS') { + this.handleLoginOk(args, evt, false); + resolve(); + } + } else { + // Should never get here. + reject(); + } + }); + }); + } + + testAuthToken(): Promise { + return Promise.resolve(); + } + + // Stash the login data + handleLoginOk(args: EgAuthLoginArgs, evt: EgEvent, isOpChange: Boolean): void { + + if (isOpChange) { + this.egStore.setLoginSessionItem('eg.auth.token.oc', this.token()); + this.egStore.setLoginSessionItem('eg.auth.time.oc', this.authtime()); + this.opChangeUser = this.activeUser; + } + + this.activeUser = new EgAuthUser( + evt.payload.authtoken, + evt.payload.authtime, + args.workstation + ); + + this.egStore.setLoginSessionItem('eg.auth.token', this.token()); + this.egStore.setLoginSessionItem('eg.auth.time', this.authtime()); + } + + undoOpChange(): Promise { + if (this.opChangeUser) { + this.activeUser = this.opChangeUser; + this.opChangeUser = null; + this.egStore.removeLoginSessionItem('eg.auth.token.oc'); + this.egStore.removeLoginSessionItem('eg.auth.time.oc'); + this.egStore.setLoginSessionItem('eg.auth.token', this.token()); + this.egStore.setLoginSessionItem('eg.auth.time', this.authtime()); + } + return this.testAuthToken(); + } +} diff --git a/Open-ILS/webby-src/src/app/core/eg-auth.service.ts b/Open-ILS/webby-src/src/app/core/eg-auth.service.ts deleted file mode 100644 index 8501133ccb..0000000000 --- a/Open-ILS/webby-src/src/app/core/eg-auth.service.ts +++ /dev/null @@ -1,85 +0,0 @@ -/** - * - */ -import { Injectable, EventEmitter } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; -import { EgNetService } from './eg-net.service'; -import { EgEventService, EgEvent } from './eg-event.service'; -import { EgIdlService, EgIdlObject } from './eg-idl.service'; - -class EgAuthUser { - user : EgIdlObject; - workstation : String; - token : String; - authtime : Number; - - constructor(token: String, authtime: Number, workstation: String) { - this.token = token; - this.workstation = workstation; - this.authtime = authtime; - } -} - -interface EgAuthArgs { - username : String, - password : String, - workstation : String, - type : String -} - -@Injectable() -export class EgAuthService { - - private activeUser : EgAuthUser; - private opChangeUser : EgAuthUser; - - user(): EgIdlObject { - return this.activeUser.user - }; - - // Workstation name. - workstation(): String { - return this.activeUser.workstation - }; - - token(): String { - return this.activeUser.token - }; - - authtime(): Number { - return this.activeUser.authtime - }; - - constructor( - private egEvt: EgEventService, - private egNet: EgNetService - ) {} - - login(args: EgAuthArgs, ops?: Object): Promise { - - return new Promise((resolve, reject) => { - this.egNet.request('open-ils.auth', 'open-ils.auth.login', args) - .subscribe(res => { - let evt = this.egEvt.parse(res); - if (evt) { - if (evt.textcode == 'SUCCESS') { - this.handleLoginOk(args, evt); - resolve(); - } - } - }); - }); - } - - // Stash the login data - handleLoginOk(args: EgAuthArgs, evt: EgEvent): void { - - this.activeUser = new EgAuthUser( - evt.payload.authtoken, - evt.payload.authtime, - args.workstation - ) - - // TODO: put stuff into login session cache; - } -} diff --git a/Open-ILS/webby-src/src/app/core/eg-event.service.ts b/Open-ILS/webby-src/src/app/core/event.service.ts similarity index 100% rename from Open-ILS/webby-src/src/app/core/eg-event.service.ts rename to Open-ILS/webby-src/src/app/core/event.service.ts diff --git a/Open-ILS/webby-src/src/app/core/eg-idl.service.ts b/Open-ILS/webby-src/src/app/core/idl.service.ts similarity index 100% rename from Open-ILS/webby-src/src/app/core/eg-idl.service.ts rename to Open-ILS/webby-src/src/app/core/idl.service.ts diff --git a/Open-ILS/webby-src/src/app/core/eg-net.service.ts b/Open-ILS/webby-src/src/app/core/net.service.ts similarity index 98% rename from Open-ILS/webby-src/src/app/core/eg-net.service.ts rename to Open-ILS/webby-src/src/app/core/net.service.ts index 9232828bc7..c6082a75b3 100644 --- a/Open-ILS/webby-src/src/app/core/eg-net.service.ts +++ b/Open-ILS/webby-src/src/app/core/net.service.ts @@ -17,7 +17,7 @@ */ import { Injectable, EventEmitter } from '@angular/core'; import { Observable, Observer } from 'rxjs/Rx'; -import { EgEventService, EgEvent } from './eg-event.service'; +import { EgEventService, EgEvent } from './event.service'; // Global vars from opensrf.js // These are availavble at runtime, but are not exported. diff --git a/Open-ILS/webby-src/src/app/core/store.service.ts b/Open-ILS/webby-src/src/app/core/store.service.ts new file mode 100644 index 0000000000..caf1625910 --- /dev/null +++ b/Open-ILS/webby-src/src/app/core/store.service.ts @@ -0,0 +1,94 @@ +/** + * Store and retrieve data from various sources. + */ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; + +@Injectable() +export class EgStoreService { + + setItem(key: string, val: any, isJson?: Boolean): Promise { + + // TODO: route keys appropriately + + this.setLocalItem(key, val, false); + return Promise.resolve(); + } + + setLocalItem(key: string, val: any, isJson?: Boolean): void { + if (!isJson) val = JSON.stringify(val); + window.localStorage.setItem(key, val); + } + + setServerItem(key: string, val: any): Promise { + // JSON-ify on the server? + return Promise.resolve(); + } + + setSessionItem(key: string, val: any, isJson?: Boolean): void { + if (!isJson) val = JSON.stringify(val); + } + + setLoginSessionItem(key: string, val: any, isJson?:Boolean): void { + if (!isJson) val = JSON.stringify(val); + } + + getItem(key: string): Promise { + // TODO: route keys appropriately + + return Promise.resolve(this.getLocalItem(key)); + } + + getLocalItem(key: string): any { + let valJson: string = window.localStorage.getItem(key); + if (valJson === null) return null; + try { + return JSON.parse(valJson); + } catch (E) { + console.error(`Deleting invalid JSON for localItem: ` + + `${key} => ${valJson} : ${E}`); + this.removeLocalItem(key); + } + return null; + } + + getServerItem(key: string): Promise { + return Promise.resolve(); + } + + getSessionItem(key: string): any { + } + + getLoginSessionItem(key: string): any { + } + + removeItem(key: string): Promise { + return Promise.resolve(); + } + + removeLocalItem(key: string): void { + let valJson: string = window.localStorage.getItem(key); + if (valJson === null) return null; + try { + return JSON.parse(valJson); + } catch (E) { + console.error( + `Deleting invalid JSON for localItem: ${key} => ${valJson}`); + this.removeLocalItem(key); + return null; + } + } + + removeServerItem(key: string): Promise { + return Promise.resolve(); + } + + removeSessionItem(key: string): void { + } + + removeLoginSessionItem(key: string): void { + } + + +} + diff --git a/Open-ILS/webby-src/src/app/staff/circ/patron/bcsearch/bcsearch.component.ts b/Open-ILS/webby-src/src/app/staff/circ/patron/bcsearch/bcsearch.component.ts index cb95c1fe57..18765e4830 100644 --- a/Open-ILS/webby-src/src/app/staff/circ/patron/bcsearch/bcsearch.component.ts +++ b/Open-ILS/webby-src/src/app/staff/circ/patron/bcsearch/bcsearch.component.ts @@ -1,8 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { EgNetService } from '@eg/core/eg-net.service'; -import { EgIdlService, EgIdlObject } from '@eg/core/eg-idl.service'; -import { EgAuthService } from '@eg/core/eg-auth.service'; +import { EgNetService } from '@eg/core/net.service'; +import { EgAuthService } from '@eg/core/auth.service'; declare var js2JSON; @@ -18,7 +17,6 @@ export class EgBcSearchComponent implements OnInit { constructor( private route: ActivatedRoute, private egNet: EgNetService, - private egIdl: EgIdlService, private egAuth: EgAuthService ) {} @@ -49,27 +47,6 @@ export class EgBcSearchComponent implements OnInit { e => console.log('echo event: ' + e), () => console.log('done') ); - - this.egIdl.parseIdl(); - - let org = new this.egIdl['aou'](); - org.name('HELLO'); - console.log(org.name() + ' : ' + js2JSON(org)); - - function foo(obj: EgIdlObject) { - console.log('org is an instance!'); - } - - foo(org); - - this.egAuth.login({ - username: 'admin', - password: 'demo123', - workstation : 'BR1-skiddoo', - type : 'staff' - }).then(res => { - console.log('login OK with auth ' + this.egAuth.token()); - }); } findUser(): void { diff --git a/Open-ILS/webby-src/src/app/staff/circ/patron/bcsearch/bcsearch.module.ts b/Open-ILS/webby-src/src/app/staff/circ/patron/bcsearch/bcsearch.module.ts index af67ff1da6..0f38729c51 100644 --- a/Open-ILS/webby-src/src/app/staff/circ/patron/bcsearch/bcsearch.module.ts +++ b/Open-ILS/webby-src/src/app/staff/circ/patron/bcsearch/bcsearch.module.ts @@ -1,7 +1,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { EgNetService } from '@eg/core/eg-net.service'; +import { EgNetService } from '@eg/core/net.service'; import { EgBcSearchComponent } from './bcsearch.component'; import { EgBcSearchRoutingModule } from './bcsearch-routing.module'; diff --git a/Open-ILS/webby-src/src/app/staff/login.component.html b/Open-ILS/webby-src/src/app/staff/login.component.html index 8bb9cd66fc..09726bff8f 100644 --- a/Open-ILS/webby-src/src/app/staff/login.component.html +++ b/Open-ILS/webby-src/src/app/staff/login.component.html @@ -7,7 +7,8 @@
- - console.log('Authtoken: ' + this.egAuth.token()) ); } diff --git a/Open-ILS/webby-src/src/app/staff/staff-resolver.service.ts b/Open-ILS/webby-src/src/app/staff/staff-resolver.service.ts index 47c8ba2c32..e7a70652c8 100644 --- a/Open-ILS/webby-src/src/app/staff/staff-resolver.service.ts +++ b/Open-ILS/webby-src/src/app/staff/staff-resolver.service.ts @@ -16,13 +16,15 @@ export class EgStaffResolver implements Resolve { route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { - // async placeholder for startup routines + console.debug('EgStaffResolver:resolve()'); + + // TODO: check auth session + + // async placeholder for staff startup routines return Observable.create( observer => { observer.next(123); - console.debug('completing EgStaffRouteResolver'); observer.complete(); - console.debug('completed EgStaffRouteResolver'); } ); } diff --git a/Open-ILS/webby-src/src/app/staff/staff-routing.module.ts b/Open-ILS/webby-src/src/app/staff/staff-routing.module.ts index 85452c76bf..55c2c68202 100644 --- a/Open-ILS/webby-src/src/app/staff/staff-routing.module.ts +++ b/Open-ILS/webby-src/src/app/staff/staff-routing.module.ts @@ -7,8 +7,6 @@ import { EgStaffResolver } from './staff-resolver.service'; const routes: Routes = [ { path: '', component: EgStaffComponent, - // base resolver. Called first and guaranteed to - // complete before any child resolvers are started. resolve : {startup : EgStaffResolver}, children : [ { -- 2.11.0