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 {
return params;
}
+ fromUrlHash(params: any): CatalogSearchContext {
+ return this.fromUrlParams(new HashParams(params));
+ }
+
/**
* Creates a new search context from the active route params.
*/
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';
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.
--- /dev/null
+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]) : [];
+ }
+}
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 =
<div class="row">
<div class="col-lg-9">
<a class="card-link"
- href='javascript:;'
- (click)="applyFacet(facetConf.facetClass, name, value.value)">
+ routerLink="/staff/catalog/search"
+ [queryParams]="getFacetUrlParams(facetConf.facetClass, name, value.value)">
{{value.value}}
</a>
</div>
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';
constructor(
private cat: CatalogService,
+ private catUrl: CatalogUrlService,
private staffCat: StaffCatalogService
) {
this.facetConfig = FACET_CONFIG;
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);
}
}
<!-- XXX hard-coded width so columns align vertically regardless
of the presence of a jacket image -->
<div class="pl-2 record-jacket-div" >
- <a href="javascript:void(0)" (click)="navigateToRecord(summary)">
- <img src="/opac/extras/ac/jacket/small/r/{{summary.id}}"/>
- </a>
+ <ng-container *ngIf="hasMrConstituentRecords(summary)">
+ <a routerLink="/staff/catalog/search"
+ [queryParams]="appendFromMrParam(summary)">
+ <img src="/opac/extras/ac/jacket/small/r/{{summary.id}}"/>
+ </a>
+ </ng-container>
+ <ng-container *ngIf="!hasMrConstituentRecords(summary)">
+ <a routerLink="/staff/catalog/record/{{summary.id}}"
+ [queryParams]="currentParams()">
+ <img src="/opac/extras/ac/jacket/small/r/{{summary.id}}"/>
+ </a>
+ </ng-container>
</div>
<!-- for call number browse display -->
<ng-container *ngIf="callNumber">
<div class="row">
<div class="col-lg-12 font-weight-bold">
<!-- nbsp allows the column to take shape when no value exists -->
- <a href="javascript:void(0)"
- (click)="navigateToRecord(summary)">
- {{summary.display.title || ' '}}
- </a>
+ <ng-container *ngIf="hasMrConstituentRecords(summary)">
+ <a routerLink="/staff/catalog/search"
+ [queryParams]="appendFromMrParam(summary)">
+ {{summary.display.title || ' '}}
+ </a>
+ </ng-container>
+ <ng-container *ngIf="!hasMrConstituentRecords(summary)">
+ <a routerLink="/staff/catalog/record/{{summary.id}}"
+ [queryParams]="currentParams()">
+ {{summary.display.title || ' '}}
+ </a>
+ </ng-container>
</div>
</div>
<div class="row pt-2">
<div class="col-lg-12">
<!-- nbsp allows the column to take shape when no value exists -->
- <a href="javascript:void(0)"
- (click)="searchAuthor(summary)">
+ <a routerLink="/staff/catalog/search"
+ [queryParams]="getAuthorSearchParams(summary)">
{{summary.display.author || ' '}}
</a>
</div>
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';
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() {