[CORD-2277] Two stage delete for models
Change-Id: Ic1b1d59a9f1d6d963d10951e694cf963f41d84d5
(cherry picked from commit e9cdf9ab429f1899b88552d8b0fd177c7cde9c94)
diff --git a/src/app/datasources/helpers/store.helpers.spec.ts b/src/app/datasources/helpers/store.helpers.spec.ts
index 2f617bc..9c4cfc6 100644
--- a/src/app/datasources/helpers/store.helpers.spec.ts
+++ b/src/app/datasources/helpers/store.helpers.spec.ts
@@ -33,6 +33,7 @@
let resource: ng.resource.IResourceClass<any>;
let $resource: ng.resource.IResourceService;
let xosModelCache: IXosModeldefsCache;
+let $log: ng.ILogService;
describe('The StoreHelpers service', () => {
@@ -54,14 +55,17 @@
});
beforeEach(angular.mock.inject((
+
StoreHelpers: IStoreHelpersService,
XosModeldefsCache: IXosModeldefsCache,
- _$resource_: ng.resource.IResourceService
+ _$resource_: ng.resource.IResourceService,
+ _$log_: ng.ILogService
) => {
$resource = _$resource_;
resource = $resource('/test');
xosModelCache = XosModeldefsCache;
service = StoreHelpers;
+ $log = _$log_;
}));
it('should have an update collection method', () => {
@@ -102,17 +106,35 @@
});
});
- describe('when updating a collection', () => {
-
+ describe('when removing an item from a collection', () => {
beforeEach(() => {
subject = new BehaviorSubject([
new resource({id: 1, name: 'test'})
]);
});
+ describe('the updateCollection method', () => {
+ beforeEach(() => {
+ spyOn($log, 'error');
+ });
+
+ it('should log an error if called with a delete event', () => {
+ const event: IWSEvent = {
+ deleted: true,
+ model: 'Deleted',
+ msg: {
+ changed_fields: []
+ }
+ };
+ service.updateCollection(event, subject);
+ expect($log.error).toHaveBeenCalled();
+ });
+ });
+
it('should remove a model if it has been deleted', () => {
const event: IWSEvent = {
model: 'Test',
+ deleted: true,
msg: {
object: {
id: 1,
@@ -121,9 +143,35 @@
changed_fields: ['deleted']
}
};
- service.updateCollection(event, subject);
+ service.removeItemFromCollection(event, subject);
expect(subject.value.length).toBe(0);
});
+ });
+
+ describe('when updating a collection', () => {
+
+ beforeEach(() => {
+ subject = new BehaviorSubject([
+ new resource({id: 1, name: 'test'})
+ ]);
+ });
+
+ describe('the removeItemFromCollection method', () => {
+ beforeEach(() => {
+ spyOn($log, 'error');
+ });
+
+ it('should log an error if called with an update event', () => {
+ const event: IWSEvent = {
+ model: 'Deleted',
+ msg: {
+ changed_fields: []
+ }
+ };
+ service.removeItemFromCollection(event, subject);
+ expect($log.error).toHaveBeenCalled();
+ });
+ });
it('should update a model if it has been updated', () => {
const event: IWSEvent = {
diff --git a/src/app/datasources/helpers/store.helpers.ts b/src/app/datasources/helpers/store.helpers.ts
index 0df37c7..514b870 100644
--- a/src/app/datasources/helpers/store.helpers.ts
+++ b/src/app/datasources/helpers/store.helpers.ts
@@ -24,28 +24,34 @@
export interface IStoreHelpersService {
updateCollection(event: IWSEvent, subject: BehaviorSubject<any>): BehaviorSubject<any>;
+ removeItemFromCollection(event: IWSEvent, subject: BehaviorSubject<any>): BehaviorSubject<any>;
}
export class StoreHelpers implements IStoreHelpersService {
static $inject = [
+ '$log',
'ModelRest',
'XosModeldefsCache'
];
constructor (
+ private $log: ng.ILogService,
private modelRest: IXosResourceService,
private XosModeldefsCache: IXosModeldefsCache
) {
}
public updateCollection(event: IWSEvent, subject: BehaviorSubject<any>): BehaviorSubject<any> {
+ if (event.deleted) {
+ this.$log.error('[XosStoreHelpers] updateCollection method has been called for a delete event, in this cale please use "removeItemFromCollection"', event);
+ return;
+ }
const collection: any[] = subject.value;
const index: number = _.findIndex(collection, (i) => {
// NOTE evaluate to use event.msg.pk
return i.id === event.msg.object.id;
});
const exist: boolean = index > -1;
- const isDeleted: boolean = _.includes(event.msg.changed_fields, 'deleted');
// generate a resource for the model
const modelDef = this.XosModeldefsCache.get(event.model); // get the model definition
@@ -53,16 +59,12 @@
const resource = this.modelRest.getResource(endpoint);
const model = new resource(event.msg.object);
- // remove
- if (exist && isDeleted) {
- _.remove(collection, {id: event.msg.object.id});
- }
// Replace item at index using native splice
- else if (exist && !isDeleted) {
+ if (exist) {
collection.splice(index, 1, model);
}
- // if the element is not deleted add it
- else if (!exist && !isDeleted) {
+ // if the element does not exist add it
+ else {
collection.push(model);
}
@@ -70,4 +72,15 @@
return subject;
}
+
+ public removeItemFromCollection(event: IWSEvent, subject: BehaviorSubject<any>): BehaviorSubject<any> {
+ if (!event.deleted) {
+ this.$log.error('[XosStoreHelpers] removeItemFromCollection method has been called for an update event, in this cale please use "updateCollection"', event);
+ return;
+ }
+ const collection: any[] = subject.value;
+ _.remove(collection, {id: event.msg.object.id});
+ subject.next(collection);
+ return subject;
+ }
}
diff --git a/src/app/datasources/rest/model.rest.ts b/src/app/datasources/rest/model.rest.ts
index f390616..dcec5d4 100644
--- a/src/app/datasources/rest/model.rest.ts
+++ b/src/app/datasources/rest/model.rest.ts
@@ -64,6 +64,10 @@
}
};
+ // resource.prototype.$delete = function() {
+ //
+ // }
+
return resource;
}
}
diff --git a/src/app/datasources/stores/model.store.ts b/src/app/datasources/stores/model.store.ts
index 10c4d2e..09bd715 100644
--- a/src/app/datasources/stores/model.store.ts
+++ b/src/app/datasources/stores/model.store.ts
@@ -73,7 +73,12 @@
.filter((e: IWSEvent) => e.model === modelName)
.subscribe(
(event: IWSEvent) => {
- this.storeHelpers.updateCollection(event, this._collections[modelName]);
+ if (event.deleted) {
+ this.storeHelpers.removeItemFromCollection(event, this._collections[modelName]);
+ }
+ else {
+ this.storeHelpers.updateCollection(event, this._collections[modelName]);
+ }
},
err => this.$log.error
);
diff --git a/src/app/datasources/websocket/global.ts b/src/app/datasources/websocket/global.ts
index e86282a..8774173 100644
--- a/src/app/datasources/websocket/global.ts
+++ b/src/app/datasources/websocket/global.ts
@@ -24,6 +24,7 @@
export interface IWSEvent {
model: string;
skip_notification?: boolean;
+ deleted?: boolean;
msg: {
changed_fields: string[],
object?: any,
@@ -53,7 +54,15 @@
const ignoredFields: string[] = ['created', 'updated', 'backend_register'];
this.socket = io(this.AppConfig.websocketClient);
- this.socket.on('event', (data: IWSEvent): void => {
+
+ this.socket.on('remove', (data: IWSEvent): void => {
+ this.$log.info(`[WebSocket] Received Remove Event for: ${data.model} [${data.msg.pk}]`, data);
+ this._events.next(data);
+
+ // TODO update observers of parent classes
+ });
+
+ this.socket.on('update', (data: IWSEvent): void => {
if (data.msg.changed_fields.length === 0 || _.intersection(data.msg.changed_fields, ignoredFields).length === data.msg.changed_fields.length) {
// NOTE means that the only updated fields does not change anything in the UI, so don't send events around