1 /* eslint-disable no-magic-numbers */
2 import {Component, Input, OnInit, OnDestroy} from '@angular/core';
3 import {ActivatedRoute, Router, ParamMap} from '@angular/router';
4 import {Subscription} from 'rxjs';
5 import {IdlObject} from '@eg/core/idl.service';
6 import {PcrudService} from '@eg/core/pcrud.service';
7 import {CatalogService} from '@eg/share/catalog/catalog.service';
8 import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.service';
9 import {CatalogUrlService} from '@eg/share/catalog/catalog-url.service';
10 import {CatalogSearchContext, CatalogSearchState} from '@eg/share/catalog/search-context';
11 import {StaffCatalogService} from '../catalog.service';
12 import {OrgService} from '@eg/core/org.service';
15 selector: 'eg-catalog-cn-browse-results',
16 templateUrl: 'results.component.html',
17 styleUrls: ['results.component.css']
19 export class CnBrowseResultsComponent implements OnInit, OnDestroy {
21 // If set, this is a bib-focused browse
22 @Input() bibSummary: BibRecordSummary;
24 @Input() rowCount = 5;
25 rowIndexList: number[] = [];
27 // hard-coded because it requires template changes.
30 searchContext: CatalogSearchContext;
32 routeSub: Subscription;
34 // When browsing by a specific record, keep tabs on the initial
35 // browse call number.
39 private router: Router,
40 private route: ActivatedRoute,
41 private org: OrgService,
42 private pcrud: PcrudService,
43 private cat: CatalogService,
44 private bib: BibRecordService,
45 private catUrl: CatalogUrlService,
46 private staffCat: StaffCatalogService
50 this.searchContext = this.staffCat.searchContext;
52 if (this.bibSummary) {
53 // Avoid clobbering the active search when browsing in
54 // the context of a specific record.
56 this.staffCat.cloneContext(this.searchContext);
59 for (let idx = 0; idx < this.rowCount; idx++) {
60 this.rowIndexList.push(idx);
63 let promise = Promise.resolve();
64 if (this.bibSummary) {
65 promise = this.getBrowseCallnumber();
69 this.routeSub = this.route.queryParamMap.subscribe(
70 (params: ParamMap) => this.browseByUrl(params)
76 this.routeSub.unsubscribe();
79 getBrowseCallnumber(): Promise<any> {
80 let org = this.searchContext.searchOrg.id();
82 if (this.searchContext.searchOrg.ou_type().can_have_vols() === 'f') {
83 // If the current search org unit cannot hold volumes, search
84 // across child org units.
85 org = this.org.descendants(this.searchContext.searchOrg, true);
88 return this.pcrud.search('acn',
89 {record: this.bibSummary.id, owning_lib: org, deleted: 'f'},
91 ).toPromise().then(cn =>
92 this.browseCn = cn ? cn.label() : this.bibSummary.bibCallNumber
96 browseByUrl(params: ParamMap): void {
97 this.catUrl.applyUrlParams(this.searchContext, params);
98 this.getBrowseResults();
102 const cbs = this.searchContext.cnBrowseSearch;
103 cbs.limit = this.rowCount * this.colCount;
106 // Override any call number browse URL parameters
107 cbs.value = this.browseCn;
110 if (cbs.isSearchable()) {
112 this.cat.cnBrowse(this.searchContext)
113 .subscribe(results => this.processResults(results));
117 processResults(results: any[]) {
118 this.results = results;
120 const depth = this.searchContext.global ?
121 this.searchContext.org.root().ou_type().depth() :
122 this.searchContext.searchOrg.ou_type().depth();
124 const bibIds = this.results.map(r => r.record().id());
125 const distinct = (value: any, index: number, self: Array<number>) => {
126 return self.indexOf(value) === index;
129 const bres: IdlObject[] = [];
130 this.bib.getBibSummaries(
131 bibIds.filter(distinct),
132 this.searchContext.searchOrg.id(), this.searchContext.isStaff
135 // Response order not guaranteed. Match the summary
136 // object up with its response object. A bib may be
137 // linked to multiple call numbers
138 const bibResults = this.results.filter(
139 r => Number(r.record().id()) === summary.id);
141 bres.push(summary.record);
143 // Use _ since result is an 'acn' object.
144 bibResults.forEach(r => r._bibSummary = summary);
149 browseIsDone(): boolean {
150 return this.searchContext.searchState === CatalogSearchState.COMPLETE;
153 browseIsActive(): boolean {
154 return this.searchContext.searchState === CatalogSearchState.SEARCHING;
157 browseHasResults(): boolean {
158 return this.browseIsDone() && this.results.length > 0;
162 this.searchContext.cnBrowseSearch.offset--;
163 if (this.bibSummary) {
164 // Browse without navigation
165 this.getBrowseResults();
167 this.staffCat.cnBrowse();
173 this.searchContext.cnBrowseSearch.offset++;
174 if (this.bibSummary) {
175 // Browse without navigation
176 this.getBrowseResults();
178 this.staffCat.cnBrowse();
183 * Propagate the search params along when navigating to each record.
185 navigateToRecord(summary: BibRecordSummary) {
186 const params = this.catUrl.toUrlParams(this.searchContext);
188 this.router.navigate(
189 ['/staff/catalog/record/' + summary.id], {queryParams: params});
192 resultSlice(rowIdx: number): number[] {
193 const offset = rowIdx * this.colCount;
194 return this.results.slice(offset, offset + this.colCount);
197 isCenter(rowIdx: number, colIdx: number): boolean {
198 const total = this.rowCount * this.colCount;
199 return Math.floor(total / 2) === ((rowIdx * this.colCount) + colIdx);
202 orgName(orgId: number): string {
203 return this.org.get(orgId).shortname();
206 getAuthorSearchParams(summary: BibRecordSummary): any {
207 return this.staffCat.getAuthorSearchParams(summary);