From a09bc5d9b61bc970c6e7d541937ed870c30ed572 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Tue, 12 Mar 2019 12:56:47 -0400 Subject: [PATCH] LP1819745 Ang staff result page link repairs Title, Title-by-Jacket-image, Author, and Facet links in the Angular staff catalog now behave like regular browser links, which means they can used to open new tabs via control-click, etc. Signed-off-by: Bill Erickson Signed-off-by: Dan Wells --- .../app/share/catalog/catalog-url.service.ts | 5 ++ .../src/app/share/catalog/catalog.service.ts | 2 +- .../src/app/share/catalog/search-context.ts | 1 - .../src/eg2/src/app/share/util/hash-params.ts | 29 +++++++++++ .../src/app/staff/catalog/catalog.service.ts | 5 ++ .../catalog/result/facets.component.html | 4 +- .../staff/catalog/result/facets.component.ts | 11 +++-- .../catalog/result/record.component.html | 35 ++++++++++---- .../staff/catalog/result/record.component.ts | 48 +++++++++++-------- 9 files changed, 102 insertions(+), 38 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/share/util/hash-params.ts 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 a59b7fc2db..91922d48d5 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 @@ -4,6 +4,7 @@ import {OrgService} from '@eg/core/org.service'; import {CatalogSearchContext, CatalogBrowseContext, CatalogMarcContext, CatalogTermContext, FacetFilter} from './search-context'; import {CATALOG_CCVM_FILTERS} from './search-context'; +import {HashParams} from '@eg/share/util/hash-params'; @Injectable() export class CatalogUrlService { @@ -130,6 +131,10 @@ export class CatalogUrlService { return params; } + fromUrlHash(params: any): CatalogSearchContext { + return this.fromUrlParams(new HashParams(params)); + } + /** * Creates a new search context from the active route params. */ 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 55fd18e188..9cff2c4e5d 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 @@ -1,6 +1,6 @@ import {Injectable, EventEmitter} from '@angular/core'; import {Observable} from 'rxjs'; -import {mergeMap, map, tap} from 'rxjs/operators'; +import {map, tap} 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'; 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 222536f69e..ef0fd552ea 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 @@ -1,7 +1,6 @@ import {OrgService} from '@eg/core/org.service'; import {IdlObject} from '@eg/core/idl.service'; import {Pager} from '@eg/share/util/pager'; -import {Params} from '@angular/router'; // CCVM's we care about in a catalog context // Don't fetch them all because there are a lot. diff --git a/Open-ILS/src/eg2/src/app/share/util/hash-params.ts b/Open-ILS/src/eg2/src/app/share/util/hash-params.ts new file mode 100644 index 0000000000..86a7bb5e2a --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/util/hash-params.ts @@ -0,0 +1,29 @@ +import {ParamMap} from '@angular/router'; + + +/** + * Class to map a generic hash to an Angular ParamMap. + */ +export class HashParams implements ParamMap { + private params: {[key: string]: any[]}; + + public get keys(): string[] { + return Object.keys(this.params); + } + + constructor(params: {[key: string]: any}) { + this.params = params || {}; + } + + has(key: string): boolean { + return key in this.params; + } + + get(key: string): string | null { + return this.has(key) ? [].concat(this.params[key])[0] : null; + } + + getAll(key: string): string[] { + return this.has(key) ? [].concat(this.params[key]) : []; + } +} diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts index 3b4f6962b6..3c1ba9579a 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/catalog.service.ts @@ -47,6 +47,11 @@ export class StaffCatalogService { this.applySearchDefaults(); } + cloneContext(context: CatalogSearchContext): CatalogSearchContext { + const params: any = this.catUrl.toUrlParams(context); + return this.catUrl.fromUrlHash(params); + } + applySearchDefaults(): void { if (!this.searchContext.searchOrg) { this.searchContext.searchOrg = diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/result/facets.component.html b/Open-ILS/src/eg2/src/app/staff/catalog/result/facets.component.html index 9681747043..2c2cb14cdb 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/result/facets.component.html +++ b/Open-ILS/src/eg2/src/app/staff/catalog/result/facets.component.html @@ -26,8 +26,8 @@
diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/result/facets.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/result/facets.component.ts index f16215a65f..aacb27c3bc 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/result/facets.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/result/facets.component.ts @@ -1,5 +1,6 @@ import {Component, OnInit, Input} from '@angular/core'; import {CatalogService} from '@eg/share/catalog/catalog.service'; +import {CatalogUrlService} from '@eg/share/catalog/catalog-url.service'; import {CatalogSearchContext, FacetFilter} from '@eg/share/catalog/search-context'; import {StaffCatalogService} from '../catalog.service'; @@ -25,6 +26,7 @@ export class ResultFacetsComponent implements OnInit { constructor( private cat: CatalogService, + private catUrl: CatalogUrlService, private staffCat: StaffCatalogService ) { this.facetConfig = FACET_CONFIG; @@ -38,10 +40,11 @@ export class ResultFacetsComponent implements OnInit { return this.searchContext.termSearch.hasFacet(new FacetFilter(cls, name, value)); } - applyFacet(cls: string, name: string, value: string): void { - this.searchContext.termSearch.toggleFacet(new FacetFilter(cls, name, value)); - this.searchContext.pager.offset = 0; - this.staffCat.search(); + getFacetUrlParams(cls: string, name: string, value: string): any { + const context = this.staffCat.cloneContext(this.searchContext); + context.termSearch.toggleFacet(new FacetFilter(cls, name, value)); + context.pager.offset = 0; + return this.catUrl.toUrlParams(context); } } 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 eb33fe8877..5ddf94e000 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 @@ -21,9 +21,18 @@
- - - + + + + + + + + + +
@@ -38,17 +47,25 @@
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 8505e768f3..b46e4ca0ba 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 @@ -1,6 +1,6 @@ import {Component, OnInit, OnDestroy, Input} from '@angular/core'; import {Subscription} from 'rxjs'; -import {Router} from '@angular/router'; +import {Router, ParamMap} from '@angular/router'; import {OrgService} from '@eg/core/org.service'; import {NetService} from '@eg/core/net.service'; import {IdlObject} from '@eg/core/idl.service'; @@ -82,29 +82,35 @@ export class ResultRecordComponent implements OnInit, OnDestroy { alert('Adding to list for bib ' + this.summary.id); } - searchAuthor(summary: any) { - this.searchContext.reset(); - this.searchContext.termSearch.fieldClass = ['author']; - this.searchContext.termSearch.query = [summary.display.author]; - this.staffCat.search(); + // Params to genreate a new author search based on a reset + // clone of the current page params. + getAuthorSearchParams(summary: BibRecordSummary): any { + const tmpContext = this.staffCat.cloneContext(this.searchContext); + tmpContext.reset(); + tmpContext.termSearch.fieldClass = ['author']; + tmpContext.termSearch.query = [summary.display.author]; + return this.catUrl.toUrlParams(tmpContext); } - /** - * Propagate the search params along when navigating to each record. - */ - navigateToRecord(summary: BibRecordSummary) { - const params = this.catUrl.toUrlParams(this.searchContext); - - // Jump to metarecord constituent records page when a - // MR has more than 1 constituents. - if (summary.metabibId && summary.metabibRecords.length > 1) { - this.searchContext.termSearch.fromMetarecord = summary.metabibId; - this.staffCat.search(); - return; - } + // Returns the URL parameters for the current page plus the + // "fromMetarecord" param used for linking title links to + // MR constituent result records list. + appendFromMrParam(summary: BibRecordSummary): any { + const tmpContext = this.staffCat.cloneContext(this.searchContext); + tmpContext.termSearch.fromMetarecord = summary.metabibId; + return this.catUrl.toUrlParams(tmpContext); + } + + // Returns true if the selected record summary is a metarecord summary + // and it links to more than one constituent bib record. + hasMrConstituentRecords(summary: BibRecordSummary): boolean { + return ( + summary.metabibId && summary.metabibRecords.length > 1 + ); + } - this.router.navigate( - ['/staff/catalog/record/' + summary.id], {queryParams: params}); + currentParams(): any { + return this.catUrl.toUrlParams(this.searchContext); } toggleBasketEntry() { -- 2.43.2