[SEBA-747] Upgraded loader to show real-time progress istead of using a time-out
Change-Id: Iafea32e3b15461dc8b6859f0e4b1813150e362d5
diff --git a/src/app/core/loader/loader.spec.ts b/src/app/core/loader/loader.spec.ts
index 0744c11..1a2d553 100644
--- a/src/app/core/loader/loader.spec.ts
+++ b/src/app/core/loader/loader.spec.ts
@@ -29,6 +29,7 @@
const MockDiscover = {
areModelsLoaded: () => loaded,
+ getStatusMessage: () => 'Test Message',
discover: null
};
diff --git a/src/app/core/loader/loader.ts b/src/app/core/loader/loader.ts
index 3606ca8..c8def42 100644
--- a/src/app/core/loader/loader.ts
+++ b/src/app/core/loader/loader.ts
@@ -27,6 +27,7 @@
'$rootScope',
'$location',
'$timeout',
+ '$interval',
'$state',
'AuthService',
'XosConfig',
@@ -35,20 +36,24 @@
];
public loader: boolean = true;
+ public message: string = 'Loading data...';
public error: string;
+ private getMessageInterval: ng.IPromise<any>;
+
constructor (
private $log: ng.ILogService,
private $rootScope: ng.IScope,
private $location: ng.ILocationService,
private $timeout: ng.ITimeoutService,
+ private $interval: ng.IIntervalService,
private $state: ng.ui.IStateService,
private XosAuthService: IXosAuthService,
private XosConfig: any,
private XosModelDiscoverer: IXosModelDiscovererService,
private XosOnboarder: IXosOnboarder
) {
-
+ this.getMessage();
this.run();
}
@@ -119,11 +124,34 @@
break;
}
}
+
+ /**
+ * This method query the model-discoverer service to have the status of the loading
+ */
+ public getMessage() {
+ this.getMessageInterval = this.$interval(() => {
+ this.message = this.XosModelDiscoverer.getStatusMessage();
+ }, 1000);
+ this.message = this.XosModelDiscoverer.getStatusMessage();
+ }
+
+ $onDestroy() {
+ this.$interval.cancel(this.getMessageInterval);
+ }
}
export const xosLoader: angular.IComponentOptions = {
template: `
- <div ng-show="vm.loader" class="loader"></div>
+ <div class="loader-container">
+ <div ng-show="vm.loader" class="loader"></div>
+ </div>
+ <div class="row">
+ <div class="col-sm-6 col-sm-offset-3">
+ <div class="alert alert-accent">
+ {{ vm.message }}
+ </div>
+ </div>
+ </div>
<div class="row" ng-show="vm.error == 'chameleon'">
<div class="col-sm-6 col-sm-offset-3">
<div class="alert alert-danger">
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);
diff --git a/src/app/datasources/rest/modeldefs.rest.ts b/src/app/datasources/rest/modeldefs.rest.ts
index 078eede..c354afe 100644
--- a/src/app/datasources/rest/modeldefs.rest.ts
+++ b/src/app/datasources/rest/modeldefs.rest.ts
@@ -54,7 +54,7 @@
public get(): IPromise<IXosModeldef[]> {
const d = this.$q.defer();
- this.$http.get(`${this.AppConfig.apiEndpoint}/modeldefs`, {timeout: 10 * 1000})
+ this.$http.get(`${this.AppConfig.apiEndpoint}/modeldefs`)
.then((res: any) => {
d.resolve(res.data.items);
})
diff --git a/src/app/style/imports/loader.scss b/src/app/style/imports/loader.scss
index a04b17f..703b910 100644
--- a/src/app/style/imports/loader.scss
+++ b/src/app/style/imports/loader.scss
@@ -18,6 +18,10 @@
@import '../vars';
+.loader-container {
+ height: 9em !important;
+}
+
.loader,
.loader:before,
.loader:after {
diff --git a/src/index.html b/src/index.html
index 0eba668..ea0c97a 100644
--- a/src/index.html
+++ b/src/index.html
@@ -31,12 +31,12 @@
</head>
<body class="{{class}}">
- <ui-view></ui-view>
<div ng-show="::false">
<div class="loader">
Loading
</div>
</div>
+ <ui-view></ui-view>
</body>
<script type="text/javascript" src="./app.config.js"></script>
<script type="text/javascript" src="./style.config.js"></script>
diff --git a/src/index.scss b/src/index.scss
index 561a741..fd2ecf7 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -74,6 +74,10 @@
@include alert-variant($background-dark-color, $alert-danger-text, $alert-danger-border);
}
+.alert-accent {
+ @include alert-variant($background-dark-color, $color-accent, #fff);
+}
+
.modal-backdrop.in {
filter: alpha(opacity=50);
opacity: .5;