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 for (let idx = 0; idx < this.rowCount; idx++) {
52 this.rowIndexList.push(idx);
55 let promise = Promise.resolve();
56 if (this.bibSummary) {
57 promise = this.getBrowseCallnumber();
61 this.routeSub = this.route.queryParamMap.subscribe(
62 (params: ParamMap) => this.browseByUrl(params)
68 this.routeSub.unsubscribe();
71 getBrowseCallnumber(): Promise<any> {
72 let org = this.searchContext.searchOrg.id();
74 if (this.searchContext.searchOrg.ou_type().can_have_vols() === 'f') {
75 // If the current search org unit cannot hold volumes, search
76 // across child org units.
77 org = this.org.descendants(this.searchContext.searchOrg, true);
80 return this.pcrud.search('acn',
81 {record: this.bibSummary.id, owning_lib: org},
83 ).toPromise().then(cn =>
84 this.browseCn = cn ? cn.label() : this.bibSummary.bibCallNumber
88 browseByUrl(params: ParamMap): void {
89 this.catUrl.applyUrlParams(this.searchContext, params);
90 this.getBrowseResults();
94 const cbs = this.searchContext.cnBrowseSearch;
95 cbs.limit = this.rowCount * this.colCount;
98 // Override any call number browse URL parameters
99 cbs.value = this.browseCn;
102 if (cbs.isSearchable()) {
104 this.cat.cnBrowse(this.searchContext)
105 .subscribe(results => this.processResults(results));
109 processResults(results: any[]) {
110 this.results = results;
112 const depth = this.searchContext.global ?
113 this.searchContext.org.root().ou_type().depth() :
114 this.searchContext.searchOrg.ou_type().depth();
116 const bibIds = this.results.map(r => r.record().id());
117 const distinct = (value: any, index: number, self: Array<number>) => {
118 return self.indexOf(value) === index;
121 const bres: IdlObject[] = [];
122 this.bib.getBibSummary(
123 bibIds.filter(distinct),
124 this.searchContext.searchOrg.id(), depth
127 // Response order not guaranteed. Match the summary
128 // object up with its response object. A bib may be
129 // linked to multiple call numbers
130 const bibResults = this.results.filter(
131 r => Number(r.record().id()) === summary.id);
133 bres.push(summary.record);
135 // Use _ since result is an 'acn' object.
136 bibResults.forEach(r => r._bibSummary = summary);
140 this.bib.fleshBibUsers(bres);
145 browseIsDone(): boolean {
146 return this.searchContext.searchState === CatalogSearchState.COMPLETE;
149 browseIsActive(): boolean {
150 return this.searchContext.searchState === CatalogSearchState.SEARCHING;
153 browseHasResults(): boolean {
154 return this.browseIsDone() && this.results.length > 0;
158 this.searchContext.cnBrowseSearch.offset--;
159 if (this.bibSummary) {
160 // Browse without navigation
161 this.getBrowseResults();
163 this.staffCat.cnBrowse();
169 this.searchContext.cnBrowseSearch.offset++;
170 if (this.bibSummary) {
171 // Browse without navigation
172 this.getBrowseResults();
174 this.staffCat.cnBrowse();
179 * Propagate the search params along when navigating to each record.
181 navigateToRecord(summary: BibRecordSummary) {
182 const params = this.catUrl.toUrlParams(this.searchContext);
184 this.router.navigate(
185 ['/staff/catalog/record/' + summary.id], {queryParams: params});
188 resultSlice(rowIdx: number): number[] {
189 const offset = rowIdx * this.colCount;
190 return this.results.slice(offset, offset + this.colCount);
193 isCenter(rowIdx: number, colIdx: number): boolean {
194 const total = this.rowCount * this.colCount;
195 return Math.floor(total / 2) === ((rowIdx * this.colCount) + colIdx);
198 orgName(orgId: number): string {
199 return this.org.get(orgId).shortname();
202 getAuthorSearchParams(summary: BibRecordSummary): any {
203 return this.staffCat.getAuthorSearchParams(summary);