LP1840050 org unit admin UI WIP
authorBill Erickson <berickxx@gmail.com>
Wed, 14 Aug 2019 20:45:37 +0000 (16:45 -0400)
committerBill Erickson <berickxx@gmail.com>
Fri, 16 Aug 2019 20:40:32 +0000 (16:40 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/core/org.service.ts
Open-ILS/src/eg2/src/app/share/combobox/combobox.component.ts
Open-ILS/src/eg2/src/app/staff/admin/server/org-unit.component.html
Open-ILS/src/eg2/src/app/staff/admin/server/org-unit.component.ts

index c666957..6615851 100644 (file)
@@ -27,6 +27,9 @@ export class OrgService {
     private orgMap: {[id: number]: IdlObject} = {};
     private settingsCache: OrgSettingsBatch = {};
 
+    private orgTypeMap: {[id: number]: IdlObject} = {};
+    private orgTypeList: IdlObject[] = [];
+
     constructor(
         private net: NetService,
         private auth: AuthService,
@@ -44,6 +47,14 @@ export class OrgService {
         return this.orgList;
     }
 
+    typeList(): IdlObject[] {
+        return this.orgTypeList;
+    }
+
+    typeMap(): {[id: number]: IdlObject} {
+        return this.orgTypeMap;
+    }
+
     /**
      * 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.
@@ -162,9 +173,16 @@ export class OrgService {
             node = this.orgTree;
             this.orgMap = {};
             this.orgList = [];
+            this.orgTypeMap = {};
         }
         this.orgMap[node.id()] = node;
         this.orgList.push(node);
+
+        this.orgTypeMap[node.ou_type().id()] = node.ou_type();
+        if (!this.orgTypeList.filter(t => t.id() === node.ou_type().id())[0]) {
+            this.orgTypeList.push(node.ou_type());
+        }
+
         node.children().forEach(c => this.absorbTree(c));
     }
 
index 0696a98..de6831a 100644 (file)
@@ -69,6 +69,21 @@ export class ComboboxComponent implements ControlValueAccessor, OnInit {
     @Input() startId: any;
     @Input() startIdFiresOnChange: boolean;
 
+    // Allow the selected entry ID to be passed via the template
+    // This does NOT not emit onChange events.
+    @Input() set selectedId(id: any) {
+        if (id) { 
+            if (this.entrylist.length) {
+                this.selected = this.entrylist.filter(e => e.id === id)[0];
+            } else {
+                this.startId = id;
+            }
+        }
+    }
+    get selectedId(): any {
+        return this.selected ? this.selected.id : null;
+    }
+
     @Input() idlClass: string;
     @Input() idlField: string;
     @Input() asyncDataSource: (term: string) => Observable<ComboboxEntry>;
@@ -172,6 +187,8 @@ export class ComboboxComponent implements ControlValueAccessor, OnInit {
         if (this.startId &&
             this.entrylist && !this.defaultSelectionApplied) {
 
+            console.log('applyg select ' + this.startId);
+
             const entry =
                 this.entrylist.filter(e => e.id === this.startId)[0];
 
@@ -194,6 +211,7 @@ export class ComboboxComponent implements ControlValueAccessor, OnInit {
 
     // Manually set the selected value by ID.
     // This does NOT fire the onChange handler.
+    // DEPRECATED: use this.selectedId = abc or [selectedId]="abc" instead.
     applyEntryId(entryId: any) {
         this.selected = this.entrylist.filter(e => e.id === entryId)[0];
     }
index 3aad241..4389217 100644 (file)
             <eg-fm-record-editor *ngIf="currentOrg()" #editDialog idlClass="aou" 
               [mode]="currentOrg().isnew() ? 'create': 'update'" [hideBanner]="true" 
               (recordSaved)="orgSaved($event)" displayMode="inline" 
-              readonlyFields="parent,ou_type,parent_ou" 
+              readonlyFields="parent,parent_ou" [preloadLinkedValues]="true"
+              [fieldOptions]="{ou_type: {customValues: orgTypeOptions()}}"
               [record]="currentOrg().isnew() ? currentOrg() : null"
               [recordId]="currentOrg().isnew() ? null : currentOrg().id()"
               fieldOrder="parent_ou,ou_type,name,shortname,phone,email,opac_visible,fiscal_calendar"
               hiddenFields="id,billing_address,mailing_address,holds_address,ill_address">
+              <eg-fm-record-editor-action label="Add Child" i18n-label 
+                [disabled]="orgChildTypes().length === 0"
+                (actionClick)="addChild()"></eg-fm-record-editor-action>
             </eg-fm-record-editor>
           </div>
         </ng-template>
index 6afef79..e2ade99 100644 (file)
@@ -10,6 +10,7 @@ import {StringComponent} from '@eg/share/string/string.component';
 import {StringService} from '@eg/share/string/string.service';
 import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
+import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
 
 @Component({
     templateUrl: './org-unit.component.html'
@@ -212,14 +213,42 @@ export class OrgUnitComponent implements OnInit {
         });
     }
 
+    orgTypeOptions(): ComboboxEntry[] {
+        let ouType = this.currentOrg().ou_type();
+
+        if (typeof ouType === 'number') {
+            // May not be fleshed for new org units
+            ouType = this.org.typeMap()[ouType];
+        }
+        const curDepth = ouType.depth();
+
+        return this.org.typeList()
+            .filter(type_ => type_.depth() === curDepth)
+            .map(type_ => ({id: type_.id(), label: type_.name()}));
+    }
+
+    orgChildTypes(): IdlObject[] {
+        let ouType = this.currentOrg().ou_type();
+
+        if (typeof ouType === 'number') {
+            // May not be fleshed for new org units
+            ouType = this.org.typeMap()[ouType];
+        }
+
+        const depth = ouType.depth();
+        return this.org.typeList()
+            .filter(type_ => type_.depth() === depth + 1);
+    }
+
     addChild() {
         const parentTreeNode = this.selected;
         const parentOrg = parentTreeNode.callerData.orgUnit;
+        const newType = this.orgChildTypes()[0];
 
         const org = this.idl.create('aou');
         org.isnew(true);
-        org.parent(parentOrg.id());
-        // TODO: limit org type selector to types at parent depth + 1
+        org.parent_ou(parentOrg.id());
+        org.ou_type(newType.id());
 
         // Create a dummy, detached org node to keep the UI happy.
         this.selected = new TreeNode({