]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/catalog/cnbrowse/results.component.ts
LP1615805 No inputs after submit in patron search (AngularJS)
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / catalog / cnbrowse / results.component.ts
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';
13
14 @Component({
15     selector: 'eg-catalog-cn-browse-results',
16     templateUrl: 'results.component.html',
17     styleUrls: ['results.component.css']
18 })
19 export class CnBrowseResultsComponent implements OnInit, OnDestroy {
20
21     // If set, this is a bib-focused browse
22     @Input() bibSummary: BibRecordSummary;
23
24     @Input() rowCount = 5;
25     rowIndexList: number[] = [];
26
27     // hard-coded because it requires template changes.
28     colCount = 3;
29
30     searchContext: CatalogSearchContext;
31     results: any[] = [];
32     routeSub: Subscription;
33
34     // When browsing by a specific record, keep tabs on the initial
35     // browse call number.
36     browseCn: string;
37
38     constructor(
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
47     ) {}
48
49     ngOnInit() {
50         this.searchContext = this.staffCat.searchContext;
51
52         if (this.bibSummary) {
53             // Avoid clobbering the active search when browsing in
54             // the context of a specific record.
55             this.searchContext =
56                 this.staffCat.cloneContext(this.searchContext);
57         }
58
59         for (let idx = 0; idx < this.rowCount; idx++) {
60             this.rowIndexList.push(idx);
61         }
62
63         let promise = Promise.resolve();
64         if (this.bibSummary) {
65             promise = this.getBrowseCallnumber();
66         }
67
68         promise.then(_ => {
69             this.routeSub = this.route.queryParamMap.subscribe(
70                 (params: ParamMap) => this.browseByUrl(params)
71             );
72         });
73     }
74
75     ngOnDestroy() {
76         this.routeSub.unsubscribe();
77     }
78
79     getBrowseCallnumber(): Promise<any> {
80         let org = this.searchContext.searchOrg.id();
81
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);
86         }
87
88         return this.pcrud.search('acn',
89             {record: this.bibSummary.id, owning_lib: org, deleted: 'f'},
90             {limit: 1}
91         ).toPromise().then(cn =>
92             this.browseCn = cn ? cn.label() : this.bibSummary.bibCallNumber
93         );
94     }
95
96     browseByUrl(params: ParamMap): void {
97         this.catUrl.applyUrlParams(this.searchContext, params);
98         this.getBrowseResults();
99     }
100
101     getBrowseResults() {
102         const cbs = this.searchContext.cnBrowseSearch;
103         cbs.limit = this.rowCount * this.colCount;
104
105         if (this.browseCn) {
106             // Override any call number browse URL parameters
107             cbs.value = this.browseCn;
108         }
109
110         if (cbs.isSearchable()) {
111             this.results = [];
112             this.cat.cnBrowse(this.searchContext)
113                 .subscribe(results => this.processResults(results));
114         }
115     }
116
117     processResults(results: any[]) {
118         this.results = results;
119
120         const depth = this.searchContext.global ?
121             this.searchContext.org.root().ou_type().depth() :
122             this.searchContext.searchOrg.ou_type().depth();
123
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;
127         };
128
129         const bres: IdlObject[] = [];
130         this.bib.getBibSummaries(
131             bibIds.filter(distinct),
132             this.searchContext.searchOrg.id(), this.searchContext.isStaff
133         ).subscribe(
134             summary => {
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);
140
141                 bres.push(summary.record);
142
143                 // Use _ since result is an 'acn' object.
144                 bibResults.forEach(r => r._bibSummary = summary);
145             }
146         );
147     }
148
149     browseIsDone(): boolean {
150         return this.searchContext.searchState === CatalogSearchState.COMPLETE;
151     }
152
153     browseIsActive(): boolean {
154         return this.searchContext.searchState === CatalogSearchState.SEARCHING;
155     }
156
157     browseHasResults(): boolean {
158         return this.browseIsDone() && this.results.length > 0;
159     }
160
161     prevPage() {
162         this.searchContext.cnBrowseSearch.offset--;
163         if (this.bibSummary) {
164             // Browse without navigation
165             this.getBrowseResults();
166         } else {
167             this.staffCat.cnBrowse();
168         }
169
170     }
171
172     nextPage() {
173         this.searchContext.cnBrowseSearch.offset++;
174         if (this.bibSummary) {
175             // Browse without navigation
176             this.getBrowseResults();
177         } else {
178             this.staffCat.cnBrowse();
179         }
180     }
181
182     /**
183      * Propagate the search params along when navigating to each record.
184      */
185     navigateToRecord(summary: BibRecordSummary) {
186         const params = this.catUrl.toUrlParams(this.searchContext);
187
188         this.router.navigate(
189             ['/staff/catalog/record/' + summary.id], {queryParams: params});
190     }
191
192     resultSlice(rowIdx: number): number[] {
193         const offset = rowIdx * this.colCount;
194         return this.results.slice(offset, offset + this.colCount);
195     }
196
197     isCenter(rowIdx: number, colIdx: number): boolean {
198         const total = this.rowCount * this.colCount;
199         return Math.floor(total / 2) === ((rowIdx * this.colCount) + colIdx);
200     }
201
202     orgName(orgId: number): string {
203         return this.org.get(orgId).shortname();
204     }
205
206     getAuthorSearchParams(summary: BibRecordSummary): any {
207         return this.staffCat.getAuthorSearchParams(summary);
208     }
209 }
210
211