UNPKG

33 kBJavaScriptView Raw
1import { ChangeDetectionStrategy, Component, Injectable, Input, NgModule } from '@angular/core';
2import { CommonModule } from '@angular/common';
3import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
4import { HttpClient } from '@angular/common/http';
5import { Router } from '@angular/router';
6import { Store } from '@ngrx/store';
7import { Observable } from 'rxjs';
8import 'rxjs/add/operator/share';
9
10/**
11 * @fileoverview added by tsickle
12 * @suppress {checkTypes} checked by tsc
13 */
14/**
15 * <api-error *ngIf="state.modifyError" [error]="state.modifyError"></api-error>
16 * @record
17 */
18
19var ApiErrorComponent = (function () {
20 function ApiErrorComponent() {
21 /**
22 * An error response passed by the API or the application
23 */
24 this.message = 'An unknown error occured';
25 /**
26 * Whether or not to show all the error details passed by the API. If false will only show the error.msg
27 */
28 this.showDetails = true;
29 /**
30 * API response keys to ignore
31 */
32 this.ignoreProps = ['headers', 'errorMsg'];
33 }
34 /**
35 * @return {?}
36 */
37 ApiErrorComponent.prototype.ngOnInit = /**
38 * @return {?}
39 */
40 function () {
41 };
42 /**
43 * @return {?}
44 */
45 ApiErrorComponent.prototype.ngOnChanges = /**
46 * @return {?}
47 */
48 function () {
49 if (this.error) {
50 this.createError();
51 }
52 };
53 /**
54 * @return {?}
55 */
56 ApiErrorComponent.prototype.createError = /**
57 * @return {?}
58 */
59 function () {
60 var _this = this;
61 // Create an array of keys to loop through and filter out anything on the ignore list
62 this.errorOfKeys = Object.keys(this.error).filter(function (key) {
63 if (_this.ignoreProps.indexOf(key) == -1) {
64 return key;
65 }
66 });
67 // If errorMsg was not set and an error message was found in the server response, use the server message instead
68 //if (!this.errorMessage && this.error && this.error._body && this.error._body.message) {
69 // this.errorMessage = JSON.parse(this.error._body).message;
70 //}
71 // If 404
72 if (!this.errorMessage && this.error.status == 404) {
73 this.errorMessage = '404 Error. Unable to connect to the Api.';
74 }
75 else if (!this.errorMessage) {
76 this.errorMessage = 'Unknown error. Please see error details for more information.';
77 }
78 };
79 /**
80 * Hide alert message
81 * @return {?}
82 */
83 ApiErrorComponent.prototype.closeAlert = /**
84 * Hide alert message
85 * @return {?}
86 */
87 function () {
88 this.error = null;
89 };
90 ApiErrorComponent.decorators = [
91 { type: Component, args: [{
92 selector: 'error',
93 template: "<div class=\"alert alert-danger icon p-2 pl-3 pr-3\" *ngIf=\"error\"> <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"closeAlert()\"> <span aria-hidden=\"true\">&times;</span> </button> <i class=\"fa fa-alert\"></i> {{message}} <ng-container *ngIf=\"showDetails && errorOfKeys.length\"> <hr class=\"mt-2 mb-2\"/> <ngb-accordion #acc=\"ngbAccordion\" class=\"accordion-inline\"> <ngb-panel> <ng-template ngbPanelTitle> <span>See error details:</span> </ng-template> <ng-template ngbPanelContent> <table class=\"table table-sm\"> <tbody> <tr *ngFor=\"let key of errorOfKeys\"> <td><strong>{{key}}</strong></td> <td style=\"word-break: break-all;\">{{error[key]}}</td> </tr> </tbody> </table> </ng-template> </ngb-panel> </ngb-accordion> </ng-container> </div> ",
94 changeDetection: ChangeDetectionStrategy.OnPush
95 },] },
96 ];
97 /** @nocollapse */
98 ApiErrorComponent.ctorParameters = function () { return []; };
99 ApiErrorComponent.propDecorators = {
100 "error": [{ type: Input },],
101 "message": [{ type: Input },],
102 "showDetails": [{ type: Input },],
103 };
104 return ApiErrorComponent;
105}());
106
107/**
108 * @fileoverview added by tsickle
109 * @suppress {checkTypes} checked by tsc
110 */
111/**
112 * <api-state [state]="conditions.state" ignore="modifying" [hover]="true" *ngIf="conditionsState$ | async as conditions">
113 * Transcluded content here
114 * </api-state>
115 * @record
116 */
117
118var ApiStateComponent = (function () {
119 function ApiStateComponent() {
120 /**
121 * Should the success/loading/error messages appear inline or as a toaster pop in the lower right of the screen
122 */
123 this.toaster = true;
124 /**
125 * Should the success message be visible or not
126 */
127 this.showSuccess = true;
128 /**
129 * Set this flag after the initial load of data
130 */
131 this.initialLoadComplete = false;
132 /**
133 * Toggle the visibility of the success message
134 */
135 this.successVisible = true;
136 }
137 /**
138 * @return {?}
139 */
140 ApiStateComponent.prototype.ngOnInit = /**
141 * @return {?}
142 */
143 function () { };
144 /**
145 * @return {?}
146 */
147 ApiStateComponent.prototype.ngOnChanges = /**
148 * @return {?}
149 */
150 function () {
151 if (this.state.loaded) {
152 this.initialLoadComplete = true;
153 }
154 this.successVisible = true;
155 };
156 /**
157 * Close the alert and clear success state
158 * @return {?}
159 */
160 ApiStateComponent.prototype.closeSuccess = /**
161 * Close the alert and clear success state
162 * @return {?}
163 */
164 function () {
165 this.successVisible = false;
166 //this.api.resetSuccess();
167 };
168 /**
169 * @return {?}
170 */
171 ApiStateComponent.prototype.ngOnDestroy = /**
172 * @return {?}
173 */
174 function () { };
175 ApiStateComponent.decorators = [
176 { type: Component, args: [{
177 selector: 'api-state',
178 template: "<ng-container *ngIf=\"state\"> <!--GET/loading --> <div *ngIf=\"state.loading && !initialLoadComplete\" class=\"p-3\"><i class=\"fa fa-spinner fa-spin\"></i> Loading data from server...</div> <div *ngIf=\"state.loading && initialLoadComplete\" class=\"p-3\" [ngClass]=\"{'toaster': toaster }\"> <i class=\"fa fa-spinner fa-spin\" [ngClass]=\"{'toaster-lg': toaster }\"></i> <ng-container *ngIf=\"!toaster\"> Refreshing data from server... </ng-container> </div> <error *ngIf=\"state.loadError\" [error]=\"state.loadError\" [ngClass]=\"{'toaster': toaster && initialLoadComplete }\"></error> <!-- Create/Update/Delete --> <div *ngIf=\"state.modified && showSuccess && successVisible\" class=\"alert alert-success icon p-2\" [ngClass]=\"{'toaster': toaster }\"> <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"closeSuccess()\" *ngIf=\"!toaster\"> <span aria-hidden=\"true\">&times;</span> </button> Success! </div> <error *ngIf=\"state.modifyError\" [error]=\"state.modifyError\" [ngClass]=\"{'toaster': toaster }\"></error> <!-- Content --> <ng-container *ngIf=\"state.loaded || (initialLoadComplete && toaster)\"> <ng-content></ng-content> </ng-container> </ng-container> ",
179 styles: ["\n .toaster{position:fixed;bottom:10px;right:20px;z-index:1000;}\n .toaster-lg{font-size:3rem;}\n "],
180 changeDetection: ChangeDetectionStrategy.OnPush
181 },] },
182 ];
183 /** @nocollapse */
184 ApiStateComponent.ctorParameters = function () { return []; };
185 ApiStateComponent.propDecorators = {
186 "state": [{ type: Input },],
187 "toaster": [{ type: Input },],
188 "showSuccess": [{ type: Input },],
189 };
190 return ApiStateComponent;
191}());
192
193/**
194 * @fileoverview added by tsickle
195 * @suppress {checkTypes} checked by tsc
196 */
197/** @enum {string} */
198var ApiActions = {
199 RESET: 'RESET',
200 STATE_CHANGE: 'STATE_CHANGE',
201 RESET_ERRORS: 'RESET_ERRORS',
202 RESET_SUCCESS: 'RESET_SUCCESS',
203 GET_COMPLETE: 'GET_COMPLETE',
204 POST_COMPLETE: 'POST_COMPLETE',
205 PUT_COMPLETE: 'PUT_COMPLETE',
206 DELETE_COMPLETE: 'DELETE_COMPLETE',
207};
208
209/**
210 * @fileoverview added by tsickle
211 * @suppress {checkTypes} checked by tsc
212 */
213var ApiHttpService = (function () {
214 function ApiHttpService(httpSvc, storeSvc, routerSvc) {
215 this.httpSvc = httpSvc;
216 this.storeSvc = storeSvc;
217 this.routerSvc = routerSvc;
218 /**
219 * Hold GET requests from an API using the URL as a primary key
220 */
221 this.cache = {};
222 }
223 /**
224 * Make a GET request with simple caching
225 * @template T
226 * @param {?} url - The URL location of the webapi
227 * @param {?=} updateCache - Refresh the version in the cache
228 * @return {?}
229 */
230 ApiHttpService.prototype.get = /**
231 * Make a GET request with simple caching
232 * @template T
233 * @param {?} url - The URL location of the webapi
234 * @param {?=} updateCache - Refresh the version in the cache
235 * @return {?}
236 */
237 function (url, updateCache) {
238 if (updateCache === void 0) { updateCache = false; }
239 // If this request is not in the cache or updateCache was requested (default behavior), load content into cache
240 if (!this.cache[url] || updateCache) {
241 this.cache[url] = this.httpSvc.get(url)
242 .publishReplay(1)
243 .refCount();
244 }
245 return this.cache[url];
246 };
247 /**
248 * Make a GET request and load the results into the store
249 * @param url - The URL location of the webapi
250 * @param id - The location to put the results in the store
251 * @param updateCache - Refresh the version in the cache
252 */
253 /**
254 * Make a GET request and load the results into the store
255 * @template T
256 * @param {?} url - The URL location of the webapi
257 * @param {?=} apiMap
258 * @param {?=} updateCache - Refresh the version in the cache
259 * @return {?}
260 */
261 ApiHttpService.prototype.getStore = /**
262 * Make a GET request and load the results into the store
263 * @template T
264 * @param {?} url - The URL location of the webapi
265 * @param {?=} apiMap
266 * @param {?=} updateCache - Refresh the version in the cache
267 * @return {?}
268 */
269 function (url, apiMap, updateCache) {
270 var _this = this;
271 if (updateCache === void 0) { updateCache = false; }
272 // If this request is not in the cache or updateCache was requested (default behavior), load content into cache
273 if (this.cache[url] == null || updateCache) {
274 // Set status to waiting
275 var /** @type {?} */ newState_1 = { loading: true, loadError: false, loaded: false };
276 this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState_1 } }); // Update store with new state
277 this.cache[url] = this.httpSvc.get(url)
278 .share()
279 .map(function (res) {
280 //Set status to success
281 //Set status to success
282 newState_1 = { loading: false, loadError: false, loaded: true };
283 _this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState_1 } }); // Update store with new state
284 var /** @type {?} */ data = apiMap.map ? apiMap.map(res) : res;
285 _this.storeSvc.dispatch({ type: ApiActions.GET_COMPLETE, payload: { apiMap: apiMap, data: data } }); // Load content into store
286 return data;
287 }).catch(function (error) {
288 if (error.status == 401 || error.status == 403) {
289 error.errorMsg = 'Please log in ';
290 return _this.endSession(error);
291 }
292 else {
293 newState_1 = { loading: false, loadError: error, loaded: false };
294 _this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState_1 } }); // Update store with new state
295 return Observable.throw(error);
296 }
297 });
298 return this.cache[url];
299 }
300 else {
301 return Observable.of(/** @type {?} */ (true));
302 }
303 //return this.cache[url];
304 };
305 /**
306 * Make a POST request and load the results into the store
307 * @param url - The URL location of the endpoint
308 * @param id - The location to put the results in the store
309 * @param data - The data to pass to the server
310 */
311 /**
312 * Make a POST request and load the results into the store
313 * @template T
314 * @param {?} url - The URL location of the endpoint
315 * @param {?} apiMap
316 * @param {?} data - The data to pass to the server
317 * @return {?}
318 */
319 ApiHttpService.prototype.postStore = /**
320 * Make a POST request and load the results into the store
321 * @template T
322 * @param {?} url - The URL location of the endpoint
323 * @param {?} apiMap
324 * @param {?} data - The data to pass to the server
325 * @return {?}
326 */
327 function (url, apiMap, data) {
328 var _this = this;
329 // Set status to modifying
330 var /** @type {?} */ newState = { modifying: true, modified: false, modifyError: false };
331 this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState } }); // Update store with new state
332 return this.httpSvc.post(url, data)
333 .map(function (res) {
334 // Set status to complete
335 var /** @type {?} */ newState = { modifying: false, modified: true, modifyError: false };
336 _this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState } }); // Update store with new state
337 // Check if the response has a payload or not
338 var /** @type {?} */ dataNew = res ? res : data;
339 _this.storeSvc.dispatch({ type: ApiActions.POST_COMPLETE, payload: { apiMap: apiMap, data: dataNew } }); // Load content into store
340 return Observable.of(res);
341 }).catch(function (error) {
342 if (error.status == 401 || error.status == 403) {
343 error.errorMsg = 'Please log in ';
344 return _this.endSession(error);
345 }
346 else {
347 error.errorMsg = 'Unable to create ' + apiMap.storeProperty;
348 // Set status to error
349 var /** @type {?} */ newState_2 = { modifying: false, modified: false, modifyError: error };
350 _this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState_2 } }); // Update store with new state
351 return Observable.throw(error);
352 }
353 });
354 }; // end post
355 /**
356 * Make a PUT request
357 * @param url - The URL location of the webapi
358 * @param data - The data to pass to the server
359 */
360 /**
361 * Make a PUT request
362 * @template T
363 * @param {?} url - The URL location of the webapi
364 * @param {?} apiMap
365 * @param {?} data - The data to pass to the server
366 * @return {?}
367 */
368 ApiHttpService.prototype.putStore = /**
369 * Make a PUT request
370 * @template T
371 * @param {?} url - The URL location of the webapi
372 * @param {?} apiMap
373 * @param {?} data - The data to pass to the server
374 * @return {?}
375 */
376 function (url, apiMap, data) {
377 var _this = this;
378 //console.warn('Putting ', url, apiMap, data);
379 // Set status to modifying
380 var /** @type {?} */ newState = { modifying: true, modified: false, modifyError: false };
381 this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState } }); // Update store with new state
382 return this.httpSvc.put(url, data)
383 .map(function (res) {
384 // Set status to complete
385 var /** @type {?} */ newState = { modifying: false, modified: true, modifyError: false };
386 _this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState } }); // Update store with new state
387 // Check if the response has a payload or not, if not then this is an upSert
388 var /** @type {?} */ dataNew = res ? res : data;
389 _this.storeSvc.dispatch({ type: ApiActions.PUT_COMPLETE, payload: { apiMap: apiMap, data: dataNew } }); // Load content into store
390 return Observable.of(res);
391 }).catch(function (error) {
392 console.warn('PUT Error, handle 403 unauth errors here', error);
393 if (error.status == 401 || error.status == 403) {
394 error.errorMsg = 'Please log in ';
395 return _this.endSession(error);
396 }
397 else {
398 error.errorMsg = 'Unable to update ' + apiMap.storeProperty;
399 // Set status to error
400 var /** @type {?} */ newState_3 = { modifying: false, modified: false, modifyError: error };
401 _this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState_3 } }); // Update store with new state
402 return Observable.throw(error);
403 }
404 });
405 }; // end put
406 /**
407 * Make a DELETE request
408 * @param url - The URL location of the webapi
409 * @param apiMap - The ApiMap object
410 * @param element - The element or collection of elements being deleted
411 */
412 /**
413 * Make a DELETE request
414 * @template T
415 * @param {?} url - The URL location of the webapi
416 * @param {?} apiMap - The ApiMap object
417 * @param {?} element - The element or collection of elements being deleted
418 * @return {?}
419 */
420 ApiHttpService.prototype.deleteStore = /**
421 * Make a DELETE request
422 * @template T
423 * @param {?} url - The URL location of the webapi
424 * @param {?} apiMap - The ApiMap object
425 * @param {?} element - The element or collection of elements being deleted
426 * @return {?}
427 */
428 function (url, apiMap, element) {
429 var _this = this;
430 // Set status to modifying
431 var /** @type {?} */ newState = { modifying: true, modified: false, modifyError: false };
432 this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState } }); // Update store with new state
433 // Delete doesn't natively support a body so this adds it in for deleting collections or other uncommon operations
434 return this.httpSvc.request('delete', url, { body: element })
435 .map(function (res) {
436 // Set status to complete
437 var /** @type {?} */ newState = { modifying: false, modified: true, modifyError: false };
438 _this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState } }); // Update store with new state
439 _this.storeSvc.dispatch({ type: ApiActions.DELETE_COMPLETE, payload: { apiMap: apiMap, data: element } }); // Load content into store
440 return Observable.of(res);
441 }).catch(function (error) {
442 console.warn('DELETE Error, handle 403 unauth errors here', error);
443 if (error.status == 401 || error.status == 403) {
444 error.errorMsg = 'Please log in ';
445 return _this.endSession(error);
446 }
447 else {
448 error.errorMsg = 'Unable to delete ' + apiMap.storeProperty;
449 // Set status to error
450 var /** @type {?} */ newState_4 = { modifying: false, modified: false, modifyError: error };
451 _this.storeSvc.dispatch({ type: ApiActions.STATE_CHANGE, payload: { apiMap: apiMap, newState: newState_4 } }); // Update store with new state
452 return Observable.throw(error);
453 }
454 });
455 }; // end post
456 /**
457 * When an authentication check fails
458 * @param {?} error
459 * @return {?}
460 */
461 ApiHttpService.prototype.endSession = /**
462 * When an authentication check fails
463 * @param {?} error
464 * @return {?}
465 */
466 function (error) {
467 this.cache = {};
468 window.localStorage.removeItem('token');
469 window.sessionStorage.clear();
470 this.routerSvc.navigate(['/login'], { queryParams: { session: 'expired' } });
471 return Observable.throw(error);
472 };
473 ApiHttpService.decorators = [
474 { type: Injectable },
475 ];
476 /** @nocollapse */
477 ApiHttpService.ctorParameters = function () { return [
478 { type: HttpClient, },
479 { type: Store, },
480 { type: Router, },
481 ]; };
482 return ApiHttpService;
483}());
484
485var __assign = (undefined && undefined.__assign) || Object.assign || function(t) {
486 for (var s, i = 1, n = arguments.length; i < n; i++) {
487 s = arguments[i];
488 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
489 t[p] = s[p];
490 }
491 return t;
492};
493/**
494 * @fileoverview added by tsickle
495 * @suppress {checkTypes} checked by tsc
496 */
497/**
498 * @param {?=} state
499 * @param {?=} __1
500 * @return {?}
501 */
502function ApiReducer(state, _a) {
503 if (state === void 0) { state = {}; }
504 var type = _a.type, payload = _a.payload;
505 //console.log('STORE REDUCER:', type, payload);
506 var /** @type {?} */ srcData;
507 switch (type) {
508 // Reset State
509 case ApiActions.RESET:
510 return {};
511 // Get response
512 case ApiActions.GET_COMPLETE:
513 // If response is an array
514 if (Array.isArray(payload.data)) {
515 state[payload.apiMap.storeProperty] = payload.data.slice();
516 }
517 else if (typeof payload.data == 'object') {
518 state[payload.apiMap.storeProperty] = __assign({}, payload.data);
519 }
520 else if (typeof payload.data == 'string') {
521 state[payload.apiMap.storeProperty][payload.apiMap.data] = payload.data;
522 }
523 else {
524 console.error('GET_COMPLETE was not an object/array/string, please write a condition for this in the api.reducer', type, payload);
525 }
526 break;
527 // Post response
528 case ApiActions.POST_COMPLETE:
529 // If a map and mapSrc element are present, grab the unfiltered content from the mapSrc property. Otherwise just get data straight out of the store
530 srcData = (payload.apiMap.map && payload.apiMap.mapSrc) ? state[payload.apiMap.storeProperty][payload.apiMap.mapSrc] : state[payload.apiMap.storeProperty];
531 // If destination is an array and response is an array, concat with new data up front
532 if (Array.isArray(srcData) && Array.isArray(payload.data)) {
533 srcData = payload.data.concat(srcData);
534 }
535 else if (srcData && typeof payload.data === 'object') {
536 /* TODO: Figure out how to do upserts. Maybe pass an additional prop
537 if (payload.data[payload.apiMap.uniqueId]) {
538
539 } else {
540 srcData = [payload.data, ...srcData];
541 }
542 */
543 srcData = [payload.data].concat(srcData);
544 }
545 else if (typeof srcData === 'object' && typeof payload.data === 'object') {
546 srcData = __assign({}, payload.data);
547 }
548 else {
549 console.error('POST_COMPLETE was not an object or an array, please write a condition for this in the api.reducer');
550 }
551 // If map and mapSrc are present, remap the data before returning it to the store, otherwise just return the store data
552 state[payload.apiMap.storeProperty] = (payload.apiMap.map && payload.apiMap.mapSrc) ? payload.apiMap.map(srcData) : srcData;
553 break;
554 // PUT response
555 case ApiActions.PUT_COMPLETE:
556 //console.warn('PUT_COMPLETE', payload)
557 // If a map and mapSrc element are present, grab the unfiltered content from the mapSrc property. Otherwise just get data straight out of the store
558 srcData = (payload.apiMap.map && payload.apiMap.mapSrc) ? state[payload.apiMap.storeProperty][payload.apiMap.mapSrc] : state[payload.apiMap.storeProperty];
559 // If destination is an array and response is an array, loop through the destination array and update all entries with the new ones
560 if (Array.isArray(srcData) && Array.isArray(payload.data)) {
561 //console.warn('Array into array')
562 for (var /** @type {?} */ i = 0; i < payload.data.length; i++) {
563 // Loop through payload
564 for (var /** @type {?} */ j = 0; j < srcData.length; j++) {
565 // Loop through response object
566 if (payload.data[i][payload.apiMap.uniqueId] == srcData[j][payload.apiMap.uniqueId]) {
567 srcData[j] = payload.data[i];
568 srcData = srcData.slice();
569 j = srcData.length + 1; // Cheap way to break the second for loop
570 }
571 }
572 }
573 }
574 else if (Array.isArray(srcData) && typeof payload.data === 'object') {
575 //console.warn('Object into array')
576 // Loop through the destination array and when the unique ID is found, update the entry
577 for (var /** @type {?} */ i = 0; i < srcData.length; i++) {
578 if (srcData[i][payload.apiMap.uniqueId] == payload.data[payload.apiMap.uniqueId]) {
579 srcData[i] = payload.data;
580 srcData = srcData.slice();
581 break;
582 }
583 }
584 }
585 else if (typeof srcData === 'object' && typeof payload.data === 'object') {
586 //console.warn('Replace object')
587 srcData = __assign({}, payload.data);
588 }
589 else {
590 console.error('PUT_COMPLETE was not an object or an array, please write a condition for this in the api.reducer');
591 }
592 // If map and mapSrc are present, remap the data before returning it to the store, otherwise just return the store data
593 state[payload.apiMap.storeProperty] = (payload.apiMap.map && payload.apiMap.mapSrc) ? payload.apiMap.map(srcData) : srcData;
594 break;
595 // Delete response
596 case ApiActions.DELETE_COMPLETE:
597 //console.warn('Delete Reducer ', payload)
598 // If a map and mapSrc element are present, grab the unfiltered content from the mapSrc property. Otherwise just get data straight out of the store
599 srcData = (payload.apiMap.map && payload.apiMap.mapSrc) ? state[payload.apiMap.storeProperty][payload.apiMap.mapSrc] : state[payload.apiMap.storeProperty];
600 // If destination is an array and response is an array, loop through the destination array and update all entries with the new ones
601 if (Array.isArray(srcData) && Array.isArray(payload.data)) {
602 //console.warn('Delete array from array')
603 for (var /** @type {?} */ i = 0; i < payload.data.length; i++) {
604 // Loop through payload
605 for (var /** @type {?} */ j = 0; j < srcData.length; j++) {
606 // Loop through response object
607 //console.warn('Looping 2', payload.data[i][payload.apiMap.uniqueId], srcData[j][payload.apiMap.uniqueId]);
608 if (payload.data[i][payload.apiMap.uniqueId] == srcData[j][payload.apiMap.uniqueId]) {
609 srcData.splice(j, 1);
610 srcData = srcData.slice();
611 j = srcData.length + 1; // Cheap way to break the second for loop
612 }
613 }
614 }
615 }
616 else if (Array.isArray(srcData)) {
617 // If this delete operation only has a single unique ID
618 if (typeof payload.apiMap.uniqueId == 'string') {
619 srcData = srcData.filter(function (element) { return element[payload.apiMap.uniqueId] != payload.data[payload.apiMap.uniqueId]; });
620 }
621 else if (payload.apiMap.uniqueId.length) {
622 srcData = srcData.filter(function (element, index) {
623 // Loop through the uniqueID's list. If the number of unique ID's match what is in the API Map then relete it
624 var /** @type {?} */ hasMatches = 0;
625 payload.apiMap.uniqueId.forEach(function (id) {
626 if (element[id] == payload.data[id]) {
627 hasMatches++;
628 }
629 });
630 return hasMatches != payload.apiMap.uniqueId.length ? true : false;
631 });
632 }
633 }
634 else if (typeof srcData === 'object' && typeof payload.data === 'object') {
635 delete srcData[payload.data];
636 }
637 else {
638 console.error('DELETE_COMPLETE was not an object or an array, please write a condition for this in the api.reducer');
639 }
640 // If map and mapSrc are present, remap the data before returning it to the store, otherwise just return the store data
641 state[payload.apiMap.storeProperty] = (payload.apiMap.map && payload.apiMap.mapSrc) ? payload.apiMap.map(srcData) : srcData;
642 break;
643 }
644 return state;
645}
646
647var __assign$1 = (undefined && undefined.__assign) || Object.assign || function(t) {
648 for (var s, i = 1, n = arguments.length; i < n; i++) {
649 s = arguments[i];
650 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
651 t[p] = s[p];
652 }
653 return t;
654};
655/**
656 * @fileoverview added by tsickle
657 * @suppress {checkTypes} checked by tsc
658 */
659var ApiStatusStore = {};
660/**
661 * @param {?=} state
662 * @param {?=} __1
663 * @return {?}
664 */
665function ApiStatusReducer(state, _a) {
666 if (state === void 0) { state = ApiStatusStore; }
667 var type = _a.type, payload = _a.payload;
668 //console.log('STORE REDUCER: ApiStatusReducer', type, payload);
669 switch (type) {
670 // Reset State
671 case ApiActions.RESET:
672 return ApiStatusStore;
673 // State change
674 case ApiActions.STATE_CHANGE:
675 state[payload.apiMap.storeProperty] = __assign$1({}, state[payload.apiMap.storeProperty], payload.newState);
676 break;
677 // Reset API errors
678 case ApiActions.RESET_ERRORS:
679 Object.keys(state).forEach(function (key) {
680 state[key].modifyError = false;
681 state[key] = __assign$1({}, state[key]);
682 });
683 break;
684 // Reset API errors
685 case ApiActions.RESET_SUCCESS:
686 Object.keys(state).forEach(function (key) {
687 state[key].modified = false;
688 state[key] = __assign$1({}, state[key]);
689 });
690 break;
691 }
692 return state;
693}
694
695/**
696 * @fileoverview added by tsickle
697 * @suppress {checkTypes} checked by tsc
698 */
699var ApiToolsModule = (function () {
700 function ApiToolsModule() {
701 }
702 /**
703 * @return {?}
704 */
705 ApiToolsModule.forRoot = /**
706 * @return {?}
707 */
708 function () {
709 return {
710 ngModule: ApiToolsModule,
711 providers: []
712 };
713 };
714 ApiToolsModule.decorators = [
715 { type: NgModule, args: [{
716 imports: [
717 CommonModule,
718 NgbModule.forRoot()
719 ],
720 declarations: [
721 ApiErrorComponent,
722 ApiStateComponent
723 ],
724 exports: [
725 ApiErrorComponent,
726 ApiStateComponent
727 ]
728 },] },
729 ];
730 /** @nocollapse */
731 ApiToolsModule.ctorParameters = function () { return []; };
732 return ApiToolsModule;
733}());
734
735export { ApiToolsModule, ApiErrorComponent, ApiStateComponent, ApiActions, ApiHttpService, ApiReducer, ApiStatusReducer };