blob: 345431be898caf29589ca150c65f7132bfc776a0 [file] [log] [blame]
Matteo Scandolof2c3ed62016-12-15 14:32:50 -08001/// <reference path="../../../../typings/index.d.ts"/>
Matteo Scandolo86bc26a2017-01-18 11:06:47 -08002import * as _ from 'lodash';
Matteo Scandolof2c3ed62016-12-15 14:32:50 -08003import {BehaviorSubject, Observable} from 'rxjs/Rx';
4import {IWSEvent, IWSEventService} from '../websocket/global';
5import {IXosResourceService} from '../rest/model.rest';
6import {IStoreHelpersService} from '../helpers/store.helpers';
7
Matteo Scandolo47860fe2017-02-02 12:05:55 -08008export interface IXosModelStoreService {
Matteo Scandolo1aee1982017-02-17 08:33:23 -08009 query(model: string, apiUrl?: string): Observable<any>;
Matteo Scandolo86bc26a2017-01-18 11:06:47 -080010 search(modelName: string): any[];
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080011}
12
Matteo Scandolo1aee1982017-02-17 08:33:23 -080013export class XosModelStore implements IXosModelStoreService {
Matteo Scandolo17bf8242017-01-23 17:30:39 -080014 static $inject = ['$log', 'WebSocket', 'StoreHelpers', 'ModelRest'];
Matteo Scandolof9dd4d02016-12-22 15:17:01 -080015 private _collections: any; // NOTE contains a map of {model: BehaviourSubject}
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080016 constructor(
Matteo Scandolo17bf8242017-01-23 17:30:39 -080017 private $log: ng.ILogService,
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080018 private webSocket: IWSEventService,
19 private storeHelpers: IStoreHelpersService,
Matteo Scandolobac22452017-01-03 16:35:32 -080020 private ModelRest: IXosResourceService,
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080021 ) {
Matteo Scandolof9dd4d02016-12-22 15:17:01 -080022 this._collections = {};
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080023 }
24
Matteo Scandolo1aee1982017-02-17 08:33:23 -080025 public query(modelName: string, apiUrl: string): Observable<any> {
Matteo Scandolo38e94a82017-03-02 12:17:27 -080026 if (modelName === 'XOSGuiExtension') {
27 this.$log.log(performance.now(), `QUERY Model ${modelName}` );
28 }
Matteo Scandolof9dd4d02016-12-22 15:17:01 -080029 // if there isn't already an observable for that item
Matteo Scandolo042ea632017-03-01 19:02:34 -080030 // create a new one and .next() is called by this.loadInitialData once data are received
Matteo Scandolo1aee1982017-02-17 08:33:23 -080031 if (!this._collections[modelName]) {
32 this._collections[modelName] = new BehaviorSubject([]); // NOTE maybe this can be created when we get response from the resource
33 this.loadInitialData(modelName, apiUrl);
Matteo Scandolof9dd4d02016-12-22 15:17:01 -080034 }
Matteo Scandolo042ea632017-03-01 19:02:34 -080035 // else manually trigger the next with the last know value to trigger the subscribe method of who's requestiong this data
36 else {
37 this._collections[modelName].next(this._collections[modelName].value);
38 }
Matteo Scandolof9dd4d02016-12-22 15:17:01 -080039
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080040 this.webSocket.list()
Matteo Scandolo1aee1982017-02-17 08:33:23 -080041 .filter((e: IWSEvent) => e.model === modelName)
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080042 .subscribe(
43 (event: IWSEvent) => {
Matteo Scandolo1aee1982017-02-17 08:33:23 -080044 this.storeHelpers.updateCollection(event, this._collections[modelName]);
Matteo Scandoloa4a47112016-12-16 10:06:13 -080045 },
Matteo Scandolo38e94a82017-03-02 12:17:27 -080046 err => this.$log.error
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080047 );
Matteo Scandolof9dd4d02016-12-22 15:17:01 -080048
Matteo Scandolo1aee1982017-02-17 08:33:23 -080049 return this._collections[modelName].asObservable();
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080050 }
51
Matteo Scandolo86bc26a2017-01-18 11:06:47 -080052 public search(modelName: string): any[] {
Matteo Scandolo1aee1982017-02-17 08:33:23 -080053 try {
54 const res = _.reduce(Object.keys(this._collections), (results, k) => {
55 let partialRes;
56 // NOTE wrapped in a try catch as some subject may be errored, due to not available REST endpoint
57 try {
58 partialRes = _.filter(this._collections[k].value, i => {
59 if (i && i.humanReadableName) {
60 return i.humanReadableName.toLowerCase().indexOf(modelName) > -1;
61 }
62 else if (i && i.name) {
63 return i.name.toLowerCase().indexOf(modelName) > -1;
64 }
65 return false;
66 });
67 } catch (e) {
68 partialRes = [];
Matteo Scandolo86bc26a2017-01-18 11:06:47 -080069 }
Matteo Scandolo1aee1982017-02-17 08:33:23 -080070 partialRes.map(m => {
Matteo Scandolo86bc26a2017-01-18 11:06:47 -080071 m.modelName = k;
72 return m;
73 });
Matteo Scandolo1aee1982017-02-17 08:33:23 -080074 return results.concat(partialRes);
75 }, []);
76 return res;
77 } catch (e) {
78 return [];
79 }
Matteo Scandolo86bc26a2017-01-18 11:06:47 -080080 }
81
Matteo Scandolo04964232017-01-07 12:53:46 -080082 public get(model: string, id: number) {
83 // TODO implement a get method
84 }
85
Matteo Scandolo1aee1982017-02-17 08:33:23 -080086 private loadInitialData(model: string, apiUrl?: string) {
Matteo Scandolo042ea632017-03-01 19:02:34 -080087 // TODO provide always the apiUrl togheter with the query() params
Matteo Scandolo1aee1982017-02-17 08:33:23 -080088 if (!angular.isDefined(apiUrl)) {
89 // NOTE check what is the correct pattern to pluralize this
90 apiUrl = this.storeHelpers.urlFromCoreModel(model);
91 }
92 this.ModelRest.getResource(apiUrl).query().$promise
Matteo Scandolof2c3ed62016-12-15 14:32:50 -080093 .then(
94 res => {
Matteo Scandolof9dd4d02016-12-22 15:17:01 -080095 this._collections[model].next(res);
Matteo Scandolo17bf8242017-01-23 17:30:39 -080096 })
97 .catch(
Matteo Scandolo1aee1982017-02-17 08:33:23 -080098 err => {
99 this._collections[model].error(err);
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800100 }
Matteo Scandolof2c3ed62016-12-15 14:32:50 -0800101 );
102 }
103}