[CORD-1232] Filtering events based on updated properies

Change-Id: If96da2f5c987f487b4d8b9ec7c68e44869cb4e12
diff --git a/conf/browsersync.conf.js b/conf/browsersync.conf.js
index 391f688..3f262ba 100644
--- a/conf/browsersync.conf.js
+++ b/conf/browsersync.conf.js
@@ -1,6 +1,7 @@
 const conf = require('./gulp.conf');
 const proxy = require('./proxy').proxy;
 const extensionsProxy = require('./proxy').extensionsProxy;
+const socketProxy = require('./proxy').socketProxy;
 
 module.exports = function () {
   return {
@@ -10,9 +11,12 @@
         conf.paths.src
       ],
       middleware: function(req, res, next){
-        if (req.url.indexOf('xosapi') !== -1 || req.url.indexOf('socket.io') !== -1) {
+        if (req.url.indexOf('xosapi') !== -1) {
           proxy.web(req, res);
         }
+        else if (req.url.indexOf('socket.io') !== -1) {
+          socketProxy.web(req, res);
+        }
         else if (req.url.indexOf('extensions') !== -1) {
           extensionsProxy.web(req, res);
         }
diff --git a/conf/proxy.js b/conf/proxy.js
index 8af184d..d45a27b 100644
--- a/conf/proxy.js
+++ b/conf/proxy.js
@@ -3,21 +3,34 @@
 const target = process.env.PROXY || '192.168.46.100';
 
 const proxy = httpProxy.createProxyServer({
-  target: `http://${target}:9101`
+  target: `http://${target}`
 });
 
 const extensionsProxy = httpProxy.createProxyServer({
   target: `http://${target}/xos/`
 });
 
+const socketProxy = httpProxy.createProxyServer({
+  target: `http://${target}/`
+});
+
 proxy.on('error', function(error, req, res) {
-  res.writeHead(500, {
-    'Content-Type': 'text/plain'
-  });
+  res.writeHead(500, {'Content-Type': 'text/plain'});
   console.error('[Proxy]', error);
 });
 
+extensionsProxy.on('error', function(error, req, res) {
+  res.writeHead(500, {'Content-Type': 'text/plain'});
+  console.error('[extensionsProxy]', error);
+});
+
+socketProxy.on('error', function(error, req, res) {
+  res.writeHead(500, {'Content-Type': 'text/plain'});
+  console.error('[socketProxy]', error);
+});
+
 module.exports = {
   proxy,
-  extensionsProxy
+  extensionsProxy,
+  socketProxy
 };
\ No newline at end of file
diff --git a/package.json b/package.json
index e6cc74e..bab009d 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
 {
-  "version": "2.0.0",
+  "version": "3.0.0",
   "dependencies": {
     "angular": "1.6.3",
     "angular-animate": "1.6.3",
diff --git a/src/app/datasources/websocket/global.ts b/src/app/datasources/websocket/global.ts
index a820269..7e5dad7 100644
--- a/src/app/datasources/websocket/global.ts
+++ b/src/app/datasources/websocket/global.ts
@@ -23,27 +23,38 @@
     '$log'
   ];
 
+
   private _events: Subject<IWSEvent> = new Subject<IWSEvent>();
-    private socket;
-    constructor(
-      private AppConfig: IXosAppConfig,
-      private $log: ng.ILogService
-    ) {
-      this.socket = io(this.AppConfig.websocketClient);
-      this.socket.on('event', (data: IWSEvent): void => {
-          this.$log.debug(`[WebSocket] Received Event for: ${data.model} [${data.msg.pk}]`);
-          this._events.next(data);
+  private socket;
+  constructor(
+    private AppConfig: IXosAppConfig,
+    private $log: ng.ILogService
+  ) {
+    // NOTE list of field that are not useful to the UI
+    const ignoredFields: string[] = ['created', 'updated', 'backend_register'];
 
-          // NOTE update observers of parent classes
-          if (data.msg.object.class_names && angular.isString(data.msg.object.class_names)) {
-            const models = data.msg.object.class_names.split(',');
-            _.forEach(models, (m: string) => {
-              data.model = m;
-              this._events.next(data);
-            });
-          }
+    this.socket = io(this.AppConfig.websocketClient);
+    this.socket.on('event', (data: IWSEvent): void => {
+        this.$log.debug(`[WebSocket] Received Event for: ${data.model} [${data.msg.pk}]`);
 
-        });
+        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
+          this.$log.debug(`[WebSocket] Ignoring Event for: ${data.model} [${data.msg.pk}]`);
+          return;
+        }
+
+        this._events.next(data);
+
+        // NOTE update observers of parent classes
+        if (data.msg.object.class_names && angular.isString(data.msg.object.class_names)) {
+          const models = data.msg.object.class_names.split(',');
+          _.forEach(models, (m: string) => {
+            data.model = m;
+            this._events.next(data);
+          });
+        }
+
+      });
     }
     list() {
       return this._events.asObservable();