[SEBA-747] Upgraded loader to show real-time progress istead of using a time-out

Change-Id: Iafea32e3b15461dc8b6859f0e4b1813150e362d5
diff --git a/src/app/datasources/helpers/model-discoverer.service.ts b/src/app/datasources/helpers/model-discoverer.service.ts
index 3ee5a15..2e5597e 100644
--- a/src/app/datasources/helpers/model-discoverer.service.ts
+++ b/src/app/datasources/helpers/model-discoverer.service.ts
@@ -47,12 +47,14 @@
   discover(): ng.IPromise<string>;
   getApiUrlFromModel(model: IXosModel): string;
   areModelsLoaded(): boolean;
+  getStatusMessage(): string;
 }
 
 export class XosModelDiscovererService implements IXosModelDiscovererService {
   static $inject = [
     '$log',
     '$q',
+    '$interval',
     'XosModelDefs',
     'ConfigHelpers',
     'XosRuntimeStates',
@@ -66,10 +68,12 @@
   private xosServices: string[] = []; // list of loaded services
   private progressBar;
   private modelsLoaded: boolean = false;
+  private statusMessage: string = 'Loading models definition';
 
   constructor (
     private $log: ng.ILogService,
     private $q: ng.IQService,
+    private $interval: ng.IIntervalService,
     private XosModelDefs: IXosModeldefsService,
     private ConfigHelpers: IXosConfigHelpersService,
     private XosRuntimeStates: IXosRuntimeStatesService,
@@ -97,13 +101,35 @@
     }
   }
 
+  public getStatusMessage(): string {
+    return this.statusMessage;
+  }
+
   public discover() {
     const d = this.$q.defer();
-    this.progressBar.start();
+    // loading stats
+    let loadingSince = 0;
+    const modelDefInerval = this.$interval(() => {
+      loadingSince += 1;
+      this.setModelDefTimeMsg(loadingSince);
+    }, 1000);
+    this.progressBar.set(1);
+
+    // start loading data
     this.XosModelDefs.get()
       .then((modelsDef: IXosModeldef[]) => {
-        // TODO store modeldefs and add a method to retrieve the model definition from the name
         const pArray = [];
+
+        // Setting up counters for the status message
+        this.$interval.cancel(modelDefInerval);
+        const modelsTotal = modelsDef.length;
+        let modelsLoaded = 0;
+        this.setModelsCountMsg(modelsLoaded, modelsTotal);
+
+        // Setting up counters for the loading bar
+        this.progressBar.set(10);
+        const progressBarStep = 90 / modelsTotal;
+
         _.forEach(modelsDef, (model: IXosModeldef) => {
           this.$log.debug(`[XosModelDiscovererService] Loading: ${model.name}`);
           let p = this.cacheModelEntries(model)
@@ -123,6 +149,13 @@
               return this.storeModel(model);
             })
             .then(model => {
+              // Updating the status message
+              modelsLoaded = modelsLoaded + 1;
+              this.setModelsCountMsg(modelsLoaded, modelsTotal);
+
+              // Updating the progress bar
+              this.progressBar.set(10 + (modelsLoaded * progressBarStep));
+
               this.$log.debug(`[XosModelDiscovererService] Model ${model.name} stored`);
               return this.$q.resolve('true');
             })
@@ -167,6 +200,15 @@
     return d.promise;
   }
 
+  private setModelDefTimeMsg(seconds: number) {
+    this.statusMessage = `Loading models definition for ${seconds} seconds...`;
+  }
+
+  private setModelsCountMsg(loaded: number, modelsTotal: number) {
+    const percent = Math.round((100 * loaded) / modelsTotal);
+    this.statusMessage = `Loading data.... ${percent}% completed (${loaded} of ${modelsTotal} models)`;
+  }
+
   private stateNameFromModel(model: IXosModel): string {
     return `xos.${this.XosModeldefsCache.serviceNameFromAppName(model.app)}.${model.name.toLowerCase()}`;
   }
diff --git a/src/app/datasources/helpers/model.discoverer.service.spec.ts b/src/app/datasources/helpers/model.discoverer.service.spec.ts
index 5deb444..bcdec0d 100644
--- a/src/app/datasources/helpers/model.discoverer.service.spec.ts
+++ b/src/app/datasources/helpers/model.discoverer.service.spec.ts
@@ -85,7 +85,7 @@
 };
 const MockProgressBar = {
   setColor: jasmine.createSpy('progressBar.setColor'),
-  start: jasmine.createSpy('progressBar.start'),
+  set: jasmine.createSpy('progressBar.set'),
   complete: jasmine.createSpy('progressBar.complete')
 };
 const MockngProgressFactory = {
@@ -279,7 +279,7 @@
     it('should call all the function chain', (done) => {
       service.discover()
         .then((res) => {
-          expect(MockProgressBar.start).toHaveBeenCalled();
+          expect(MockProgressBar.set).toHaveBeenCalled();
           expect(MockXosModelDefs.get).toHaveBeenCalled();
           expect(service['cacheModelEntries'].calls.count()).toBe(2);
           expect(service['addState'].calls.count()).toBe(2);