793767b38f83f9b6607494b9cd431f8d8bfce2a6
[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     @Input() set recordId(id: number) {
22         this.id = id;
23         // Only apply new record data after the initial load
24         if (this.initDone) {
25             this.setIndex();
26         }
27     }
28
29     constructor(
30         private router: Router,
31         private cat: CatalogService,
32         private catUrl: CatalogUrlService,
33         private staffCat: StaffCatalogService,
34     ) {}
35
36     ngOnInit() {
37         this.initDone = true;
38         this.setIndex();
39     }
40
41     firstRecord(): void {
42         this.findRecordAtIndex(0).then(id => {
43             const params = this.catUrl.toUrlParams(this.searchContext);
44             this.router.navigate(
45                 ['/staff/catalog/record/' + id], {queryParams: params});
46         });
47     }
48
49     lastRecord(): void {
50         this.findRecordAtIndex(
51             this.searchContext.result.count - 1
52         ).then(id => {
53             const params = this.catUrl.toUrlParams(this.searchContext);
54             this.router.navigate(
55                 ['/staff/catalog/record/' + id], {queryParams: params});
56         });
57     }
58
59     nextRecord(): void {
60         this.findRecordAtIndex(this.index + 1).then(id => {
61             const params = this.catUrl.toUrlParams(this.searchContext);
62             this.router.navigate(
63                 ['/staff/catalog/record/' + id], {queryParams: params});
64         });
65     }
66
67     prevRecord(): void {
68         this.findRecordAtIndex(this.index - 1).then(id => {
69             const params = this.catUrl.toUrlParams(this.searchContext);
70             this.router.navigate(
71                 ['/staff/catalog/record/' + id], {queryParams: params});
72         });
73     }
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                 if (this.index === null) {
98                     console.warn(
99                         'No search results found containing the focused record.');
100                 }
101                 resolve();
102             });
103         });
104     }
105
106     // Find the record ID at the specified search index.
107     // If no data exists for the requested index, expand the search
108     // to include data for that index.
109     findRecordAtIndex(index: number): Promise<number> {
110
111         // First see if the selected record sits in the current page
112         // of search results.
113         return new Promise((resolve, reject) => {
114             const id = this.searchContext.resultIdAt(index);
115             if (id) { return resolve(id); }
116
117             console.debug(
118                 'Record paginator unable to find record at index ' + index);
119
120             // If we have to re-run the search to find the record,
121             // expand the search limit out just enough to find the
122             // requested record plus one more.
123             return this.refreshSearch(index + 2).then(
124                 ok => {
125                     const rid = this.searchContext.resultIdAt(index);
126                     if (rid) {
127                         resolve(rid);
128                     } else {
129                         reject('no record found');
130                     }
131                 }
132             );
133         });
134     }
135
136     refreshSearch(limit?: number): Promise<any> {
137
138         console.debug('paginator refreshing search');
139
140         if (!this.searchContext.isSearchable()) {
141             return Promise.resolve();
142         }
143
144         const origPager = this.searchContext.pager;
145         const tmpPager = new Pager();
146         tmpPager.limit = limit || 1000;
147
148         this.searchContext.pager = tmpPager;
149
150         return this.cat.search(this.searchContext)
151         .then(
152             ok => this.searchContext.pager = origPager,
153             notOk => this.searchContext.pager = origPager
154         );
155     }
156
157     returnToSearch(): void {
158         // Fire the main search.  This will direct us back to /results/
159         this.staffCat.search();
160     }
161
162 }
163
164