2 * Store and retrieve data from various sources.
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.
12 import {Injectable} from '@angular/core';
13 import {CookieService} from 'ngx-cookie';
14 import {HatchService} from './hatch.service';
16 const WS_ALL_KEY = 'eg.workstation.all';
17 const WS_DEF_KEY = 'eg.workstation.default';
19 @Injectable({providedIn: 'root'})
20 export class StoreService {
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 = '/';
28 // Set of keys whose values should disappear at logout.
29 loginSessionKeys: string[] = [
37 private cookieService: CookieService,
38 private hatch: HatchService) {
41 private parseJson(valJson: string): any {
42 if (valJson === undefined || valJson === null || valJson === '') {
46 return JSON.parse(valJson);
48 console.error(`Failure to parse JSON: ${E} => ${valJson}`);
54 * Add a an app-local login session key
56 addLoginSessionKey(key: string): void {
57 if (!this.loginSessionKeys.includes(key)) {
58 this.loginSessionKeys.push(key);
62 setLocalItem(key: string, val: any, isJson?: boolean): void {
64 val = JSON.stringify(val);
66 window.localStorage.setItem(key, val);
69 setSessionItem(key: string, val: any, isJson?: boolean): void {
70 console.log(`Setting session item: key=${key}, value=`, val, `isJson=${isJson}`);
72 val = JSON.stringify(val);
74 window.sessionStorage.setItem(key, val);
77 setLoginSessionItem(key: string, val: any, isJson?: boolean): void {
79 val = JSON.stringify(val);
81 this.cookieService.put(key, val,
82 {path : this.loginSessionBasePath, secure: true});
85 setWorkstations(val: any, isJson?: boolean): Promise<any> {
86 if (this.hatch.isAvailable) {
87 return this.hatch.setItem(WS_ALL_KEY, val).then(
89 // When clearing workstations, remove the default.
90 if (!val || val.length === 0) {
91 return this.hatch.removeItem(WS_DEF_KEY);
96 return Promise.resolve(
97 this.setLocalItem(WS_ALL_KEY, val, isJson));
101 setDefaultWorkstation(val: string, isJson?: boolean): Promise<any> {
102 if (this.hatch.isAvailable) {
103 return this.hatch.setItem(WS_DEF_KEY, val);
105 return Promise.resolve(
106 this.setLocalItem(WS_DEF_KEY, val, isJson));
110 getLocalItem(key: string): any {
111 return this.parseJson(window.localStorage.getItem(key));
114 getSessionItem(key: string): any {
115 return this.parseJson(window.sessionStorage.getItem(key));
118 getLoginSessionItem(key: string): any {
119 return this.parseJson(this.cookieService.get(key));
122 getWorkstations(): Promise<any> {
123 if (this.hatch.isAvailable) {
124 return this.mergeWorkstations().then(ok => {
125 this.removeLocalItem(WS_ALL_KEY);
126 return this.hatch.getItem(WS_ALL_KEY);
129 return Promise.resolve(this.getLocalItem(WS_ALL_KEY));
133 // See if any workstatoins are stored in local storage. If so, also
134 // see if we have any stored in Hatch. If both, merged workstations
135 // from localStorage in Hatch storage, skipping any whose name
136 // collide with a workstation in Hatch. If none exist in Hatch,
137 // copy the localStorage workstations over wholesale.
138 mergeWorkstations(): Promise<any> {
139 const existing = this.getLocalItem(WS_ALL_KEY);
141 if (!existing || existing.length === 0) {
142 return Promise.resolve();
145 return this.hatch.getItem(WS_ALL_KEY).then(inHatch => {
147 if (!inHatch || inHatch.length === 0) {
148 // Nothing to merge, copy the data over directly
149 return this.hatch.setItem('eg.workstation.all', existing);
152 const addMe: any = [];
153 existing.forEach(ws => {
154 const match = inHatch.filter(w => w.name === ws.name)[0];
157 'Migrating workstation from local storage to hatch: '
163 inHatch = inHatch.concat(addMe);
164 return this.hatch.setItem(WS_ALL_KEY, inHatch);
168 getDefaultWorkstation(): Promise<any> {
169 if (this.hatch.isAvailable) {
170 return this.hatch.getItem(WS_DEF_KEY).then(name => {
172 // We have a default in Hatch, remove any lingering
173 // value from localStorage.
174 this.removeLocalItem(WS_DEF_KEY);
177 // Nothing in Hatch, see if we have a localStorage
178 // value to migrate to Hatch
179 name = this.getLocalItem(WS_DEF_KEY);
182 'Migrating default workstation to Hatch ' + name);
183 return this.hatch.setItem(WS_DEF_KEY, name)
191 return Promise.resolve(this.getLocalItem(WS_DEF_KEY));
195 removeLocalItem(key: string): void {
196 window.localStorage.removeItem(key);
199 removeSessionItem(key: string): void {
200 window.sessionStorage.removeItem(key);
203 removeLoginSessionItem(key: string): void {
204 this.cookieService.remove(key, {path : this.loginSessionBasePath});
207 removeDefaultWorkstation(val: string, isJson?: boolean): Promise<any> {
208 if (this.hatch.isAvailable) {
209 return this.hatch.removeItem(WS_DEF_KEY);
211 return Promise.resolve(
212 this.removeLocalItem(WS_DEF_KEY));
217 clearLoginSessionItems(): void {
218 this.loginSessionKeys.forEach(
219 key => this.removeLoginSessionItem(key)