1 import {Component, OnInit, OnDestroy, Input} from '@angular/core';
2 import {Observable, Subscription} from 'rxjs';
3 import {tap, map, switchMap, distinctUntilChanged} from 'rxjs/operators';
4 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
5 import {CatalogService} from '@eg/share/catalog/catalog.service';
6 import {BibRecordService} from '@eg/share/catalog/bib-record.service';
7 import {CatalogUrlService} from '@eg/share/catalog/catalog-url.service';
8 import {CatalogSearchContext, CatalogSearchState} from '@eg/share/catalog/search-context';
9 import {PcrudService} from '@eg/core/pcrud.service';
10 import {StaffCatalogService} from '../catalog.service';
11 import {IdlObject} from '@eg/core/idl.service';
12 import {BasketService} from '@eg/share/catalog/basket.service';
13 import {ServerStoreService} from '@eg/core/server-store.service';
16 selector: 'eg-catalog-results',
17 templateUrl: 'results.component.html',
18 styleUrls: ['results.component.css']
20 export class ResultsComponent implements OnInit, OnDestroy {
22 searchContext: CatalogSearchContext;
24 // Cache record creator/editor since this will likely be a
25 // reasonably small set of data w/ lots of repitition.
26 userCache: {[id: number]: IdlObject} = {};
28 allRecsSelected: boolean;
30 searchSub: Subscription;
31 routeSub: Subscription;
32 basketSub: Subscription;
33 showMoreDetails = false;
36 private route: ActivatedRoute,
37 private pcrud: PcrudService,
38 private cat: CatalogService,
39 private bib: BibRecordService,
40 private catUrl: CatalogUrlService,
41 private staffCat: StaffCatalogService,
42 private serverStore: ServerStoreService,
43 private basket: BasketService,
44 private router: Router
48 this.searchContext = this.staffCat.searchContext;
49 this.staffCat.browsePagerData = [];
51 // Our search context is initialized on page load. Once
52 // ResultsComponent is active, it will not be reinitialized,
53 // even if the route parameters changes (unless we change the
54 // route reuse policy). Watch for changes here to pick up new
57 // This will also fire on page load.
59 this.route.queryParamMap.subscribe((params: ParamMap) => {
61 // TODO: Angular docs suggest using switchMap(), but
62 // it's not firing for some reason. Also, could avoid
63 // firing unnecessary searches when a param unrelated to
64 // searching is changed by .map()'ing out only the desired
65 // params and running through .distinctUntilChanged(), but
66 // .map() is not firing either. I'm missing something.
67 this.searchByUrl(params);
70 // After each completed search, update the record selector.
71 this.searchSub = this.cat.onSearchComplete.subscribe(
73 this.jumpIfNecessary();
74 this.applyRecordSelection();
78 // Watch for basket changes applied by other components.
79 this.basketSub = this.basket.onChange.subscribe(
80 () => this.applyRecordSelection());
85 this.routeSub.unsubscribe();
86 this.searchSub.unsubscribe();
87 this.basketSub.unsubscribe();
91 // For non-metarecord searches, jump to record page if only a
92 // single hit is returned and the jump is enabled by library setting.
93 // Unlike the OPAC version of jump-on-single-hit, the staff version
94 // does not attempt to jump to the bib if it is the single member
95 // of a sole metarecord returned by a metarecord search.
97 const ids = this.searchContext.currentResultIds();
99 this.staffCat.jumpOnSingleHit &&
101 !this.searchContext.termSearch.isMetarecordSearch()
103 this.router.navigate(['/staff/catalog/record/' + ids[0]], {queryParamsHandling: 'merge'});
107 // Apply the select-all checkbox when all visible records
109 applyRecordSelection() {
110 const ids = this.searchContext.currentResultIds();
111 let allChecked = true;
113 if (!this.basket.hasRecordId(id)) {
117 this.allRecsSelected = allChecked;
120 // Pull values from the URL and run the requested search.
121 searchByUrl(params: ParamMap): void {
122 this.catUrl.applyUrlParams(this.searchContext, params);
125 if (this.searchContext.isSearchable()) {
127 this.serverStore.getItem('eg.staff.catalog.results.show_more')
130 this.showMoreDetails =
131 this.searchContext.showResultExtras = showMore;
133 if (this.staffCat.prefOrg) {
134 this.searchContext.prefOu = this.staffCat.prefOrg.id();
137 this.cat.search(this.searchContext)
139 this.cat.fetchFacets(this.searchContext);
140 this.cat.fetchBibSummaries(this.searchContext);
147 this.showMoreDetails = !this.showMoreDetails;
149 this.serverStore.setItem(
150 'eg.staff.catalog.results.show_more', this.showMoreDetails)
153 this.searchContext.showResultExtras = this.showMoreDetails;
155 if (this.showMoreDetails) {
156 this.staffCat.search();
158 // Clear the collected copies. No need for another search.
159 this.searchContext.result.records.forEach(rec => rec.copies = undefined);
164 searchIsDone(): boolean {
165 return this.searchContext.searchState === CatalogSearchState.COMPLETE;
168 searchIsActive(): boolean {
169 return this.searchContext.searchState === CatalogSearchState.SEARCHING;
172 searchHasResults(): boolean {
173 return this.searchIsDone() && this.searchContext.result.count > 0;
176 toggleAllRecsSelected() {
177 const ids = this.searchContext.currentResultIds();
179 if (this.allRecsSelected) {
180 this.basket.addRecordIds(ids);
182 this.basket.removeRecordIds(ids);