]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/catalog/cnbrowse/results.component.ts
LP1850546 Call number browse grid
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / catalog / cnbrowse / results.component.ts
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 {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 {StaffCatalogService} from '../catalog.service';
10 import {BibRecordSummary} from '@eg/share/catalog/bib-record.service';
11 import {OrgService} from '@eg/core/org.service';
12
13 @Component({
14   selector: 'eg-catalog-cn-browse-results',
15   templateUrl: 'results.component.html'
16 })
17 export class CnBrowseResultsComponent implements OnInit, OnDestroy {
18
19     @Input() rowCount = 5;
20     rowIndexList: number[] = [];
21
22     // hard-coded because it requires template changes.
23     colCount = 3;
24
25     searchContext: CatalogSearchContext;
26     results: any[];
27     routeSub: Subscription;
28
29     constructor(
30         private router: Router,
31         private route: ActivatedRoute,
32         private org: OrgService,
33         private cat: CatalogService,
34         private bib: BibRecordService,
35         private catUrl: CatalogUrlService,
36         private staffCat: StaffCatalogService
37     ) {}
38
39     ngOnInit() {
40         this.searchContext = this.staffCat.searchContext;
41
42         for (let idx = 0; idx < this.rowCount; idx++) {
43             this.rowIndexList.push(idx);
44         }
45
46         this.routeSub = this.route.queryParamMap.subscribe(
47             (params: ParamMap) => this.browseByUrl(params)
48         );
49     }
50
51     ngOnDestroy() {
52         this.routeSub.unsubscribe();
53     }
54
55     browseByUrl(params: ParamMap): void {
56         this.catUrl.applyUrlParams(this.searchContext, params);
57         const cbs = this.searchContext.cnBrowseSearch;
58         cbs.limit = this.rowCount * this.colCount;
59
60         if (cbs.isSearchable()) {
61             this.results = [];
62             this.cat.cnBrowse(this.searchContext)
63                 .subscribe(results => this.processResults(results));
64         }
65     }
66
67     processResults(results: any[]) {
68         this.results = results;
69
70         const depth = this.searchContext.global ?
71             this.searchContext.org.root().ou_type().depth() :
72             this.searchContext.searchOrg.ou_type().depth();
73
74         const bibIds = this.results.map(r => r.record().id());
75         const distinct = (value: any, index: number, self: Array<number>) => {
76             return self.indexOf(value) === index;
77         };
78
79         const bres: IdlObject[] = [];
80         this.bib.getBibSummary(
81             bibIds.filter(distinct),
82             this.searchContext.searchOrg.id(), depth
83         ).subscribe(
84             summary => {
85                 // Response order not guaranteed.  Match the summary
86                 // object up with its response object.  A bib may be
87                 // linked to multiple call numbers
88                 const bibResults = this.results.filter(
89                     r => Number(r.record().id()) === summary.id);
90
91                 bres.push(summary.record);
92
93                 // Use _ since result is an 'acn' object.
94                 bibResults.forEach(r => r._bibSummary = summary);
95             },
96             err => {},
97             ()  => {
98                 this.bib.fleshBibUsers(bres);
99             }
100         );
101     }
102
103     browseIsDone(): boolean {
104         return this.searchContext.searchState === CatalogSearchState.COMPLETE;
105     }
106
107     browseIsActive(): boolean {
108         return this.searchContext.searchState === CatalogSearchState.SEARCHING;
109     }
110
111     browseHasResults(): boolean {
112         return this.browseIsDone() && this.results.length > 0;
113     }
114
115     prevPage() {
116         this.searchContext.cnBrowseSearch.offset--;
117         this.staffCat.cnBrowse();
118     }
119
120     nextPage() {
121         this.searchContext.cnBrowseSearch.offset++;
122         this.staffCat.cnBrowse();
123     }
124
125     /**
126      * Propagate the search params along when navigating to each record.
127      */
128     navigateToRecord(summary: BibRecordSummary) {
129         const params = this.catUrl.toUrlParams(this.searchContext);
130
131         this.router.navigate(
132             ['/staff/catalog/record/' + summary.id], {queryParams: params});
133     }
134
135     resultSlice(rowIdx: number): number[] {
136         const offset = rowIdx * this.colCount;
137         return this.results.slice(offset, offset + this.colCount);
138     }
139
140     isCenter(rowIdx: number, colIdx: number): boolean {
141         const total = this.rowCount * this.colCount;
142         return Math.floor(total / 2) === ((rowIdx * this.colCount) + colIdx);
143     }
144
145     orgName(orgId: number): string {
146         return this.org.get(orgId).shortname();
147     }
148 }
149
150