diff --git a/components/app-core/frontend/src/utils/busy.service.js b/components/app-core/frontend/src/utils/busy.service.js index e86129b053..4229530e84 100644 --- a/components/app-core/frontend/src/utils/busy.service.js +++ b/components/app-core/frontend/src/utils/busy.service.js @@ -9,10 +9,18 @@ * @memberof app.utils * @name appBusyService * @description The application busy service - * @param {object} appEventService - the event service + * @param {object} $timeout - the $timeout service * @returns {object} the busy service */ - function appBusyServiceFactory() { + function appBusyServiceFactory($timeout) { + + // Time to wait before showing the progress indicator - if a close occurs in this time, no progress is shown + // This prevents indicators being shown for quick operations + var OPEN_TIMEOUT = 250; + + // Time period after the last close, where if a new progress indicator is requested, it will be shown immediately rather than obeying the open timeout + // This prevents progress indicators flicking on and off when different ui-view's show and hide progress indicators + var CLOSE_TIMEOUT = 500; var nextBusyId = 0; @@ -21,6 +29,8 @@ var busyStates = {}; + var openTimer, closeTimer; + return { busyState: {}, @@ -28,13 +38,34 @@ _update: function () { if (busyStack.length === 0) { this.busyState.active = false; + if (openTimer) { + $timeout.cancel(openTimer); + openTimer = undefined; + } else { + closeTimer = $timeout(function () { + closeTimer = undefined; + }, CLOSE_TIMEOUT); + } } else { // Get the last item - that is the most recent var newestId = busyStack[busyStack.length - 1]; var busyInfo = busyStates[newestId]; this.busyState.label = busyInfo.label; this.busyState.local = busyInfo.local || false; - this.busyState.active = true; + + if (!this.busyState.active && !openTimer) { + if (closeTimer) { + $timeout.cancel(closeTimer); + closeTimer = undefined; + this.busyState.active = true; + } else { + var that = this; + openTimer = $timeout(function () { + openTimer = undefined; + that.busyState.active = true; + }, OPEN_TIMEOUT); + } + } } }, diff --git a/components/cloud-foundry/frontend/i18n/en_US/cloud-foundry.json b/components/cloud-foundry/frontend/i18n/en_US/cloud-foundry.json index d4bcc3d3c3..1a959a0ab8 100644 --- a/components/cloud-foundry/frontend/i18n/en_US/cloud-foundry.json +++ b/components/cloud-foundry/frontend/i18n/en_US/cloud-foundry.json @@ -1,6 +1,7 @@ { "cloud-foundry": "Cloud Foundry", "cf.busy": "Collecting Cloud Foundry Metadata", + "cf.endpoints.busy": "Checking Cloud Foundry Endpoints", "org": "Org", "space": "Space", "menu": { diff --git a/components/cloud-foundry/frontend/src/view/dashboard/cluster/router.module.js b/components/cloud-foundry/frontend/src/view/dashboard/cluster/router.module.js index 92ea54c319..b48246184f 100644 --- a/components/cloud-foundry/frontend/src/view/dashboard/cluster/router.module.js +++ b/components/cloud-foundry/frontend/src/view/dashboard/cluster/router.module.js @@ -27,9 +27,10 @@ * @param {object} $state - the UI router $state service * @param {app.model.modelManager} modelManager - the Model management service * @param {app.utils.appUtilsService} appUtilsService - the appUtilsService service + * @param {object} appBusyService - the appBusyService service * @constructor */ - function ClustersRouterController($q, $state, modelManager, appUtilsService) { + function ClustersRouterController($q, $state, modelManager, appUtilsService, appBusyService) { var serviceInstanceModel = modelManager.retrieve('app.model.serviceInstance'); var userServiceInstanceModel = modelManager.retrieve('app.model.serviceInstance.user'); @@ -37,6 +38,7 @@ appUtilsService.chainStateResolve('endpoint.clusters.router', $state, init); function init() { + var appBusyId = appBusyService.set('cf.busy'); return $q.all([serviceInstanceModel.list(), userServiceInstanceModel.list()]) .then(function () { @@ -51,6 +53,8 @@ } }); + appBusyService.clear(appBusyId); + if (connectedInstances === 1) { $state.go('endpoint.clusters.cluster.detail.organizations', {guid: serviceInstanceGuid}); } else { diff --git a/components/cloud-foundry/frontend/src/view/dashboard/tiles/cluster-tiles.module.js b/components/cloud-foundry/frontend/src/view/dashboard/tiles/cluster-tiles.module.js index f6a473d197..039eb4189f 100644 --- a/components/cloud-foundry/frontend/src/view/dashboard/tiles/cluster-tiles.module.js +++ b/components/cloud-foundry/frontend/src/view/dashboard/tiles/cluster-tiles.module.js @@ -41,8 +41,9 @@ * @property {$stateParams} $stateParams - UI Router state params * @property {app.model.modelManager} modelManager - the Model management service * @property {appUtilsService} appUtilsService - the appUtilsService service + * @param {object} appBusyService - the appBusyService service */ - function ClusterTilesController($q, $state, $stateParams, modelManager, appUtilsService) { + function ClusterTilesController($q, $state, $stateParams, modelManager, appUtilsService, appBusyService) { var vm = this; vm.currentUserAccount = modelManager.retrieve('app.model.account'); @@ -62,7 +63,10 @@ appUtilsService.chainStateResolve('endpoint.clusters.tiles', $state, init); function init() { + var appBusyId = appBusyService.set('cf.endpoints.busy'); + return refreshClusterModel().then(function () { + appBusyService.clear(appBusyId); if (_.keys(vm.serviceInstances).length === 1 && !vm.isEndpointsDashboardAvailable) { // We are running without the Endpoints Dashboard and there is only one instance available // redirecting to Organisations Detail page diff --git a/components/cloud-foundry/frontend/test/unit/view/dashboard/tiles/cluster-tiles.module.spec.js b/components/cloud-foundry/frontend/test/unit/view/dashboard/tiles/cluster-tiles.module.spec.js index bbc863c461..92025d2c2b 100644 --- a/components/cloud-foundry/frontend/test/unit/view/dashboard/tiles/cluster-tiles.module.spec.js +++ b/components/cloud-foundry/frontend/test/unit/view/dashboard/tiles/cluster-tiles.module.spec.js @@ -2,7 +2,7 @@ 'use strict'; describe('endpoint clusters', function () { - var $q, $state, $scope, modelManager, appUtilsService, clusterTilesCtrl, serviceInstanceModel, + var $q, $state, $scope, modelManager, appUtilsService, appBusyService, clusterTilesCtrl, serviceInstanceModel, userServiceInstanceModel, consoleInfo, $stateParams; var unknownService = { @@ -77,6 +77,7 @@ modelManager = $injector.get('modelManager'); appUtilsService = $injector.get('appUtilsService'); + appBusyService = $injector.get('appBusyService'); serviceInstanceModel = modelManager.retrieve('app.model.serviceInstance'); userServiceInstanceModel = modelManager.retrieve('app.model.serviceInstance.user'); consoleInfo = modelManager.retrieve('app.model.consoleInfo'); @@ -89,7 +90,7 @@ function createCluster() { var ClusterTilesCtrl = $state.get('endpoint.clusters.tiles').controller; - clusterTilesCtrl = new ClusterTilesCtrl($q, $state, $stateParams, modelManager, appUtilsService); + clusterTilesCtrl = new ClusterTilesCtrl($q, $state, $stateParams, modelManager, appUtilsService, appBusyService); } describe('Init', function () { diff --git a/components/endpoints-dashboard/i18n/en_US/dashboard.json b/components/endpoints-dashboard/i18n/en_US/dashboard.json index 17570b90d0..182093b317 100644 --- a/components/endpoints-dashboard/i18n/en_US/dashboard.json +++ b/components/endpoints-dashboard/i18n/en_US/dashboard.json @@ -2,6 +2,7 @@ "endpoints-dashboard": { "title": "Endpoints", "register-button": "Register Endpoint", + "busy": "Retrieving Endpoint metadata", "table": { "name": "name", "connection": "connection", diff --git a/components/endpoints-dashboard/src/view/view.module.js b/components/endpoints-dashboard/src/view/view.module.js index 80c831739a..ced9dbb45b 100644 --- a/components/endpoints-dashboard/src/view/view.module.js +++ b/components/endpoints-dashboard/src/view/view.module.js @@ -28,10 +28,11 @@ * @param {app.utils.appUtilsService} appUtilsService - the appUtilsService service * @param {app.view.appRegisterService} appRegisterService register service to display the core slide out * @param {app.view.endpoints.dashboard.appEndpointsDashboardService} appEndpointsDashboardService - service to support endpoints dashboard + * @param {object} appBusyService - the appBusyService service * @constructor */ function EndpointsDashboardController($scope, $state, modelManager, appUtilsService, appRegisterService, - appEndpointsDashboardService) { + appEndpointsDashboardService, appBusyService) { var vm = this; var currentUserAccount = modelManager.retrieve('app.model.account'); @@ -116,6 +117,7 @@ } function init() { + vm.appBusyId = appBusyService.set('endpoints-dashboard.busy'); vm.initialised = false; return appEndpointsDashboardService.update() .then(function () { @@ -139,6 +141,8 @@ _updateWelcomeMessage(); }).catch(function () { vm.listError = true; + }).finally(function () { + appBusyService.clear(vm.appBusyId); }); } diff --git a/components/endpoints-dashboard/test/unit/view/endpoints-dashboard.module.spec.js b/components/endpoints-dashboard/test/unit/view/endpoints-dashboard.module.spec.js index f292a44147..844af973be 100644 --- a/components/endpoints-dashboard/test/unit/view/endpoints-dashboard.module.spec.js +++ b/components/endpoints-dashboard/test/unit/view/endpoints-dashboard.module.spec.js @@ -67,6 +67,7 @@ modelManager = $injector.get('modelManager'); var appRegisterService = $injector.get('appRegisterService'); var appUtilsService = $injector.get('appUtilsService'); + var appBusyService = $injector.get('appBusyService'); var appEndpointsDashboardService = $injector.get('appEndpointsDashboardService'); // Patch user account model @@ -84,7 +85,7 @@ var EndpointsDashboardController = $state.get('endpoint.dashboard').controller; controller = new EndpointsDashboardController($scope, $state, modelManager, appUtilsService, - appRegisterService, appEndpointsDashboardService); + appRegisterService, appEndpointsDashboardService, appBusyService); $httpBackend.when('GET', '/pp/v1/cnsis').respond(200, items); $httpBackend.when('GET', '/pp/v1/cnsis/registered').respond(200, items);