1 import {Injectable, EventEmitter} from '@angular/core';
2 import {Router, ActivatedRoute} from '@angular/router';
3 import {IdlObject} from '@eg/core/idl.service';
4 import {OrgService} from '@eg/core/org.service';
5 import {CatalogService} from '@eg/share/catalog/catalog.service';
6 import {CatalogUrlService} from '@eg/share/catalog/catalog-url.service';
7 import {CatalogSearchContext} from '@eg/share/catalog/search-context';
8 import {BibRecordSummary} from '@eg/share/catalog/bib-record.service';
9 import {PatronService} from '@eg/staff/share/patron/patron.service';
10 import {StoreService} from '@eg/core/store.service';
13 * Shared bits needed by the staff version of the catalog.
17 export class StaffCatalogService {
19 searchContext: CatalogSearchContext;
21 defaultSearchOrg: IdlObject;
22 defaultSearchLimit: number;
23 // Track the current template through route changes.
24 selectedTemplate: string;
26 // Display the Exclude Electronic checkbox
27 showExcludeElectronic = false;
29 // Advanced search filters to display
30 searchFilters: string[];
32 // TODO: does unapi support pref-lib for result-page copy counts?
38 // Patron barcode we hope to place a hold for.
39 holdForBarcode: string;
40 // User object for above barcode.
41 holdForUser: IdlObject;
43 // Emit that the value has changed so components can detect
44 // the change even when the component is not itself digesting
46 holdForChange: EventEmitter<void> = new EventEmitter<void>();
48 // Cache the currently selected detail record (i.g. catalog/record/123)
49 // summary so the record detail component can avoid duplicate fetches
50 // during record tab navigation.
51 currentDetailRecordSummary: any;
53 // Add digital bookplate to search options.
54 enableBookplates = false;
56 // Cache of browse results so the browse pager is not forced to
57 // re-run the browse search on each navigation.
58 browsePagerData: any[];
60 // whether to redirect to record page upon a single search
62 jumpOnSingleHit = false;
65 private router: Router,
66 private route: ActivatedRoute,
67 private store: StoreService,
68 private org: OrgService,
69 private cat: CatalogService,
70 private patron: PatronService,
71 private catUrl: CatalogUrlService
74 createContext(): void {
75 // Initialize the search context from the load-time URL params.
76 // Do this here so the search form and other context data are
77 // applied on every page, not just the search results page. The
78 // search results pages will handle running the actual search.
80 this.catUrl.fromUrlParams(this.route.snapshot.queryParamMap);
82 this.holdForBarcode = this.store.getLocalItem('eg.circ.patron_hold_target');
84 if (this.holdForBarcode) {
85 this.patron.getByBarcode(this.holdForBarcode)
87 this.holdForUser = user;
88 this.holdForChange.emit();
92 this.searchContext.org = this.org; // service, not searchOrg
93 this.searchContext.isStaff = true;
94 this.applySearchDefaults();
98 this.holdForUser = null;
99 this.holdForBarcode = null;
100 this.store.removeLocalItem('eg.circ.patron_hold_target');
101 this.holdForChange.emit();
104 cloneContext(context: CatalogSearchContext): CatalogSearchContext {
105 const params: any = this.catUrl.toUrlParams(context);
106 const ctx = this.catUrl.fromUrlHash(params);
107 ctx.isStaff = true; // not carried in the URL
111 applySearchDefaults(): void {
112 if (!this.searchContext.searchOrg) {
113 this.searchContext.searchOrg =
114 this.defaultSearchOrg || this.org.root();
117 if (!this.searchContext.pager.limit) {
118 this.searchContext.pager.limit = this.defaultSearchLimit || 10;
123 * Redirect to the search results page while propagating the current
124 * search paramters into the URL. Let the search results component
125 * execute the actual search.
128 if (!this.searchContext.isSearchable()) { return; }
130 // Clear cached detail summary for new searches.
131 this.currentDetailRecordSummary = null;
133 const params = this.catUrl.toUrlParams(this.searchContext);
135 // Force a new search every time this method is called, even if
136 // it's the same as the active search. Since router navigation
137 // exits early when the route + params is identical, add a
138 // random token to the route params to force a full navigation.
139 // This also resolves a problem where only removing secondary+
140 // versions of a query param fail to cause a route navigation.
141 // (E.g. going from two query= params to one). Investigation
143 params.ridx = '' + this.routeIndex++;
145 this.router.navigate(
146 ['/staff/catalog/search'], {queryParams: params});
150 * Redirect to the browse results page while propagating the current
151 * browse paramters into the URL. Let the browse results component
152 * execute the actual browse.
155 if (!this.searchContext.browseSearch.isSearchable()) { return; }
156 const params = this.catUrl.toUrlParams(this.searchContext);
158 // Force a new browse every time this method is called, even if
159 // it's the same as the active browse. Since router navigation
160 // exits early when the route + params is identical, add a
161 // random token to the route params to force a full navigation.
162 // This also resolves a problem where only removing secondary+
163 // versions of a query param fail to cause a route navigation.
164 // (E.g. going from two query= params to one).
165 params.ridx = '' + this.routeIndex++;
167 this.router.navigate(
168 ['/staff/catalog/browse'], {queryParams: params});
171 // Call number browse.
172 // Redirect to cn browse page and let its component perform the search
174 if (!this.searchContext.cnBrowseSearch.isSearchable()) { return; }
175 const params = this.catUrl.toUrlParams(this.searchContext);
176 params.ridx = '' + this.routeIndex++; // see comments above
177 this.router.navigate(['/staff/catalog/cnbrowse'], {queryParams: params});
180 // Params to genreate a new author search based on a reset
181 // clone of the current page params.
182 getAuthorSearchParams(summary: BibRecordSummary): any {
183 const tmpContext = this.cloneContext(this.searchContext);
185 tmpContext.termSearch.fieldClass = ['author'];
186 tmpContext.termSearch.query = [summary.display.author];
187 return this.catUrl.toUrlParams(tmpContext);