LP1849523 Angular catalog split record batches user/berick/lp1849523-ang-cat-display-efficiency
authorBill Erickson <berickxx@gmail.com>
Wed, 23 Oct 2019 15:37:40 +0000 (11:37 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 23 Oct 2019 16:01:00 +0000 (12:01 -0400)
The result page of the Angular catalog now fetches the record info in 2
batches.  The first batch is relatively small (currently 5 records) and
allows the results page to start rendering results earlier in the
display process.  The second batch of records, which includes all the
rest of the results, then drops in as they arrive.

Note the first batch of records will be the first 5 results from the
search so the second batch of results can simply be appended and avoid
page shuffling.

Includes thinko fix for batched holds retrieval.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts
Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts

index 2aaaf1f..9a81a4d 100644 (file)
@@ -1,6 +1,6 @@
 import {Injectable, EventEmitter} from '@angular/core';
 import {Observable} from 'rxjs';
-import {map, tap, finalize} from 'rxjs/operators';
+import {map, tap, finalize, merge} from 'rxjs/operators';
 import {OrgService} from '@eg/core/org.service';
 import {UnapiService} from '@eg/share/catalog/unapi.service';
 import {IdlService, IdlObject} from '@eg/core/idl.service';
@@ -11,6 +11,11 @@ import {BibRecordService, BibRecordSummary} from './bib-record.service';
 import {BasketService} from './basket.service';
 import {CATALOG_CCVM_FILTERS} from './search-context';
 
+// Start with this number of records in the first batch so results
+// can start displaying sooner.  A batch of 5 gets a decent chunk of
+// data on the page while waiting for the other results to appear.
+const INITIAL_REC_BATCH_SIZE = 5;
+
 @Injectable()
 export class CatalogService {
 
@@ -189,14 +194,25 @@ export class CatalogService {
 
         const isMeta = ctx.termSearch.isMetarecordSearch();
 
+        // When fetching batches of search results, fetch the first
+        // few records first so results lists can start rendering
+        // before the full data set has arrived and been processed.
+        let ids1 = ctx.currentResultIds();
+        let ids2 = [];
+        if (ids1.length > INITIAL_REC_BATCH_SIZE) {
+            ids1 = ctx.currentResultIds().slice(0, INITIAL_REC_BATCH_SIZE);
+            ids2 = ctx.currentResultIds().slice(INITIAL_REC_BATCH_SIZE);
+        }
+
         let observable: Observable<BibRecordSummary>;
+        const bibFunc = isMeta ? 'getMetabibSummary' : 'getBibSummary';
 
-        if (isMeta) {
-            observable = this.bibService.getMetabibSummary(
-                ctx.currentResultIds(), ctx.searchOrg.id(), depth);
-        } else {
-            observable = this.bibService.getBibSummary(
-                ctx.currentResultIds(), ctx.searchOrg.id(), depth);
+        observable = this.bibService[bibFunc](ids1, ctx.searchOrg.id(), depth);
+
+        if (ids2.length > 0) {
+            observable = observable.pipe(merge(
+                this.bibService.getBibSummary(ids2, ctx.searchOrg.id(), depth)
+            ));
         }
 
         return observable.pipe(map(summary => {
index 014505e..e113678 100644 (file)
@@ -124,11 +124,13 @@ export class ResultsComponent implements OnInit, OnDestroy {
             // Flesh the creator / editor fields with the user object.
             this.bib.fleshBibUsers(records.map(r => r.record));
 
+            const isMeta = this.searchContext.termSearch.isMetarecordSearch();
             this.bib.getHoldCounts(this.searchContext.currentResultIds())
                 .subscribe(result => {
+                    const idField = isMeta ? 'metabibId' : 'id';
                     const targetId = Object.keys(result)[0];
                     const record =
-                        records.filter(r => r.id === Number(targetId))[0];
+                        records.filter(r => r[idField] === Number(targetId))[0];
                     record.holdCount = result[targetId];
                 });
         });