import {WelcomeComponent} from './welcome.component';
// Import and 'provide' globally required services.
-import {EgEventService} from '@eg/core/event.service';
-import {EgStoreService} from '@eg/core/store.service';
-import {EgIdlService} from '@eg/core/idl.service';
+import {EgEventService} from '@eg/core/event';
+import {EgStoreService} from '@eg/core/store';
+import {EgIdlService} from '@eg/core/idl';
import {EgNetService} from '@eg/core/net.service';
-import {EgAuthService} from '@eg/core/auth.service';
-import {EgPcrudService} from '@eg/core/pcrud.service';
-import {EgOrgService} from '@eg/core/org.service';
+import {EgAuthService} from '@eg/core/auth';
+import {EgPcrudService} from '@eg/core/pcrud';
+import {EgOrgService} from '@eg/core/org';
@NgModule({
declarations: [
+++ /dev/null
-/**
- *
- */
-import { Injectable, EventEmitter } from '@angular/core';
-import { Observable } from 'rxjs/Rx';
-import { EgNetService } from './net.service';
-import { EgEventService, EgEvent } from './event.service';
-import { EgIdlService, EgIdlObject } from './idl.service';
-import { EgStoreService } from './store.service';
-
-// Models a login instance.
-class EgAuthUser {
- user: EgIdlObject;
- workstation: string; // workstation name
- token: string;
- authtime: number;
-
- constructor(token: string, authtime: number, workstation?: string) {
- this.token = token;
- this.workstation = workstation;
- this.authtime = authtime;
- }
-}
-
-// Params required for calling the login() method.
-interface EgAuthLoginArgs {
- username: string,
- password: string,
- type: string,
- workstation?: string
-}
-
-export enum EgAuthWsState {
- PENDING,
- NOT_USED,
- NOT_FOUND_SERVER,
- NOT_FOUND_LOCAL,
- VALID
-};
-
-@Injectable()
-export class EgAuthService {
-
- private activeUser: EgAuthUser;
-
- // opChangeUser refers to the user that has been superseded during
- // an op-change event. This use will become the activeUser once
- // again, when the op-change cycle has completed.
- private opChangeUser: EgAuthUser;
-
- workstationState: EgAuthWsState = EgAuthWsState.PENDING;
-
- redirectUrl: string;
-
- constructor(
- private egEvt: EgEventService,
- private egNet: EgNetService,
- private egStore: EgStoreService
- ) {}
-
- // - Accessor functions alway refer to the active user.
-
- user(): EgIdlObject {
- return this.activeUser.user
- };
-
- // Workstation name.
- workstation(): string {
- return this.activeUser.workstation;
- };
-
- token(): string {
- return this.activeUser ? this.activeUser.token : null;
- };
-
- authtime(): Number {
- return this.activeUser.authtime
- };
-
- // NOTE: EgNetService emits an event if the auth session has expired.
- testAuthToken(): Promise<any> {
-
- this.activeUser = new EgAuthUser(
- this.egStore.getLoginSessionItem('eg.auth.token'),
- this.egStore.getLoginSessionItem('eg.auth.time')
- );
-
- if (!this.token()) return Promise.reject('no authtoken');
-
- return new Promise<any>( (resolve, reject) => {
- this.egNet.request(
- 'open-ils.auth',
- 'open-ils.auth.session.retrieve', this.token()
- ).subscribe(
- user => {
- // EgNetService interceps NO_SESSION events.
- // We can only get here if the session is valid.
- this.activeUser.user = user;
- this.sessionPoll();
- resolve();
- },
- err => { reject(); }
- );
- });
- }
-
- checkWorkstation(): void {
- // TODO:
- // Emits event on invalid workstation.
- }
-
- login(args: EgAuthLoginArgs, isOpChange?: boolean): Promise<void> {
-
- return new Promise<void>((resolve, reject) => {
- this.egNet.request('open-ils.auth', 'open-ils.auth.login', args)
- .subscribe(res => {
- this.handleLoginResponse(args, this.egEvt.parse(res), isOpChange)
- .then(
- ok => resolve(ok),
- notOk => reject(notOk)
- );
- });
- });
- }
-
- handleLoginResponse(
- args: EgAuthLoginArgs, evt: EgEvent, isOpChange: boolean): Promise<void> {
-
- 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.egStore.setLoginSessionItem('eg.auth.token.oc', this.token());
- this.egStore.setLoginSessionItem('eg.auth.time.oc', this.authtime());
- this.opChangeUser = this.activeUser;
- }
-
- this.activeUser = new EgAuthUser(
- evt.payload.authtoken,
- evt.payload.authtime,
- args.workstation
- );
-
- this.egStore.setLoginSessionItem('eg.auth.token', this.token());
- this.egStore.setLoginSessionItem('eg.auth.time', this.authtime());
- }
-
- undoOpChange(): Promise<any> {
- if (this.opChangeUser) {
- this.deleteSession();
- this.activeUser = this.opChangeUser;
- this.opChangeUser = null;
- this.egStore.removeLoginSessionItem('eg.auth.token.oc');
- this.egStore.removeLoginSessionItem('eg.auth.time.oc');
- this.egStore.setLoginSessionItem('eg.auth.token', this.token());
- this.egStore.setLoginSessionItem('eg.auth.time', this.authtime());
- }
- return this.testAuthToken();
- }
-
- sessionPoll(): void {
- // TODO
- }
-
- // Resolves if login workstation matches a workstation known to this
- // browser instance.
- verifyWorkstation(): Promise<void> {
- return new Promise((resolve, reject) => {
-
- if (!this.user()) {
- this.workstationState = EgAuthWsState.PENDING;
- reject();
- return;
- }
-
- if (!this.user().wsid()) {
- this.workstationState = EgAuthWsState.NOT_USED;
- reject();
- return;
- }
-
- this.egStore.getItem('eg.workstation.all')
- .then(workstations => {
- if (!workstations) workstations = [];
-
- let ws = workstations.filter(
- w => {return w.id == this.user().wsid()})[0];
-
- if (ws) {
- this.activeUser.workstation = ws.name;
- this.workstationState = EgAuthWsState.VALID;
- resolve();
- } else {
- this.workstationState = EgAuthWsState.NOT_FOUND_LOCAL;
- reject();
- }
- });
- });
- }
-
- deleteSession(): void {
- if (this.token()) {
- this.egNet.request(
- 'open-ils.auth',
- 'open-ils.auth.session.delete', this.token())
- .subscribe(x => console.log('logged out'))
- }
- }
-
- logout(broadcast?: boolean) {
-
- if (broadcast) {
- // TODO
- //this.authChannel.postMessage({action : 'logout'});
- }
-
- this.deleteSession();
- this.egStore.clearLoginSessionItems();
- this.activeUser = null;
- this.opChangeUser = null;
- }
-}
--- /dev/null
+/**
+ *
+ */
+import { Injectable, EventEmitter } from '@angular/core';
+import { Observable } from 'rxjs/Rx';
+import { EgNetService } from './net.service';
+import { EgEventService, EgEvent } from './event';
+import { EgIdlService, EgIdlObject } from './idl';
+import { EgStoreService } from './store';
+
+// Models a login instance.
+class EgAuthUser {
+ user: EgIdlObject;
+ workstation: string; // workstation name
+ token: string;
+ authtime: number;
+
+ constructor(token: string, authtime: number, workstation?: string) {
+ this.token = token;
+ this.workstation = workstation;
+ this.authtime = authtime;
+ }
+}
+
+// Params required for calling the login() method.
+interface EgAuthLoginArgs {
+ username: string,
+ password: string,
+ type: string,
+ workstation?: string
+}
+
+export enum EgAuthWsState {
+ PENDING,
+ NOT_USED,
+ NOT_FOUND_SERVER,
+ NOT_FOUND_LOCAL,
+ VALID
+};
+
+@Injectable()
+export class EgAuthService {
+
+ private activeUser: EgAuthUser;
+
+ // opChangeUser refers to the user that has been superseded during
+ // an op-change event. This use will become the activeUser once
+ // again, when the op-change cycle has completed.
+ private opChangeUser: EgAuthUser;
+
+ workstationState: EgAuthWsState = EgAuthWsState.PENDING;
+
+ redirectUrl: string;
+
+ constructor(
+ private egEvt: EgEventService,
+ private egNet: EgNetService,
+ private egStore: EgStoreService
+ ) {}
+
+ // - Accessor functions alway refer to the active user.
+
+ user(): EgIdlObject {
+ return this.activeUser.user
+ };
+
+ // Workstation name.
+ workstation(): string {
+ return this.activeUser.workstation;
+ };
+
+ token(): string {
+ return this.activeUser ? this.activeUser.token : null;
+ };
+
+ authtime(): Number {
+ return this.activeUser.authtime
+ };
+
+ // NOTE: EgNetService emits an event if the auth session has expired.
+ testAuthToken(): Promise<any> {
+
+ this.activeUser = new EgAuthUser(
+ this.egStore.getLoginSessionItem('eg.auth.token'),
+ this.egStore.getLoginSessionItem('eg.auth.time')
+ );
+
+ if (!this.token()) return Promise.reject('no authtoken');
+
+ return new Promise<any>( (resolve, reject) => {
+ this.egNet.request(
+ 'open-ils.auth',
+ 'open-ils.auth.session.retrieve', this.token()
+ ).subscribe(
+ user => {
+ // EgNetService interceps NO_SESSION events.
+ // We can only get here if the session is valid.
+ this.activeUser.user = user;
+ this.sessionPoll();
+ resolve();
+ },
+ err => { reject(); }
+ );
+ });
+ }
+
+ checkWorkstation(): void {
+ // TODO:
+ // Emits event on invalid workstation.
+ }
+
+ login(args: EgAuthLoginArgs, isOpChange?: boolean): Promise<void> {
+
+ return new Promise<void>((resolve, reject) => {
+ this.egNet.request('open-ils.auth', 'open-ils.auth.login', args)
+ .subscribe(res => {
+ this.handleLoginResponse(args, this.egEvt.parse(res), isOpChange)
+ .then(
+ ok => resolve(ok),
+ notOk => reject(notOk)
+ );
+ });
+ });
+ }
+
+ handleLoginResponse(
+ args: EgAuthLoginArgs, evt: EgEvent, isOpChange: boolean): Promise<void> {
+
+ 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.egStore.setLoginSessionItem('eg.auth.token.oc', this.token());
+ this.egStore.setLoginSessionItem('eg.auth.time.oc', this.authtime());
+ this.opChangeUser = this.activeUser;
+ }
+
+ this.activeUser = new EgAuthUser(
+ evt.payload.authtoken,
+ evt.payload.authtime,
+ args.workstation
+ );
+
+ this.egStore.setLoginSessionItem('eg.auth.token', this.token());
+ this.egStore.setLoginSessionItem('eg.auth.time', this.authtime());
+ }
+
+ undoOpChange(): Promise<any> {
+ if (this.opChangeUser) {
+ this.deleteSession();
+ this.activeUser = this.opChangeUser;
+ this.opChangeUser = null;
+ this.egStore.removeLoginSessionItem('eg.auth.token.oc');
+ this.egStore.removeLoginSessionItem('eg.auth.time.oc');
+ this.egStore.setLoginSessionItem('eg.auth.token', this.token());
+ this.egStore.setLoginSessionItem('eg.auth.time', this.authtime());
+ }
+ return this.testAuthToken();
+ }
+
+ sessionPoll(): void {
+ // TODO
+ }
+
+ // Resolves if login workstation matches a workstation known to this
+ // browser instance.
+ verifyWorkstation(): Promise<void> {
+ return new Promise((resolve, reject) => {
+
+ if (!this.user()) {
+ this.workstationState = EgAuthWsState.PENDING;
+ reject();
+ return;
+ }
+
+ if (!this.user().wsid()) {
+ this.workstationState = EgAuthWsState.NOT_USED;
+ reject();
+ return;
+ }
+
+ this.egStore.getItem('eg.workstation.all')
+ .then(workstations => {
+ if (!workstations) workstations = [];
+
+ let ws = workstations.filter(
+ w => {return w.id == this.user().wsid()})[0];
+
+ if (ws) {
+ this.activeUser.workstation = ws.name;
+ this.workstationState = EgAuthWsState.VALID;
+ resolve();
+ } else {
+ this.workstationState = EgAuthWsState.NOT_FOUND_LOCAL;
+ reject();
+ }
+ });
+ });
+ }
+
+ deleteSession(): void {
+ if (this.token()) {
+ this.egNet.request(
+ 'open-ils.auth',
+ 'open-ils.auth.session.delete', this.token())
+ .subscribe(x => console.log('logged out'))
+ }
+ }
+
+ logout(broadcast?: boolean) {
+
+ if (broadcast) {
+ // TODO
+ //this.authChannel.postMessage({action : 'logout'});
+ }
+
+ this.deleteSession();
+ this.egStore.clearLoginSessionItems();
+ this.activeUser = null;
+ this.opChangeUser = null;
+ }
+}
+++ /dev/null
-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 = new Number(thing.code);
- evt.ilspermloc = new Number(thing.ilspermloc);
- evt.success = thing.textcode == 'SUCCESS';
-
- return evt;
- }
-
- return null;
- }
-}
-
-
--- /dev/null
+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 = new Number(thing.code);
+ evt.ilspermloc = new Number(thing.ilspermloc);
+ evt.success = thing.textcode == 'SUCCESS';
+
+ return evt;
+ }
+
+ return null;
+ }
+}
+
+
+++ /dev/null
-import { Injectable } from '@angular/core';
-
-// Added globally by /IDL2js
-declare var _preload_fieldmapper_IDL: Object;
-
-/**
- * NOTE: To achieve full type strictness and avoid compile warnings,
- * we would likely have to pre-compile the IDL down to a .ts file with all
- * of the IDL class and field definitions.
- */
-
-/**
- * Every IDL object class implements this interface.
- */
-export interface EgIdlObject {
- a: any[];
- classname: String;
- _isfieldmapper: Boolean;
- // 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 {
- let this_ = this;
- this_.classes = _preload_fieldmapper_IDL;
-
- /**
- * 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);
- };
-}
-
--- /dev/null
+import { Injectable } from '@angular/core';
+
+// Added globally by /IDL2js
+declare var _preload_fieldmapper_IDL: Object;
+
+/**
+ * NOTE: To achieve full type strictness and avoid compile warnings,
+ * we would likely have to pre-compile the IDL down to a .ts file with all
+ * of the IDL class and field definitions.
+ */
+
+/**
+ * Every IDL object class implements this interface.
+ */
+export interface EgIdlObject {
+ a: any[];
+ classname: String;
+ _isfieldmapper: Boolean;
+ // 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 {
+ let this_ = this;
+ this_.classes = _preload_fieldmapper_IDL;
+
+ /**
+ * 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);
+ };
+}
+
*/
import { Injectable, EventEmitter } from '@angular/core';
import { Observable, Observer } from 'rxjs/Rx';
-import { EgEventService, EgEvent } from './event.service';
+import { EgEventService, EgEvent } from './event';
// Global vars from opensrf.js
// These are availavble at runtime, but are not exported.
+++ /dev/null
-import {Injectable} from '@angular/core';
-import {Observable} from 'rxjs/Rx';
-import {EgIdlObject, EgIdlService} from './idl.service';
-import {EgPcrudService} from './pcrud.service';
-
-type EgOrgNodeOrId = number | EgIdlObject;
-
-@Injectable()
-export class EgOrgService {
-
- private orgMap = {};
- private orgList: EgIdlObject[] = [];
- private orgTree: EgIdlObject; // root node + children
-
- constructor(
- private egPcrud: EgPcrudService
- ) {}
-
- get(nodeOrId: EgOrgNodeOrId): EgIdlObject {
- if (typeof nodeOrId == 'object')
- return nodeOrId;
- return this.orgMap[nodeOrId];
- };
-
- list(): EgIdlObject[] {
- return this.orgList;
- };
-
- 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): EgIdlObject[] {
- 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(function(n){return 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';
- }
-
- // list of org_unit objects or IDs for me + descendants
- descendants(nodeOrId: EgOrgNodeOrId, asId: Boolean): EgIdlObject[] {
- 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): EgIdlObject[] {
- 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<void> {
-
- console.log('fetching..');
- return this.egPcrud.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();
- console.log('TREE FETCHED: ' + tree);
- });
- }
-
- // NOTE: see ./org-settings.service for settings
- // TODO: ^--
-}
--- /dev/null
+import {Injectable} from '@angular/core';
+import {Observable} from 'rxjs/Rx';
+import {EgIdlObject, EgIdlService} from './idl';
+import {EgPcrudService} from './pcrud';
+
+type EgOrgNodeOrId = number | EgIdlObject;
+
+@Injectable()
+export class EgOrgService {
+
+ private orgMap = {};
+ private orgList: EgIdlObject[] = [];
+ private orgTree: EgIdlObject; // root node + children
+
+ constructor(
+ private egPcrud: EgPcrudService
+ ) {}
+
+ get(nodeOrId: EgOrgNodeOrId): EgIdlObject {
+ if (typeof nodeOrId == 'object')
+ return nodeOrId;
+ return this.orgMap[nodeOrId];
+ };
+
+ list(): EgIdlObject[] {
+ return this.orgList;
+ };
+
+ 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): EgIdlObject[] {
+ 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(function(n){return 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';
+ }
+
+ // list of org_unit objects or IDs for me + descendants
+ descendants(nodeOrId: EgOrgNodeOrId, asId: Boolean): EgIdlObject[] {
+ 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): EgIdlObject[] {
+ 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<void> {
+
+ console.log('fetching..');
+ return this.egPcrud.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();
+ console.log('TREE FETCHED: ' + tree);
+ });
+ }
+
+ // NOTE: see ./org-settings.service for settings
+ // TODO: ^--
+}
+++ /dev/null
-import {Injectable} from '@angular/core';
-import {Observable, Observer} from 'rxjs/Rx';
-//import {toPromise} from 'rxjs/operators';
-import {EgIdlService, EgIdlObject} from './idl.service';
-import {EgNetService, EgNetRequest} from './net.service';
-import {EgAuthService} from './auth.service';
-
-// Used for debugging.
-declare var js2JSON: (jsThing:any) => string;
-declare var OpenSRF: any; // creating sessions
-
-export 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 egIdl: EgIdlService;
- private egNet: EgNetService;
- private egAuth: EgAuthService;
-
- // Tracks nested CUD actions
- cudObserver: Observer<EgPcrudResponse>;
-
- session: any; // OpenSRF.ClientSession
-
- constructor( // passed in by parent service -- not injected
- egIdl: EgIdlService,
- egNet: EgNetService,
- egAuth: EgAuthService
- ) {
- this.egIdl = egIdl;
- this.egNet = egNet;
- this.egAuth = 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.egAuth.token();
- }
-
- connect(): Promise<EgPcrudContext> {
- 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<EgPcrudResponse> {
- 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<EgPcrudResponse> {
- let search = {};
- search[this.egIdl.classes[fmClass].pkey] = {'!=' : null};
- return this.search(fmClass, search, pcrudOps, reqOps);
- }
-
- search(fmClass: string, search: any,
- pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable<EgPcrudResponse> {
- 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<EgPcrudResponse> {
- return this.cud('create', list)
- }
- update(list: EgIdlObject[]): Observable<EgPcrudResponse> {
- return this.cud('update', list)
- }
- remove(list: EgIdlObject[]): Observable<EgPcrudResponse> {
- return this.cud('delete', list)
- }
- autoApply(list: EgIdlObject[]): Observable<EgPcrudResponse> { // RENAMED
- return this.cud('auto', list)
- }
-
- xactClose(): Observable<EgPcrudResponse> {
- return this.sendRequest(
- 'open-ils.pcrud.transaction.' + this.xactCloseMode,
- [this.token()]
- );
- };
-
- xactBegin(): Observable<EgPcrudResponse> {
- return this.sendRequest(
- 'open-ils.pcrud.transaction.begin', [this.token()]
- );
- };
-
- private dispatch(method: string, params: any[]): Observable<EgPcrudResponse> {
- 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<EgPcrudResponse>): Observable<EgPcrudResponse> {
- let this_ = this;
-
- 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<EgPcrudResponse> {
-
- this.log(`sendRequest(${method})`);
-
- return this.egNet.requestCompiled(
- new EgNetRequest(
- 'open-ils.pcrud', method, params, this.session)
- );
- }
-
- private cud(action: string,
- list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
-
- this.log(`CUD(): ${action}`);
-
- this.cudIdx = 0;
- this.cudAction = action;
- this.xactCloseMode = 'commit';
-
- if (!Array.isArray(list)) this.cudList = [list];
-
- let this_ = this;
-
- 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 {
- let this_ = this;
-
- 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 egIdl: EgIdlService,
- private egNet: EgNetService,
- private egAuth: EgAuthService
- ) {}
-
- // Pass-thru functions for one-off PCRUD calls
-
- connect(): Promise<EgPcrudContext> {
- return this.newContext().connect();
- }
-
- newContext(): EgPcrudContext {
- return new EgPcrudContext(this.egIdl, this.egNet, this.egAuth);
- }
-
- retrieve(fmClass: string, pkey: Number | string,
- pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable<EgPcrudResponse> {
- return this.newContext().retrieve(fmClass, pkey, pcrudOps, reqOps);
- }
-
- retrieveAll(fmClass: string, pcrudOps?: any,
- reqOps?: EgPcrudReqOps): Observable<EgPcrudResponse> {
- return this.newContext().retrieveAll(fmClass, pcrudOps, reqOps);
- }
-
- search(fmClass: string, search: any,
- pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable<EgPcrudResponse> {
- return this.newContext().search(fmClass, search, pcrudOps, reqOps);
- }
-
- create(list: EgIdlObject[]): Observable<EgPcrudResponse> {
- return this.newContext().create(list);
- }
-
- update(list: EgIdlObject[]): Observable<EgPcrudResponse> {
- return this.newContext().update(list);
- }
-
- remove(list: EgIdlObject[]): Observable<EgPcrudResponse> {
- return this.newContext().remove(list);
- }
-
- autoApply(list: EgIdlObject[]): Observable<EgPcrudResponse> {
- return this.newContext().autoApply(list);
- }
-}
-
-
--- /dev/null
+import {Injectable} from '@angular/core';
+import {Observable, Observer} from 'rxjs/Rx';
+//import {toPromise} from 'rxjs/operators';
+import {EgIdlService, EgIdlObject} from './idl';
+import {EgNetService, EgNetRequest} from './net.service';
+import {EgAuthService} from './auth';
+
+// Used for debugging.
+declare var js2JSON: (jsThing:any) => string;
+declare var OpenSRF: any; // creating sessions
+
+export 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 egIdl: EgIdlService;
+ private egNet: EgNetService;
+ private egAuth: EgAuthService;
+
+ // Tracks nested CUD actions
+ cudObserver: Observer<EgPcrudResponse>;
+
+ session: any; // OpenSRF.ClientSession
+
+ constructor( // passed in by parent service -- not injected
+ egIdl: EgIdlService,
+ egNet: EgNetService,
+ egAuth: EgAuthService
+ ) {
+ this.egIdl = egIdl;
+ this.egNet = egNet;
+ this.egAuth = 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.egAuth.token();
+ }
+
+ connect(): Promise<EgPcrudContext> {
+ 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<EgPcrudResponse> {
+ 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<EgPcrudResponse> {
+ let search = {};
+ search[this.egIdl.classes[fmClass].pkey] = {'!=' : null};
+ return this.search(fmClass, search, pcrudOps, reqOps);
+ }
+
+ search(fmClass: string, search: any,
+ pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable<EgPcrudResponse> {
+ 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<EgPcrudResponse> {
+ return this.cud('create', list)
+ }
+ update(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ return this.cud('update', list)
+ }
+ remove(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ return this.cud('delete', list)
+ }
+ autoApply(list: EgIdlObject[]): Observable<EgPcrudResponse> { // RENAMED
+ return this.cud('auto', list)
+ }
+
+ xactClose(): Observable<EgPcrudResponse> {
+ return this.sendRequest(
+ 'open-ils.pcrud.transaction.' + this.xactCloseMode,
+ [this.token()]
+ );
+ };
+
+ xactBegin(): Observable<EgPcrudResponse> {
+ return this.sendRequest(
+ 'open-ils.pcrud.transaction.begin', [this.token()]
+ );
+ };
+
+ private dispatch(method: string, params: any[]): Observable<EgPcrudResponse> {
+ 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<EgPcrudResponse>): Observable<EgPcrudResponse> {
+ let this_ = this;
+
+ 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<EgPcrudResponse> {
+
+ this.log(`sendRequest(${method})`);
+
+ return this.egNet.requestCompiled(
+ new EgNetRequest(
+ 'open-ils.pcrud', method, params, this.session)
+ );
+ }
+
+ private cud(action: string,
+ list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
+
+ this.log(`CUD(): ${action}`);
+
+ this.cudIdx = 0;
+ this.cudAction = action;
+ this.xactCloseMode = 'commit';
+
+ if (!Array.isArray(list)) this.cudList = [list];
+
+ let this_ = this;
+
+ 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 {
+ let this_ = this;
+
+ 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 egIdl: EgIdlService,
+ private egNet: EgNetService,
+ private egAuth: EgAuthService
+ ) {}
+
+ // Pass-thru functions for one-off PCRUD calls
+
+ connect(): Promise<EgPcrudContext> {
+ return this.newContext().connect();
+ }
+
+ newContext(): EgPcrudContext {
+ return new EgPcrudContext(this.egIdl, this.egNet, this.egAuth);
+ }
+
+ retrieve(fmClass: string, pkey: Number | string,
+ pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable<EgPcrudResponse> {
+ return this.newContext().retrieve(fmClass, pkey, pcrudOps, reqOps);
+ }
+
+ retrieveAll(fmClass: string, pcrudOps?: any,
+ reqOps?: EgPcrudReqOps): Observable<EgPcrudResponse> {
+ return this.newContext().retrieveAll(fmClass, pcrudOps, reqOps);
+ }
+
+ search(fmClass: string, search: any,
+ pcrudOps?: any, reqOps?: EgPcrudReqOps): Observable<EgPcrudResponse> {
+ return this.newContext().search(fmClass, search, pcrudOps, reqOps);
+ }
+
+ create(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ return this.newContext().create(list);
+ }
+
+ update(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ return this.newContext().update(list);
+ }
+
+ remove(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ return this.newContext().remove(list);
+ }
+
+ autoApply(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ return this.newContext().autoApply(list);
+ }
+}
+
+
+++ /dev/null
-/**
- * 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.
- 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<any> {
- // 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<any> {
- 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);
- console.log(`storing ses item ${key} : ${val}`);
- this.cookieService.put(key, val, {path : this.loginSessionBasePath});
- }
-
- getItem(key: string): Promise<any> {
- // 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<any> {
- 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<any> {
- // TODO: route keys appropriately
- return Promise.resolve(this.removeLocalItem(key));
- }
-
- removeLocalItem(key: string): void {
- window.localStorage.removeItem(key);
- }
-
- removeServerItem(key: string): Promise<any> {
- 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)
- );
- }
-}
-
--- /dev/null
+/**
+ * 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.
+ 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<any> {
+ // 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<any> {
+ 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);
+ console.log(`storing ses item ${key} : ${val}`);
+ this.cookieService.put(key, val, {path : this.loginSessionBasePath});
+ }
+
+ getItem(key: string): Promise<any> {
+ // 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<any> {
+ 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<any> {
+ // TODO: route keys appropriately
+ return Promise.resolve(this.removeLocalItem(key));
+ }
+
+ removeLocalItem(key: string): void {
+ window.localStorage.removeItem(key);
+ }
+
+ removeServerItem(key: string): Promise<any> {
+ 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)
+ );
+ }
+}
+
import {Injectable} from '@angular/core';
import {Router, Resolve, RouterStateSnapshot,
ActivatedRouteSnapshot} from '@angular/router';
-import {EgIdlService} from '@eg/core/idl.service';
-import {EgOrgService} from '@eg/core/org.service';
+import {EgIdlService} from '@eg/core/idl';
+import {EgOrgService} from '@eg/core/org';
@Injectable()
export class EgBaseResolver implements Resolve<Promise<void>> {
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
-import {EgStoreService} from '@eg/core/store.service';
-import {EgIdlObject} from '@eg/core/idl.service';
+import {EgStoreService} from '@eg/core/store';
+import {EgIdlObject} from '@eg/core/idl';
import {EgNetService} from '@eg/core/net.service';
-import {EgAuthService} from '@eg/core/auth.service';
-import {EgOrgService} from '@eg/core/org.service';
+import {EgAuthService} from '@eg/core/auth';
+import {EgOrgService} from '@eg/core/org';
// Slim version of the WS that's stored in the cache.
interface Workstation {
selectedId: Number;
workstations: Workstation[] = [];
isRemoving: boolean = false;
-
newOwner: EgIdlObject;
newName: String;
private route: ActivatedRoute,
private egNet: EgNetService,
private egAuth: EgAuthService,
- private egStore: EgStoreService
+ private egStore: EgStoreService,
+ private egOrg: EgOrgService
) {}
ngOnInit() {
this.egStore.getItem('eg.workstation.all')
.then(res => this.workstations = res);
+
+ this.newOwner = this.egOrg.root();
}
selected(): Workstation {
}
registerWorkstation(): void {
- console.log('registering ' + this.newName);
+ console.log(this.newOwner);
+ console.log('registering ' + this.newName + ' : ' + this.newOwner.shortname());
}
}
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { EgNetService } from '@eg/core/net.service';
-import { EgAuthService } from '@eg/core/auth.service';
+import { EgAuthService } from '@eg/core/auth';
@Component({
templateUrl: 'bcsearch.component.html'
import { Component, OnInit, Renderer } from '@angular/core';
import { Location } from '@angular/common';
import { Router } from '@angular/router';
-import { EgAuthService, EgAuthWsState } from '@eg/core/auth.service';
-import { EgStoreService } from '@eg/core/store.service'; // TODO: testing
+import { EgAuthService, EgAuthWsState } from '@eg/core/auth';
+import { EgStoreService } from '@eg/core/store'; // TODO: testing
@Component({
templateUrl : './login.component.html'
import { Observable, Observer } from 'rxjs/Rx';
import { Router, Resolve, RouterStateSnapshot,
ActivatedRouteSnapshot } from '@angular/router';
-import { EgStoreService } from '@eg/core/store.service';
+import { EgStoreService } from '@eg/core/store';
import { EgNetService } from '@eg/core/net.service';
-import { EgAuthService } from '@eg/core/auth.service';
+import { EgAuthService } from '@eg/core/auth';
/**
* Apply configuration, etc. required by all staff components.
-
+<style>
+ .org-depth-1 { padding-left:3px; }
+ .org-depth-2 { padding-left:6px; }
+ .org-depth-3 { padding-left:9px; }
+ .org-depth-4 { padding-left:12px; }
+</style>
<div>
<input type="text"
class="form-control"
import {Component, OnInit, Input} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {map, tap, debounceTime, distinctUntilChanged} from 'rxjs/operators';
-import {EgAuthService} from '@eg/core/auth.service';
-import {EgStoreService} from '@eg/core/store.service';
-import {EgIdlObject} from '@eg/core/idl.service';
+import {EgAuthService} from '@eg/core/auth';
+import {EgStoreService} from '@eg/core/store';
+import {EgOrgService} from '@eg/core/org';
+import {EgIdlObject} from '@eg/core/idl';
@Component({
selector: 'eg-org-select',
templateUrl: './org-select.component.html'
})
-
export class EgOrgSelectComponent implements OnInit {
@Input() placeholder: String;
constructor(
private egAuth: EgAuthService,
- private egStore: EgStoreService
+ private egStore: EgStoreService,
+ private egOrg: EgOrgService
) {}
ngOnInit() {
}
- states = ['Alabama', 'Alaska', 'American Samoa', 'Arizona'];
-
orgFilter = (text$: Observable<string>): Observable<string[]> => {
return text$
.debounceTime(100)
.distinctUntilChanged()
- .map(term => this.states.filter(
- v => v.toLowerCase().indexOf(term.toLowerCase()) > -1)
- );
+ .map(term => {
+ return this.egOrg.list().filter(org => {
+ let sn = org.shortname().toLowerCase();
+ return sn.indexOf(term.toLowerCase()) > -1
+ }).map(org => {
+ // The browser won't collapse multiple spaces when
+ // using a space-ish unicode char instead of regular spaces.
+ let space = ' '; // U+2007
+ let sn = org.shortname();
+ for (var i = 0; i < org.ou_type().depth(); i++) {
+ sn = space + sn;
+ }
+ return sn;
+ })
+ });
}
}
-
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
-import { EgAuthService, EgAuthWsState } from '@eg/core/auth.service';
+import { EgAuthService, EgAuthWsState } from '@eg/core/auth';
import { EgNetService } from '@eg/core/net.service';
@Component({