From b8341a4e0adfda6499d1a4d680d9505ddca55bf3 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Tue, 18 Dec 2018 16:15:17 -0500 Subject: [PATCH] LP1806087 Group formats and editions (WIP) Signed-off-by: Bill Erickson --- .../src/app/share/catalog/bib-record.service.ts | 73 ++++++++++++---------- .../src/app/share/catalog/catalog-url.service.ts | 7 ++- .../eg2/src/app/share/catalog/catalog.service.ts | 9 ++- .../eg2/src/app/share/catalog/search-context.ts | 12 ++++ .../app/staff/catalog/result/record.component.html | 3 +- .../app/staff/catalog/result/record.component.ts | 10 ++- .../src/app/staff/catalog/search-form.component.ts | 1 + 7 files changed, 74 insertions(+), 41 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/share/catalog/bib-record.service.ts b/Open-ILS/src/eg2/src/app/share/catalog/bib-record.service.ts index c29c33a470..6b00e7912b 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/bib-record.service.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/bib-record.service.ts @@ -3,6 +3,7 @@ import {Observable} from 'rxjs/Observable'; import {mergeMap} from 'rxjs/operators/mergeMap'; import {from} from 'rxjs/observable/from'; import {map} from 'rxjs/operators/map'; +import {tap} from 'rxjs/operators/tap'; import {OrgService} from '@eg/core/org.service'; import {UnapiService} from '@eg/share/catalog/unapi.service'; import {IdlService, IdlObject} from '@eg/core/idl.service'; @@ -204,47 +205,53 @@ export class BibRecordService { compileMetabib(metabib: IdlObject, orgId?: number, orgDepth?: number): Observable { - const bibIds = metabib.source_maps().map(map => map.source()); + // TODO: Create an API similar to the one that builds a combined + // mods blob for metarecords, except using display fields, etc. + // For now, this seems to get the job done. + + // Non-master records + const relatedBibIds = metabib.source_maps() + .map(map => map.source()) + .filter(id => id !== metabib.master_record()); + let observer; - const observable = - new Observable(o => observer = o); - - let master; - const summaries = []; - - // NOTE if we only need to augment with 'mattrs' it would be - // faster to just grab those than to fetch the full bib-summary - // for related records. Revisit. - - this.getBibSummary(bibIds, orgId, orgDepth).subscribe( - sum => { - summaries.push(sum); - if (sum.id === Number(metabib.master_record())) { - master = sum; - master.metabibId = metabib.id(); - } - }, - err => {}, - () => { - summaries.forEach(sum => { - if (sum.id !== master.id) { - master.record.mattrs( - master.record.mattrs().concat(sum.record.mattrs())) - } - }); + const observable = new Observable(o => observer = o); + + // NOTE: getBibSummary calls getHoldingsSummary against + // the bib record unnecessarily. It's called again below. + // Reconsider this approach (see also note above about API). + this.getBibSummary(metabib.master_record(), orgId, orgDepth) + .subscribe(summary => { + summary.metabibId = metabib.id(); - // Recompile attributes now that the data has been augmented - master.compileRecordAttrs(); + let promise; + + if (relatedBibIds.length > 0) { + + // Grab data for MR bib summary augmentation + promise = this.pcrud.search('mraf', {id: relatedBibIds}) + .pipe(tap(attr => summary.record.mattrs().push(attr))) + .toPromise(); + } else { + + // Metarecord has only one constituent bib. + promise = Promise.resolve(); + } + + promise.then(() => { + + // Re-compile with augmented data + summary.compileRecordAttrs(); // Fetch holdings data for the metarecord this.getHoldingsSummary(metabib.id(), orgId, orgDepth, true) .then(holdingsSummary => { - master.holdingsSummary = holdingsSummary; - observer.next(master); + summary.holdingsSummary = holdingsSummary; + observer.next(summary); observer.complete(); }); - } - ); + }); + }); return observable; } diff --git a/Open-ILS/src/eg2/src/app/share/catalog/catalog-url.service.ts b/Open-ILS/src/eg2/src/app/share/catalog/catalog-url.service.ts index 1b85d71a8d..cfec1d9076 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/catalog-url.service.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/catalog-url.service.ts @@ -80,8 +80,8 @@ export class CatalogUrlService { params.joinOp = []; params.matchOp = []; - ['format', 'available', 'hasBrowseEntry', - 'date1', 'date2', 'dateOp', 'isMetarecord'] + ['format', 'available', 'hasBrowseEntry', 'date1', + 'date2', 'dateOp', 'isMetarecord', 'fromMetarecord'] .forEach(field => { if (ts[field]) { params[field] = ts[field]; @@ -196,7 +196,8 @@ export class CatalogUrlService { } else if (params.has('query')) { // Scalars - ['format', 'available', 'date1', 'date2', 'dateOp', 'isMetarecord'] + ['format', 'available', 'date1', 'date2', + 'dateOp', 'isMetarecord', 'fromMetarecord'] .forEach(field => { if (params.has(field)) { ts[field] = params.get(field); diff --git a/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts b/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts index b210103937..c741acbae6 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts @@ -122,7 +122,9 @@ export class CatalogService { console.debug(`search query: ${fullQuery}`); let method = 'open-ils.search.biblio.multiclass.query'; - if (ctx.termSearch.isSearchable() && ctx.termSearch.isMetarecord) { + if (ctx.termSearch.isSearchable() + && ctx.termSearch.isMetarecord + && !ctx.termSearch.fromMetarecord) { method = 'open-ils.search.metabib.multiclass.query'; } @@ -169,9 +171,12 @@ export class CatalogService { ctx.org.root().ou_type().depth() : ctx.searchOrg.ou_type().depth(); + // Term search, looking for metarecords, but no + // specific metarecord has been selected for display. const isMeta = ( ctx.termSearch.isSearchable() && - ctx.termSearch.isMetarecord + ctx.termSearch.isMetarecord && + !ctx.termSearch.fromMetarecord ); let observable: Observable; diff --git a/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts b/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts index c4bb4933cd..56ab52783d 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts @@ -122,7 +122,13 @@ export class CatalogTermContext { ccvmFilters: {[ccvmCode: string]: string[]}; facetFilters: FacetFilter[]; copyLocations: string[]; // ID's, but treated as strings in the UI. + + // True when searching for metarecords isMetarecord: boolean; + + // Filter results by records which link to this metarecord ID. + fromMetarecord: number; + hasBrowseEntry: string; // "entryId,fieldId" date1: number; date2: number; @@ -140,6 +146,7 @@ export class CatalogTermContext { this.date1 = null; this.date2 = null; this.dateOp = 'is'; + this.fromMetarecord = null; // Apply empty string values for each ccvm filter this.ccvmFilters = {}; @@ -150,6 +157,7 @@ export class CatalogTermContext { return ( this.query[0] !== '' || this.hasBrowseEntry !== '' + || this.fromMetarecord !== null ); } @@ -416,6 +424,10 @@ export class CatalogSearchContext { str += ` has_browse_entry(${ts.hasBrowseEntry})`; } + if (ts.fromMetarecord) { + str += ` from_metarecord(${ts.fromMetarecord})`; + } + if (ts.format) { str += ' format(' + ts.format + ')'; } diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.html b/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.html index 928d1a1152..ddfacc0fb5 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.html +++ b/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.html @@ -32,7 +32,7 @@ @@ -122,6 +122,7 @@