From bb9397d7828d7abc5b035d4e5c130a878ad6045e Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 15 May 2020 17:51:09 -0400 Subject: [PATCH] LP1879335 Manage Authorities Angular WIP Signed-off-by: Bill Erickson --- .../app/staff/cat/authority/manage.component.html | 64 ++++++++++++++++++++-- .../app/staff/cat/authority/manage.component.ts | 55 +++++++++++++++---- .../lib/OpenILS/Application/Search/Authority.pm | 58 ++++++++++++-------- 3 files changed, 138 insertions(+), 39 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/staff/cat/authority/manage.component.html b/Open-ILS/src/eg2/src/app/staff/cat/authority/manage.component.html index ab508f81c8..bf619be0a7 100644 --- a/Open-ILS/src/eg2/src/app/staff/cat/authority/manage.component.html +++ b/Open-ILS/src/eg2/src/app/staff/cat/authority/manage.component.html @@ -1,10 +1,62 @@ - - - - - - +
+
+
+
+ Search Term +
+ +
+
+
+
+
+ Authority Type +
+ + + +
+
+
+
+
+ + + + +
+
+
+ + + + + + + + + + + + + + + + diff --git a/Open-ILS/src/eg2/src/app/staff/cat/authority/manage.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/authority/manage.component.ts index f0f7a3e503..661857d4e5 100644 --- a/Open-ILS/src/eg2/src/app/staff/cat/authority/manage.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/cat/authority/manage.component.ts @@ -1,64 +1,97 @@ import {Component, OnInit, ViewChild} from '@angular/core'; -import {Observable} from 'rxjs'; +import {Observable, empty} from 'rxjs'; import {map, switchMap} from 'rxjs/operators'; import {IdlObject} from '@eg/core/idl.service'; import {Pager} from '@eg/share/util/pager'; import {NetService} from '@eg/core/net.service'; import {PcrudService} from '@eg/core/pcrud.service'; +import {OrgService} from '@eg/core/org.service'; +import {GridComponent} from '@eg/share/grid/grid.component'; import {GridContext, GridDataSource} from '@eg/share/grid/grid'; import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; /* Find, merge, and edit authority records */ @Component({ - templateUrl: 'manage.component.html' + templateUrl: 'manage.component.html', + styles: [`#offset-input { width: 4em; }`] }) export class ManageAuthorityComponent implements OnInit { - authorityAxis: string; + // Grid paging is disabled in this UI to support browsing in + // both directions. Define our own paging trackers. + pageSize = 15; + searchOffset = 0; + + searchTerm: string; + authorityAxis: ComboboxEntry; authorityAxes: ComboboxEntry[]; dataSource: GridDataSource; + @ViewChild('grid', {static: false}) grid: GridComponent; + constructor( private net: NetService, + private org: OrgService, private pcrud: PcrudService ) { } ngOnInit() { - // TODO fetch axes + this.pcrud.retrieveAll('aba', {}, {atomic: true}) + .subscribe(axes => { + this.authorityAxes = axes + .map(axis => ({id: axis.code(), label: axis.name()})) + .sort((a1, a2) => a1.label < a2.label ? -1 : 1); + }); this.dataSource = new GridDataSource(); this.dataSource.getRows = (pager: Pager, sort: any): Observable => { - return this.loadAuthorities(pager, sort); + return this.loadAuthorities(); } } - loadAuthorities(pager: Pager, sort: any): Observable { + loadAuthorities(): Observable { + + if (!this.searchTerm || !this.authorityAxis.id) { + return empty(); + } return this.net.request( 'open-ils.supercat', 'open-ils.supercat.authority.browse.by_axis', - 'subject', 'g', pager.limit, pager.offset + this.authorityAxis.id, this.searchTerm, + this.pageSize, this.searchOffset ).pipe(switchMap(authIds => { + return this.net.request( 'open-ils.search', 'open-ils.search.authority.main_entry', authIds ); })).pipe(map(authMeta => { + + const oOrg = this.org.get(authMeta.authority.owner()); + return { - id: authMeta.authority_id, + authority: authMeta.authority, link_count: authMeta.linked_bibs.length, - heading: authMeta.heading.value(), - control_set: authMeta.control_set.name(), - thesaurus: authMeta.heading.thesaurus() + heading: authMeta.heading, + thesaurus: authMeta.thesaurus, + thesaurus_code: authMeta.thesaurus_code, + owner: oOrg ? oOrg.shortname() : '' }; })); } + + search(offset?: number) { + if (offset) { this.searchOffset += offset; } + + this.grid.reload(); + } } diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Authority.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Authority.pm index c8e99cb29e..549593a2ac 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Authority.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Authority.pm @@ -4,6 +4,9 @@ use strict; use warnings; use OpenILS::Utils::Fieldmapper; use OpenILS::Application::AppUtils; +use MARC::Record; +use MARC::File::XML (BinaryEncoding => 'UTF-8'); +use MARC::Charset; use XML::LibXML; use XML::LibXSLT; use OpenILS::Utils::CStoreEditor q/:funcs/; @@ -353,10 +356,12 @@ __PACKAGE__->register_method( return => { desc => q/ Stream of authority metadata objects. - { authority_id: $id, - heading: $main_entry_heading, # fleshed atag - control_set: $control_set, - linked_bibs: [$id1, $id2, ...] + { authority: are_object, + heading: heading_text, + thesaurus: short_code, + thesaurus_code: code, + control_set: control_set_object, + linked_bibs: [id1, id2, ...] } /, type => 'object' @@ -376,34 +381,43 @@ sub authority_main_entry { my $rec = $e->retrieve_authority_record_entry([ $auth_id, { flesh => 1, - flesh_fields => {are => [qw/control_set bib_links/]} + flesh_fields => {are => [qw/control_set bib_links creator/]} } ]) or return $e->event; - my $main_entry = $e->json_query({ - select => {ash => [qw/id/]}, - from => {ash => 'acsaf'}, - where => { - '+ash' => {record => $auth_id}, - '+acsaf' => {main_entry => undef} - }, - limit => 1 - })->[0]; - my $response = { - authority_id => $auth_id, + authority => $rec, control_set => $rec->control_set, linked_bibs => [ map {$_->bib} @{$rec->bib_links} ] }; - if ($main_entry) { - $response->{heading} = - $e->search_authority_simple_heading([ - {id => $main_entry->{id}}, - {flesh => 1, flesh_fields => {ash => [qw/atag/]}} - ])->[0]; + # Extract the heading and thesaurus. + # In theory this data has already been extracted in the DB, + # but my results vary quite a bit from the previous authority + # manage interface. I took the MARC parsing approach because + # it matches the logic (and results) of the previous UI. + + my $marc = MARC::Record->new_from_xml($rec->marc); + my $heading_field = $marc->field('1..'); + $response->{heading} = $heading_field->as_string if $heading_field; + + my $field_008 = $marc->field('008'); + if ($field_008) { + my $thes = substr($field_008->data, 11, 1); + + if (defined $thes) { + $response->{thesaurus} = $thes; + + if ($thes ne 'z') { # 'z' ('Other') maps to many entries + my $thesaurus = + $e->search_authority_thesaurus({short_code => $thes})->[0]; + + $response->{thesaurus_code} = $thesaurus->code if $thesaurus; + } + } } + $rec->clear_marc; $client->respond($response); } -- 2.11.0