From e86e5f115768807dabccdc459df66e25fb8beee2 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 20 Nov 2017 17:05:33 -0500 Subject: [PATCH] LP#626157 Ang2 experiments Signed-off-by: Bill Erickson --- Open-ILS/webby-src/package.json | 1 + Open-ILS/webby-src/src/app/base.module.ts | 8 ++- Open-ILS/webby-src/src/app/core/eg-auth.service.ts | 82 ++++++++++++++++++++++ Open-ILS/webby-src/src/app/core/eg-idl.service.ts | 57 ++++++++++----- Open-ILS/webby-src/src/app/core/eg-net-request.ts | 21 ------ Open-ILS/webby-src/src/app/core/eg-net.service.ts | 20 +++++- .../circ/patron/bcsearch/bcsearch.component.ts | 26 ++++++- Open-ILS/webby-src/src/app/staff/nav.component.css | 24 +++++++ .../webby-src/src/app/staff/nav.component.html | 5 +- Open-ILS/webby-src/src/app/staff/nav.component.ts | 1 + 10 files changed, 198 insertions(+), 47 deletions(-) create mode 100644 Open-ILS/webby-src/src/app/core/eg-auth.service.ts delete mode 100644 Open-ILS/webby-src/src/app/core/eg-net-request.ts create mode 100644 Open-ILS/webby-src/src/app/staff/nav.component.css diff --git a/Open-ILS/webby-src/package.json b/Open-ILS/webby-src/package.json index 69892f8fd9..88f8edc6f0 100644 --- a/Open-ILS/webby-src/package.json +++ b/Open-ILS/webby-src/package.json @@ -24,6 +24,7 @@ "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.5", "core-js": "^2.4.1", "jquery": "^3.2.1", + "ngx-cookie": "^2.0.1", "rxjs": "^5.5.2", "zone.js": "^0.8.14" }, diff --git a/Open-ILS/webby-src/src/app/base.module.ts b/Open-ILS/webby-src/src/app/base.module.ts index 02a487b736..7358b00a72 100644 --- a/Open-ILS/webby-src/src/app/base.module.ts +++ b/Open-ILS/webby-src/src/app/base.module.ts @@ -12,6 +12,8 @@ import { EgBaseComponent } from './base.component'; import { EgBaseRoutingModule } from './base-routing.module'; import { WelcomeComponent } from './welcome.component'; import { EgIdlService } from '@eg/core/eg-idl.service'; +import { EgNetService } from '@eg/core/eg-net.service'; +import { EgAuthService } from '@eg/core/eg-auth.service'; @NgModule({ declarations: [ @@ -23,7 +25,11 @@ import { EgIdlService } from '@eg/core/eg-idl.service'; BrowserModule, NgbModule.forRoot() ], - providers: [EgIdlService], + providers: [ + EgIdlService, + EgNetService, + EgAuthService + ], bootstrap: [EgBaseComponent] }) 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 new file mode 100644 index 0000000000..f73720b6d7 --- /dev/null +++ b/Open-ILS/webby-src/src/app/core/eg-auth.service.ts @@ -0,0 +1,82 @@ +/** + * + */ +import { Injectable, EventEmitter } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; +import { EgNetService } from './eg-net.service'; +import { EgEvent } from './eg-event'; +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 +} + +@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 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 = EgEvent.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-idl.service.ts b/Open-ILS/webby-src/src/app/core/eg-idl.service.ts index 787d6a927d..3fffd125cb 100644 --- a/Open-ILS/webby-src/src/app/core/eg-idl.service.ts +++ b/Open-ILS/webby-src/src/app/core/eg-idl.service.ts @@ -3,6 +3,21 @@ import { Injectable } from '@angular/core'; // Added globally by /IDL2js declare var _preload_fieldmapper_IDL: Object; +/** + * NOTE: To achieve full type strictness and avoid compile warnings, + * we would likely have to pre-compile the IDL down to a .ts file with all + * of the IDL class and field definitions. + */ + +/** + * Every IDL object class implements this interface. + */ +export interface EgIdlObject { + a: any[]; + classname: String; + _isfieldmapper: Boolean; +} + @Injectable() export class EgIdlService { @@ -10,38 +25,46 @@ export class EgIdlService { parseIdl(): void { let this_ = this; - - // retain a copy of the full IDL within the this - this.classes = _preload_fieldmapper_IDL; + this_.classes = _preload_fieldmapper_IDL; /** * Creates the class constructor and getter/setter * methods for each IDL class. */ - let mkclass = function(cls, fields) { + let mkclass = (cls, fields) => { this_.classes[cls].classname = cls; - this_[cls] = function(seed) { - this.a = seed || []; - this.classname = cls; - this._isfieldmapper = true; - } + // This dance lets us encode each IDL object with the + // EgIdlObject interface. Useful for adding type restrictions + // where desired for functions, etc. + let generator:any = ((): EgIdlObject => { + + var x:any = function(seed) { + this.a = seed || []; + this.classname = cls; + this._isfieldmapper = true; + }; - /** creates the getter/setter methods for each field */ - fields.forEach(function(field, idx) { - this_[cls].prototype[fields[idx].name] = function(n) { - if (arguments.length==1) this.a[idx] = n; - return this.a[idx]; - } - }); + fields.forEach(function(field, idx) { + x.prototype[field.name] = function(n) { + if (arguments.length==1) this.a[idx] = n; + return this.a[idx]; + } + }); + + return x; + }) + + this_[cls] = generator(); // global class constructors required for JSON_v1.js + // TODO: Move away from requiring we add classes to window. window[cls] = this_[cls]; } for (var cls in this_.classes) mkclass(cls, this_.classes[cls].fields); }; - } + diff --git a/Open-ILS/webby-src/src/app/core/eg-net-request.ts b/Open-ILS/webby-src/src/app/core/eg-net-request.ts deleted file mode 100644 index e2c9179ac2..0000000000 --- a/Open-ILS/webby-src/src/app/core/eg-net-request.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { EgEvent } from './eg-event'; -import { Observer } from 'rxjs/Rx'; - -export class EgNetRequest { - service : String; - method : String; - params : any[]; - observer : Observer; - superseded : Boolean = false; - - // Last EgEvent encountered by this request. - // Most callers will not need to import EgEvent since the parsed - // event will be available here. - evt: EgEvent; - - constructor(service: String, method: String, params: any[]) { - this.service = service; - this.method = method; - this.params = params; - } -} diff --git a/Open-ILS/webby-src/src/app/core/eg-net.service.ts b/Open-ILS/webby-src/src/app/core/eg-net.service.ts index 8cc6b17f78..c279cca027 100644 --- a/Open-ILS/webby-src/src/app/core/eg-net.service.ts +++ b/Open-ILS/webby-src/src/app/core/eg-net.service.ts @@ -17,13 +17,31 @@ */ import { Injectable, EventEmitter } from '@angular/core'; import { Observable, Observer } from 'rxjs/Rx'; -import { EgNetRequest } from './eg-net-request'; import { EgEvent } from './eg-event'; // Global vars from opensrf.js // These are availavble at runtime, but are not exported. declare var OpenSRF, OSRF_TRANSPORT_TYPE_WS; +export class EgNetRequest { + service : String; + method : String; + params : any[]; + observer : Observer; + superseded : Boolean = false; + + // Last EgEvent encountered by this request. + // Most callers will not need to import EgEvent since the parsed + // event will be available here. + evt: EgEvent; + + constructor(service: String, method: String, params: any[]) { + this.service = service; + this.method = method; + this.params = params; + } +} + @Injectable() export class EgNetService { 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 adb2e21b98..e93db6e5e5 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,7 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { EgNetService } from '@eg/core/eg-net.service'; -import { EgIdlService } from '@eg/core/eg-idl.service'; +import { EgIdlService, EgIdlObject } from '@eg/core/eg-idl.service'; +import { EgAuthService } from '@eg/core/eg-auth.service'; + +declare var js2JSON; @Component({ templateUrl: 'bcsearch.component.html' @@ -15,7 +18,8 @@ export class EgBcSearchComponent implements OnInit { constructor( private route: ActivatedRoute, private egNet: EgNetService, - private egIdl : EgIdlService + private egIdl: EgIdlService, + private egAuth: EgAuthService ) {} ngOnInit() { @@ -47,8 +51,24 @@ export class EgBcSearchComponent implements OnInit { ); this.egIdl.parseIdl(); - console.log(this.egIdl.aou); + + 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' + }).then(res => { + console.log('login OK with auth ' + this.egAuth.token()); + }); } findUser(): void { diff --git a/Open-ILS/webby-src/src/app/staff/nav.component.css b/Open-ILS/webby-src/src/app/staff/nav.component.css new file mode 100644 index 0000000000..11ae8525c9 --- /dev/null +++ b/Open-ILS/webby-src/src/app/staff/nav.component.css @@ -0,0 +1,24 @@ +#staff-navbar.navbar-default { + background: -webkit-linear-gradient(#00593d, #007a54); + background-color: #007a54; + color: #fff; +} +#staff-navbar.navbar-default .navbar-nav>li>a { + color: #fff; +} +#staff-navbar.navbar-default .navbar-nav>li>a:hover { + color: #ddd; +} +#staff-navbar.navbar-default .navbar-nav > .open > a, +#staff-navbar.navbar-default .navbar-nav > .open > a:focus, +#staff-navbar.navbar-default .navbar-nav > .open > a:hover { + background-color: #7a7a7a; +} +#staff-navbar.navbar-default .navbar-nav>.dropdown>a .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +#staff-navbar.navbar-default .navbar-nav>.dropdown>a:hover .caret { + border-top-color: #ddd; + border-bottom-color: #ddd; +} diff --git a/Open-ILS/webby-src/src/app/staff/nav.component.html b/Open-ILS/webby-src/src/app/staff/nav.component.html index 299c96a53a..cdb95bf5e1 100644 --- a/Open-ILS/webby-src/src/app/staff/nav.component.html +++ b/Open-ILS/webby-src/src/app/staff/nav.component.html @@ -4,7 +4,7 @@ href="./stuff" direct routing routerLink="/suff" --> -