]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/eg2/src/app/core/store.service.ts
LP1847800 Admin grids support config_field links
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / core / store.service.ts
1 /**
2  * Store and retrieve data from various sources.
3  *
4  * Data Types:
5  * 1. LocalItem: Stored in window.localStorage and persist indefinitely.
6  * 2. SessionItem: Stored in window.sessionStorage and persist until
7  *    the end of the current browser tab/window.  Data is only available
8  *    to the tab/window where the data was set.
9  * 3. LoginItem: Stored as session cookies and persist until the browser
10  *    is closed.  These values are avalable to all browser windows/tabs.
11  */
12 import {Injectable} from '@angular/core';
13 import {CookieService} from 'ngx-cookie';
14 import {HatchService} from './hatch.service';
15
16 const WS_ALL_KEY = 'eg.workstation.all';
17 const WS_DEF_KEY = 'eg.workstation.default';
18
19 @Injectable({providedIn: 'root'})
20 export class StoreService {
21
22     // Base path for cookie-based storage.
23     // Useful for limiting cookies to subsections of the application.
24     // Store cookies globally by default.
25     // Note cookies shared with /eg/staff must be stored at "/"
26     loginSessionBasePath = '/';
27
28     // Set of keys whose values should disappear at logout.
29     loginSessionKeys: string[] = [
30         'eg.auth.token',
31         'eg.auth.time',
32         'eg.auth.token.oc',
33         'eg.auth.time.oc'
34     ];
35
36     constructor(
37         private cookieService: CookieService,
38         private hatch: HatchService) {
39     }
40
41     private parseJson(valJson: string): any {
42         if (valJson === undefined || valJson === null || valJson === '') {
43             return null;
44         }
45         try {
46             return JSON.parse(valJson);
47         } catch (E) {
48             console.error(`Failure to parse JSON: ${E} => ${valJson}`);
49             return null;
50         }
51     }
52
53     /**
54      * Add a an app-local login session key
55      */
56     addLoginSessionKey(key: string): void {
57         this.loginSessionKeys.push(key);
58     }
59
60     setLocalItem(key: string, val: any, isJson?: boolean): void {
61         if (!isJson) {
62             val = JSON.stringify(val);
63         }
64         window.localStorage.setItem(key, val);
65     }
66
67     setSessionItem(key: string, val: any, isJson?: boolean): void {
68         if (!isJson) {
69             val = JSON.stringify(val);
70         }
71         window.sessionStorage.setItem(key, val);
72     }
73
74     setLoginSessionItem(key: string, val: any, isJson?: boolean): void {
75         if (!isJson) {
76             val = JSON.stringify(val);
77         }
78         this.cookieService.put(key, val,
79             {path : this.loginSessionBasePath, secure: true});
80     }
81
82     setWorkstations(val: any, isJson?: boolean): Promise<any> {
83         if (this.hatch.isAvailable) {
84             return this.hatch.setItem(WS_ALL_KEY, val).then(
85                 ok => {
86                     // When clearing workstations, remove the default.
87                     if (!val || val.length === 0) {
88                         return this.hatch.removeItem(WS_DEF_KEY);
89                     }
90                 }
91             );
92         } else {
93             return Promise.resolve(
94                 this.setLocalItem(WS_ALL_KEY, val, isJson));
95         }
96     }
97
98     setDefaultWorkstation(val: string, isJson?: boolean): Promise<any> {
99         if (this.hatch.isAvailable) {
100             return this.hatch.setItem(WS_DEF_KEY, val);
101         } else {
102             return Promise.resolve(
103                 this.setLocalItem(WS_DEF_KEY, val, isJson));
104         }
105     }
106
107     getLocalItem(key: string): any {
108         return this.parseJson(window.localStorage.getItem(key));
109     }
110
111     getSessionItem(key: string): any {
112         return this.parseJson(window.sessionStorage.getItem(key));
113     }
114
115     getLoginSessionItem(key: string): any {
116         return this.parseJson(this.cookieService.get(key));
117     }
118
119     getWorkstations(): Promise<any> {
120         if (this.hatch.isAvailable) {
121             return this.mergeWorkstations().then(ok => {
122                 this.removeLocalItem(WS_ALL_KEY);
123                 return this.hatch.getItem(WS_ALL_KEY);
124             });
125         } else {
126             return Promise.resolve(this.getLocalItem(WS_ALL_KEY));
127         }
128     }
129
130     // See if any workstatoins are stored in local storage.  If so, also
131     // see if we have any stored in Hatch.  If both, merged workstations
132     // from localStorage in Hatch storage, skipping any whose name
133     // collide with a workstation in Hatch.  If none exist in Hatch,
134     // copy the localStorage workstations over wholesale.
135     mergeWorkstations(): Promise<any> {
136         const existing = this.getLocalItem(WS_ALL_KEY);
137
138         if (!existing || existing.length === 0) {
139             return Promise.resolve();
140         }
141
142         return this.hatch.getItem(WS_ALL_KEY).then(inHatch => {
143
144             if (!inHatch || inHatch.length === 0) {
145                 // Nothing to merge, copy the data over directly
146                 return this.hatch.setItem('eg.workstation.all', existing);
147             }
148
149             const addMe: any = [];
150             existing.forEach(ws => {
151                 const match = inHatch.filter(w => w.name === ws.name)[0];
152                 if (!match) {
153                     console.log(
154                         'Migrating workstation from local storage to hatch: '
155                         + ws.name
156                     );
157                     addMe.push(ws);
158                 }
159             });
160             inHatch = inHatch.concat(addMe);
161             return this.hatch.setItem(WS_ALL_KEY, inHatch);
162         });
163     }
164
165     getDefaultWorkstation(): Promise<any> {
166         if (this.hatch.isAvailable) {
167             return this.hatch.getItem(WS_DEF_KEY).then(name => {
168                 if (name) {
169                     // We have a default in Hatch, remove any lingering
170                     // value from localStorage.
171                     this.removeLocalItem(WS_DEF_KEY);
172                     return name;
173                 } else {
174                     // Nothing in Hatch, see if we have a localStorage
175                     // value to migrate to Hatch
176                     name = this.getLocalItem(WS_DEF_KEY);
177                     if (name) {
178                         console.debug(
179                             'Migrating default workstation to Hatch ' + name);
180                         return this.hatch.setItem(WS_DEF_KEY, name)
181                         .then(ok => name);
182                     } else {
183                         return null;
184                     }
185                 }
186             });
187         } else {
188             return Promise.resolve(this.getLocalItem(WS_DEF_KEY));
189         }
190     }
191
192     removeLocalItem(key: string): void {
193         window.localStorage.removeItem(key);
194     }
195
196     removeSessionItem(key: string): void {
197         window.sessionStorage.removeItem(key);
198     }
199
200     removeLoginSessionItem(key: string): void {
201         this.cookieService.remove(key, {path : this.loginSessionBasePath});
202     }
203
204     removeDefaultWorkstation(val: string, isJson?: boolean): Promise<any> {
205         if (this.hatch.isAvailable) {
206             return this.hatch.removeItem(WS_DEF_KEY);
207         } else {
208             return Promise.resolve(
209                 this.removeLocalItem(WS_DEF_KEY));
210         }
211     }
212
213
214     clearLoginSessionItems(): void {
215         this.loginSessionKeys.forEach(
216             key => this.removeLoginSessionItem(key)
217         );
218     }
219 }
220