LP1861701 Staff catalog copy location groups WIP
authorBill Erickson <berickxx@gmail.com>
Mon, 3 Feb 2020 17:08:14 +0000 (12:08 -0500)
committerBill Erickson <berickxx@gmail.com>
Mon, 3 Feb 2020 17:08:14 +0000 (12:08 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/catalog/catalog-common.module.ts
Open-ILS/src/eg2/src/app/share/catalog/eg-org-copy-loc-select.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/share/catalog/org-copy-loc-select.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/catalog/search-form.component.html
Open-ILS/src/eg2/src/app/staff/catalog/search-form.component.ts

index 5b45d00..2bc4718 100644 (file)
@@ -1,5 +1,6 @@
 import {NgModule} from '@angular/core';
 import {EgCommonModule} from '@eg/common.module';
+import {CommonWidgetsModule} from '@eg/share/common-widgets.module';
 import {CatalogService} from './catalog.service';
 import {AnonCacheService} from '@eg/share/util/anon-cache.service';
 import {BasketService} from './basket.service';
@@ -7,17 +8,21 @@ import {CatalogUrlService} from './catalog-url.service';
 import {BibRecordService} from './bib-record.service';
 import {UnapiService} from './unapi.service';
 import {MarcHtmlComponent} from './marc-html.component';
+import {OrgCopyLocSelectComponent} from './org-copy-loc-select.component';
 
 
 @NgModule({
     declarations: [
-        MarcHtmlComponent
+        MarcHtmlComponent,
+        OrgCopyLocSelectComponent
     ],
     imports: [
-        EgCommonModule
+        EgCommonModule,
+        CommonWidgetsModule
     ],
     exports: [
-        MarcHtmlComponent
+        MarcHtmlComponent,
+        OrgCopyLocSelectComponent
     ],
     providers: [
         AnonCacheService,
diff --git a/Open-ILS/src/eg2/src/app/share/catalog/eg-org-copy-loc-select.html b/Open-ILS/src/eg2/src/app/share/catalog/eg-org-copy-loc-select.html
new file mode 100644 (file)
index 0000000..6a0d087
--- /dev/null
@@ -0,0 +1,2 @@
+
+<eg-combobox #cbox></eg-combobox>
diff --git a/Open-ILS/src/eg2/src/app/share/catalog/org-copy-loc-select.component.ts b/Open-ILS/src/eg2/src/app/share/catalog/org-copy-loc-select.component.ts
new file mode 100644 (file)
index 0000000..0f8db65
--- /dev/null
@@ -0,0 +1,116 @@
+import {Component, EventEmitter, OnInit, AfterViewInit, Input,
+    Output, ViewChild, forwardRef} from '@angular/core';
+import {ControlValueAccessor, FormGroup, FormControl, NG_VALUE_ACCESSOR} from '@angular/forms';
+import {IdlObject} from '@eg/core/idl.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {OrgService} from '@eg/core/org.service';
+import {AuthService} from '@eg/core/auth.service';
+import {ComboboxComponent, ComboboxEntry} from '@eg/share/combobox/combobox.component';
+
+/** Ingtegrated org unit and copy location selector */
+
+const PAD_SPACE = ' '; // U+2007
+
+@Component({
+  selector: 'eg-org-copy-loc-select',
+  templateUrl: 'eg-org-copy-loc-select.html',
+  providers: [
+    {
+      provide: NG_VALUE_ACCESSOR,
+      useExisting: forwardRef(() => OrgCopyLocSelectComponent),
+      multi: true
+    }
+  ]
+})
+export class OrgCopyLocSelectComponent implements AfterViewInit {
+
+    @Input() orgDisplayField = 'shortname';
+
+    @ViewChild('cbox', {static: false}) cbox: ComboboxComponent;
+
+    entries: ComboboxEntry[] = [];
+
+    propagateChange = (_: ComboboxEntry) => {};
+    propagateTouch = () => {};
+
+    constructor(
+        private org: OrgService,
+        private pcrud: PcrudService,
+        private auth: AuthService
+    ) {}
+
+    ngAfterViewInit() {
+        this.pcrud.search('acplg',
+            {owner: this.org.fullPath(this.auth.user().ws_ou(), true)},
+            {}, {atomic: true}
+        ).toPromise().then(groups => this.buildTree(groups));
+    }
+
+    buildTree(groups: IdlObject[], org?: IdlObject) {
+
+        if (!org) {
+            org = this.org.root();
+            this.entries = [];
+        }
+
+        const depth = org.ou_type().depth();
+
+        // Current org unit
+        this.entries.push({
+            id: 'org_' + org.id(),
+            label: this.formatLabel(org[this.orgDisplayField](), depth)
+        });
+
+        // Groups sorted above this org unit's children.
+        groups
+            .filter(grp => grp.owner() === org.id() && grp.top() === 't')
+            .sort((a, b) => a.pos() < b.pos() ? -1 : 1)
+            .forEach(grp => this.entries.push({
+                id: 'grp_' + grp.id(),
+                label: this.formatLabel(grp.name(), depth + 1)
+            }));
+
+        // Org unit children
+        org.children()
+            .sort((a, b) => a[this.orgDisplayField]() < b[this.orgDisplayField]() ? -1 : 1)
+            .forEach(org => this.buildTree(groups, org));
+
+        // Groups sorted below this org unit's children.
+        groups
+            .filter(grp => grp.owner() === org.id() && grp.top() === 'f')
+            .sort((a, b) => a.pos() < b.pos() ? -1 : 1)
+            .forEach(grp => this.entries.push({
+                id: 'grp_' + grp.id(),
+                label: this.formatLabel(grp.name(), depth + 1)
+            }));
+
+        if (org.id() === this.org.root().id()) {
+            // Pass the list of entries afters fully compiled.
+            this.cbox.entries = this.entries;
+        }
+    }
+
+    formatLabel(label: string, depth: number): string {
+        return PAD_SPACE.repeat(depth) + label;
+    }
+
+    cboxChange(entry: ComboboxEntry) {
+        this.propagateChange(entry);
+    }
+
+    writeValue(entry: ComboboxEntry) {
+        if (this.cbox) {
+            this.cbox.selectedId = entry ? entry.id : null;
+        }
+    }
+
+    registerOnChange(fn) {
+        this.propagateChange = fn;
+    }
+
+    registerOnTouched(fn) {
+        this.propagateTouch = fn;
+    }
+}
+
+
index d032f3d..a0fd96a 100644 (file)
@@ -319,11 +319,15 @@ TODO focus search input
         <div class="card">
           <div class="card-body">
             <div class="float-right d-flex">
+              <!--
               <eg-org-select 
                 (onChange)="orgOnChange($event)"
                 [initialOrg]="context.searchOrg"
                 [placeholder]="'Library'" >
               </eg-org-select>
+              -->
+              <eg-org-copy-loc-select [(ngModel)]="orgCopyLoc">
+              </eg-org-copy-loc-select>
               <button class="btn btn-success mr-1 ml-1" type="button"
                 [disabled]="searchIsActive()"
                 (click)="context.pager.offset=0;searchByForm()" i18n>
index 84dd830..3287e1d 100644 (file)
@@ -6,6 +6,7 @@ import {CatalogService} from '@eg/share/catalog/catalog.service';
 import {CatalogSearchContext, CatalogSearchState} from '@eg/share/catalog/search-context';
 import {StaffCatalogService} from './catalog.service';
 import {NgbTabset, NgbTabChangeEvent} from '@ng-bootstrap/ng-bootstrap';
+import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
 
 @Component({
   selector: 'eg-catalog-search-form',
@@ -20,6 +21,7 @@ export class SearchFormComponent implements OnInit, AfterViewInit {
     showSearchFilters = false;
     copyLocations: IdlObject[];
     searchTab: string;
+    orgCopyLoc: ComboboxEntry;
 
     constructor(
         private renderer: Renderer2,