[CORD-873] CRUD for Core and Service model from Chameleon
Change-Id: I45c533feba6720b82de3681d862773047e7fd6f8
diff --git a/src/app/datasources/helpers/model-discoverer.service.ts b/src/app/datasources/helpers/model-discoverer.service.ts
new file mode 100644
index 0000000..deaed33
--- /dev/null
+++ b/src/app/datasources/helpers/model-discoverer.service.ts
@@ -0,0 +1,258 @@
+// TODO test me hard!!!
+
+import * as _ from 'lodash';
+import {IXosModeldefsService, IXosModeldef, IXosModelDefsField, IXosModelDefsRelation} from '../rest/modeldefs.rest';
+import {IXosTableCfg} from '../../core/table/table';
+import {IXosFormCfg} from '../../core/form/form';
+import {IXosNavigationService} from '../../core/services/navigation';
+import {IXosConfigHelpersService} from '../../core/services/helpers/config.helpers';
+import {IXosRuntimeStatesService, IXosState} from '../../core/services/runtime-states';
+import {IXosModelStoreService} from '../stores/model.store';
+
+export interface IXosModel {
+ name: string; // the model name
+ app: string; // the service to wich it belong
+ fields: IXosModelDefsField[];
+ relations?: IXosModelDefsRelation[];
+ backendUrl?: string; // the api endpoint
+ clientUrl?: string; // the view url
+ tableCfg?: IXosTableCfg;
+ formCfg?: IXosFormCfg;
+}
+
+// Service
+export interface IXosModelDiscovererService {
+ discover(): ng.IPromise<boolean>;
+ get(modelName: string): IXosModel;
+}
+
+export class XosModelDiscovererService implements IXosModelDiscovererService {
+ static $inject = [
+ '$log',
+ '$q',
+ 'XosModelDefs',
+ 'ConfigHelpers',
+ 'XosRuntimeStates',
+ 'XosNavigationService',
+ 'XosModelStore'
+ ];
+ private xosModels: IXosModel[] = []; // list of augmented model definitions;
+ private xosServices: string[] = []; // list of loaded services
+
+ constructor (
+ private $log: ng.ILogService,
+ private $q: ng.IQService,
+ private XosModelDefs: IXosModeldefsService,
+ private ConfigHelpers: IXosConfigHelpersService,
+ private XosRuntimeStates: IXosRuntimeStatesService,
+ private XosNavigationService: IXosNavigationService,
+ private XosModelStore: IXosModelStoreService
+ ) {
+ }
+
+ public get(modelName: string): IXosModel|null {
+ return _.find(this.xosModels, m => m.name === modelName);
+ }
+
+ public discover() {
+ const d = this.$q.defer();
+
+ this.XosModelDefs.get()
+ .then((modelsDef: IXosModeldef[]) => {
+
+ const pArray = [];
+ _.forEach(modelsDef, (model: IXosModeldef) => {
+ let p = this.cacheModelEntries(model)
+ .then(model => {
+ return this.addState(model);
+ })
+ .then(model => {
+ return this.addNavItem(model);
+ })
+ .then(model => {
+ return this.getTableCfg(model);
+ })
+ .then(model => {
+ return this.getFormCfg(model);
+ })
+ .then(model => {
+ return this.storeModel(model);
+ })
+ .then(model => {
+ this.$log.debug(`[XosModelDiscovererService] Model ${model.name} stored`);
+ return this.$q.resolve();
+ })
+ .catch(err => {
+ this.$log.error(`[XosModelDiscovererService] Model ${model.name} NOT stored`);
+ // NOTE why this does not resolve?????
+ // return this.$q.resolve();
+ return this.$q.reject();
+ });
+ pArray.push(p);
+ });
+ this.$q.all(pArray)
+ .then(() => {
+ d.resolve(true);
+ this.$log.info('[XosModelDiscovererService] All models loaded!');
+ })
+ .catch(() => {
+ d.resolve(false);
+ });
+ });
+ return d.promise;
+ }
+
+ private serviceNameFromAppName(appName: string): string {
+ return appName.replace('services.', '');
+ }
+
+ private stateNameFromModel(model: IXosModel): string {
+ return `xos.${this.serviceNameFromAppName(model.app)}.${model.name.toLowerCase()}`;
+ }
+
+ private getParentStateFromModel(model: IXosModel): string {
+ let parentState: string;
+ if (model.app === 'core') {
+ parentState = 'xos.core';
+ }
+ else {
+ const serviceName = this.addService(model);
+ parentState = `xos.${serviceName}`;
+ }
+ return parentState;
+ }
+
+ private getApiUrlFromModel(model: IXosModel): string {
+ if (model.app === 'core') {
+ return `/core/${this.ConfigHelpers.pluralize(model.name.toLowerCase())}`;
+ }
+ else {
+ const serviceName = this.serviceNameFromAppName(model.app);
+ return `/${serviceName}/${this.ConfigHelpers.pluralize(model.name.toLowerCase())}`;
+ }
+ }
+
+ // add a service state and navigation item if it is not already there
+ private addService(model: IXosModel): string {
+ const serviceName: string = this.serviceNameFromAppName(model.app);
+ if (!_.find(this.xosServices, n => n === serviceName)) {
+ const serviceState = {
+ url: serviceName,
+ parent: 'xos',
+ abstract: true,
+ template: '<div ui-view></div>'
+ };
+ this.XosRuntimeStates.addState(`xos.${serviceName}`, serviceState);
+
+ this.XosNavigationService.add({
+ label: this.ConfigHelpers.toLabel(serviceName),
+ state: `xos.${serviceName}`,
+ });
+ this.xosServices.push(serviceName);
+ }
+ return serviceName;
+ }
+
+ private addState(model: IXosModel): ng.IPromise<IXosModel> {
+ const d = this.$q.defer();
+ const clientUrl = `/${this.ConfigHelpers.pluralize(model.name.toLowerCase())}/:id?`;
+ const state: IXosState = {
+ parent: this.getParentStateFromModel(model),
+ url: clientUrl,
+ params: {
+ id: null
+ },
+ data: {
+ model: model.name
+ },
+ component: 'xosCrud',
+ };
+ this.XosRuntimeStates.addState(
+ this.stateNameFromModel(model),
+ state
+ );
+
+ // extend model
+ model.clientUrl = `${this.serviceNameFromAppName(model.app)}${clientUrl}`;
+
+ d.resolve(model);
+ return d.promise;
+ }
+
+ private addNavItem(model: IXosModel): ng.IPromise<IXosModel> {
+ const d = this.$q.defer();
+
+ const stateName = this.stateNameFromModel(model);
+
+ const parentState: string = this.getParentStateFromModel(model);
+
+ this.XosNavigationService.add({
+ label: this.ConfigHelpers.pluralize(model.name),
+ state: stateName,
+ parent: parentState
+ });
+
+ d.resolve(model);
+
+ return d.promise;
+ }
+
+ private cacheModelEntries(model: IXosModel): ng.IPromise<IXosModel> {
+ const d = this.$q.defer();
+
+ let called = false;
+ const apiUrl = this.getApiUrlFromModel(model);
+ this.XosModelStore.query(model.name, apiUrl)
+ .subscribe(
+ () => {
+ // skipping the first response as the observable gets created as an empty array
+ if (called) {
+ return d.resolve(model);
+ }
+ called = true;
+ },
+ err => {
+ d.reject(err);
+ }
+ );
+
+ return d.promise;
+ }
+
+ private getTableCfg(model: IXosModel): ng.IPromise<IXosModel> {
+
+ const d = this.$q.defer();
+
+ const stateUrl = this.stateNameFromModel(model);
+
+ model.tableCfg = this.ConfigHelpers.modelToTableCfg(model, stateUrl);
+
+ d.resolve(model);
+
+ return d.promise;
+ }
+
+ private getFormCfg(model: IXosModel): ng.IPromise<IXosModel> {
+
+ const d = this.$q.defer();
+
+ model.formCfg = this.ConfigHelpers.modelToFormCfg(model);
+
+ d.resolve(model);
+
+ return d.promise;
+ }
+
+ private storeModel(model: IXosModel): ng.IPromise<IXosModel> {
+
+ const d = this.$q.defer();
+
+ if (!_.find(this.xosModels, m => m.name === model.name)) {
+ this.xosModels.push(model);
+ }
+
+ d.resolve(model);
+
+ return d.promise;
+ }
+}
diff --git a/src/app/datasources/helpers/search.service.ts b/src/app/datasources/helpers/search.service.ts
index 5565b2c..8cee4d1 100644
--- a/src/app/datasources/helpers/search.service.ts
+++ b/src/app/datasources/helpers/search.service.ts
@@ -1,8 +1,8 @@
import * as _ from 'lodash';
import {IXosNavigationService} from '../../core/services/navigation';
-import {IXosState} from '../../../index';
import {IXosModelStoreService} from '../stores/model.store';
import {IXosConfigHelpersService} from '../../core/services/helpers/config.helpers';
+import {IXosState} from '../../core/services/runtime-states';
export interface IXosSearchResult {
label: string;
@@ -15,16 +15,18 @@
}
export class SearchService {
- static $inject = ['$rootScope', 'NavigationService', 'ModelStore', 'ConfigHelpers'];
+ static $inject = ['$rootScope', '$log', 'XosNavigationService', 'XosModelStore', 'ConfigHelpers'];
private states: IXosState[];
constructor (
private $rootScope: ng.IScope,
+ private $log: ng.ILogService,
private NavigationService: IXosNavigationService,
- private ModelStore: IXosModelStoreService,
+ private XosModelStore: IXosModelStoreService,
private ConfigHelpers: IXosConfigHelpersService
) {
this.$rootScope.$on('xos.core.modelSetup', () => {
+ this.$log.info(`[XosSearchService] Loading views`);
this.states = this.NavigationService.query().reduce((list, state) => {
// if it does not have child (otherwise it is abstract)
if (!state.children || state.children.length === 0) {
@@ -39,18 +41,21 @@
return list;
}, []);
this.states = _.uniqBy(this.states, 'state');
+ this.$log.debug(`[XosSearchService] Views Loaded: `, this.states);
});
}
public search(query: string): IXosSearchResult[] {
+ this.$log.info(`[XosSearchService] Searching for: ${query}`);
const routes: IXosSearchResult[] = _.filter(this.states, s => {
return s.label.toLowerCase().indexOf(query) > -1;
}).map(r => {
r.type = 'View';
return r;
});
-
- const models = _.map(this.ModelStore.search(query), m => {
+ // TODO XosModelStore.search throws an error,
+ // probably there is something wrong saved in the cache!!
+ const models = _.map(this.XosModelStore.search(query), m => {
return {
label: m.humanReadableName ? m.humanReadableName : m.name,
state: this.ConfigHelpers.stateWithParamsForJs(m.modelName, m),
diff --git a/src/app/datasources/helpers/store.helpers.spec.ts b/src/app/datasources/helpers/store.helpers.spec.ts
index 2cb1eaf..9f4370c 100644
--- a/src/app/datasources/helpers/store.helpers.spec.ts
+++ b/src/app/datasources/helpers/store.helpers.spec.ts
@@ -44,11 +44,9 @@
it('should convert a core model name in an URL', () => {
expect(service.urlFromCoreModel('Slice')).toBe('/core/slices');
expect(service.urlFromCoreModel('Xos')).toBe('/core/xoses');
-
- // handling exceptions
- expect(service.urlFromCoreModel('SiteRole')).toBe('/core/site_roles');
- expect(service.urlFromCoreModel('SliceRole')).toBe('/core/slice_roles');
- expect(service.urlFromCoreModel('SlicePrivilege')).toBe('/core/slice_privileges');
+ expect(service.urlFromCoreModel('SiteRole')).toBe('/core/siteroles');
+ expect(service.urlFromCoreModel('SliceRole')).toBe('/core/sliceroles');
+ expect(service.urlFromCoreModel('SlicePrivilege')).toBe('/core/sliceprivileges');
});
describe('when updating a collection', () => {
diff --git a/src/app/datasources/helpers/store.helpers.ts b/src/app/datasources/helpers/store.helpers.ts
index 7792590..c26e235 100644
--- a/src/app/datasources/helpers/store.helpers.ts
+++ b/src/app/datasources/helpers/store.helpers.ts
@@ -9,7 +9,7 @@
updateCollection(event: IWSEvent, subject: BehaviorSubject<any>): BehaviorSubject<any>;
}
-export class StoreHelpers {
+export class StoreHelpers implements IStoreHelpersService {
static $inject = ['ModelRest'];
constructor (
@@ -18,15 +18,7 @@
}
public urlFromCoreModel(name: string): string {
- switch (name) {
- // FIXME handling exceptions, understand why these 3 endpoints are autogenerated with an _f
- case 'SiteRole':
- case 'SliceRole':
- case 'SlicePrivilege':
- return `/core/${pluralize(name.split(/(?=[A-Z])/).map(w => w.toLowerCase()).join('_'))}`;
- default:
- return `/core/${pluralize(name.toLowerCase())}`;
- }
+ return `/core/${pluralize(name.toLowerCase())}`;
}
public updateCollection(event: IWSEvent, subject: BehaviorSubject<any>): BehaviorSubject<any> {
diff --git a/src/app/datasources/index.ts b/src/app/datasources/index.ts
index 04c58db..80d348a 100644
--- a/src/app/datasources/index.ts
+++ b/src/app/datasources/index.ts
@@ -1,22 +1,27 @@
import {ModelRest} from './rest/model.rest';
import {AuthService} from './rest/auth.rest';
import {WebSocketEvent} from './websocket/global';
-import {ModelStore} from './stores/model.store';
+import {XosModelStore} from './stores/model.store';
import {StoreHelpers} from './helpers/store.helpers';
import {SynchronizerStore} from './stores/synchronizer.store';
-import {ModeldefsService} from './rest/modeldefs.rest';
+import {XosModeldefsService} from './rest/modeldefs.rest';
import {xosCore} from '../core/index';
import {SearchService} from './helpers/search.service';
+import {XosModelDiscovererService} from './helpers/model-discoverer.service';
export const xosDataSources = 'xosDataSources';
angular
- .module('xosDataSources', ['ngCookies', 'ngResource', xosCore])
+ .module(xosDataSources, ['ngCookies', 'ngResource', xosCore])
.service('ModelRest', ModelRest)
.service('AuthService', AuthService)
.service('WebSocket', WebSocketEvent)
.service('StoreHelpers', StoreHelpers)
.service('SynchronizerStore', SynchronizerStore)
- .service('ModelStore', ModelStore)
- .service('ModelDefs', ModeldefsService)
+ .service('XosModelStore', XosModelStore)
+ .service('XosModelDefs', XosModeldefsService)
.service('SearchService', SearchService);
+
+angular
+ .module(xosDataSources)
+ .service('XosModelDiscoverer', XosModelDiscovererService);
diff --git a/src/app/datasources/rest/auth.rest.ts b/src/app/datasources/rest/auth.rest.ts
index 2979bf1..edc2a65 100644
--- a/src/app/datasources/rest/auth.rest.ts
+++ b/src/app/datasources/rest/auth.rest.ts
@@ -7,9 +7,9 @@
export interface IAuthResponseData extends IHttpPromiseCallbackArg<any> {
data: {
- user: string;
- xoscsrftoken: string;
- xossessionid: string;
+ // user: string;
+ // xoscsrftoken: string;
+ sessionid: string;
};
}
@@ -37,12 +37,12 @@
public login(data: IAuthRequestData): Promise<any> {
const d = this.$q.defer();
- this.$http.post(`${this.AppConfig.apiEndpoint}/utility/login/`, data)
+ this.$http.post(`${this.AppConfig.apiEndpoint}/utility/login`, data)
.then((res: IAuthResponseData) => {
- this.$cookies.put('xoscsrftoken', res.data.xoscsrftoken, {path: '/'});
- this.$cookies.put('xossessionid', res.data.xossessionid, {path: '/'});
- this.$cookies.put('xosuser', res.data.user, {path: '/'});
- res.data.user = JSON.parse(res.data.user);
+ // this.$cookies.put('xoscsrftoken', res.data.xoscsrftoken, {path: '/'});
+ this.$cookies.put('sessionid', res.data.sessionid, {path: '/'});
+ // this.$cookies.put('xosuser', res.data.user, {path: '/'});
+ // res.data.user = JSON.parse(res.data.user);
d.resolve(res.data);
})
.catch(e => {
@@ -53,9 +53,9 @@
public logout(): Promise<any> {
const d = this.$q.defer();
- this.$http.post(`${this.AppConfig.apiEndpoint}/utility/logout/`, {
- xoscsrftoken: this.$cookies.get('xoscsrftoken'),
- xossessionid: this.$cookies.get('xossessionid')
+ this.$http.post(`${this.AppConfig.apiEndpoint}/utility/logout`, {
+ // xoscsrftoken: this.$cookies.get('xoscsrftoken'),
+ // sessionid: this.$cookies.get('sessionid')
})
.then(() => {
this.clearUser();
@@ -68,9 +68,9 @@
}
public clearUser(): void {
- this.$cookies.remove('xoscsrftoken', {path: '/'});
- this.$cookies.remove('xossessionid', {path: '/'});
- this.$cookies.remove('xosuser', {path: '/'});
+ // this.$cookies.remove('xoscsrftoken', {path: '/'});
+ this.$cookies.remove('sessionid', {path: '/'});
+ // this.$cookies.remove('xosuser', {path: '/'});
}
public getUser(): IXosUser {
@@ -82,8 +82,8 @@
}
public isAuthenticated(): boolean {
- const token = this.$cookies.get('xoscsrftoken');
- const session = this.$cookies.get('xossessionid');
- return angular.isDefined(token) && angular.isDefined(session);
+ // const token = this.$cookies.get('xoscsrftoken');
+ const session = this.$cookies.get('sessionid');
+ return angular.isDefined(session);
}
}
diff --git a/src/app/datasources/rest/model.rest.ts b/src/app/datasources/rest/model.rest.ts
index 12590af..4aa862c 100644
--- a/src/app/datasources/rest/model.rest.ts
+++ b/src/app/datasources/rest/model.rest.ts
@@ -16,7 +16,15 @@
public getResource(url: string): ng.resource.IResourceClass<ng.resource.IResource<any>> {
const resource: angular.resource.IResourceClass<any> = this.$resource(`${this.AppConfig.apiEndpoint}${url}/:id/`, {id: '@id'}, {
- update: { method: 'PUT' }
+ update: { method: 'PUT' },
+ query: {
+ method: 'GET',
+ isArray: true,
+ transformResponse: (res) => {
+ // FIXME chameleon return everything inside "items"
+ return res.items ? res.items : res;
+ }
+ }
});
resource.prototype.$save = function() {
diff --git a/src/app/datasources/rest/modeldefs.rest.spec.ts b/src/app/datasources/rest/modeldefs.rest.spec.ts
index 9dc4025..677463b 100644
--- a/src/app/datasources/rest/modeldefs.rest.spec.ts
+++ b/src/app/datasources/rest/modeldefs.rest.spec.ts
@@ -3,9 +3,9 @@
import 'angular-resource';
import 'angular-cookies';
import {xosDataSources} from '../index';
-import {IModeldefsService} from './modeldefs.rest';
+import {IXosModeldefsService} from './modeldefs.rest';
-let service: IModeldefsService;
+let service: IXosModeldefsService;
let httpBackend: ng.IHttpBackendService;
let $scope;
@@ -14,7 +14,7 @@
websocketClient: 'http://xos-test:3000'
};
-describe('The ModelDefs service', () => {
+describe('The XosModelDefs service', () => {
beforeEach(angular.mock.module(xosDataSources));
@@ -26,14 +26,13 @@
angular.mock.module(xosDataSources);
});
-
beforeEach(angular.mock.inject((
- ModelDefs: IModeldefsService,
+ XosModelDefs: IXosModeldefsService,
$httpBackend: ng.IHttpBackendService,
_$resource_: ng.resource.IResourceService,
_$rootScope_: ng.IRootScopeService
) => {
- service = ModelDefs;
+ service = XosModelDefs;
httpBackend = $httpBackend;
$scope = _$rootScope_;
}));
diff --git a/src/app/datasources/rest/modeldefs.rest.ts b/src/app/datasources/rest/modeldefs.rest.ts
index d927f8c..fdb4b99 100644
--- a/src/app/datasources/rest/modeldefs.rest.ts
+++ b/src/app/datasources/rest/modeldefs.rest.ts
@@ -1,17 +1,35 @@
import {IXosModelDefsField} from '../../core/services/helpers/config.helpers';
import {IXosAppConfig} from '../../../index';
-export interface IModeldef {
- fields: IXosModelDefsField[];
- relations?: string[];
+// Models interfaces
+export interface IXosModelDefsField {
name: string;
+ type: string;
+ validators?: any;
+ hint?: string;
+ relation?: {
+ model: string;
+ type: string;
+ };
}
-export interface IModeldefsService {
- get(): Promise<IModeldef[]>;
+export interface IXosModelDefsRelation {
+ model: string; // model name
+ type: string; // relation type
}
-export class ModeldefsService {
+export interface IXosModeldef {
+ fields: IXosModelDefsField[];
+ relations?: IXosModelDefsRelation[];
+ name: string;
+ app: string;
+}
+
+export interface IXosModeldefsService {
+ get(): Promise<IXosModeldef[]>;
+}
+
+export class XosModeldefsService implements IXosModeldefsService {
static $inject = ['$http', '$q', 'AppConfig'];
@@ -24,9 +42,9 @@
public get(): Promise<any> {
const d = this.$q.defer();
- this.$http.get(`${this.AppConfig.apiEndpoint}/utility/modeldefs/`)
- .then((res) => {
- d.resolve(res.data);
+ this.$http.get(`${this.AppConfig.apiEndpoint}/modeldefs`)
+ .then((res: any) => {
+ d.resolve(res.data.items);
})
.catch(e => {
d.reject(e);
diff --git a/src/app/datasources/stores/model.store.spec.ts b/src/app/datasources/stores/model.store.spec.ts
index 7173658..533a53d 100644
--- a/src/app/datasources/stores/model.store.spec.ts
+++ b/src/app/datasources/stores/model.store.spec.ts
@@ -1,7 +1,7 @@
import * as angular from 'angular';
import 'angular-mocks';
import 'angular-resource';
-import {IXosModelStoreService, ModelStore} from './model.store';
+import {IXosModelStoreService, XosModelStore} from './model.store';
import {Subject} from 'rxjs';
import {IWSEvent} from '../websocket/global';
import {StoreHelpers} from '../helpers/store.helpers';
@@ -46,7 +46,7 @@
.service('WebSocket', MockWs)
.service('StoreHelpers', StoreHelpers) // TODO mock
.service('ModelRest', ModelRest) // TODO mock
- .service('ModelStore', ModelStore)
+ .service('XosModelStore', XosModelStore)
.service('ConfigHelpers', ConfigHelpers) // TODO mock
.service('AuthService', AuthService)
.constant('AppConfig', MockAppCfg);
@@ -55,12 +55,12 @@
});
beforeEach(angular.mock.inject((
- ModelStore: IXosModelStoreService,
+ XosModelStore: IXosModelStoreService,
$httpBackend: ng.IHttpBackendService,
_$rootScope_: ng.IRootScopeService,
_WebSocket_: any
) => {
- service = ModelStore;
+ service = XosModelStore;
httpBackend = $httpBackend;
$scope = _$rootScope_;
WebSocket = _WebSocket_;
diff --git a/src/app/datasources/stores/model.store.ts b/src/app/datasources/stores/model.store.ts
index 291e7c0..4958015 100644
--- a/src/app/datasources/stores/model.store.ts
+++ b/src/app/datasources/stores/model.store.ts
@@ -6,11 +6,11 @@
import {IStoreHelpersService} from '../helpers/store.helpers';
export interface IXosModelStoreService {
- query(model: string): Observable<any>;
+ query(model: string, apiUrl?: string): Observable<any>;
search(modelName: string): any[];
}
-export class ModelStore implements IXosModelStoreService {
+export class XosModelStore implements IXosModelStoreService {
static $inject = ['$log', 'WebSocket', 'StoreHelpers', 'ModelRest'];
private _collections: any; // NOTE contains a map of {model: BehaviourSubject}
constructor(
@@ -22,59 +22,76 @@
this._collections = {};
}
- public query(model: string): Observable<any> {
+ public query(modelName: string, apiUrl: string): Observable<any> {
// if there isn't already an observable for that item
- if (!this._collections[model]) {
- this._collections[model] = new BehaviorSubject([]); // NOTE maybe this can be created when we get response from the resource
- this.loadInitialData(model);
+ if (!this._collections[modelName]) {
+ this._collections[modelName] = new BehaviorSubject([]); // NOTE maybe this can be created when we get response from the resource
+ this.loadInitialData(modelName, apiUrl);
}
this.webSocket.list()
- .filter((e: IWSEvent) => e.model === model)
+ .filter((e: IWSEvent) => e.model === modelName)
.subscribe(
(event: IWSEvent) => {
- this.storeHelpers.updateCollection(event, this._collections[model]);
+ this.storeHelpers.updateCollection(event, this._collections[modelName]);
},
err => console.error
);
- return this._collections[model].asObservable();
+ return this._collections[modelName].asObservable();
}
public search(modelName: string): any[] {
- return _.reduce(Object.keys(this._collections), (results, k) => {
- // console.log(k, this._collections[k].value)
- const partialRes = _.filter(this._collections[k].value, i => {
- if (i.humanReadableName) {
- return i.humanReadableName.toLowerCase().indexOf(modelName) > -1;
+ try {
+ const res = _.reduce(Object.keys(this._collections), (results, k) => {
+ let partialRes;
+ // NOTE wrapped in a try catch as some subject may be errored, due to not available REST endpoint
+ try {
+ partialRes = _.filter(this._collections[k].value, i => {
+ if (i && i.humanReadableName) {
+ return i.humanReadableName.toLowerCase().indexOf(modelName) > -1;
+ }
+ else if (i && i.name) {
+ return i.name.toLowerCase().indexOf(modelName) > -1;
+ }
+ return false;
+ });
+ } catch (e) {
+ partialRes = [];
}
- else if (i.name) {
- return i.name.toLowerCase().indexOf(modelName) > -1;
- }
- return false;
- })
- .map(m => {
+ partialRes.map(m => {
m.modelName = k;
return m;
});
- return results.concat(partialRes);
- }, []);
+ return results.concat(partialRes);
+ }, []);
+ return res;
+ } catch (e) {
+ return [];
+ }
}
public get(model: string, id: number) {
// TODO implement a get method
}
- private loadInitialData(model: string) {
- // NOTE check what is the correct pattern to pluralize this
- const endpoint = this.storeHelpers.urlFromCoreModel(model);
- this.ModelRest.getResource(endpoint).query().$promise
+ private loadInitialData(model: string, apiUrl?: string) {
+ // TODO provide alway the apiUrl togheter with the query() params
+ if (!angular.isDefined(apiUrl)) {
+ // NOTE check what is the correct pattern to pluralize this
+ apiUrl = this.storeHelpers.urlFromCoreModel(model);
+ }
+ this.ModelRest.getResource(apiUrl).query().$promise
.then(
res => {
this._collections[model].next(res);
})
.catch(
- err => this.$log.log(`Error retrieving ${model}`, err)
+ // TODO understand how to send an error to an observable
+ err => {
+ this._collections[model].error(err);
+ // this.$log.log(`Error retrieving ${model}`, err);
+ }
);
}
}