1 import {Component, Input, OnInit, OnDestroy} from '@angular/core';
2 import {ActivatedRoute, Router, ParamMap} from '@angular/router';
3 import {Subscription} from 'rxjs';
4 import {IdlObject} from '@eg/core/idl.service';
5 import {PcrudService} from '@eg/core/pcrud.service';
6 import {CatalogService} from '@eg/share/catalog/catalog.service';
7 import {BibRecordService} from '@eg/share/catalog/bib-record.service';
8 import {CatalogUrlService} from '@eg/share/catalog/catalog-url.service';
9 import {CatalogSearchContext, CatalogSearchState} from '@eg/share/catalog/search-context';
10 import {StaffCatalogService} from '../catalog.service';
11 import {BibRecordSummary} from '@eg/share/catalog/bib-record.service';
12 import {OrgService} from '@eg/core/org.service';
15 selector: 'eg-catalog-cn-browse-results',
16 templateUrl: 'results.component.html'
18 export class CnBrowseResultsComponent implements OnInit, OnDestroy {
20 // If set, this is a bib-focused browse
21 @Input() bibSummary: BibRecordSummary;
23 @Input() rowCount = 5;
24 rowIndexList: number[] = [];
26 // hard-coded because it requires template changes.
29 searchContext: CatalogSearchContext;
31 routeSub: Subscription;
33 // When browsing by a specific record, keep tabs on the initial
34 // browse call number.
38 private router: Router,
39 private route: ActivatedRoute,
40 private org: OrgService,
41 private pcrud: PcrudService,
42 private cat: CatalogService,
43 private bib: BibRecordService,
44 private catUrl: CatalogUrlService,
45 private staffCat: StaffCatalogService
49 this.searchContext = this.staffCat.searchContext;
51 if (this.bibSummary) {
52 // Avoid clobbering the active search when browsing in
53 // the context of a specific record.
55 this.staffCat.cloneContext(this.searchContext);
58 for (let idx = 0; idx < this.rowCount; idx++) {
59 this.rowIndexList.push(idx);
62 let promise = Promise.resolve();
63 if (this.bibSummary) {
64 promise = this.getBrowseCallnumber();
68 this.routeSub = this.route.queryParamMap.subscribe(
69 (params: ParamMap) => this.browseByUrl(params)
75 this.routeSub.unsubscribe();
78 getBrowseCallnumber(): Promise<any> {
79 let org = this.searchContext.searchOrg.id();
81 if (this.searchContext.searchOrg.ou_type().can_have_vols() === 'f') {
82 // If the current search org unit cannot hold volumes, search
83 // across child org units.
84 org = this.org.descendants(this.searchContext.searchOrg, true);
87 return this.pcrud.search('acn',
88 {record: this.bibSummary.id, owning_lib: org},
90 ).toPromise().then(cn =>
91 this.browseCn = cn ? cn.label() : this.bibSummary.bibCallNumber
95 browseByUrl(params: ParamMap): void {
96 this.catUrl.applyUrlParams(this.searchContext, params);
97 this.getBrowseResults();
101 const cbs = this.searchContext.cnBrowseSearch;
102 cbs.limit = this.rowCount * this.colCount;
105 // Override any call number browse URL parameters
106 cbs.value = this.browseCn;
109 if (cbs.isSearchable()) {
111 this.cat.cnBrowse(this.searchContext)
112 .subscribe(results => this.processResults(results));
116 processResults(results: any[]) {
117 this.results = results;
119 const depth = this.searchContext.global ?
120 this.searchContext.org.root().ou_type().depth() :
121 this.searchContext.searchOrg.ou_type().depth();
123 const bibIds = this.results.map(r => r.record().id());
124 const distinct = (value: any, index: number, self: Array<number>) => {
125 return self.indexOf(value) === index;
128 const bres: IdlObject[] = [];
129 this.bib.getBibSummaries(
130 bibIds.filter(distinct),
131 this.searchContext.searchOrg.id(), this.searchContext.isStaff
134 // Response order not guaranteed. Match the summary
135 // object up with its response object. A bib may be
136 // linked to multiple call numbers
137 const bibResults = this.results.filter(
138 r => Number(r.record().id()) === summary.id);
140 bres.push(summary.record);
142 // Use _ since result is an 'acn' object.
143 bibResults.forEach(r => r._bibSummary = summary);
148 browseIsDone(): boolean {
149 return this.searchContext.searchState === CatalogSearchState.COMPLETE;
152 browseIsActive(): boolean {
153 return this.searchContext.searchState === CatalogSearchState.SEARCHING;
156 browseHasResults(): boolean {
157 return this.browseIsDone() && this.results.length > 0;
161 this.searchContext.cnBrowseSearch.offset--;
162 if (this.bibSummary) {
163 // Browse without navigation
164 this.getBrowseResults();
166 this.staffCat.cnBrowse();
172 this.searchContext.cnBrowseSearch.offset++;
173 if (this.bibSummary) {
174 // Browse without navigation
175 this.getBrowseResults();
177 this.staffCat.cnBrowse();
182 * Propagate the search params along when navigating to each record.
184 navigateToRecord(summary: BibRecordSummary) {
185 const params = this.catUrl.toUrlParams(this.searchContext);
187 this.router.navigate(
188 ['/staff/catalog/record/' + summary.id], {queryParams: params});
191 resultSlice(rowIdx: number): number[] {
192 const offset = rowIdx * this.colCount;
193 return this.results.slice(offset, offset + this.colCount);
196 isCenter(rowIdx: number, colIdx: number): boolean {
197 const total = this.rowCount * this.colCount;
198 return Math.floor(total / 2) === ((rowIdx * this.colCount) + colIdx);
201 orgName(orgId: number): string {
202 return this.org.get(orgId).shortname();
205 getAuthorSearchParams(summary: BibRecordSummary): any {
206 return this.staffCat.getAuthorSearchParams(summary);