LP1806087 Angular catalog Ang7 & lint repairs
[Evergreen.git] / Open-ILS / src / eg2 / src / app / share / catalog / basket.service.ts
1 import {Injectable, EventEmitter} from '@angular/core';
2 import {Observable} from 'rxjs';
3 import {StoreService} from '@eg/core/store.service';
4 import {NetService} from '@eg/core/net.service';
5 import {PcrudService} from '@eg/core/pcrud.service';
6 import {AnonCacheService} from '@eg/share/util/anon-cache.service';
7
8 // Baskets are stored in an anonymous cache using the cache key stored
9 // in a LoginSessionItem (i.e. cookie) at name BASKET_CACHE_KEY_COOKIE.
10 // The list is stored under attribute BASKET_CACHE_ATTR.
11 // Avoid conflicts with the AngularJS embedded catalog basket by
12 // using a different value for the cookie name, since our version
13 // stores all cookies as JSON, unlike the TPAC.
14 const BASKET_CACHE_KEY_COOKIE = 'basket';
15 const BASKET_CACHE_ATTR = 'recordIds';
16
17 @Injectable()
18 export class BasketService {
19
20     idList: number[];
21
22     // Fired every time our list of ID's are updated.
23     onChange: EventEmitter<number[]>;
24
25     constructor(
26         private net: NetService,
27         private pcrud: PcrudService,
28         private store: StoreService,
29         private anonCache: AnonCacheService
30     ) {
31         this.idList = [];
32         this.onChange = new EventEmitter<number[]>();
33     }
34
35     hasRecordId(id: number): boolean {
36         return this.idList.indexOf(Number(id)) > -1;
37     }
38
39     recordCount(): number {
40         return this.idList.length;
41     }
42
43     // TODO: Add server-side API for sorting a set of bibs by ID.
44     // See EGCatLoader/Container::fetch_mylist
45     getRecordIds(): Promise<number[]> {
46         const cacheKey = this.store.getLoginSessionItem(BASKET_CACHE_KEY_COOKIE);
47         this.idList = [];
48
49         if (!cacheKey) { return Promise.resolve(this.idList); }
50
51         return this.anonCache.getItem(cacheKey, BASKET_CACHE_ATTR).then(
52             list => {
53                 if (!list) { return this.idList; }
54                 this.idList = list.map(id => Number(id));
55                 return this.idList;
56             }
57         );
58     }
59
60     setRecordIds(ids: number[]): Promise<number[]> {
61         this.idList = ids;
62
63         // If we have no cache key, that's OK, assume this is the first
64         // attempt at adding a value and let the server create the cache
65         // key for us, then store the value in our cookie.
66         const cacheKey = this.store.getLoginSessionItem(BASKET_CACHE_KEY_COOKIE);
67
68         return this.anonCache.setItem(cacheKey, BASKET_CACHE_ATTR, this.idList)
69         .then(key => {
70             this.store.setLoginSessionItem(BASKET_CACHE_KEY_COOKIE, key);
71             this.onChange.emit(this.idList);
72             return this.idList;
73         });
74     }
75
76     addRecordIds(ids: number[]): Promise<number[]> {
77         ids = ids.filter(id => !this.hasRecordId(id)); // avoid dupes
78
79         if (ids.length === 0) {
80             return Promise.resolve(this.idList);
81         }
82         return this.setRecordIds(
83             this.idList.concat(ids.map(id => Number(id))));
84     }
85
86     removeRecordIds(ids: number[]): Promise<number[]> {
87
88         if (this.idList.length === 0) {
89             return Promise.resolve(this.idList);
90         }
91
92         const wantedIds = this.idList.filter(
93             id => ids.indexOf(Number(id)) < 0);
94
95         return this.setRecordIds(wantedIds); // OK if empty
96     }
97
98     removeAllRecordIds(): Promise<number[]> {
99         return this.setRecordIds([]);
100     }
101 }
102
103