diff --git a/app/js/controllers/test-details.js b/app/js/controllers/test-details.js index 1bc803a..ccffe90 100644 --- a/app/js/controllers/test-details.js +++ b/app/js/controllers/test-details.js @@ -5,13 +5,15 @@ var controllersModule = require('./_index'); /** * @ngInject */ -function TestDetailsCtrl($scope, $location, $stateParams, datasetService) { +function TestDetailsCtrl($scope, $location, $stateParams, datasetService, progressService) { // ViewModel var vm = this; $scope.datasetId = $stateParams.datasetId; var testName = $stateParams.test; $scope.testName = testName; + progressService.start({ parent: 'div[role="main"] .panel-body' }); + // load dataset, raw json, and details json datasetService.get($stateParams.datasetId).then(function(response) { $scope.dataset = response; @@ -24,18 +26,25 @@ function TestDetailsCtrl($scope, $location, $stateParams, datasetService) { } } $scope.item = item; + + progressService.inc(); }).catch(function(ex) { $log.error(ex); + progressService.done(); }); datasetService.details(response).then(function(deets) { $scope.details = deets; $scope.originalDetails = angular.copy(deets.data[testName]); $scope.itemDetails = deets.data[testName]; + + progressService.done(); }).catch(function(ex) { $log.error(ex); + progressService.done(); }); }).catch(function(ex) { $log.error(ex); + progressService.done(); }); $scope.parsePythonLogging = function(showINFO, showDEBUG, showWARNING, showERROR) { diff --git a/app/js/directives/timeline.js b/app/js/directives/timeline.js index 3901ac7..6c66f90 100644 --- a/app/js/directives/timeline.js +++ b/app/js/directives/timeline.js @@ -29,7 +29,7 @@ var parseWorker = function(tags) { /** * @ngInject */ -function timeline($log, datasetService) { +function timeline($log, datasetService, progressService) { /** * @ngInject @@ -227,20 +227,25 @@ function timeline($log, datasetService) { return; } + progressService.start({ parent: 'timeline .panel-body' }); + // load dataset details (raw log entries and dstat) sequentially // we need to determine the initial date from the subunit data to parse // dstat datasetService.raw(dataset).then(function(response) { + progressService.set(0.33); initData(response.data); return datasetService.dstat(dataset); }).then(function(response) { + progressService.set(0.66); var firstDate = new Date(self.dataRaw[0].timestamps[0]); var raw = parseDstat(response.data, firstDate.getYear()); initDstat(raw); $scope.$broadcast('update'); + progressService.done(); }).catch(function(ex) { $log.error(ex); }); diff --git a/app/js/services/progress.js b/app/js/services/progress.js new file mode 100644 index 0000000..84af073 --- /dev/null +++ b/app/js/services/progress.js @@ -0,0 +1,40 @@ +'use strict'; + +var nprogress = require('nprogress'); + +var servicesModule = require('./_index.js'); + +/** + * @ngInject + */ +function ProgressService() { + + return { + start: function(options) { + if (options) { + nprogress.configure(options); + } + + nprogress.start(); + }, + + done: function() { + nprogress.done(); + }, + + remove: function() { + nprogress.remove(); + }, + + set: function(val) { + nprogress.set(val); + }, + + inc: function() { + nprogress.inc(); + } + }; + +} + +servicesModule.service('progressService', ProgressService); diff --git a/app/styles/_nprogress.scss b/app/styles/_nprogress.scss new file mode 100644 index 0000000..12d8abd --- /dev/null +++ b/app/styles/_nprogress.scss @@ -0,0 +1,73 @@ +/* Make clicks pass-through */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: #29d; + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 2px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px #29d, 0 0 5px #29d; + opacity: 1.0; + + -webkit-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: #29d; + border-left-color: #29d; + border-radius: 50%; + + -webkit-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } +} +@keyframes nprogress-spinner { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} diff --git a/app/styles/main.scss b/app/styles/main.scss index c1337c0..07e7d42 100644 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -3,6 +3,7 @@ @import 'bootstrap'; @import 'font-awesome/font-awesome'; @import 'sb-admin-2'; +@import 'nprogress'; @import 'directives/_test-details-search.scss'; @import 'directives/_timeline-details.scss'; diff --git a/package.json b/package.json index 0e31b02..9498c21 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "karma-jasmine": "^0.3.6", "karma-phantomjs-launcher": "0.2.0", "morgan": "^1.6.1", + "nprogress": "^0.2.0", "phantomjs": "1.9.17", "pretty-hrtime": "^1.0.0", "protractor": "^2.2.0",