]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/catalog/record/pagination.component.ts
LP1852782 Avoid unnecessary catalog pagination search
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / catalog / record / pagination.component.ts
1 import {Component, OnInit, Input} from '@angular/core';
2 import {Router} from '@angular/router';
3 import {CatalogService} from '@eg/share/catalog/catalog.service';
4 import {CatalogSearchContext} from '@eg/share/catalog/search-context';
5 import {CatalogUrlService} from '@eg/share/catalog/catalog-url.service';
6 import {StaffCatalogService} from '../catalog.service';
7 import {Pager} from '@eg/share/util/pager';
8
9
10 @Component({
11   selector: 'eg-catalog-record-pagination',
12   templateUrl: 'pagination.component.html'
13 })
14 export class RecordPaginationComponent implements OnInit {
15
16     id: number;
17     index: number;
18     initDone = false;
19     searchContext: CatalogSearchContext;
20
21     _recordTab: string;
22     @Input() set recordTab(tab: string) {
23         this._recordTab = tab;
24     }
25     get recordTab(): string {
26         return this._recordTab;
27     }
28
29     @Input() set recordId(id: number) {
30         this.id = id;
31         // Only apply new record data after the initial load
32         if (this.initDone) {
33             this.setIndex();
34         }
35     }
36
37     constructor(
38         private router: Router,
39         private cat: CatalogService,
40         private catUrl: CatalogUrlService,
41         private staffCat: StaffCatalogService,
42     ) {}
43
44     ngOnInit() {
45         this.initDone = true;
46         this.setIndex();
47     }
48
49     routeToRecord(id: number) {
50         let url = '/staff/catalog/record/' + id;
51         if (this.recordTab) { url += '/' + this.recordTab; }
52         const params = this.catUrl.toUrlParams(this.searchContext);
53         this.router.navigate([url], {queryParams: params});
54     }
55
56     firstRecord(): void {
57         this.findRecordAtIndex(0)
58         .then(id => this.routeToRecord(id));
59     }
60
61     lastRecord(): void {
62         this.findRecordAtIndex(this.searchContext.result.count - 1)
63         .then(id => this.routeToRecord(id));
64     }
65
66     nextRecord(): void {
67         this.findRecordAtIndex(this.index + 1)
68         .then(id => this.routeToRecord(id));
69     }
70
71     prevRecord(): void {
72         this.findRecordAtIndex(this.index - 1)
73         .then(id => this.routeToRecord(id));
74     }
75
76     // Returns the offset of the record within the search results as a whole.
77     searchIndex(idx: number): number {
78         return idx + this.searchContext.pager.offset;
79     }
80
81     // Find the position of the current record in the search results
82     // If no results are present or the record is not found, expand
83     // the search scope to find the record.
84     setIndex(): Promise<void> {
85         this.searchContext = this.staffCat.searchContext;
86         this.index = null;
87
88         return new Promise((resolve, reject) => {
89
90             this.index = this.searchContext.indexForResult(this.id);
91             if (this.index !== null) {
92                 return resolve();
93             }
94
95             return this.refreshSearch().then(ok => {
96                 this.index = this.searchContext.indexForResult(this.id);
97                 resolve();
98             });
99         });
100     }
101
102     // Find the record ID at the specified search index.
103     // If no data exists for the requested index, expand the search
104     // to include data for that index.
105     findRecordAtIndex(index: number): Promise<number> {
106
107         // First see if the selected record sits in the current page
108         // of search results.
109         return new Promise((resolve, reject) => {
110             const id = this.searchContext.resultIdAt(index);
111             if (id) { return resolve(id); }
112
113             console.debug(
114                 'Record paginator unable to find record at index ' + index);
115
116             // If we have to re-run the search to find the record,
117             // expand the search limit out just enough to find the
118             // requested record plus one more.
119             return this.refreshSearch(index + 2).then(
120                 ok => {
121                     const rid = this.searchContext.resultIdAt(index);
122                     if (rid) {
123                         resolve(rid);
124                     } else {
125                         reject('no record found');
126                     }
127                 }
128             );
129         });
130     }
131
132     refreshSearch(limit?: number): Promise<any> {
133
134         console.debug('paginator refreshing search');
135
136         if (!this.searchContext.isSearchable()) {
137             return Promise.resolve();
138         }
139
140         const origPager = this.searchContext.pager;
141         const tmpPager = new Pager();
142         tmpPager.limit = limit || 1000;
143
144         this.searchContext.pager = tmpPager;
145
146         return this.cat.search(this.searchContext)
147         .then(
148             ok => this.searchContext.pager = origPager,
149             notOk => this.searchContext.pager = origPager
150         );
151     }
152
153     returnToSearch(): void {
154         // Fire the main search.  This will direct us back to /results/
155         this.staffCat.search();
156     }
157
158 }
159
160