LP#626157 Ang2 experiments
authorBill Erickson <berickxx@gmail.com>
Mon, 18 Dec 2017 15:45:33 +0000 (10:45 -0500)
committerBill Erickson <berickxx@gmail.com>
Mon, 18 Dec 2017 15:45:36 +0000 (10:45 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/eg2-src/src/app/core/auth.ts
Open-ILS/eg2-src/src/app/core/net.ts
Open-ILS/eg2-src/src/app/core/org.ts
Open-ILS/eg2-src/src/app/staff/catalog/resolver.service.ts

index 9052f3a..aba9dea 100644 (file)
@@ -1,12 +1,9 @@
-/**
- * 
- */
-import { Injectable, EventEmitter } from '@angular/core';
-import { Observable } from 'rxjs/Rx';
-import { EgNetService } from './net';
-import { EgEventService, EgEvent } from './event';
-import { EgIdlService, EgIdlObject } from './idl';
-import { EgStoreService } from './store';
+import {Injectable, EventEmitter} from '@angular/core';
+import {Observable} from 'rxjs/Rx';
+import {EgNetService} from './net';
+import {EgEventService, EgEvent} from './event';
+import {EgIdlService, EgIdlObject} from './idl';
+import {EgStoreService} from './store';
 
 // Models a login instance.
 class EgAuthUser {
index b037de1..121601c 100644 (file)
@@ -90,34 +90,34 @@ export class EgNetService {
     // Version with pre-compiled EgNetRequest object
     sendCompiledRequest(request: EgNetRequest): void {
         OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS;
-        var this_ = this;
+        console.debug(`EgNet: request ${request.method}`);
 
         request.session.request({
             async  : true,
             method : request.method,
             params : request.params,
-            oncomplete : function() {
+            oncomplete : () => {
                 // A superseded request will be complete()'ed by the 
                 // superseder at a later time.
                 if (!request.superseded)
                     request.observer.complete();
             },
-            onresponse : function(r) {
-                this_.dispatchResponse(request, r.recv().content());
+            onresponse : r => {
+                this.dispatchResponse(request, r.recv().content());
             },
-            onerror : function(errmsg) {
+            onerror : errmsg => {
                 let msg = `${request.method} failed! See server logs. ${errmsg}`;
                 console.error(msg);
                 request.observer.error(msg);
             },
-            onmethoderror : function(req, statCode, statMsg) { 
+            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);
+                    this.authExpired$.emit(request);
                 }
 
                 request.observer.error(msg);
@@ -128,7 +128,7 @@ export class EgNetService {
 
     // Relay response object to the caller for typical/successful responses.  
     // Applies special handling to response events that require global attention.
-    private dispatchResponse = function(request, response) {
+    private dispatchResponse(request, response): void {
         request.evt = this.egEvt.parse(response);
 
         if (request.evt) {
index 44eddd6..bc1124a 100644 (file)
@@ -1,6 +1,8 @@
 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;
@@ -11,14 +13,21 @@ interface OrgFilter {
     opacVisible?: boolean;
 }
 
+interface OrgSettingsBatch {
+    [key: string]: any;
+}
+
 @Injectable()
 export class EgOrgService {
 
     private orgMap = {};
     private orgList: EgIdlObject[] = [];
     private orgTree: EgIdlObject; // root node + children
+    private settingsCache: OrgSettingsBatch = {};
 
     constructor(
+        private net: EgNetService,
+        private auth: EgAuthService,
         private pcrud: EgPcrudService
     ) {}
 
@@ -160,6 +169,90 @@ export class EgOrgService {
         });
     }
 
-    // NOTE: see ./org-settings.service for settings 
-    // TODO: ^--
+    /** 
+     * 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<any> {
+
+        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<OrgSettingsBatch> {
+
+        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;
+        });
+    }
 }
index 8929d55..67cfbac 100644 (file)
@@ -1,10 +1,10 @@
 import {Injectable} from '@angular/core';
-import {Location} from '@angular/common';
 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 {EgCatalogService} from '@eg/share/catalog/catalog.service';
@@ -14,8 +14,8 @@ export class EgCatalogResolver implements Resolve<Promise<any[]>> {
 
     constructor(
         private router: Router, 
-        private ngLocation: Location,
         private store: EgStoreService,
+        private org: EgOrgService,
         private net: EgNetService,
         private auth: EgAuthService,
         private cat: EgCatalogService
@@ -29,7 +29,14 @@ export class EgCatalogResolver implements Resolve<Promise<any[]>> {
 
         return Promise.all([
             this.cat.fetchCcvms(),
-            this.cat.fetchCmfs()
+            this.cat.fetchCmfs(),
+            this.fetchSettings()
+        ]);
+    }
+
+    fetchSettings(): Promise<any> {
+        return this.org.settings([
+            // catalog-related org settings loaded here...
         ]);
     }
 }