From 7b910858b9868950a68e256e947f34500c1fbe21 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 31 Jul 2020 10:54:28 -0400 Subject: [PATCH] LP1889694 catalog record summary condensed WIP Signed-off-by: Bill Erickson --- .../src/app/share/catalog/bib-record.service.ts | 23 +++++- .../eg2/src/app/share/catalog/catalog.service.ts | 4 +- .../app/staff/catalog/result/record.component.ts | 1 - .../app/staff/catalog/result/results.component.ts | 11 +-- .../lib/OpenILS/Application/Search/Biblio.pm | 89 +++++++++++++++++++++- 5 files changed, 111 insertions(+), 17 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 d29c4bdef8..e641a11291 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 @@ -33,7 +33,7 @@ export class BibRecordSummary { net: NetService; displayHighlights: {[name: string]: string | string[]} = {}; - constructor(record: IdlObject, orgId: number, orgDepth: number) { + constructor(record: IdlObject, orgId: number, orgDepth?: number) { this.id = Number(record.id()); this.record = record; this.orgId = orgId; @@ -149,6 +149,27 @@ export class BibRecordService { .map(f => f.name); } + // newstyle + getBibSummaries(bibIds: number[], + orgId: number, isStaff?: boolean): Observable { + + if (bibIds.length === 0) { return from([]); } + + let method = 'open-ils.search.biblio.record.catalog_summary'; + if (isStaff) { method += '.staff'; } + + return this.net.request('open-ils.search', method, orgId, bibIds) + .pipe(map(bibSummary => { + const summary = new BibRecordSummary(bibSummary.record, orgId); + summary.net = this.net; // inject + summary.display = bibSummary.display; + summary.attributes = bibSummary.attributes; + summary.holdCount = bibSummary.hold_count; + summary.holdingsSummary = bibSummary.copy_counts; + return summary; + })); + } + // Note when multiple IDs are provided, responses are emitted in order // of receipt, not necessarily in the requested ID order. getBibSummary(bibIds: number | number[], 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 c80d0b2683..2e7f1648a7 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 @@ -193,8 +193,8 @@ export class CatalogService { observable = this.bibService.getMetabibSummary( ctx.currentResultIds(), ctx.searchOrg.id(), depth); } else { - observable = this.bibService.getBibSummary( - ctx.currentResultIds(), ctx.searchOrg.id(), depth); + observable = this.bibService.getBibSummaries( + ctx.currentResultIds(), ctx.searchOrg.id(), ctx.isStaff); } return observable.pipe(map(summary => { diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.ts index 8cb7f03c6c..664d36661e 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.ts @@ -43,7 +43,6 @@ export class ResultRecordComponent implements OnInit, OnDestroy { ngOnInit() { this.searchContext = this.staffCat.searchContext; - this.summary.getHoldCount(); this.isRecordSelected = this.basket.hasRecordId(this.summary.id); // Watch for basket changes caused by other components diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts index 50ed7914e4..c84d4df343 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/result/results.component.ts @@ -100,8 +100,7 @@ export class ResultsComponent implements OnInit, OnDestroy { this.cat.search(this.searchContext) .then(ok => { this.cat.fetchFacets(this.searchContext); - this.cat.fetchBibSummaries(this.searchContext) - .then(ok2 => this.fleshSearchResults()); + this.cat.fetchBibSummaries(this.searchContext); }); } } @@ -125,14 +124,6 @@ export class ResultsComponent implements OnInit, OnDestroy { return false; } - fleshSearchResults(): void { - const records = this.searchContext.result.records; - if (!records || records.length === 0) { return; } - - // Flesh the creator / editor fields with the user object. - this.bib.fleshBibUsers(records.map(r => r.record)); - } - searchIsDone(): boolean { return this.searchContext.searchState === CatalogSearchState.COMPLETE; } diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Biblio.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Biblio.pm index 159ecd78b9..3254c4ff4c 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Biblio.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Biblio.pm @@ -13,9 +13,6 @@ use Encode; use OpenSRF::Utils::Logger qw/:logger/; - -use OpenSRF::Utils::JSON; - use Time::HiRes qw(time sleep); use OpenSRF::EX qw(:try); use Digest::MD5 qw(md5_hex); @@ -2744,5 +2741,91 @@ sub mk_copy_query { } +__PACKAGE__->register_method( + method => 'catalog_record_summary', + api_name => 'open-ils.search.biblio.record.catalog_summary', + stream => 1, + max_bundle_count => 1, + signature => { + desc => 'Stream of record data suitable for catalog display', + params => [ + {desc => 'Context org unit ID', type => 'number'}, + {desc => 'Array of Record IDs', type => 'array'} + ], + return => { + desc => 'Stream of record summary objects' + } + } +); + +__PACKAGE__->register_method( + method => 'catalog_record_summary', + api_name => 'open-ils.search.biblio.record.catalog_summary.staff', + stream => 1, + max_bundle_count => 1, + signature => q/see open-ils.search.biblio.record.catalog_summary/ +); + +sub catalog_record_summary { + my ($self, $client, $org_id, $record_ids) = @_; + + my $e = new_editor(); + + for my $rec_id (@$record_ids) { + + my ($bre, $display, $attributes) = get_one_catalog_record($e, $rec_id); + + my $copy_counts = + record_id_to_copy_count($self, $client, $org_id, $rec_id); + + my $hold_count = $U->simplereq( + 'open-ils.circ', + 'open-ils.circ.bre.holds.count', $rec_id); + + $client->respond({ + id => $rec_id, + record => $bre, + display => $display, + attributes => $attributes, + copy_counts => $copy_counts, + hold_count => $hold_count + }); + } + + return undef; +} + +sub get_one_catalog_record { + my ($e, $rec_id) = @_; + + my $bre = $e->retrieve_biblio_record_entry([$rec_id, { + flesh => 1, + flesh_fields => { + bre => [qw/compressed_display_entries mattrs creator editor/] + } + }]) or return (); + + my $display = {}; + $display->{$_->name} = OpenSRF::Utils::JSON->JSON2perl($_->value) + foreach @{$bre->compressed_display_entries}; + + # Create an object of 'mraf' attributes. + # Any attribute can be multi so dedupe and array-ify all of them. + my $attributes = {}; + for my $attr (@{$bre->mattrs}) { + $attributes->{$attr->attr} = {} unless $attributes->{$attr->attr}; + $attributes->{$attr->attr}->{$attr->value} = 1; # avoid dupes + } + $attributes->{$_} = [keys %{$attributes->{$_}}] for keys %$attributes; + + # clear bulk + $bre->clear_marc; + $bre->clear_mattrs; + $bre->clear_compressed_display_entries; + + return ($bre, $display, $attributes); +} + + 1; -- 2.11.0