LP#1626157 grid experiment
authorBill Erickson <berickxx@gmail.com>
Tue, 1 May 2018 22:39:59 +0000 (18:39 -0400)
committerBill Erickson <berickxx@gmail.com>
Tue, 1 May 2018 22:39:59 +0000 (18:39 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html
Open-ILS/src/eg2/src/app/share/grid/grid-body.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid-data-source.ts
Open-ILS/src/eg2/src/app/share/grid/grid.component.html
Open-ILS/src/eg2/src/app/share/util/pager.ts
Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts

index c659033..97008bf 100644 (file)
@@ -1,7 +1,7 @@
 
 <div class="eg-grid-row eg-grid-body-row"
   [ngClass]="{'eg-grid-row-selected': selector[idx]}"
-  *ngFor="let row of dataSource.getPage(pager) | async; let idx = index">
+  *ngFor="let row of dataSource.getPageOfRows(pager); let idx = index">
 
   <div class="eg-grid-cell eg-grid-checkbox-cell eg-grid-cell-skinny">
     <input type='checkbox' [(ngModel)]="selector[idx]">
index 16a8738..82031aa 100644 (file)
@@ -10,12 +10,15 @@ import {Pager} from '@eg/share/util/pager';
 
 export class EgGridBodyComponent implements OnInit {
 
+    @Input() pager: Pager;
     @Input() dataSource: EgGridDataSource;
     @Input() columnSet: EgGridColumnSet;
-    @Input() pager: Pager;
     @Input() selector: {[idx:number] : boolean};
 
     ngOnInit() {
+
+        // fetch the first page of data
+        this.dataSource.requestPage(this.pager);
     }
 }
 
index a498100..66da827 100644 (file)
@@ -1,29 +1,62 @@
+import {EventEmitter} from '@angular/core';
 import {Observable} from 'rxjs/Rx';
 import {Pager} from '@eg/share/util/pager';
 
 export class EgGridDataSource {
 
     data: any[];
-    sortSpec: any[];
-
-    // Do we know how many items we have in total?
-    indeterminate: boolean
+    pager: Pager;
+    allRowsRetrieved: boolean;
+    getRows: (pager: Pager) => Observable<any>;
 
     constructor() {
         this.data = [];
-        this.sortSpec = [];
+        this.allRowsRetrieved = false;
     }
 
-    applySort() {
+    setAllRetrieved() {
+        this.allRowsRetrieved = true;
+        this.pager.resultCount = this.data.length;
     }
 
-    getPage(pager: Pager): Observable<Array<any>> {
+    // called from the template -- no data fetching
+    getPageOfRows(pager: Pager): any[] {
+        if (this && this.data) {
+            return this.data.slice(
+                pager.offset, pager.limit + pager.offset);
+        }
+        return [];
+    }
+
+    // called on initial component load and user action (e.g. paging, sorting).
+    requestPage(pager: Pager) {
+
+        // see if the page of data is already present in the data
+        if (this.getPageOfRows(pager).length > 0) return;
+
+        if (this.allRowsRetrieved) return;
+
+        if (!this.getRows) return;
+
+        let idx = pager.offset;
+        this.getRows(pager).subscribe(
+            row => this.data[idx++] = row,
+            err => console.error(`grid getRows() error ${err}`),
+            ()  => this.checkAllRetrieved(pager, idx)
+        );
+    }
 
-        if (!this.data) return Observable.from([]);
+    // See if the last getRows() call resulted in the final set of data.
+    checkAllRetrieved(pager: Pager, idx: number) {
+        if (this.allRowsRetrieved) return;
 
-        if (this.data[pager.offset] !== undefined) {
-            return Observable.of(
-                this.data.slice(pager.offset, pager.limit + pager.offset));
+        if (idx == 0 || idx < (pager.limit + pager.offset)) {
+            // last query returned nothing or less than one page.
+            // confirm we have all of the preceding pages.
+            if (!this.data.includes(undefined)) {
+                this.allRowsRetrieved = true;
+                pager.resultCount = this.data.length;
+            }
         }
     }
 }
index 813e6bc..3d0434f 100644 (file)
@@ -1,6 +1,7 @@
 
 <div class="eg-grid">
-  <eg-grid-toolbar [pager]="pager"></eg-grid-toolbar>
+  <eg-grid-toolbar [dataSource]="dataSource" [pager]="pager">
+  </eg-grid-toolbar>
   <eg-grid-header [columnSet]="columnSet"></eg-grid-header>
   <eg-grid-body 
     [columnSet]="columnSet" 
index b1d1861..524e178 100644 (file)
@@ -33,6 +33,16 @@ export class Pager {
         this.setPage(this.currentPage() - 1);
     }
 
+    toFirst() {
+        if (!this.isFirstPage())
+            this.setPage(1);
+    }
+
+    toLast() {
+        if (!this.isLastPage())
+            this.setPage(this.pageCount());
+    }
+
     setPage(page: number): void {
         this.offset = (this.limit * (page - 1));
         this.onChange$.emit(this.offset);
index 67dbf0f..78d2263 100644 (file)
@@ -6,6 +6,7 @@ import {Observable} from 'rxjs/Rx';
 import {EgGridDataSource} from '@eg/share/grid/grid-data-source';
 import {EgIdlService, EgIdlObject} from '@eg/core/idl.service';
 import {EgPcrudService} from '@eg/core/pcrud.service';
+import {Pager} from '@eg/share/util/pager';
 
 @Component({
   templateUrl: 'sandbox.component.html'
@@ -21,7 +22,6 @@ export class EgSandboxComponent implements OnInit {
 
     btSource: EgGridDataSource = new EgGridDataSource();
 
-
     testStr: string;
     @Input() set testString(str: string) {
         this.testStr = str;
@@ -44,8 +44,13 @@ export class EgSandboxComponent implements OnInit {
             {name: 'The Tick', state: 'TX'}
         ];
 
-        this.pcrud.retrieveAll('cbt').subscribe(
-            bt => this.btSource.data.push(bt));
+        this.btSource.getRows = (pager: Pager) => {
+            return this.pcrud.retrieveAll('cbt', {
+                offset: pager.offset, 
+                limit: pager.limit,
+                order_by: {cbt: 'name'}
+            });
+        }
     }
 
     showProgress() {