From: Bill Erickson Date: Fri, 8 Dec 2017 04:28:08 +0000 (-0500) Subject: LP#626157 Ang2 experiments X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=ba7861e2ab1cf325a9a6cfb7c2e110ecb5d7e59a;p=working%2FEvergreen.git LP#626157 Ang2 experiments Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/webby-src/src/app/share/catalog/catalog.service.ts b/Open-ILS/webby-src/src/app/share/catalog/catalog.service.ts index 7f3e376902..02e67e076f 100644 --- a/Open-ILS/webby-src/src/app/share/catalog/catalog.service.ts +++ b/Open-ILS/webby-src/src/app/share/catalog/catalog.service.ts @@ -18,6 +18,27 @@ export const CATALOG_CCVM_FILTERS = [ 'search_format' ]; +const MODS_XPATH_AUTO = { + title : '/mods:mods/mods:titleInfo/mods:title', + author: '/mods:mods/mods:name/mods:namePart', + edition: '/mods:mods/mods:originInfo/mods:edition', + pubdate: '/mods:mods/mods:originInfo/mods:dateIssued', + genre: '/mods:mods/mods:genre' +}; + +const MODS_XPATH = { + extern: '/mods:mods/biblio:extern', + copyCounts: '/mods:mods/holdings:holdings/holdings:counts/holdings:count', + attributes: '/mods:mods/indexing:attributes/indexing:field' +}; + +const NAMESPACE_MAPS = { + 'mods': 'http://www.loc.gov/mods/v3', + 'biblio': 'http://open-ils.org/spec/biblio/v1', + 'holdings': 'http://open-ils.org/spec/holdings/v1', + 'indexing': 'http://open-ils.org/spec/indexing/v1' +}; + @Injectable() export class EgCatalogService { @@ -163,20 +184,20 @@ export class EgCatalogService { /** - * Bib record via UNAPI as mods32 (for now) with holdings summary + * Bib record via UNAPI as mods (for now) with holdings summary * and record attributes. */ getBibSummary(bibId: number, orgId: number, depth: number): Promise { return new Promise((resolve, reject) => { - this.unapi.getAsObject({ + this.unapi.getAsXmlDocument({ target: 'bre', id: bibId, extras: '{bre.extern,holdings_xml,mra}', format: 'mods32', orgId: orgId, depth: depth - }).then(summary => { - summary = this.translateBibSummary(summary); + }).then(xmlDoc => { + let summary = this.translateBibSummary(xmlDoc); summary.id = bibId; resolve(summary); }); @@ -190,47 +211,59 @@ export class EgCatalogService { * UNAPI content into a more digestable form. * TODO: Add display field support */ - translateBibSummary(summary: any): any { // TODO: bib summary interface - const UNAPI_PATHS = { - title : 'titleInfo[0].title[0]', - author: 'name[0].namePart[0]', - edition: 'originInfo[0].edition[0]', - pubdate: 'originInfo[0].dateIssued[0]', - genre: 'genre[0]._' - } + translateBibSummary(xmlDoc: XMLDocument): any { // TODO: bib summary interface let response = { copyCounts : [], ccvms : {} }; - Object.keys(UNAPI_PATHS).forEach(key => { - try { - response[key] = eval(`summary.mods.${UNAPI_PATHS[key]}`); - } catch(E) { - response[key] = ''; - } - }); + let resolver:any = (prefix: string): string => { + return NAMESPACE_MAPS[prefix] || null; + }; - Object.keys(summary.mods.extern[0]['$']).forEach(field => { - if (field == 'xmlns') return; - response[field] = summary.mods.extern[0]['$'][field]; - }); + Object.keys(MODS_XPATH_AUTO).forEach(key => { + let result = xmlDoc.evaluate(MODS_XPATH_AUTO[key], xmlDoc, + resolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null); - summary.mods.attributes[0].field.forEach(attrField => { - response.ccvms[attrField['$'].name] = { - code: attrField['_'], - label: attrField['$']['coded-value'] - }; + let node = result.singleNodeValue; + if (node) response[key] = node.textContent; }); - summary.mods.holdings[0].counts[0].count.forEach(count => { - response.copyCounts.push(count['$']); - }); + let result = xmlDoc.evaluate(MODS_XPATH.extern, xmlDoc, + resolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null); - //console.log(summary); - //console.log(response); + let node:any = result.singleNodeValue; + if (node) { + let attrs = node.attributes; + for(let i = attrs.length - 1; i >= 0; i--) { + response[attrs[i].name] = attrs[i].value; + } + } + result = xmlDoc.evaluate(MODS_XPATH.attributes, xmlDoc, + resolver, XPathResult.ANY_TYPE, null); + + while(node = result.iterateNext()) { + response.ccvms[node.getAttribute('name')] = { + code : node.getAttribute('value'), + label : node.getAttribute('coded-value') + } + } + + result = xmlDoc.evaluate(MODS_XPATH.copyCounts, xmlDoc, + resolver, XPathResult.ANY_TYPE, null); + + while(node = result.iterateNext()) { + let counts = {}; + ['type', 'depth', 'org_unit', 'transcendant', + 'available', 'count', 'unshadow'].forEach(field => { + counts[field] = node.getAttribute(field); + }); + response.copyCounts.push(counts); + } + + //console.log(response); return response; } } diff --git a/Open-ILS/webby-src/src/app/share/unapi.ts b/Open-ILS/webby-src/src/app/share/unapi.ts index 6a7ea1f067..3de344b8a3 100644 --- a/Open-ILS/webby-src/src/app/share/unapi.ts +++ b/Open-ILS/webby-src/src/app/share/unapi.ts @@ -1,7 +1,6 @@ import {Injectable, EventEmitter} from '@angular/core'; import {EgOrgService} from '@eg/core/org'; import {HttpClient} from '@angular/common/http'; -import {Parser} from 'xml2js'; /* TODO: Add Display Fields to UNAPI @@ -27,40 +26,31 @@ export class EgUnapiService { private http: HttpClient ) {} - /** - * Retrieve an UNAPI document and return it as an XML string - */ - getAsXmlString(params: EgUnapiParams): Promise { + createUrl(params: EgUnapiParams): string { let depth = params.depth || 0; let org = params.orgId ? this.org.get(params.orgId) : this.org.root(); - let url = `${UNAPI_PATH}${params.target}/${params.id}${params.extras}/` + + return `${UNAPI_PATH}${params.target}/${params.id}${params.extras}/` + `${org.shortname()}/${depth}&format=${params.format}`; - - //console.debug(`UNAPI: ${url}`); - - return new Promise((resolve, reject) => { - this.http.get(url, {responseType: 'text'}) - .subscribe(xmlStr => resolve(xmlStr)); - }); } - /** - * Retrieve an UNAPI document and return its object form, as - * generated by xml2js. - */ - getAsObject(params: EgUnapiParams): Promise { + getAsXmlDocument(params: EgUnapiParams): Promise { + // XReq creates an XML document for us. Seems like the right + // tool for the job. + let url = this.createUrl(params); return new Promise((resolve, reject) => { - this.getAsXmlString(params) - .then(xmlStr => { - new Parser().parseString(xmlStr, (err, unapiBlob) => { - if (err) { - reject(err); + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4) { + if (this.status == 200) { + resolve(xhttp.responseXML); } else { - resolve(unapiBlob); + reject(`UNAPI request failed for ${url}`); } - }); - }); + } + } + xhttp.open("GET", url, true); + xhttp.send(); }); } } diff --git a/Open-ILS/webby-src/src/app/share/util/pager.ts b/Open-ILS/webby-src/src/app/share/util/pager.ts index 5f33d4ae4a..1c21a8dcaf 100644 --- a/Open-ILS/webby-src/src/app/share/util/pager.ts +++ b/Open-ILS/webby-src/src/app/share/util/pager.ts @@ -4,7 +4,7 @@ */ export class Pager { offset: number = 0; - limit: number = 15; + limit: number = null; resultCount: number; isFirstPage(): boolean { diff --git a/Open-ILS/webby-src/src/app/staff/catalog/result/pagination.component.ts b/Open-ILS/webby-src/src/app/staff/catalog/result/pagination.component.ts index ff5aabc61c..ff1746ccd0 100644 --- a/Open-ILS/webby-src/src/app/staff/catalog/result/pagination.component.ts +++ b/Open-ILS/webby-src/src/app/staff/catalog/result/pagination.component.ts @@ -37,7 +37,6 @@ export class ResultPaginationComponent implements OnInit { this.searchContext.pager.setPage(page); this.staffCat.search(); } - } diff --git a/Open-ILS/webby-src/src/app/staff/catalog/result/record.component.html b/Open-ILS/webby-src/src/app/staff/catalog/result/record.component.html index 98baa0acf3..63571f3de3 100644 --- a/Open-ILS/webby-src/src/app/staff/catalog/result/record.component.html +++ b/Open-ILS/webby-src/src/app/staff/catalog/result/record.component.html @@ -47,17 +47,24 @@
-
- {{copyCount.available}} / {{copyCount.count}} - items @ {{orgName(copyCount.org_unit)}} +
+
+ + {{copyCount.available}} / {{copyCount.count}} items + +
+
+ @ {{orgName(copyCount.org_unit)}} +
-
+
+
- Holds: {{bibSummary.holdCount}} + TCN: {{bibSummary.tcn_value}}
@@ -76,7 +83,7 @@
- TCN: {{bibSummary.tcn_value}} + Holds: {{bibSummary.holdCount}}
@@ -91,12 +98,7 @@
-
-
- ID: {{bibSummary.id}} -
-
-
+
-
+
-
+
-
+
-
+
Searching..
diff --git a/Open-ILS/webby-src/src/app/staff/catalog/search-form.component.ts b/Open-ILS/webby-src/src/app/staff/catalog/search-form.component.ts index db2dbaf679..0d70807ab2 100644 --- a/Open-ILS/webby-src/src/app/staff/catalog/search-form.component.ts +++ b/Open-ILS/webby-src/src/app/staff/catalog/search-form.component.ts @@ -1,8 +1,9 @@ import {Component, OnInit} from '@angular/core'; import {EgIdlObject} from '@eg/core/idl'; import {EgOrgService} from '@eg/core/org'; -import {EgCatalogService} from '@eg/share/catalog/catalog.service'; -import {CatalogSearchContext} from '@eg/share/catalog/search-context'; +import {EgCatalogService,} from '@eg/share/catalog/catalog.service'; +import {CatalogSearchContext, CatalogSearchState} + from '@eg/share/catalog/search-context'; import {StaffCatalogService} from './staff-catalog.service'; @Component({ @@ -82,6 +83,11 @@ export class SearchFormComponent implements OnInit { searchByForm(): void { this.staffCat.search(); } + + searchIsActive(): boolean { + return this.searchContext.searchState == CatalogSearchState.SEARCHING; + } + } diff --git a/Open-ILS/webby-src/src/app/staff/catalog/staff-catalog.service.ts b/Open-ILS/webby-src/src/app/staff/catalog/staff-catalog.service.ts index 2a70760c45..31512d5f31 100644 --- a/Open-ILS/webby-src/src/app/staff/catalog/staff-catalog.service.ts +++ b/Open-ILS/webby-src/src/app/staff/catalog/staff-catalog.service.ts @@ -33,6 +33,8 @@ export class StaffCatalogService { this.searchContext.org = this.org; this.searchContext.isStaff = true; + if (!this.searchContext.pager.limit) + this.searchContext.pager.limit = 20; } /**