LP#626157 Ang2 experiments
authorBill Erickson <berickxx@gmail.com>
Thu, 30 Nov 2017 22:05:22 +0000 (17:05 -0500)
committerBill Erickson <berickxx@gmail.com>
Mon, 5 Mar 2018 17:24:06 +0000 (17:24 +0000)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/webby-src/src/app/staff/admin/workstation/workstations.component.html
Open-ILS/webby-src/src/app/staff/admin/workstation/workstations.component.ts
Open-ILS/webby-src/src/app/staff/share/org-select.component.html
Open-ILS/webby-src/src/app/staff/share/org-select.component.ts

index d3b6bb4..cc6fc30 100644 (file)
@@ -13,7 +13,9 @@
     <div class="row mt-2">
       <div class="col-2">
         <eg-org-select 
-          [selectedOrg]="newOwner"
+          [onChange]="orgOnChange"
+          [shouldHide]="shouldHideOrg"
+          [shouldDisable]="shouldDisableOrg"
           [placeholder]="'Owner'" >
         </eg-org-select>
       </div>
index 231bcb4..456e2c2 100644 (file)
@@ -24,6 +24,21 @@ export class EgWorkstationsComponent implements OnInit {
     newOwner: EgIdlObject;
     newName: String;
 
+    // Org selector callbacks
+    shouldDisableOrg = (org: EgIdlObject): boolean => {
+        // TODO: check register perms too
+        return !this.egOrg.canHaveUsers(org);
+    }
+
+    shouldHideOrg = (org: EgIdlObject): boolean => {
+        return org.id() == 1; // XXX TESTING
+    }
+
+    orgOnChange = (org: EgIdlObject): void => {
+        console.log('org changed to ' + org.shortname());
+    }
+
+
     constructor(
         private route: ActivatedRoute,
         private egNet: EgNetService,
index 50ec19b..d7b9101 100644 (file)
@@ -1,14 +1,15 @@
-<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" 
-    [placeholder]="placeholder"
-    [(ngModel)]="selectedOrg" 
-    [ngbTypeahead]="orgFilter"
-  />
-</div>
+
+<!-- todo disabled -->
+<ng-template #displayTemplate let-r="result">
+{{r.label}}
+</ng-template>
+
+<input type="text" 
+  class="form-control" 
+  [placeholder]="placeholder"
+  [(ngModel)]="selected" 
+  [ngbTypeahead]="filter"
+  [resultTemplate]="displayTemplate"
+  [inputFormatter]="formatter"
+  (selectItem)="orgChanged($event)"
+/>
index 4c81aea..ee1fa5f 100644 (file)
@@ -1,28 +1,42 @@
 import {Component, OnInit, Input} from '@angular/core';
 import {Observable} from 'rxjs/Observable';
-import {map, tap, debounceTime, distinctUntilChanged} from 'rxjs/operators';
+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 {NgbTypeaheadSelectItemEvent} from '@ng-bootstrap/ng-bootstrap';
+
+// Use a unicode char for spacing instead of ASCII=32 so the browser 
+// won't collapse the nested display entries down to a single space.
+const PAD_SPACE: string = ' '; // U+2007 
+
+interface OrgDisplay {
+  id: number;
+  label: string;
+  disabled: boolean;
+}
 
 @Component({
   selector: 'eg-org-select',
   templateUrl: './org-select.component.html'
 })
-
 export class EgOrgSelectComponent implements OnInit {
 
+    selected: OrgDisplay;
+
+    // Read-only properties optionally provided by the calling component.
     @Input() placeholder: String;
-    @Input() selectedOrg: EgIdlObject;
-    @Input() displayField: String = 'shortname';
+    @Input() initialOrg: EgIdlObject;
     @Input() stickySetting: String;
-    @Input() onChange: (org:EgIdlObject) => void;
-    @Input() shouldDisable: (org:EgIdlObject) => Boolean;
-    @Input() shouldHide: (org:EgIdlObject) => Boolean;
-    @Input() allDisabled: Boolean = false;
+    @Input() displayField: String = 'shortname';
 
-    testString: String = '';
+    // Call-backs
+    // Note onChange could be handled via an EventEmitter, but
+    // should* functions require real time two-way communication.
+    @Input() onChange: (org:EgIdlObject) => void;
+    @Input() shouldDisable: (org:EgIdlObject) => boolean;
+    @Input() shouldHide: (org:EgIdlObject) => boolean;
 
     constructor(
       private egAuth: EgAuthService,
@@ -33,23 +47,39 @@ export class EgOrgSelectComponent implements OnInit {
     ngOnInit() {
     }
 
-    orgFilter = (text$: Observable<string>): Observable<string[]> => {
+    orgChanged(selEvent: NgbTypeaheadSelectItemEvent) {
+        if (this.onChange) {
+            this.onChange(this.egOrg.get(selEvent.item.id));
+        }
+    }
+
+    // Formats the selected value
+    formatter = (result: OrgDisplay) => result.label.trim();
+
+    filter = (text$: Observable<string>): Observable<OrgDisplay[]> => {
         return text$
             .debounceTime(100)
             .distinctUntilChanged()
             .map(term => {
+
+                // TODO: displayField / shortname
                 return this.egOrg.list().filter(org => {
-                    let sn = org.shortname().toLowerCase(); 
-                    return sn.indexOf(term.toLowerCase()) > -1
+
+                    // Find orgs matching the search term
+                    return org.shortname()
+                      .toLowerCase().indexOf(term.toLowerCase()) > -1
+
+                }).filter(org => {
+                    // Exclude hidden orgs
+                    return !this.shouldHide || !this.shouldHide(org)
+
                 }).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 {
+                        id : org.id(),
+                        label : PAD_SPACE.repeat(org.ou_type().depth()) + org.shortname(),
+                        disabled : this.shouldDisable && this.shouldDisable(org)
                     }
-                    return sn;
                 })
             });
     }