From: Bill Erickson Date: Thu, 12 Apr 2018 21:55:58 +0000 (+0000) Subject: LP#1626157 More file name best practices X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=45ed53565c49f325c9f4374ddaf9529259b5b66f;p=working%2FEvergreen.git LP#1626157 More file name best practices Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/eg2/src/app/common.module.ts b/Open-ILS/src/eg2/src/app/common.module.ts index ea68a75ac5..20a9b5e767 100644 --- a/Open-ILS/src/eg2/src/app/common.module.ts +++ b/Open-ILS/src/eg2/src/app/common.module.ts @@ -6,14 +6,14 @@ import {NgModule, ModuleWithProviders} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; -import {EgEventService} from '@eg/core/event'; -import {EgStoreService} from '@eg/core/store'; -import {EgIdlService} from '@eg/core/idl'; -import {EgNetService} from '@eg/core/net'; -import {EgAuthService} from '@eg/core/auth'; -import {EgPermService} from '@eg/core/perm'; -import {EgPcrudService} from '@eg/core/pcrud'; -import {EgOrgService} from '@eg/core/org'; +import {EgEventService} from '@eg/core/event.service'; +import {EgStoreService} from '@eg/core/store.service'; +import {EgIdlService} from '@eg/core/idl.service'; +import {EgNetService} from '@eg/core/net.service'; +import {EgAuthService} from '@eg/core/auth.service'; +import {EgPermService} from '@eg/core/perm.service'; +import {EgPcrudService} from '@eg/core/pcrud.service'; +import {EgOrgService} from '@eg/core/org.service'; @NgModule({ declarations: [ diff --git a/Open-ILS/src/eg2/src/app/core/auth.service.ts b/Open-ILS/src/eg2/src/app/core/auth.service.ts new file mode 100644 index 0000000000..a14fd9f90d --- /dev/null +++ b/Open-ILS/src/eg2/src/app/core/auth.service.ts @@ -0,0 +1,292 @@ +import {Injectable, EventEmitter} from '@angular/core'; +import {EgNetService} from './net.service'; +import {EgEventService, EgEvent} from './event.service'; +import {EgIdlService, EgIdlObject} from './idl.service'; +import {EgStoreService} from './store.service'; + +// Not universally available. +declare var BroadcastChannel; + +// Models a login instance. +class EgAuthUser { + user: EgIdlObject; // actor.usr (au) object + 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, + type: string, + workstation?: string +} + +export enum EgAuthWsState { + PENDING, + NOT_USED, + NOT_FOUND_SERVER, + NOT_FOUND_LOCAL, + VALID +}; + +@Injectable() +export class EgAuthService { + + private authChannel: any; + + private activeUser: EgAuthUser; + + // opChangeUser refers to the user that has been superseded during + // an op-change event. opChangeUser resumes its status as the + // activeUser once the op-change cycle has completed. + private opChangeUser: EgAuthUser; + + workstationState: EgAuthWsState = EgAuthWsState.PENDING; + + // Used by auth-checking resolvers + redirectUrl: string; + + // reference to active auth validity setTimeout handler. + pollTimeout: any; + + constructor( + private egEvt: EgEventService, + private net: EgNetService, + private store: EgStoreService + ) { + + console.log("egAuth constructor()"); + + // BroadcastChannel is not yet defined in PhantomJS + this.authChannel = BroadcastChannel ? + new BroadcastChannel('eg.auth') : {}; + } + + + // - Accessor functions always refer to the active user. + + user(): EgIdlObject { + return this.activeUser ? this.activeUser.user : null; + }; + + // Workstation name. + workstation(): string { + return this.activeUser ? this.activeUser.workstation : null; + }; + + token(): string { + return this.activeUser ? this.activeUser.token : null; + }; + + authtime(): number { + return this.activeUser ? this.activeUser.authtime : 0; + }; + + // NOTE: EgNetService emits an event if the auth session has expired. + testAuthToken(): Promise { + + this.activeUser = new EgAuthUser( + this.store.getLoginSessionItem('eg.auth.token'), + this.store.getLoginSessionItem('eg.auth.time') + ); + + if (!this.token()) return Promise.reject('no authtoken'); + + return this.net.request( + 'open-ils.auth', + 'open-ils.auth.session.retrieve', this.token()).toPromise() + .then(user => { + // EgNetService interceps NO_SESSION events. + // We can only get here if the session is valid. + this.activeUser.user = user; + this.listenForLogout(); + this.sessionPoll(); + }); + } + + login(args: EgAuthLoginArgs, isOpChange?: boolean): Promise { + return this.net.request('open-ils.auth', 'open-ils.auth.login', args) + .toPromise().then(res => { + return this.handleLoginResponse( + args, this.egEvt.parse(res), isOpChange) + }) + } + + handleLoginResponse( + args: EgAuthLoginArgs, evt: EgEvent, isOpChange: boolean): Promise { + + switch (evt.textcode) { + case 'SUCCESS': + this.handleLoginOk(args, evt, isOpChange); + return Promise.resolve(); + + case 'WORKSTATION_NOT_FOUND': + console.error(`No such workstation "${args.workstation}"`); + this.workstationState = EgAuthWsState.NOT_FOUND_SERVER; + delete args.workstation; + return this.login(args, isOpChange); + + default: + console.error(`Login returned unexpected event: ${evt}`); + return Promise.reject('login failed'); + } + } + + // Stash the login data + handleLoginOk(args: EgAuthLoginArgs, evt: EgEvent, isOpChange: boolean): void { + + if (isOpChange) { + this.store.setLoginSessionItem('eg.auth.token.oc', this.token()); + this.store.setLoginSessionItem('eg.auth.time.oc', this.authtime()); + this.opChangeUser = this.activeUser; + } + + this.activeUser = new EgAuthUser( + evt.payload.authtoken, + evt.payload.authtime, + args.workstation + ); + + this.store.setLoginSessionItem('eg.auth.token', this.token()); + this.store.setLoginSessionItem('eg.auth.time', this.authtime()); + } + + undoOpChange(): Promise { + if (this.opChangeUser) { + this.deleteSession(); + this.activeUser = this.opChangeUser; + this.opChangeUser = null; + this.store.removeLoginSessionItem('eg.auth.token.oc'); + this.store.removeLoginSessionItem('eg.auth.time.oc'); + this.store.setLoginSessionItem('eg.auth.token', this.token()); + this.store.setLoginSessionItem('eg.auth.time', this.authtime()); + } + return this.testAuthToken(); + } + + /** + * Listen for logout events initiated by other browser tabs. + */ + listenForLogout(): void { + if (this.authChannel.onmessage) return; + + this.authChannel.onmessage = (e) => { + console.debug( + `received eg.auth broadcast ${JSON.stringify(e.data)}`); + + if (e.data.action == 'logout') { + // Logout will be handled by the originating tab. + // We just need to clear tab-local memory. + this.cleanup(); + this.net.authExpired$.emit({viaExternal: true}); + } + } + } + + /** + * Force-check the validity of the authtoken on occasion. + * This allows us to redirect an idle staff client back to the login + * page after the session times out. Otherwise, the UI would stay + * open with potentially sensitive data visible. + * TODO: What is the practical difference (for a browser) between + * checking auth validity and the ui.general.idle_timeout setting? + * Does that setting serve a purpose in a browser environment? + */ + sessionPoll(): void { + + // add a 5 second delay to give the token plenty of time + // to expire on the server. + let pollTime = this.authtime() * 1000 + 5000; + + this.pollTimeout = setTimeout(() => { + this.net.request( + 'open-ils.auth', + 'open-ils.auth.session.retrieve', + this.token(), + 0, // return extra auth details, unneeded here. + 1 // avoid extending the auth timeout + + // EgNetService intercepts NO_SESSION events. + // If the promise resolves, the session is valid. + ).toPromise().then(user => this.sessionPoll()) + + }, pollTime); + } + + + // Resolves if login workstation matches a workstation known to this + // browser instance. + verifyWorkstation(): Promise { + + if (!this.user()) { + this.workstationState = EgAuthWsState.PENDING; + return Promise.reject('Cannot verify workstation without user'); + } + + if (!this.user().wsid()) { + this.workstationState = EgAuthWsState.NOT_USED; + return Promise.reject('User has no workstation ID to verify'); + } + + return new Promise((resolve, reject) => { + this.store.getItem('eg.workstation.all') + .then(workstations => { + + if (workstations) { + let ws = workstations.filter( + w => {return w.id == this.user().wsid()})[0]; + + if (ws) { + this.activeUser.workstation = ws.name; + this.workstationState = EgAuthWsState.VALID; + return resolve(); + } + } + + this.workstationState = EgAuthWsState.NOT_FOUND_LOCAL; + reject(); + }); + }); + } + + deleteSession(): void { + if (this.token()) { + this.net.request( + 'open-ils.auth', + 'open-ils.auth.session.delete', this.token()) + .subscribe(x => console.debug('logged out')) + } + } + + // Tell all listening browser tabs that it's time to logout. + // This should only be invoked by one tab. + broadcastLogout(): void { + console.debug('Notifying tabs of imminent auth token removal'); + this.authChannel.postMessage({action : 'logout'}); + } + + // Remove/reset session data + cleanup(): void { + this.activeUser = null; + this.opChangeUser = null; + if (this.pollTimeout) { + clearTimeout(this.pollTimeout); + this.pollTimeout = null; + } + } + + // Invalidate server auth token and clean up. + logout(): void { + this.deleteSession(); + this.store.clearLoginSessionItems(); + this.cleanup(); + } +} diff --git a/Open-ILS/src/eg2/src/app/core/auth.ts b/Open-ILS/src/eg2/src/app/core/auth.ts deleted file mode 100644 index ab4b133285..0000000000 --- a/Open-ILS/src/eg2/src/app/core/auth.ts +++ /dev/null @@ -1,292 +0,0 @@ -import {Injectable, EventEmitter} from '@angular/core'; -import {EgNetService} from './net'; -import {EgEventService, EgEvent} from './event'; -import {EgIdlService, EgIdlObject} from './idl'; -import {EgStoreService} from './store'; - -// Not universally available. -declare var BroadcastChannel; - -// Models a login instance. -class EgAuthUser { - user: EgIdlObject; // actor.usr (au) object - 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, - type: string, - workstation?: string -} - -export enum EgAuthWsState { - PENDING, - NOT_USED, - NOT_FOUND_SERVER, - NOT_FOUND_LOCAL, - VALID -}; - -@Injectable() -export class EgAuthService { - - private authChannel: any; - - private activeUser: EgAuthUser; - - // opChangeUser refers to the user that has been superseded during - // an op-change event. opChangeUser resumes its status as the - // activeUser once the op-change cycle has completed. - private opChangeUser: EgAuthUser; - - workstationState: EgAuthWsState = EgAuthWsState.PENDING; - - // Used by auth-checking resolvers - redirectUrl: string; - - // reference to active auth validity setTimeout handler. - pollTimeout: any; - - constructor( - private egEvt: EgEventService, - private net: EgNetService, - private store: EgStoreService - ) { - - console.log("egAuth constructor()"); - - // BroadcastChannel is not yet defined in PhantomJS - this.authChannel = BroadcastChannel ? - new BroadcastChannel('eg.auth') : {}; - } - - - // - Accessor functions always refer to the active user. - - user(): EgIdlObject { - return this.activeUser ? this.activeUser.user : null; - }; - - // Workstation name. - workstation(): string { - return this.activeUser ? this.activeUser.workstation : null; - }; - - token(): string { - return this.activeUser ? this.activeUser.token : null; - }; - - authtime(): number { - return this.activeUser ? this.activeUser.authtime : 0; - }; - - // NOTE: EgNetService emits an event if the auth session has expired. - testAuthToken(): Promise { - - this.activeUser = new EgAuthUser( - this.store.getLoginSessionItem('eg.auth.token'), - this.store.getLoginSessionItem('eg.auth.time') - ); - - if (!this.token()) return Promise.reject('no authtoken'); - - return this.net.request( - 'open-ils.auth', - 'open-ils.auth.session.retrieve', this.token()).toPromise() - .then(user => { - // EgNetService interceps NO_SESSION events. - // We can only get here if the session is valid. - this.activeUser.user = user; - this.listenForLogout(); - this.sessionPoll(); - }); - } - - login(args: EgAuthLoginArgs, isOpChange?: boolean): Promise { - return this.net.request('open-ils.auth', 'open-ils.auth.login', args) - .toPromise().then(res => { - return this.handleLoginResponse( - args, this.egEvt.parse(res), isOpChange) - }) - } - - handleLoginResponse( - args: EgAuthLoginArgs, evt: EgEvent, isOpChange: boolean): Promise { - - switch (evt.textcode) { - case 'SUCCESS': - this.handleLoginOk(args, evt, isOpChange); - return Promise.resolve(); - - case 'WORKSTATION_NOT_FOUND': - console.error(`No such workstation "${args.workstation}"`); - this.workstationState = EgAuthWsState.NOT_FOUND_SERVER; - delete args.workstation; - return this.login(args, isOpChange); - - default: - console.error(`Login returned unexpected event: ${evt}`); - return Promise.reject('login failed'); - } - } - - // Stash the login data - handleLoginOk(args: EgAuthLoginArgs, evt: EgEvent, isOpChange: boolean): void { - - if (isOpChange) { - this.store.setLoginSessionItem('eg.auth.token.oc', this.token()); - this.store.setLoginSessionItem('eg.auth.time.oc', this.authtime()); - this.opChangeUser = this.activeUser; - } - - this.activeUser = new EgAuthUser( - evt.payload.authtoken, - evt.payload.authtime, - args.workstation - ); - - this.store.setLoginSessionItem('eg.auth.token', this.token()); - this.store.setLoginSessionItem('eg.auth.time', this.authtime()); - } - - undoOpChange(): Promise { - if (this.opChangeUser) { - this.deleteSession(); - this.activeUser = this.opChangeUser; - this.opChangeUser = null; - this.store.removeLoginSessionItem('eg.auth.token.oc'); - this.store.removeLoginSessionItem('eg.auth.time.oc'); - this.store.setLoginSessionItem('eg.auth.token', this.token()); - this.store.setLoginSessionItem('eg.auth.time', this.authtime()); - } - return this.testAuthToken(); - } - - /** - * Listen for logout events initiated by other browser tabs. - */ - listenForLogout(): void { - if (this.authChannel.onmessage) return; - - this.authChannel.onmessage = (e) => { - console.debug( - `received eg.auth broadcast ${JSON.stringify(e.data)}`); - - if (e.data.action == 'logout') { - // Logout will be handled by the originating tab. - // We just need to clear tab-local memory. - this.cleanup(); - this.net.authExpired$.emit({viaExternal: true}); - } - } - } - - /** - * Force-check the validity of the authtoken on occasion. - * This allows us to redirect an idle staff client back to the login - * page after the session times out. Otherwise, the UI would stay - * open with potentially sensitive data visible. - * TODO: What is the practical difference (for a browser) between - * checking auth validity and the ui.general.idle_timeout setting? - * Does that setting serve a purpose in a browser environment? - */ - sessionPoll(): void { - - // add a 5 second delay to give the token plenty of time - // to expire on the server. - let pollTime = this.authtime() * 1000 + 5000; - - this.pollTimeout = setTimeout(() => { - this.net.request( - 'open-ils.auth', - 'open-ils.auth.session.retrieve', - this.token(), - 0, // return extra auth details, unneeded here. - 1 // avoid extending the auth timeout - - // EgNetService intercepts NO_SESSION events. - // If the promise resolves, the session is valid. - ).toPromise().then(user => this.sessionPoll()) - - }, pollTime); - } - - - // Resolves if login workstation matches a workstation known to this - // browser instance. - verifyWorkstation(): Promise { - - if (!this.user()) { - this.workstationState = EgAuthWsState.PENDING; - return Promise.reject('Cannot verify workstation without user'); - } - - if (!this.user().wsid()) { - this.workstationState = EgAuthWsState.NOT_USED; - return Promise.reject('User has no workstation ID to verify'); - } - - return new Promise((resolve, reject) => { - this.store.getItem('eg.workstation.all') - .then(workstations => { - - if (workstations) { - let ws = workstations.filter( - w => {return w.id == this.user().wsid()})[0]; - - if (ws) { - this.activeUser.workstation = ws.name; - this.workstationState = EgAuthWsState.VALID; - return resolve(); - } - } - - this.workstationState = EgAuthWsState.NOT_FOUND_LOCAL; - reject(); - }); - }); - } - - deleteSession(): void { - if (this.token()) { - this.net.request( - 'open-ils.auth', - 'open-ils.auth.session.delete', this.token()) - .subscribe(x => console.debug('logged out')) - } - } - - // Tell all listening browser tabs that it's time to logout. - // This should only be invoked by one tab. - broadcastLogout(): void { - console.debug('Notifying tabs of imminent auth token removal'); - this.authChannel.postMessage({action : 'logout'}); - } - - // Remove/reset session data - cleanup(): void { - this.activeUser = null; - this.opChangeUser = null; - if (this.pollTimeout) { - clearTimeout(this.pollTimeout); - this.pollTimeout = null; - } - } - - // Invalidate server auth token and clean up. - logout(): void { - this.deleteSession(); - this.store.clearLoginSessionItems(); - this.cleanup(); - } -} diff --git a/Open-ILS/src/eg2/src/app/core/event.service.ts b/Open-ILS/src/eg2/src/app/core/event.service.ts new file mode 100644 index 0000000000..33e3f84697 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/core/event.service.ts @@ -0,0 +1,53 @@ +import {Injectable} from '@angular/core'; + +export class EgEvent { + code : number; + textcode : string; + payload : any; + desc : string; + debug : string; + note : string; + servertime : string; + ilsperm : string; + ilspermloc : number; + success : Boolean = false; + + toString(): string { + let s = `Event: ${this.code}:${this.textcode} -> ${this.desc}`; + if (this.ilsperm) + s += ` ${this.ilsperm}@${this.ilspermloc}`; + if (this.note) + s += `\n${this.note}`; + return s; + } +} + +@Injectable() +export class EgEventService { + + /** + * Returns an EgEvent if 'thing' is an event, null otherwise. + */ + parse(thing: any): EgEvent { + + // All events have a textcode + if (thing && typeof thing == 'object' && 'textcode' in thing) { + + let evt = new EgEvent(); + + ['textcode','payload','desc','note','servertime','ilsperm'] + .forEach(field => { evt[field] = thing[field]; }); + + evt.debug = thing.stacktrace; + evt.code = +(thing.ilsevent || -1); + evt.ilspermloc = +(thing.ilspermloc || -1); + evt.success = thing.textcode == 'SUCCESS'; + + return evt; + } + + return null; + } +} + + diff --git a/Open-ILS/src/eg2/src/app/core/event.ts b/Open-ILS/src/eg2/src/app/core/event.ts deleted file mode 100644 index 33e3f84697..0000000000 --- a/Open-ILS/src/eg2/src/app/core/event.ts +++ /dev/null @@ -1,53 +0,0 @@ -import {Injectable} from '@angular/core'; - -export class EgEvent { - code : number; - textcode : string; - payload : any; - desc : string; - debug : string; - note : string; - servertime : string; - ilsperm : string; - ilspermloc : number; - success : Boolean = false; - - toString(): string { - let s = `Event: ${this.code}:${this.textcode} -> ${this.desc}`; - if (this.ilsperm) - s += ` ${this.ilsperm}@${this.ilspermloc}`; - if (this.note) - s += `\n${this.note}`; - return s; - } -} - -@Injectable() -export class EgEventService { - - /** - * Returns an EgEvent if 'thing' is an event, null otherwise. - */ - parse(thing: any): EgEvent { - - // All events have a textcode - if (thing && typeof thing == 'object' && 'textcode' in thing) { - - let evt = new EgEvent(); - - ['textcode','payload','desc','note','servertime','ilsperm'] - .forEach(field => { evt[field] = thing[field]; }); - - evt.debug = thing.stacktrace; - evt.code = +(thing.ilsevent || -1); - evt.ilspermloc = +(thing.ilspermloc || -1); - evt.success = thing.textcode == 'SUCCESS'; - - return evt; - } - - return null; - } -} - - diff --git a/Open-ILS/src/eg2/src/app/core/idl.service.ts b/Open-ILS/src/eg2/src/app/core/idl.service.ts new file mode 100644 index 0000000000..fdbd1113cc --- /dev/null +++ b/Open-ILS/src/eg2/src/app/core/idl.service.ts @@ -0,0 +1,81 @@ +import {Injectable} from '@angular/core'; + +// Added globally by /IDL2js +declare var _preload_fieldmapper_IDL: Object; + +/** + * Every IDL object class implements this interface. + */ +export interface EgIdlObject { + a: any[]; + classname: string; + _isfieldmapper: boolean; + // Dynamically appended functions from the IDL. + [fields: string]: any; +} + +@Injectable() +export class EgIdlService { + + classes = {}; // IDL class metadata + constructors = {}; // IDL instance generators + + /** + * Create a new IDL object instance. + */ + create(cls: string, seed?:any[]): EgIdlObject { + if (this.constructors[cls]) + return new this.constructors[cls](seed); + throw new Error(`No such IDL class ${cls}`); + } + + parseIdl(): void { + + try { + this.classes = _preload_fieldmapper_IDL; + } catch (E) { + console.error('IDL (IDL2js) not found. Is the system running?'); + return; + } + + /** + * Creates the class constructor and getter/setter + * methods for each IDL class. + */ + let mkclass = (cls, fields) => { + this.classes[cls].classname = cls; + + // 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; + }; + + 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.constructors[cls] = generator(); + + // global class constructors required for JSON_v1.js + // TODO: polluting the window namespace w/ every IDL class + // is less than ideal. + window[cls] = this.constructors[cls]; + } + + for (var cls in this.classes) + mkclass(cls, this.classes[cls].fields); + }; +} + diff --git a/Open-ILS/src/eg2/src/app/core/idl.ts b/Open-ILS/src/eg2/src/app/core/idl.ts deleted file mode 100644 index fdbd1113cc..0000000000 --- a/Open-ILS/src/eg2/src/app/core/idl.ts +++ /dev/null @@ -1,81 +0,0 @@ -import {Injectable} from '@angular/core'; - -// Added globally by /IDL2js -declare var _preload_fieldmapper_IDL: Object; - -/** - * Every IDL object class implements this interface. - */ -export interface EgIdlObject { - a: any[]; - classname: string; - _isfieldmapper: boolean; - // Dynamically appended functions from the IDL. - [fields: string]: any; -} - -@Injectable() -export class EgIdlService { - - classes = {}; // IDL class metadata - constructors = {}; // IDL instance generators - - /** - * Create a new IDL object instance. - */ - create(cls: string, seed?:any[]): EgIdlObject { - if (this.constructors[cls]) - return new this.constructors[cls](seed); - throw new Error(`No such IDL class ${cls}`); - } - - parseIdl(): void { - - try { - this.classes = _preload_fieldmapper_IDL; - } catch (E) { - console.error('IDL (IDL2js) not found. Is the system running?'); - return; - } - - /** - * Creates the class constructor and getter/setter - * methods for each IDL class. - */ - let mkclass = (cls, fields) => { - this.classes[cls].classname = cls; - - // 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; - }; - - 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.constructors[cls] = generator(); - - // global class constructors required for JSON_v1.js - // TODO: polluting the window namespace w/ every IDL class - // is less than ideal. - window[cls] = this.constructors[cls]; - } - - for (var cls in this.classes) - mkclass(cls, this.classes[cls].fields); - }; -} - diff --git a/Open-ILS/src/eg2/src/app/core/net.service.ts b/Open-ILS/src/eg2/src/app/core/net.service.ts new file mode 100644 index 0000000000..bcedfc7033 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/core/net.service.ts @@ -0,0 +1,183 @@ +/** + * + * constructor(private net : EgNetService) { + * ... + * this.net.request(service, method, param1 [, param2, ...]) + * .subscribe( + * (res) => console.log('received one resopnse: ' + res), + * (err) => console.error('recived request error: ' + err), + * () => console.log('request complete') + * ) + * ); + * ... + * + * // Example translating a net request into a promise. + * this.net.request(service, method, param1) + * .toPromise().then(result => console.log(result)); + * + * } + * + * Each response is relayed via Observable.next(). The interface is + * the same for streaming and atomic requests. + */ +import {Injectable, EventEmitter} from '@angular/core'; +import {Observable, Observer} from 'rxjs/Rx'; +import {EgEventService, EgEvent} from './event.service'; + +// 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; + // If set, this will be used instead of a one-off OpenSRF.ClientSession. + session? : any; + // True if we're using a single-use local session + localSession: boolean = true; + + // 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[], session?: any) { + this.service = service; + this.method = method; + this.params = params; + if (session) { + this.session = session; + this.localSession = false; + } else { + this.session = new OpenSRF.ClientSession(service); + } + } +} + +export interface EgAuthExpiredEvent { + // request is set when the auth expiration was determined as a + // by-product of making an API call. + request?: EgNetRequest; + + // True if this environment (e.g. browser tab) was notified of the + // expired auth token from an external source (e.g. another browser tab). + viaExternal?: boolean; +} + +@Injectable() +export class EgNetService { + + permFailed$: EventEmitter; + authExpired$: EventEmitter; + + // If true, permission failures are emitted via permFailed$ + // and the active request is marked as superseded. + permFailedHasHandler: Boolean = false; + + constructor( + private egEvt: EgEventService + ) { + this.permFailed$ = new EventEmitter(); + this.authExpired$ = new EventEmitter(); + } + + // Standard request call -- Variadic params version + request(service: string, method: string, ...params: any[]): Observable { + return this.requestWithParamList(service, method, params); + } + + // Array params version + requestWithParamList(service: string, + method: string, params: any[]): Observable { + return this.requestCompiled( + new EgNetRequest(service, method, params)); + } + + // Request with pre-compiled EgNetRequest + requestCompiled(request: EgNetRequest): Observable { + return Observable.create( + observer => { + request.observer = observer; + this.sendCompiledRequest(request); + } + ); + } + + // Send the compiled request to the server via WebSockets + sendCompiledRequest(request: EgNetRequest): void { + OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS; + console.debug(`EgNet: request ${request.method}`); + + request.session.request({ + async : true, // WS only operates in async mode + method : request.method, + params : request.params, + oncomplete : () => { + + // TODO: teach opensrf.js to call cleanup() inside + // disconnect() and teach EgPcrud to call cleanup() + // as needed to avoid long-lived session data bloat. + if (request.localSession) + request.session.cleanup(); + + // A superseded request will be complete()'ed by the + // superseder at a later time. + if (!request.superseded) + request.observer.complete(); + }, + onresponse : r => { + this.dispatchResponse(request, r.recv().content()); + }, + onerror : errmsg => { + let msg = `${request.method} failed! See server logs. ${errmsg}`; + console.error(msg); + request.observer.error(msg); + }, + onmethoderror : (req, statCode, statMsg) => { + let msg = + `${request.method} failed! stat=${statCode} msg=${statMsg}`; + console.error(msg); + + if (request.service == 'open-ils.pcrud' && statCode == 401) { + // 401 is the PCRUD equivalent of a NO_SESSION event + this.authExpired$.emit({request: request}); + } + + request.observer.error(msg); + } + + }).send(); + } + + // Relay response object to the caller for typical/successful + // responses. Applies special handling to response events that + // require global attention. + private dispatchResponse(request, response): void { + request.evt = this.egEvt.parse(response); + + if (request.evt) { + switch(request.evt.textcode) { + + case 'NO_SESSION': + console.debug(`EgNet emitting event: ${request.evt}`); + request.observer.error(request.evt.toString()); + this.authExpired$.emit({request: request}); + return; + + case 'PERM_FAILURE': + if (this.permFailedHasHandler) { + console.debug(`EgNet emitting event: ${request.evt}`); + request.superseded = true; + this.permFailed$.emit(request); + return; + } + } + } + + // Pass the response to the caller. + request.observer.next(response); + }; +} diff --git a/Open-ILS/src/eg2/src/app/core/net.ts b/Open-ILS/src/eg2/src/app/core/net.ts deleted file mode 100644 index f6ec6b258b..0000000000 --- a/Open-ILS/src/eg2/src/app/core/net.ts +++ /dev/null @@ -1,183 +0,0 @@ -/** - * - * constructor(private net : EgNetService) { - * ... - * this.net.request(service, method, param1 [, param2, ...]) - * .subscribe( - * (res) => console.log('received one resopnse: ' + res), - * (err) => console.error('recived request error: ' + err), - * () => console.log('request complete') - * ) - * ); - * ... - * - * // Example translating a net request into a promise. - * this.net.request(service, method, param1) - * .toPromise().then(result => console.log(result)); - * - * } - * - * Each response is relayed via Observable.next(). The interface is - * the same for streaming and atomic requests. - */ -import {Injectable, EventEmitter} from '@angular/core'; -import {Observable, Observer} from 'rxjs/Rx'; -import {EgEventService, EgEvent} from './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; - // If set, this will be used instead of a one-off OpenSRF.ClientSession. - session? : any; - // True if we're using a single-use local session - localSession: boolean = true; - - // 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[], session?: any) { - this.service = service; - this.method = method; - this.params = params; - if (session) { - this.session = session; - this.localSession = false; - } else { - this.session = new OpenSRF.ClientSession(service); - } - } -} - -export interface EgAuthExpiredEvent { - // request is set when the auth expiration was determined as a - // by-product of making an API call. - request?: EgNetRequest; - - // True if this environment (e.g. browser tab) was notified of the - // expired auth token from an external source (e.g. another browser tab). - viaExternal?: boolean; -} - -@Injectable() -export class EgNetService { - - permFailed$: EventEmitter; - authExpired$: EventEmitter; - - // If true, permission failures are emitted via permFailed$ - // and the active request is marked as superseded. - permFailedHasHandler: Boolean = false; - - constructor( - private egEvt: EgEventService - ) { - this.permFailed$ = new EventEmitter(); - this.authExpired$ = new EventEmitter(); - } - - // Standard request call -- Variadic params version - request(service: string, method: string, ...params: any[]): Observable { - return this.requestWithParamList(service, method, params); - } - - // Array params version - requestWithParamList(service: string, - method: string, params: any[]): Observable { - return this.requestCompiled( - new EgNetRequest(service, method, params)); - } - - // Request with pre-compiled EgNetRequest - requestCompiled(request: EgNetRequest): Observable { - return Observable.create( - observer => { - request.observer = observer; - this.sendCompiledRequest(request); - } - ); - } - - // Send the compiled request to the server via WebSockets - sendCompiledRequest(request: EgNetRequest): void { - OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS; - console.debug(`EgNet: request ${request.method}`); - - request.session.request({ - async : true, // WS only operates in async mode - method : request.method, - params : request.params, - oncomplete : () => { - - // TODO: teach opensrf.js to call cleanup() inside - // disconnect() and teach EgPcrud to call cleanup() - // as needed to avoid long-lived session data bloat. - if (request.localSession) - request.session.cleanup(); - - // A superseded request will be complete()'ed by the - // superseder at a later time. - if (!request.superseded) - request.observer.complete(); - }, - onresponse : r => { - this.dispatchResponse(request, r.recv().content()); - }, - onerror : errmsg => { - let msg = `${request.method} failed! See server logs. ${errmsg}`; - console.error(msg); - request.observer.error(msg); - }, - onmethoderror : (req, statCode, statMsg) => { - let msg = - `${request.method} failed! stat=${statCode} msg=${statMsg}`; - console.error(msg); - - if (request.service == 'open-ils.pcrud' && statCode == 401) { - // 401 is the PCRUD equivalent of a NO_SESSION event - this.authExpired$.emit({request: request}); - } - - request.observer.error(msg); - } - - }).send(); - } - - // Relay response object to the caller for typical/successful - // responses. Applies special handling to response events that - // require global attention. - private dispatchResponse(request, response): void { - request.evt = this.egEvt.parse(response); - - if (request.evt) { - switch(request.evt.textcode) { - - case 'NO_SESSION': - console.debug(`EgNet emitting event: ${request.evt}`); - request.observer.error(request.evt.toString()); - this.authExpired$.emit({request: request}); - return; - - case 'PERM_FAILURE': - if (this.permFailedHasHandler) { - console.debug(`EgNet emitting event: ${request.evt}`); - request.superseded = true; - this.permFailed$.emit(request); - return; - } - } - } - - // Pass the response to the caller. - request.observer.next(response); - }; -} diff --git a/Open-ILS/src/eg2/src/app/core/org.service.ts b/Open-ILS/src/eg2/src/app/core/org.service.ts new file mode 100644 index 0000000000..b2ad2505da --- /dev/null +++ b/Open-ILS/src/eg2/src/app/core/org.service.ts @@ -0,0 +1,267 @@ +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs/Rx'; +import {EgIdlObject, EgIdlService} from './idl.service'; +import {EgNetService} from './net.service'; +import {EgAuthService} from './auth.service'; +import {EgPcrudService} from './pcrud.service'; + +type EgOrgNodeOrId = number | EgIdlObject; + +interface OrgFilter { + canHaveUsers?: boolean; + canHaveVolumes?: boolean; + opacVisible?: boolean; + inList?: number[]; + notInList?: number[]; +} + +interface OrgSettingsBatch { + [key: string]: any; +} + +@Injectable() +export class EgOrgService { + + private orgList: EgIdlObject[] = []; + private orgTree: EgIdlObject; // root node + children + private orgMap: {[id:number] : EgIdlObject} = {}; + private settingsCache: OrgSettingsBatch = {}; + + constructor( + private net: EgNetService, + private auth: EgAuthService, + private pcrud: EgPcrudService + ) {} + + get(nodeOrId: EgOrgNodeOrId): EgIdlObject { + if (typeof nodeOrId == 'object') + return nodeOrId; + return this.orgMap[nodeOrId]; + } + + list(): EgIdlObject[] { + return this.orgList; + } + + /** + * Returns a list of org units that match the selected criteria. + * All filters must match for an org to be included in the result set. + * Unset filter options are ignored. + */ + filterList(filter: OrgFilter, asId?: boolean): any[] { + let list = []; + this.list().forEach(org => { + + let chu = filter.canHaveUsers; + if (chu && !this.canHaveUsers(org)) return; + if (chu === false && this.canHaveUsers(org)) return; + + let chv = filter.canHaveVolumes; + if (chv && !this.canHaveVolumes(org)) return; + if (chv === false && this.canHaveVolumes(org)) return; + + let ov = filter.opacVisible; + if (ov && !this.opacVisible(org)) return; + if (ov === false && this.opacVisible(org)) return; + + if (filter.inList && filter.inList.indexOf(org.id()) == -1) + return; + + if (filter.notInList && filter.notInList.indexOf(org.id()) > -1) + return; + + // All filter tests passed. Add it to the list + list.push(asId ? org.id() : org); + }); + + return list; + } + + tree(): EgIdlObject { + return this.orgTree; + } + + // get the root OU + root(): EgIdlObject { + return this.orgList[0]; + } + + // list of org_unit objects or IDs for ancestors + me + ancestors(nodeOrId: EgOrgNodeOrId, asId?: boolean): any[] { + let node = this.get(nodeOrId); + if (!node) return []; + let nodes = [node]; + while( (node = this.get(node.parent_ou()))) + nodes.push(node); + if (asId) return nodes.map(n => n.id()); + return nodes; + } + + // tests that a node can have users + canHaveUsers(nodeOrId): boolean { + return this + .get(nodeOrId) + .ou_type() + .can_have_users() == 't'; + } + + // tests that a node can have volumes + canHaveVolumes(nodeOrId): boolean { + return this + .get(nodeOrId) + .ou_type() + .can_have_vols() == 't'; + } + + opacVisible(nodeOrId): boolean { + return this.get(nodeOrId).opac_visible() == 't'; + } + + // list of org_unit objects or IDs for me + descendants + descendants(nodeOrId: EgOrgNodeOrId, asId?: boolean): any[] { + let node = this.get(nodeOrId); + if (!node) return []; + let nodes = []; + function descend(n) { + nodes.push(n); + n.children().forEach(descend); + } + descend(node); + if (asId) + return nodes.map(function(n){return n.id()}); + return nodes; + } + + // list of org_unit objects or IDs for ancestors + me + descendants + fullPath(nodeOrId: EgOrgNodeOrId, asId?: boolean): any[] { + let list = this.ancestors(nodeOrId, false).concat( + this.descendants(nodeOrId, false).slice(1)); + if (asId) + return list.map(function(n){return n.id()}); + return list; + } + + sortTree(sortField?: string, node?: EgIdlObject): void { + if (!sortField) sortField = 'shortname'; + if (!node) node = this.orgTree; + node.children( + node.children.sort((a, b) => { + return a[sortField]() < b[sortField]() ? -1 : 1 + }) + ); + node.children.forEach(n => this.sortTree(n)); + } + + absorbTree(node?: EgIdlObject): void { + if (!node) { + node = this.orgTree; + this.orgMap = {}; + this.orgList = []; + } + this.orgMap[node.id()] = node; + this.orgList.push(node); + node.children().forEach(c => this.absorbTree(c)); + } + + /** + * Grabs all of the org units from the server, chops them up into + * various shapes, then returns an "all done" promise. + */ + fetchOrgs(): Promise { + return this.pcrud.search('aou', {parent_ou : null}, + {flesh : -1, flesh_fields : {aou : ['children', 'ou_type']}}, + {anonymous : true} + ).toPromise().then(tree => { + // ingest tree, etc. + this.orgTree = tree; + this.absorbTree(); + }); + } + + /** + * Populate 'target' with settings from cache where available. + * Return the list of settings /not/ pulled from cache. + */ + private settingsFromCache(names: string[], target: any) { + let cacheKeys = Object.keys(this.settingsCache); + + cacheKeys.forEach(key => { + let matchIdx = names.indexOf(key); + if (matchIdx > -1) { + target[key] = this.settingsCache[key]; + names.splice(matchIdx, 1); + } + }); + + return names; + } + + /** + * Fetch org settings from the network. + * 'auth' is null for anonymous lookup. + */ + private settingsFromNet(orgId: number, + names: string[], auth?: string): Promise { + + let settings = {}; + return new Promise((resolve, reject) => { + this.net.request( + 'open-ils.actor', + 'open-ils.actor.ou_setting.ancestor_default.batch', + orgId, names, auth + ).subscribe( + blob => { + Object.keys(blob).forEach(key => { + let val = blob[key]; // null or hash + settings[key] = val ? val.value : null; + }); + resolve(settings); + }, + err => reject(err) + ); + }); + } + + + /** + * + */ + settings(names: string[], + orgId?: number, anonymous?: boolean): Promise { + + let settings = {}; + let auth: string = null; + let useCache: boolean = false; + + if (this.auth.user()) { + if (orgId) { + useCache = orgId == this.auth.user().ws_ou(); + } else { + orgId = this.auth.user().ws_ou(); + useCache = true; + } + + // avoid passing auth token when anonymous is requested. + if (!anonymous) auth = this.auth.token(); + + } else if (!anonymous) { + return Promise.reject( + 'Use "anonymous" To retrieve org settings without an authtoken'); + } + + if (useCache) names = this.settingsFromCache(names, settings); + + // All requested settings found in cache (or name list is empty) + if (names.length == 0) return Promise.resolve(settings); + + return this.settingsFromNet(orgId, names, auth) + .then(settings => { + if (useCache) { + Object.keys(settings).forEach(key => { + this.settingsCache[key] = settings[key]; + }); + } + return settings; + }); + } +} diff --git a/Open-ILS/src/eg2/src/app/core/org.ts b/Open-ILS/src/eg2/src/app/core/org.ts deleted file mode 100644 index 0cf87a4ab1..0000000000 --- a/Open-ILS/src/eg2/src/app/core/org.ts +++ /dev/null @@ -1,267 +0,0 @@ -import {Injectable} from '@angular/core'; -import {Observable} from 'rxjs/Rx'; -import {EgIdlObject, EgIdlService} from './idl'; -import {EgNetService} from './net'; -import {EgAuthService} from './auth'; -import {EgPcrudService} from './pcrud'; - -type EgOrgNodeOrId = number | EgIdlObject; - -interface OrgFilter { - canHaveUsers?: boolean; - canHaveVolumes?: boolean; - opacVisible?: boolean; - inList?: number[]; - notInList?: number[]; -} - -interface OrgSettingsBatch { - [key: string]: any; -} - -@Injectable() -export class EgOrgService { - - private orgList: EgIdlObject[] = []; - private orgTree: EgIdlObject; // root node + children - private orgMap: {[id:number] : EgIdlObject} = {}; - private settingsCache: OrgSettingsBatch = {}; - - constructor( - private net: EgNetService, - private auth: EgAuthService, - private pcrud: EgPcrudService - ) {} - - get(nodeOrId: EgOrgNodeOrId): EgIdlObject { - if (typeof nodeOrId == 'object') - return nodeOrId; - return this.orgMap[nodeOrId]; - } - - list(): EgIdlObject[] { - return this.orgList; - } - - /** - * Returns a list of org units that match the selected criteria. - * All filters must match for an org to be included in the result set. - * Unset filter options are ignored. - */ - filterList(filter: OrgFilter, asId?: boolean): any[] { - let list = []; - this.list().forEach(org => { - - let chu = filter.canHaveUsers; - if (chu && !this.canHaveUsers(org)) return; - if (chu === false && this.canHaveUsers(org)) return; - - let chv = filter.canHaveVolumes; - if (chv && !this.canHaveVolumes(org)) return; - if (chv === false && this.canHaveVolumes(org)) return; - - let ov = filter.opacVisible; - if (ov && !this.opacVisible(org)) return; - if (ov === false && this.opacVisible(org)) return; - - if (filter.inList && filter.inList.indexOf(org.id()) == -1) - return; - - if (filter.notInList && filter.notInList.indexOf(org.id()) > -1) - return; - - // All filter tests passed. Add it to the list - list.push(asId ? org.id() : org); - }); - - return list; - } - - tree(): EgIdlObject { - return this.orgTree; - } - - // get the root OU - root(): EgIdlObject { - return this.orgList[0]; - } - - // list of org_unit objects or IDs for ancestors + me - ancestors(nodeOrId: EgOrgNodeOrId, asId?: boolean): any[] { - let node = this.get(nodeOrId); - if (!node) return []; - let nodes = [node]; - while( (node = this.get(node.parent_ou()))) - nodes.push(node); - if (asId) return nodes.map(n => n.id()); - return nodes; - } - - // tests that a node can have users - canHaveUsers(nodeOrId): boolean { - return this - .get(nodeOrId) - .ou_type() - .can_have_users() == 't'; - } - - // tests that a node can have volumes - canHaveVolumes(nodeOrId): boolean { - return this - .get(nodeOrId) - .ou_type() - .can_have_vols() == 't'; - } - - opacVisible(nodeOrId): boolean { - return this.get(nodeOrId).opac_visible() == 't'; - } - - // list of org_unit objects or IDs for me + descendants - descendants(nodeOrId: EgOrgNodeOrId, asId?: boolean): any[] { - let node = this.get(nodeOrId); - if (!node) return []; - let nodes = []; - function descend(n) { - nodes.push(n); - n.children().forEach(descend); - } - descend(node); - if (asId) - return nodes.map(function(n){return n.id()}); - return nodes; - } - - // list of org_unit objects or IDs for ancestors + me + descendants - fullPath(nodeOrId: EgOrgNodeOrId, asId?: boolean): any[] { - let list = this.ancestors(nodeOrId, false).concat( - this.descendants(nodeOrId, false).slice(1)); - if (asId) - return list.map(function(n){return n.id()}); - return list; - } - - sortTree(sortField?: string, node?: EgIdlObject): void { - if (!sortField) sortField = 'shortname'; - if (!node) node = this.orgTree; - node.children( - node.children.sort((a, b) => { - return a[sortField]() < b[sortField]() ? -1 : 1 - }) - ); - node.children.forEach(n => this.sortTree(n)); - } - - absorbTree(node?: EgIdlObject): void { - if (!node) { - node = this.orgTree; - this.orgMap = {}; - this.orgList = []; - } - this.orgMap[node.id()] = node; - this.orgList.push(node); - node.children().forEach(c => this.absorbTree(c)); - } - - /** - * Grabs all of the org units from the server, chops them up into - * various shapes, then returns an "all done" promise. - */ - fetchOrgs(): Promise { - return this.pcrud.search('aou', {parent_ou : null}, - {flesh : -1, flesh_fields : {aou : ['children', 'ou_type']}}, - {anonymous : true} - ).toPromise().then(tree => { - // ingest tree, etc. - this.orgTree = tree; - this.absorbTree(); - }); - } - - /** - * Populate 'target' with settings from cache where available. - * Return the list of settings /not/ pulled from cache. - */ - private settingsFromCache(names: string[], target: any) { - let cacheKeys = Object.keys(this.settingsCache); - - cacheKeys.forEach(key => { - let matchIdx = names.indexOf(key); - if (matchIdx > -1) { - target[key] = this.settingsCache[key]; - names.splice(matchIdx, 1); - } - }); - - return names; - } - - /** - * Fetch org settings from the network. - * 'auth' is null for anonymous lookup. - */ - private settingsFromNet(orgId: number, - names: string[], auth?: string): Promise { - - let settings = {}; - return new Promise((resolve, reject) => { - this.net.request( - 'open-ils.actor', - 'open-ils.actor.ou_setting.ancestor_default.batch', - orgId, names, auth - ).subscribe( - blob => { - Object.keys(blob).forEach(key => { - let val = blob[key]; // null or hash - settings[key] = val ? val.value : null; - }); - resolve(settings); - }, - err => reject(err) - ); - }); - } - - - /** - * - */ - settings(names: string[], - orgId?: number, anonymous?: boolean): Promise { - - let settings = {}; - let auth: string = null; - let useCache: boolean = false; - - if (this.auth.user()) { - if (orgId) { - useCache = orgId == this.auth.user().ws_ou(); - } else { - orgId = this.auth.user().ws_ou(); - useCache = true; - } - - // avoid passing auth token when anonymous is requested. - if (!anonymous) auth = this.auth.token(); - - } else if (!anonymous) { - return Promise.reject( - 'Use "anonymous" To retrieve org settings without an authtoken'); - } - - if (useCache) names = this.settingsFromCache(names, settings); - - // All requested settings found in cache (or name list is empty) - if (names.length == 0) return Promise.resolve(settings); - - return this.settingsFromNet(orgId, names, auth) - .then(settings => { - if (useCache) { - Object.keys(settings).forEach(key => { - this.settingsCache[key] = settings[key]; - }); - } - return settings; - }); - } -} diff --git a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts new file mode 100644 index 0000000000..614f0ca9ef --- /dev/null +++ b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts @@ -0,0 +1,304 @@ +import {Injectable} from '@angular/core'; +import {Observable, Observer} from 'rxjs/Rx'; +import {EgIdlService, EgIdlObject} from './idl.service'; +import {EgNetService, EgNetRequest} from './net.service'; +import {EgAuthService} from './auth.service'; + +// Externally defined. Used here for debugging. +declare var js2JSON: (jsThing:any) => string; +declare var OpenSRF: any; // creating sessions + +interface EgPcrudReqOps { + authoritative?: boolean; + anonymous?: boolean; + idlist?: boolean; + atomic?: boolean; +} + +// For for documentation purposes. +type EgPcrudResponse = any; + +export class EgPcrudContext { + + static verboseLogging: boolean = true; // + static identGenerator: number = 0; // for debug logging + + private ident: number; + private authoritative: boolean; + private xactCloseMode: string; + private cudIdx: number; + private cudAction: string; + private cudLast: EgPcrudResponse; + private cudList: EgIdlObject[]; + + private idl: EgIdlService; + private net: EgNetService; + private auth: EgAuthService; + + // Tracks nested CUD actions + cudObserver: Observer; + + session: any; // OpenSRF.ClientSession + + constructor( // passed in by parent service -- not injected + egIdl: EgIdlService, + egNet: EgNetService, + egAuth: EgAuthService + ) { + this.idl = egIdl; + this.net = egNet; + this.auth = egAuth; + this.xactCloseMode = 'rollback'; + this.ident = EgPcrudContext.identGenerator++; + this.session = new OpenSRF.ClientSession('open-ils.pcrud'); + } + + toString(): string { + return '[PCRUDContext ' + this.ident + ']'; + } + + log(msg: string): void { + if (EgPcrudContext.verboseLogging) + console.debug(this + ': ' + msg); + } + + err(msg: string): void { + console.error(this + ': ' + msg); + } + + token(reqOps?: EgPcrudReqOps): string { + return (reqOps && reqOps.anonymous) ? + 'ANONYMOUS' : this.auth.token(); + } + + connect(): Promise { + this.log('connect'); + return new Promise( (resolve, reject) => { + this.session.connect({ + onconnect : () => { resolve(this); } + }); + }) + } + + disconnect(): void { + this.log('disconnect'); + this.session.disconnect(); + } + + retrieve(fmClass: string, pkey: Number | string, + pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable { + if (!reqOps) reqOps = {}; + this.authoritative = reqOps.authoritative || false; + return this.dispatch( + `open-ils.pcrud.retrieve.${fmClass}`, + [this.token(reqOps), pkey, pcrudOps]); + } + + retrieveAll(fmClass: string, pcrudOps?: any, + reqOps?: EgPcrudReqOps): Observable { + let search = {}; + search[this.idl.classes[fmClass].pkey] = {'!=' : null}; + return this.search(fmClass, search, pcrudOps, reqOps); + } + + search(fmClass: string, search: any, + pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable { + reqOps = reqOps || {}; + this.authoritative = reqOps.authoritative || false; + + let returnType = reqOps.idlist ? 'id_list' : 'search'; + let method = `open-ils.pcrud.${returnType}.${fmClass}`; + + if (reqOps.atomic) method += '.atomic'; + + return this.dispatch(method, [this.token(reqOps), search, pcrudOps]); + } + + create(list: EgIdlObject[]): Observable { + return this.cud('create', list) + } + update(list: EgIdlObject[]): Observable { + return this.cud('update', list) + } + remove(list: EgIdlObject[]): Observable { + return this.cud('delete', list) + } + autoApply(list: EgIdlObject[]): Observable { // RENAMED + return this.cud('auto', list) + } + + xactClose(): Observable { + return this.sendRequest( + 'open-ils.pcrud.transaction.' + this.xactCloseMode, + [this.token()] + ); + }; + + xactBegin(): Observable { + return this.sendRequest( + 'open-ils.pcrud.transaction.begin', [this.token()] + ); + }; + + private dispatch(method: string, params: any[]): Observable { + if (this.authoritative) { + return this.wrapXact(() => { + return this.sendRequest(method, params); + }); + } else { + return this.sendRequest(method, params) + } + }; + + + // => connect + // => xact_begin + // => action + // => xact_close(commit/rollback) + // => disconnect + wrapXact(mainFunc: () => Observable): Observable { + return Observable.create(observer => { + + // 1. connect + this.connect() + + // 2. start the transaction + .then(() => {return this.xactBegin().toPromise()}) + + // 3. execute the main body + .then(() => { + + mainFunc().subscribe( + res => observer.next(res), + err => observer.error(err), + () => { + this.xactClose().toPromise().then(() => { + // 5. disconnect + this.disconnect(); + // 6. all done + observer.complete(); + }); + } + ); + }) + }); + }; + + private sendRequest(method: string, + params: any[]): Observable { + + this.log(`sendRequest(${method})`); + + return this.net.requestCompiled( + new EgNetRequest( + 'open-ils.pcrud', method, params, this.session) + ); + } + + private cud(action: string, + list: EgIdlObject | EgIdlObject[]): Observable { + + this.log(`CUD(): ${action}`); + + this.cudIdx = 0; + this.cudAction = action; + this.xactCloseMode = 'commit'; + + if (!Array.isArray(list)) this.cudList = [list]; + + return this.wrapXact(() => { + return Observable.create(observer => { + this.cudObserver = observer; + this.nextCudRequest(); + }); + }); + } + + /** + * Loops through the list of objects to update and sends + * them one at a time to the server for processing. Once + * all are done, the cudObserver is resolved. + */ + nextCudRequest(): void { + if (this.cudIdx >= this.cudList.length) { + this.cudObserver.complete(); + return; + } + + let action = this.cudAction; + let fmObj = this.cudList[this.cudIdx++]; + + if (action == 'auto') { + if (fmObj.ischanged()) action = 'update'; + if (fmObj.isnew()) action = 'create'; + if (fmObj.isdeleted()) action = 'delete'; + + if (action == 'auto') { + // object does not need updating; move along + this.nextCudRequest(); + } + } + + this.sendRequest( + `open-ils.pcrud.${action}.${fmObj.classname}`, + [this.token(), fmObj] + ).subscribe( + res => this.cudObserver.next(res), + err => this.cudObserver.error(err), + () => this.nextCudRequest() + ); + }; +} + +@Injectable() +export class EgPcrudService { + + constructor( + private idl: EgIdlService, + private net: EgNetService, + private auth: EgAuthService + ) {} + + // Pass-thru functions for one-off PCRUD calls + + connect(): Promise { + return this.newContext().connect(); + } + + newContext(): EgPcrudContext { + return new EgPcrudContext(this.idl, this.net, this.auth); + } + + retrieve(fmClass: string, pkey: Number | string, + pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable { + return this.newContext().retrieve(fmClass, pkey, pcrudOps, reqOps); + } + + retrieveAll(fmClass: string, pcrudOps?: any, + reqOps?: EgPcrudReqOps): Observable { + return this.newContext().retrieveAll(fmClass, pcrudOps, reqOps); + } + + search(fmClass: string, search: any, + pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable { + return this.newContext().search(fmClass, search, pcrudOps, reqOps); + } + + create(list: EgIdlObject[]): Observable { + return this.newContext().create(list); + } + + update(list: EgIdlObject[]): Observable { + return this.newContext().update(list); + } + + remove(list: EgIdlObject[]): Observable { + return this.newContext().remove(list); + } + + autoApply(list: EgIdlObject[]): Observable { + return this.newContext().autoApply(list); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/core/pcrud.ts b/Open-ILS/src/eg2/src/app/core/pcrud.ts deleted file mode 100644 index 6a8dc7dcf9..0000000000 --- a/Open-ILS/src/eg2/src/app/core/pcrud.ts +++ /dev/null @@ -1,304 +0,0 @@ -import {Injectable} from '@angular/core'; -import {Observable, Observer} from 'rxjs/Rx'; -import {EgIdlService, EgIdlObject} from './idl'; -import {EgNetService, EgNetRequest} from './net'; -import {EgAuthService} from './auth'; - -// Externally defined. Used here for debugging. -declare var js2JSON: (jsThing:any) => string; -declare var OpenSRF: any; // creating sessions - -interface EgPcrudReqOps { - authoritative?: boolean; - anonymous?: boolean; - idlist?: boolean; - atomic?: boolean; -} - -// For for documentation purposes. -type EgPcrudResponse = any; - -export class EgPcrudContext { - - static verboseLogging: boolean = true; // - static identGenerator: number = 0; // for debug logging - - private ident: number; - private authoritative: boolean; - private xactCloseMode: string; - private cudIdx: number; - private cudAction: string; - private cudLast: EgPcrudResponse; - private cudList: EgIdlObject[]; - - private idl: EgIdlService; - private net: EgNetService; - private auth: EgAuthService; - - // Tracks nested CUD actions - cudObserver: Observer; - - session: any; // OpenSRF.ClientSession - - constructor( // passed in by parent service -- not injected - egIdl: EgIdlService, - egNet: EgNetService, - egAuth: EgAuthService - ) { - this.idl = egIdl; - this.net = egNet; - this.auth = egAuth; - this.xactCloseMode = 'rollback'; - this.ident = EgPcrudContext.identGenerator++; - this.session = new OpenSRF.ClientSession('open-ils.pcrud'); - } - - toString(): string { - return '[PCRUDContext ' + this.ident + ']'; - } - - log(msg: string): void { - if (EgPcrudContext.verboseLogging) - console.debug(this + ': ' + msg); - } - - err(msg: string): void { - console.error(this + ': ' + msg); - } - - token(reqOps?: EgPcrudReqOps): string { - return (reqOps && reqOps.anonymous) ? - 'ANONYMOUS' : this.auth.token(); - } - - connect(): Promise { - this.log('connect'); - return new Promise( (resolve, reject) => { - this.session.connect({ - onconnect : () => { resolve(this); } - }); - }) - } - - disconnect(): void { - this.log('disconnect'); - this.session.disconnect(); - } - - retrieve(fmClass: string, pkey: Number | string, - pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable { - if (!reqOps) reqOps = {}; - this.authoritative = reqOps.authoritative || false; - return this.dispatch( - `open-ils.pcrud.retrieve.${fmClass}`, - [this.token(reqOps), pkey, pcrudOps]); - } - - retrieveAll(fmClass: string, pcrudOps?: any, - reqOps?: EgPcrudReqOps): Observable { - let search = {}; - search[this.idl.classes[fmClass].pkey] = {'!=' : null}; - return this.search(fmClass, search, pcrudOps, reqOps); - } - - search(fmClass: string, search: any, - pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable { - reqOps = reqOps || {}; - this.authoritative = reqOps.authoritative || false; - - let returnType = reqOps.idlist ? 'id_list' : 'search'; - let method = `open-ils.pcrud.${returnType}.${fmClass}`; - - if (reqOps.atomic) method += '.atomic'; - - return this.dispatch(method, [this.token(reqOps), search, pcrudOps]); - } - - create(list: EgIdlObject[]): Observable { - return this.cud('create', list) - } - update(list: EgIdlObject[]): Observable { - return this.cud('update', list) - } - remove(list: EgIdlObject[]): Observable { - return this.cud('delete', list) - } - autoApply(list: EgIdlObject[]): Observable { // RENAMED - return this.cud('auto', list) - } - - xactClose(): Observable { - return this.sendRequest( - 'open-ils.pcrud.transaction.' + this.xactCloseMode, - [this.token()] - ); - }; - - xactBegin(): Observable { - return this.sendRequest( - 'open-ils.pcrud.transaction.begin', [this.token()] - ); - }; - - private dispatch(method: string, params: any[]): Observable { - if (this.authoritative) { - return this.wrapXact(() => { - return this.sendRequest(method, params); - }); - } else { - return this.sendRequest(method, params) - } - }; - - - // => connect - // => xact_begin - // => action - // => xact_close(commit/rollback) - // => disconnect - wrapXact(mainFunc: () => Observable): Observable { - return Observable.create(observer => { - - // 1. connect - this.connect() - - // 2. start the transaction - .then(() => {return this.xactBegin().toPromise()}) - - // 3. execute the main body - .then(() => { - - mainFunc().subscribe( - res => observer.next(res), - err => observer.error(err), - () => { - this.xactClose().toPromise().then(() => { - // 5. disconnect - this.disconnect(); - // 6. all done - observer.complete(); - }); - } - ); - }) - }); - }; - - private sendRequest(method: string, - params: any[]): Observable { - - this.log(`sendRequest(${method})`); - - return this.net.requestCompiled( - new EgNetRequest( - 'open-ils.pcrud', method, params, this.session) - ); - } - - private cud(action: string, - list: EgIdlObject | EgIdlObject[]): Observable { - - this.log(`CUD(): ${action}`); - - this.cudIdx = 0; - this.cudAction = action; - this.xactCloseMode = 'commit'; - - if (!Array.isArray(list)) this.cudList = [list]; - - return this.wrapXact(() => { - return Observable.create(observer => { - this.cudObserver = observer; - this.nextCudRequest(); - }); - }); - } - - /** - * Loops through the list of objects to update and sends - * them one at a time to the server for processing. Once - * all are done, the cudObserver is resolved. - */ - nextCudRequest(): void { - if (this.cudIdx >= this.cudList.length) { - this.cudObserver.complete(); - return; - } - - let action = this.cudAction; - let fmObj = this.cudList[this.cudIdx++]; - - if (action == 'auto') { - if (fmObj.ischanged()) action = 'update'; - if (fmObj.isnew()) action = 'create'; - if (fmObj.isdeleted()) action = 'delete'; - - if (action == 'auto') { - // object does not need updating; move along - this.nextCudRequest(); - } - } - - this.sendRequest( - `open-ils.pcrud.${action}.${fmObj.classname}`, - [this.token(), fmObj] - ).subscribe( - res => this.cudObserver.next(res), - err => this.cudObserver.error(err), - () => this.nextCudRequest() - ); - }; -} - -@Injectable() -export class EgPcrudService { - - constructor( - private idl: EgIdlService, - private net: EgNetService, - private auth: EgAuthService - ) {} - - // Pass-thru functions for one-off PCRUD calls - - connect(): Promise { - return this.newContext().connect(); - } - - newContext(): EgPcrudContext { - return new EgPcrudContext(this.idl, this.net, this.auth); - } - - retrieve(fmClass: string, pkey: Number | string, - pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable { - return this.newContext().retrieve(fmClass, pkey, pcrudOps, reqOps); - } - - retrieveAll(fmClass: string, pcrudOps?: any, - reqOps?: EgPcrudReqOps): Observable { - return this.newContext().retrieveAll(fmClass, pcrudOps, reqOps); - } - - search(fmClass: string, search: any, - pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable { - return this.newContext().search(fmClass, search, pcrudOps, reqOps); - } - - create(list: EgIdlObject[]): Observable { - return this.newContext().create(list); - } - - update(list: EgIdlObject[]): Observable { - return this.newContext().update(list); - } - - remove(list: EgIdlObject[]): Observable { - return this.newContext().remove(list); - } - - autoApply(list: EgIdlObject[]): Observable { - return this.newContext().autoApply(list); - } -} - - diff --git a/Open-ILS/src/eg2/src/app/core/perm.service.ts b/Open-ILS/src/eg2/src/app/core/perm.service.ts new file mode 100644 index 0000000000..a2c439bbec --- /dev/null +++ b/Open-ILS/src/eg2/src/app/core/perm.service.ts @@ -0,0 +1,58 @@ +import {Injectable} from '@angular/core'; +import {EgNetService} from './net.service'; +import {EgOrgService} from './org.service'; +import {EgAuthService} from './auth.service'; + +interface HasPermAtResult { + [permName: string]: number[]; +} + +interface HasPermHereResult { + [permName: string]: boolean; +} + +@Injectable() +export class EgPermService { + + constructor( + private net: EgNetService, + private org: EgOrgService, + private auth: EgAuthService, + ) {} + + // workstation not required. + hasWorkPermAt(permNames: string[], asId?: boolean): Promise { + return this.net.request( + 'open-ils.actor', + 'open-ils.actor.user.has_work_perm_at.batch', + this.auth.token(), permNames + ).toPromise().then(resp => { + var answer: HasPermAtResult = {}; + permNames.forEach(perm => { + var orgs = []; + resp[perm].forEach(oneOrg => { + orgs = orgs.concat(this.org.descendants(oneOrg, asId)); + }); + answer[perm] = orgs; + }); + + return answer; + }); + } + + // workstation required + hasWorkPermHere(permNames: string[]): Promise { + let wsId: number = +this.auth.user().wsid(); + + if (!wsId) + return Promise.reject('hasWorkPermHere requires a workstation'); + + return this.hasWorkPermAt(permNames, true).then(resp => { + let answer: HasPermHereResult = {}; + Object.keys(resp).forEach(perm => { + answer[perm] = resp[perm].indexOf(wsId) > -1; + }); + return answer; + }); + } +} diff --git a/Open-ILS/src/eg2/src/app/core/perm.ts b/Open-ILS/src/eg2/src/app/core/perm.ts deleted file mode 100644 index 6f7cd9faae..0000000000 --- a/Open-ILS/src/eg2/src/app/core/perm.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {Injectable} from '@angular/core'; -import {EgNetService} from './net'; -import {EgOrgService} from './org'; -import {EgAuthService} from './auth'; - -interface HasPermAtResult { - [permName: string]: number[]; -} - -interface HasPermHereResult { - [permName: string]: boolean; -} - -@Injectable() -export class EgPermService { - - constructor( - private net: EgNetService, - private org: EgOrgService, - private auth: EgAuthService, - ) {} - - // workstation not required. - hasWorkPermAt(permNames: string[], asId?: boolean): Promise { - return this.net.request( - 'open-ils.actor', - 'open-ils.actor.user.has_work_perm_at.batch', - this.auth.token(), permNames - ).toPromise().then(resp => { - var answer: HasPermAtResult = {}; - permNames.forEach(perm => { - var orgs = []; - resp[perm].forEach(oneOrg => { - orgs = orgs.concat(this.org.descendants(oneOrg, asId)); - }); - answer[perm] = orgs; - }); - - return answer; - }); - } - - // workstation required - hasWorkPermHere(permNames: string[]): Promise { - let wsId: number = +this.auth.user().wsid(); - - if (!wsId) - return Promise.reject('hasWorkPermHere requires a workstation'); - - return this.hasWorkPermAt(permNames, true).then(resp => { - let answer: HasPermHereResult = {}; - Object.keys(resp).forEach(perm => { - answer[perm] = resp[perm].indexOf(wsId) > -1; - }); - return answer; - }); - } -} diff --git a/Open-ILS/src/eg2/src/app/core/store.service.ts b/Open-ILS/src/eg2/src/app/core/store.service.ts new file mode 100644 index 0000000000..218ad8375b --- /dev/null +++ b/Open-ILS/src/eg2/src/app/core/store.service.ts @@ -0,0 +1,117 @@ +/** + * Store and retrieve data from various sources. + */ +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs/Rx'; +import {CookieService} from 'ngx-cookie'; + +@Injectable() +export class EgStoreService { + + // Base path for cookie-based storage. + // Useful for limiting cookies to subsections of the application. + // Store cookies globally by default. + // Note cookies shared with /eg/staff must be stored at "/" + loginSessionBasePath: string = '/'; + + // Set of keys whose values should disappear at logout. + loginSessionKeys: string[] = [ + 'eg.auth.token', + 'eg.auth.time', + 'eg.auth.token.oc', + 'eg.auth.time.oc' + ]; + + constructor(private cookieService: CookieService) {} + + private parseJson(valJson: string): any { + if (valJson == null || valJson == '') return null; + try { + return JSON.parse(valJson); + } catch(E) { + console.error(`Failure to parse JSON: ${E} => ${valJson}`); + return null; + } + } + + /** + * Add a an app-local login session key + */ + addLoginSessionKey(key: string): void { + this.loginSessionKeys.push(key); + } + + 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 { + return Promise.resolve(); + } + + setSessionItem(key: string, val: any, isJson?: Boolean): void { + if (!isJson) val = JSON.stringify(val); + window.sessionStorage.setItem(key, val); + } + + setLoginSessionItem(key: string, val: any, isJson?:Boolean): void { + if (!isJson) val = JSON.stringify(val); + this.cookieService.put(key, val, {path : this.loginSessionBasePath}); + } + + getItem(key: string): Promise { + // TODO: route keys appropriately + return Promise.resolve(this.getLocalItem(key)); + } + + getLocalItem(key: string): any { + return this.parseJson(window.localStorage.getItem(key)); + } + + getServerItem(key: string): Promise { + return Promise.resolve(); + } + + getSessionItem(key: string): any { + return this.parseJson(window.sessionStorage.getItem(key)); + } + + getLoginSessionItem(key: string): any { + return this.parseJson(this.cookieService.get(key)); + } + + removeItem(key: string): Promise { + // TODO: route keys appropriately + return Promise.resolve(this.removeLocalItem(key)); + } + + removeLocalItem(key: string): void { + window.localStorage.removeItem(key); + } + + removeServerItem(key: string): Promise { + return Promise.resolve(); + } + + removeSessionItem(key: string): void { + window.sessionStorage.removeItem(key); + } + + removeLoginSessionItem(key: string): void { + this.cookieService.remove(key, {path : this.loginSessionBasePath}); + } + + clearLoginSessionItems(): void { + this.loginSessionKeys.forEach( + key => this.removeLoginSessionItem(key) + ); + } +} + diff --git a/Open-ILS/src/eg2/src/app/core/store.ts b/Open-ILS/src/eg2/src/app/core/store.ts deleted file mode 100644 index 218ad8375b..0000000000 --- a/Open-ILS/src/eg2/src/app/core/store.ts +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Store and retrieve data from various sources. - */ -import {Injectable} from '@angular/core'; -import {Observable} from 'rxjs/Rx'; -import {CookieService} from 'ngx-cookie'; - -@Injectable() -export class EgStoreService { - - // Base path for cookie-based storage. - // Useful for limiting cookies to subsections of the application. - // Store cookies globally by default. - // Note cookies shared with /eg/staff must be stored at "/" - loginSessionBasePath: string = '/'; - - // Set of keys whose values should disappear at logout. - loginSessionKeys: string[] = [ - 'eg.auth.token', - 'eg.auth.time', - 'eg.auth.token.oc', - 'eg.auth.time.oc' - ]; - - constructor(private cookieService: CookieService) {} - - private parseJson(valJson: string): any { - if (valJson == null || valJson == '') return null; - try { - return JSON.parse(valJson); - } catch(E) { - console.error(`Failure to parse JSON: ${E} => ${valJson}`); - return null; - } - } - - /** - * Add a an app-local login session key - */ - addLoginSessionKey(key: string): void { - this.loginSessionKeys.push(key); - } - - 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 { - return Promise.resolve(); - } - - setSessionItem(key: string, val: any, isJson?: Boolean): void { - if (!isJson) val = JSON.stringify(val); - window.sessionStorage.setItem(key, val); - } - - setLoginSessionItem(key: string, val: any, isJson?:Boolean): void { - if (!isJson) val = JSON.stringify(val); - this.cookieService.put(key, val, {path : this.loginSessionBasePath}); - } - - getItem(key: string): Promise { - // TODO: route keys appropriately - return Promise.resolve(this.getLocalItem(key)); - } - - getLocalItem(key: string): any { - return this.parseJson(window.localStorage.getItem(key)); - } - - getServerItem(key: string): Promise { - return Promise.resolve(); - } - - getSessionItem(key: string): any { - return this.parseJson(window.sessionStorage.getItem(key)); - } - - getLoginSessionItem(key: string): any { - return this.parseJson(this.cookieService.get(key)); - } - - removeItem(key: string): Promise { - // TODO: route keys appropriately - return Promise.resolve(this.removeLocalItem(key)); - } - - removeLocalItem(key: string): void { - window.localStorage.removeItem(key); - } - - removeServerItem(key: string): Promise { - return Promise.resolve(); - } - - removeSessionItem(key: string): void { - window.sessionStorage.removeItem(key); - } - - removeLoginSessionItem(key: string): void { - this.cookieService.remove(key, {path : this.loginSessionBasePath}); - } - - clearLoginSessionItems(): void { - this.loginSessionKeys.forEach( - key => this.removeLoginSessionItem(key) - ); - } -} - diff --git a/Open-ILS/src/eg2/src/app/migration.module.ts b/Open-ILS/src/eg2/src/app/migration.module.ts index 92cec105e6..88c84ae7d5 100644 --- a/Open-ILS/src/eg2/src/app/migration.module.ts +++ b/Open-ILS/src/eg2/src/app/migration.module.ts @@ -21,14 +21,14 @@ import {Title} from '@angular/platform-browser'; // Import service handles so we can downgrade them. import {EgCommonModule} from './common.module'; -import {EgEventService} from '@eg/core/event'; -import {EgStoreService} from '@eg/core/store'; -import {EgIdlService} from '@eg/core/idl'; -import {EgNetService} from '@eg/core/net'; -import {EgAuthService} from '@eg/core/auth'; -import {EgPermService} from '@eg/core/perm'; -import {EgPcrudService} from '@eg/core/pcrud'; -import {EgOrgService} from '@eg/core/org'; +import {EgEventService} from '@eg/core/event.service'; +import {EgStoreService} from '@eg/core/store.service'; +import {EgIdlService} from '@eg/core/idl.service'; +import {EgNetService} from '@eg/core/net.service'; +import {EgAuthService} from '@eg/core/auth.service'; +import {EgPermService} from '@eg/core/perm.service'; +import {EgPcrudService} from '@eg/core/pcrud.service'; +import {EgOrgService} from '@eg/core/org.service'; // Downgraded components //import {EgDialogComponent} from '@eg/share/dialog/dialog.component'; diff --git a/Open-ILS/src/eg2/src/app/resolver.service.ts b/Open-ILS/src/eg2/src/app/resolver.service.ts index 8fd14d778d..0049c40452 100644 --- a/Open-ILS/src/eg2/src/app/resolver.service.ts +++ b/Open-ILS/src/eg2/src/app/resolver.service.ts @@ -1,8 +1,8 @@ import {Injectable} from '@angular/core'; import {Router, Resolve, RouterStateSnapshot, ActivatedRouteSnapshot} from '@angular/router'; -import {EgIdlService} from '@eg/core/idl'; -import {EgOrgService} from '@eg/core/org'; +import {EgIdlService} from '@eg/core/idl.service'; +import {EgOrgService} from '@eg/core/org.service'; @Injectable() export class EgBaseResolver implements Resolve> { diff --git a/Open-ILS/src/eg2/src/app/share/catalog/catalog-url.service.ts b/Open-ILS/src/eg2/src/app/share/catalog/catalog-url.service.ts index 932416f2cf..707d44f91e 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/catalog-url.service.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/catalog-url.service.ts @@ -1,6 +1,6 @@ import {Injectable} from '@angular/core'; import {ParamMap} from '@angular/router'; -import {EgOrgService} from '@eg/core/org'; +import {EgOrgService} from '@eg/core/org.service'; import {CatalogSearchContext, FacetFilter} from './search-context'; import {CATALOG_CCVM_FILTERS} from './catalog.service'; diff --git a/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts b/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts index 34336957de..f59c6c12e1 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts @@ -1,9 +1,9 @@ import {Injectable} from '@angular/core'; -import {EgOrgService} from '@eg/core/org'; -import {EgUnapiService} from '@eg/share/unapi'; -import {EgIdlObject} from '@eg/core/idl'; -import {EgNetService} from '@eg/core/net'; -import {EgPcrudService} from '@eg/core/pcrud'; +import {EgOrgService} from '@eg/core/org.service'; +import {EgUnapiService} from '@eg/share/unapi.service'; +import {EgIdlObject} from '@eg/core/idl.service'; +import {EgNetService} from '@eg/core/net.service'; +import {EgPcrudService} from '@eg/core/pcrud.service'; import {CatalogSearchContext, CatalogSearchState} from './search-context'; export const CATALOG_CCVM_FILTERS = [ diff --git a/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts b/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts index 6bd538039b..54224ff8c1 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts @@ -1,5 +1,5 @@ -import {EgOrgService} from '@eg/core/org'; -import {EgIdlObject} from '@eg/core/idl'; +import {EgOrgService} from '@eg/core/org.service'; +import {EgIdlObject} from '@eg/core/idl.service'; import {Pager} from '@eg/share/util/pager'; import {Params} from '@angular/router'; diff --git a/Open-ILS/src/eg2/src/app/share/org-select.component.ts b/Open-ILS/src/eg2/src/app/share/org-select.component.ts index 7738215b4b..f502c9e7fd 100644 --- a/Open-ILS/src/eg2/src/app/share/org-select.component.ts +++ b/Open-ILS/src/eg2/src/app/share/org-select.component.ts @@ -1,10 +1,10 @@ import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {map, debounceTime} from 'rxjs/operators'; -import {EgAuthService} from '@eg/core/auth'; -import {EgStoreService} from '@eg/core/store'; -import {EgOrgService} from '@eg/core/org'; -import {EgIdlObject} from '@eg/core/idl'; +import {EgAuthService} from '@eg/core/auth.service'; +import {EgStoreService} from '@eg/core/store.service'; +import {EgOrgService} from '@eg/core/org.service'; +import {EgIdlObject} from '@eg/core/idl.service'; import {NgbTypeaheadSelectItemEvent} from '@ng-bootstrap/ng-bootstrap'; // Use a unicode char for spacing instead of ASCII=32 so the browser diff --git a/Open-ILS/src/eg2/src/app/share/unapi.service.ts b/Open-ILS/src/eg2/src/app/share/unapi.service.ts new file mode 100644 index 0000000000..9034ae43f0 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/unapi.service.ts @@ -0,0 +1,54 @@ +import {Injectable, EventEmitter} from '@angular/core'; +import {EgOrgService} from '@eg/core/org.service'; + +/* +TODO: Add Display Fields to UNAPI +https://library.biz/opac/extras/unapi?id=tag::U2@bre/1{bre.extern,holdings_xml,mra}/BR1/0&format=mods32 +*/ + +const UNAPI_PATH = '/opac/extras/unapi?id=tag::U2@'; + +interface EgUnapiParams { + target: string; // bre, ... + id: number | string; // 1 | 1,2,3,4,5 + extras: string; // {holdings_xml,mra,...} + format: string; // mods32, marxml, ... + orgId?: number; // org unit ID + depth?: number; // org unit depth +}; + +@Injectable() +export class EgUnapiService { + + constructor(private org: EgOrgService) {} + + createUrl(params: EgUnapiParams): string { + let depth = params.depth || 0; + let org = params.orgId ? this.org.get(params.orgId) : this.org.root(); + + return `${UNAPI_PATH}${params.target}/${params.id}${params.extras}/` + + `${org.shortname()}/${depth}&format=${params.format}`; + } + + getAsXmlDocument(params: EgUnapiParams): Promise { + // XReq creates an XML document for us. Seems like the right + // tool for the job. + let url = this.createUrl(params); + return new Promise((resolve, reject) => { + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4) { + if (this.status == 200) { + resolve(xhttp.responseXML); + } else { + reject(`UNAPI request failed for ${url}`); + } + } + } + xhttp.open("GET", url, true); + xhttp.send(); + }); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/share/unapi.ts b/Open-ILS/src/eg2/src/app/share/unapi.ts deleted file mode 100644 index 28c25896c0..0000000000 --- a/Open-ILS/src/eg2/src/app/share/unapi.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {Injectable, EventEmitter} from '@angular/core'; -import {EgOrgService} from '@eg/core/org'; - -/* -TODO: Add Display Fields to UNAPI -https://library.biz/opac/extras/unapi?id=tag::U2@bre/1{bre.extern,holdings_xml,mra}/BR1/0&format=mods32 -*/ - -const UNAPI_PATH = '/opac/extras/unapi?id=tag::U2@'; - -interface EgUnapiParams { - target: string; // bre, ... - id: number | string; // 1 | 1,2,3,4,5 - extras: string; // {holdings_xml,mra,...} - format: string; // mods32, marxml, ... - orgId?: number; // org unit ID - depth?: number; // org unit depth -}; - -@Injectable() -export class EgUnapiService { - - constructor(private org: EgOrgService) {} - - createUrl(params: EgUnapiParams): string { - let depth = params.depth || 0; - let org = params.orgId ? this.org.get(params.orgId) : this.org.root(); - - return `${UNAPI_PATH}${params.target}/${params.id}${params.extras}/` + - `${org.shortname()}/${depth}&format=${params.format}`; - } - - getAsXmlDocument(params: EgUnapiParams): Promise { - // XReq creates an XML document for us. Seems like the right - // tool for the job. - let url = this.createUrl(params); - return new Promise((resolve, reject) => { - var xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function() { - if (this.readyState == 4) { - if (this.status == 200) { - resolve(xhttp.responseXML); - } else { - reject(`UNAPI request failed for ${url}`); - } - } - } - xhttp.open("GET", url, true); - xhttp.send(); - }); - } -} - - diff --git a/Open-ILS/src/eg2/src/app/staff/admin/workstation/workstations/workstations.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/workstation/workstations/workstations.component.ts index 690a485e62..6ee04d2ad4 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/workstation/workstations/workstations.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/admin/workstation/workstations/workstations.component.ts @@ -1,12 +1,12 @@ import {Component, OnInit, ViewChild} from '@angular/core'; import {Router, ActivatedRoute} from '@angular/router'; -import {EgStoreService} from '@eg/core/store'; -import {EgIdlObject} from '@eg/core/idl'; -import {EgNetService} from '@eg/core/net'; -import {EgPermService} from '@eg/core/perm'; -import {EgAuthService} from '@eg/core/auth'; -import {EgOrgService} from '@eg/core/org'; -import {EgEventService} from '@eg/core/event'; +import {EgStoreService} from '@eg/core/store.service'; +import {EgIdlObject} from '@eg/core/idl.service'; +import {EgNetService} from '@eg/core/net.service'; +import {EgPermService} from '@eg/core/perm.service'; +import {EgAuthService} from '@eg/core/auth.service'; +import {EgOrgService} from '@eg/core/org.service'; +import {EgEventService} from '@eg/core/event.service'; import {EgConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; // Slim version of the WS that's stored in the cache. diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.module.ts b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.module.ts index 80a1499746..7438ec9bae 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.module.ts @@ -1,6 +1,6 @@ import {NgModule} from '@angular/core'; import {EgStaffCommonModule} from '@eg/staff/common.module'; -import {EgUnapiService} from '@eg/share/unapi'; +import {EgUnapiService} from '@eg/share/unapi.service'; import {EgCatalogRoutingModule} from './routing.module'; import {EgCatalogService} from '@eg/share/catalog/catalog.service'; import {EgCatalogUrlService} from '@eg/share/catalog/catalog-url.service'; diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts index 0cf04ca7f2..6cfc715816 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts @@ -1,7 +1,7 @@ import {Injectable} from '@angular/core'; import {Router, ActivatedRoute} from '@angular/router'; -import {EgIdlObject} from '@eg/core/idl'; -import {EgOrgService} from '@eg/core/org'; +import {EgIdlObject} from '@eg/core/idl.service'; +import {EgOrgService} from '@eg/core/org.service'; import {EgCatalogService} from '@eg/share/catalog/catalog.service'; import {EgCatalogUrlService} from '@eg/share/catalog/catalog-url.service'; import {CatalogSearchContext} from '@eg/share/catalog/search-context'; diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/record/copies.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/record/copies.component.ts index cae7920175..d4b69571c3 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/record/copies.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/record/copies.component.ts @@ -1,8 +1,8 @@ import {Component, OnInit, Input} from '@angular/core'; -import {EgNetService} from '@eg/core/net'; +import {EgNetService} from '@eg/core/net.service'; import {StaffCatalogService} from '../catalog.service'; import {Pager} from '@eg/share/util/pager'; -import {EgOrgService} from '@eg/core/org'; +import {EgOrgService} from '@eg/core/org.service'; @Component({ selector: 'eg-catalog-copies', diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts index 61e5759cd8..7df0e4a18b 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts @@ -1,7 +1,7 @@ import {Component, OnInit, Input} from '@angular/core'; import {ActivatedRoute, ParamMap} from '@angular/router'; -import {EgPcrudService} from '@eg/core/pcrud'; -import {EgIdlObject} from '@eg/core/idl'; +import {EgPcrudService} from '@eg/core/pcrud.service'; +import {EgIdlObject} from '@eg/core/idl.service'; import {CatalogSearchContext, CatalogSearchState} from '@eg/share/catalog/search-context'; import {EgCatalogService} from '@eg/share/catalog/catalog.service'; diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/resolver.service.ts b/Open-ILS/src/eg2/src/app/staff/catalog/resolver.service.ts index 8452323a94..f081fc2077 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/resolver.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/resolver.service.ts @@ -2,11 +2,11 @@ import {Injectable} from '@angular/core'; import {Observable, Observer} from 'rxjs/Rx'; import {Router, Resolve, RouterStateSnapshot, ActivatedRouteSnapshot} from '@angular/router'; -import {EgStoreService} from '@eg/core/store'; -import {EgNetService} from '@eg/core/net'; -import {EgOrgService} from '@eg/core/org'; -import {EgAuthService} from '@eg/core/auth'; -import {EgPcrudService} from '@eg/core/pcrud'; +import {EgStoreService} from '@eg/core/store.service'; +import {EgNetService} from '@eg/core/net.service'; +import {EgOrgService} from '@eg/core/org.service'; +import {EgAuthService} from '@eg/core/auth.service'; +import {EgPcrudService} from '@eg/core/pcrud.service'; import {EgCatalogService} from '@eg/share/catalog/catalog.service'; import {StaffCatalogService} from './catalog.service'; diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.ts index cf903f56c2..14f33e2d79 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.ts @@ -1,9 +1,9 @@ import {Component, OnInit, Input} from '@angular/core'; import {Router} from '@angular/router'; -import {EgOrgService} from '@eg/core/org'; +import {EgOrgService} from '@eg/core/org.service'; +import {EgNetService} from '@eg/core/net.service'; import {EgCatalogService} from '@eg/share/catalog/catalog.service'; import {CatalogSearchContext} from '@eg/share/catalog/search-context'; -import {EgNetService} from '@eg/core/net'; import {EgCatalogUrlService} from '@eg/share/catalog/catalog-url.service'; import {StaffCatalogService} from '../catalog.service'; diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts index ff9c259a25..a970154831 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts @@ -6,9 +6,9 @@ import {EgCatalogService} from '@eg/share/catalog/catalog.service'; import {EgCatalogUrlService} from '@eg/share/catalog/catalog-url.service'; import {CatalogSearchContext, CatalogSearchState} from '@eg/share/catalog/search-context'; -import {EgPcrudService} from '@eg/core/pcrud'; +import {EgPcrudService} from '@eg/core/pcrud.service'; import {StaffCatalogService} from '../catalog.service'; -import {EgIdlObject} from '@eg/core/idl'; +import {EgIdlObject} from '@eg/core/idl.service'; @Component({ selector: 'eg-catalog-results', diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/search-form.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/search-form.component.ts index 615e608f34..cf6d66dc6a 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/search-form.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/search-form.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit, AfterViewInit, Renderer} from '@angular/core'; -import {EgIdlObject} from '@eg/core/idl'; -import {EgOrgService} from '@eg/core/org'; +import {EgIdlObject} from '@eg/core/idl.service'; +import {EgOrgService} from '@eg/core/org.service'; import {EgCatalogService,} from '@eg/share/catalog/catalog.service'; import {CatalogSearchContext, CatalogSearchState} from '@eg/share/catalog/search-context'; diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/bcsearch/bcsearch.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/bcsearch/bcsearch.component.ts index 35e9e85a78..86e85f3e7d 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/bcsearch/bcsearch.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/bcsearch/bcsearch.component.ts @@ -1,7 +1,7 @@ import {Component, OnInit, Renderer} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; -import {EgNetService} from '@eg/core/net'; -import {EgAuthService} from '@eg/core/auth'; +import {EgNetService} from '@eg/core/net.service'; +import {EgAuthService} from '@eg/core/auth.service'; @Component({ templateUrl: 'bcsearch.component.html' diff --git a/Open-ILS/src/eg2/src/app/staff/login.component.ts b/Open-ILS/src/eg2/src/app/staff/login.component.ts index 85d0490f25..d46bb749a1 100644 --- a/Open-ILS/src/eg2/src/app/staff/login.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/login.component.ts @@ -1,8 +1,8 @@ import {Component, OnInit, Renderer} from '@angular/core'; import {Location} from '@angular/common'; import {Router, ActivatedRoute} from '@angular/router'; -import {EgAuthService, EgAuthWsState} from '@eg/core/auth'; -import {EgStoreService} from '@eg/core/store'; +import {EgAuthService, EgAuthWsState} from '@eg/core/auth.service'; +import {EgStoreService} from '@eg/core/store.service'; @Component({ templateUrl : './login.component.html' diff --git a/Open-ILS/src/eg2/src/app/staff/nav.component.ts b/Open-ILS/src/eg2/src/app/staff/nav.component.ts index 7b87841e05..32577ad7dd 100644 --- a/Open-ILS/src/eg2/src/app/staff/nav.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/nav.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit} from '@angular/core'; import {ActivatedRoute, Router} from '@angular/router'; -import {EgAuthService} from '@eg/core/auth'; +import {EgAuthService} from '@eg/core/auth.service'; @Component({ selector: 'eg-staff-nav-bar', diff --git a/Open-ILS/src/eg2/src/app/staff/resolver.service.ts b/Open-ILS/src/eg2/src/app/staff/resolver.service.ts index 63a86f9b11..530aeb1b94 100644 --- a/Open-ILS/src/eg2/src/app/staff/resolver.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/resolver.service.ts @@ -3,9 +3,9 @@ import {Location} from '@angular/common'; import {Observable, Observer} from 'rxjs/Rx'; import {Router, Resolve, RouterStateSnapshot, ActivatedRoute, ActivatedRouteSnapshot} from '@angular/router'; -import {EgStoreService} from '@eg/core/store'; -import {EgNetService} from '@eg/core/net'; -import {EgAuthService} from '@eg/core/auth'; +import {EgStoreService} from '@eg/core/store.service'; +import {EgNetService} from '@eg/core/net.service'; +import {EgAuthService} from '@eg/core/auth.service'; /** * Load data used by all staff modules. diff --git a/Open-ILS/src/eg2/src/app/staff/share/bib-summary.component.ts b/Open-ILS/src/eg2/src/app/staff/share/bib-summary.component.ts index 877b18a4f5..c672adda2c 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/bib-summary.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/bib-summary.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit, Input} from '@angular/core'; -import {EgNetService} from '@eg/core/net'; -import {EgPcrudService} from '@eg/core/pcrud'; +import {EgNetService} from '@eg/core/net.service'; +import {EgPcrudService} from '@eg/core/pcrud.service'; import {EgCatalogService} from '@eg/share/catalog/catalog.service'; @Component({ diff --git a/Open-ILS/src/eg2/src/app/staff/staff.component.ts b/Open-ILS/src/eg2/src/app/staff/staff.component.ts index 864beab8eb..7bdce0b274 100644 --- a/Open-ILS/src/eg2/src/app/staff/staff.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/staff.component.ts @@ -1,7 +1,7 @@ import {Component, OnInit, NgZone} from '@angular/core'; import {Router, ActivatedRoute, NavigationEnd} from '@angular/router'; -import {EgAuthService, EgAuthWsState} from '@eg/core/auth'; -import {EgNetService} from '@eg/core/net'; +import {EgAuthService, EgAuthWsState} from '@eg/core/auth.service'; +import {EgNetService} from '@eg/core/net.service'; @Component({ templateUrl: 'staff.component.html',