LP#1775466 Catalog copies now use grid
authorBill Erickson <berickxx@gmail.com>
Fri, 22 Jun 2018 16:47:03 +0000 (12:47 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 5 Sep 2018 14:05:23 +0000 (10:05 -0400)
For added display flexibility, grid printing, possible future
multi-select actions.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/grid/grid-column.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid.ts
Open-ILS/src/eg2/src/app/staff/catalog/catalog.module.ts
Open-ILS/src/eg2/src/app/staff/catalog/record/copies.component.html
Open-ILS/src/eg2/src/app/staff/catalog/record/copies.component.ts

index 34548a9..dd8adb2 100644 (file)
@@ -47,6 +47,7 @@ export class GridColumnComponent implements OnInit {
         col.cellContext = this.cellContext;
         col.isSortable = this.sortable;
         col.isMultiSortable = this.multiSortable;
+        col.datatype = this.datatype;
         this.grid.context.columnSet.add(col);
     }
 }
index 3a967a7..4b4fc84 100644 (file)
@@ -80,7 +80,7 @@ export class GridColumnSet {
     }
 
     idlInfoFromDotpath(dotpath: string): any {
-        if (!dotpath) { return null; }
+        if (!dotpath || !this.idlClass) { return null; }
 
         let idlParent;
         let idlField;
index e9870e9..b8de7cb 100644 (file)
@@ -1,5 +1,6 @@
 import {NgModule} from '@angular/core';
 import {StaffCommonModule} from '@eg/staff/common.module';
+import {GridModule} from '@eg/share/grid/grid.module';
 import {UnapiService} from '@eg/share/catalog/unapi.service';
 import {CatalogRoutingModule} from './routing.module';
 import {CatalogService} from '@eg/share/catalog/catalog.service';
@@ -33,6 +34,7 @@ import {MarcViewComponent} from './record/marc-view.component';
   ],
   imports: [
     StaffCommonModule,
+    GridModule,
     CatalogRoutingModule
   ],
   providers: [
index 8c7a4f3..e7d8249 100644 (file)
@@ -1,71 +1,53 @@
-<div class='eg-copies w-100'>
-  <ul class="pagination mb-1">
-    <li class="page-item" [ngClass]="{disabled : pager.offset == 0}">
-      <a class="no-href page-link" 
-        i18n-aria-label aria-label="Start" (click)="firstPage()">
-        <span i18n>Start</span>
-      </a>
-    </li>
-    <li class="page-item" [ngClass]="{disabled : pager.offset == 0}">
-      <a class="no-href page-link" 
-        i18n-aria-label aria-label="Previous" (click)="prevPage()">
-        <span i18n>Previous</span>
-      </a>
-    </li>
-    <!-- note disable logic is incomplete -->
-    <li class="page-item"
-      [ngClass]="{disabled: copies.length < pager.limit}">
-      <a class="no-href page-link" 
-        i18n-aria-label aria-label="Next" (click)="nextPage()">
-        <span i18n>Next</span>
-      </a>
-    </li>
-  </ul>
-  <div class='card tight-card w-100'>
-    <div class="card-header font-weight-bold d-flex bg-info">
-      <div class="flex-1" i18n>Location</div>
-      <div class="flex-1 pl-1" i18n>Call Number / Copy Notes</div>
-      <div class="flex-1 pl-1" i18n>Barcode</div>
-      <div class="flex-1 pl-1" i18n>Shelving Location</div>
-      <div class="flex-1 pl-1" i18n>Circulation Modifier</div>
-      <div class="flex-1 pl-1" i18n>Age Hold Protection</div>
-      <div class="flex-1 pl-1" i18n>Active/Create Date</div>
-      <div class="flex-1 pl-1" i18n>Holdable?</div>
-      <div class="flex-1 pl-1" i18n>Status</div>
-      <div class="flex-1 pl-1" i18n>Due Date</div>
-    </div>
-    <div class="card-body">
-      <ul class="list-group list-group-flush" *ngIf="copies && copies.length">
-        <li class="list-group-item" *ngFor="let copy of copies; let idx = index" 
-          [ngClass]="{'list-group-item-info': (idx % 2) == 1}">
-          <div class="d-flex">
-            <div class="flex-1" i18n>{{orgName(copy.circ_lib)}}</div>
-            <div class="flex-1 pl-1" i18n>
-              {{copy.call_number_prefix_label}}
-              {{copy.call_number_label}}
-              {{copy.call_number_suffix_label}}
-            </div>
-            <div class="flex-1 pl-1">
-              {{copy.barcode}}
-              <a class="pl-1" href="/eg/staff/cat/item/{{copy.id}}" i18n>View</a>
-              | 
-              <a class="pl-1" href="/eg/staff/cat/item/{{copy.id}}/edit" i18n>Edit</a>
-            </div>
-            <div class="flex-1 pl-1" i18n>{{copy.copy_location}}</div>
-            <div class="flex-1 pl-1" i18n>{{copy.circ_modifier || ''}}</div>
-            <div class="flex-1 pl-1" i18n>{{copy.age_protect}}</div>
-            <div class="flex-1 pl-1" i18n>
-              {{copy.active_date || copy.create_date | date:'shortDate'}}
-            </div>
-            <div class="flex-1 pl-1">
-              <span *ngIf="holdable(copy)" i18n>Yes</span>
-              <span *ngIf="!holdable(copy)" i18n>No</span>
-            </div>
-            <div class="flex-1 pl-1" i18n>{{copy.copy_status}}</div>
-            <div class="flex-1 pl-1" i18n>{{copy.due_date | date:'shortDate'}}</div>
-          </div>
-        </li>
-      </ul>
-    </div>
+<ng-template #cnTemplate let-copy="row">
+  {{copy.call_number_prefix_label}}
+  {{copy.call_number_label}}
+  {{copy.call_number_suffix_label}}
+</ng-template>
+
+<ng-template #barcodeTemplate let-copy="row">
+  <div>{{copy.barcode}}</div>
+  <div>
+  <a class="pl-1" href="/eg/staff/cat/item/{{copy.id}}" i18n>View</a>
+  | 
+  <a class="pl-1" href="/eg/staff/cat/item/{{copy.id}}/edit" i18n>Edit</a>
   </div>
+</ng-template>
+
+<ng-template #holdableTemplate let-copy="row" let-context="userContext">
+  <span *ngIf="context.holdable(copy)" i18n>Yes</span>
+  <span *ngIf="!context.holdable(copy)" i18n>No</span>
+</ng-template>
+
+<div class='eg-copies w-100 mt-3'>
+  <eg-grid #copyGrid [dataSource]="gridDataSource" 
+    [sortable]="false" persistKey="catalog.record.copies">
+    <eg-grid-column i18n-label label="Copy ID" path="id" 
+      [hidden]="true" [index]="true">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Location" path="circ_lib" datatype="org_unit">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Call Number / Copy Notes" 
+      name="callnumber" [cellTemplate]="cnTemplate">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Barcode" name="barcode"
+      [cellTemplate]="barcodeTemplate">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Shelving Location" path="copy_location">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Circulation Modifier" path="circ_modifier">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Age Hold Protection" path="age_protect">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Active/Create Date" 
+      path="active_date" datatype="timestamp">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Holdable?" name="holdable" 
+      [cellTemplate]="holdableTemplate" [cellContext]="copyContext">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Status" path="copy_status">
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Due Date" path="due_date" datatype="timestamp">
+    </eg-grid-column>
+  </eg-grid>
 </div>
+
index 86ac3e3..b868c8f 100644 (file)
@@ -1,8 +1,12 @@
-import {Component, OnInit, Input} from '@angular/core';
+import {Component, OnInit, Input, ViewChild} from '@angular/core';
+import {Observable} from 'rxjs/Observable';
+import {map} from 'rxjs/operators/map';
 import {NetService} from '@eg/core/net.service';
 import {StaffCatalogService} from '../catalog.service';
 import {Pager} from '@eg/share/util/pager';
 import {OrgService} from '@eg/core/org.service';
+import {GridDataSource} from '@eg/share/grid/grid';
+import {GridComponent} from '@eg/share/grid/grid.component';
 
 @Component({
   selector: 'eg-catalog-copies',
@@ -10,17 +14,18 @@ import {OrgService} from '@eg/core/org.service';
 })
 export class CopiesComponent implements OnInit {
 
-    pager: Pager;
-    copies: any[];
     recId: number;
     initDone = false;
+    gridDataSource: GridDataSource;
+    copyContext: any; // grid context
+    @ViewChild('copyGrid') copyGrid: GridComponent;
 
     @Input() set recordId(id: number) {
         this.recId = id;
         // Only force new data collection when recordId()
         // is invoked after ngInit() has already run.
         if (this.initDone) {
-            this.collectData();
+            this.copyGrid.reload();
         }
     }
 
@@ -28,26 +33,37 @@ export class CopiesComponent implements OnInit {
         private net: NetService,
         private org: OrgService,
         private staffCat: StaffCatalogService,
-    ) {}
+    ) {
+        this.gridDataSource = new GridDataSource();
+    }
 
     ngOnInit() {
         this.initDone = true;
-        this.collectData();
+
+        this.gridDataSource.getRows = (pager: Pager, sort: any[]) => {
+            // sorting not currently supported
+            return this.fetchCopies(pager);
+        }
+
+        this.copyContext = {
+            holdable: (copy: any) => {
+                return copy.holdable === 't'
+                    && copy.location_holdable === 't'
+                    && copy.status_holdable === 't';
+            }
+        }
     }
 
     collectData() {
         if (!this.recId) { return; }
-        this.pager = new Pager();
-        this.pager.limit = 10; // TODO UI
-        this.fetchCopies();
     }
 
     orgName(orgId: number): string {
         return this.org.get(orgId).shortname();
     }
 
-    fetchCopies(): void {
-        this.copies = [];
+    fetchCopies(pager: Pager): Observable<any> {
+        if (!this.recId) { return Observable.of([]); }
 
         // "Show Result from All Libraries" i.e. global search displays
         // copies from all branches, sorted by search/pref libs.
@@ -55,39 +71,20 @@ export class CopiesComponent implements OnInit {
             this.org.root().ou_type().depth() :
             this.staffCat.searchContext.searchOrg.ou_type().depth();
 
-        this.net.request(
+        return this.net.request(
             'open-ils.search',
             'open-ils.search.bib.copies.staff',
             this.recId,
             this.staffCat.searchContext.searchOrg.id(),
             copy_depth,
-            this.pager.limit,
-            this.pager.offset,
+            pager.limit,
+            pager.offset,
             this.staffCat.prefOrg ? this.staffCat.prefOrg.id() : null
-        ).subscribe(copy => {
-            this.copies.push(copy);
-        });
-    }
-
-    holdable(copy: any): boolean {
-        return copy.holdable === 't'
-            && copy.location_holdable === 't'
-            && copy.status_holdable === 't';
-    }
-
-    firstPage(): void {
-        this.pager.offset = 0;
-        this.fetchCopies();
+        ).pipe(map(copy => {
+            copy.active_date = copy.active_date || copy.create_date
+            return copy;
+        }));
     }
-    prevPage(): void {
-        this.pager.decrement();
-        this.fetchCopies();
-    }
-    nextPage(): void {
-        this.pager.increment();
-        this.fetchCopies();
-    }
-
 }