diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js index fcfb27ee..46dc370d 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.js @@ -22,6 +22,9 @@ .controller('HealthMonitorDetailController', HealthMonitorDetailController); HealthMonitorDetailController.$inject = [ + '$timeout', + 'horizon.dashboard.project.lbaasv2.events', + '$scope', 'loadbalancer', 'listener', 'pool', @@ -40,6 +43,9 @@ * @description * Controller for the LBaaS v2 health monitor detail page. * + * @param $timeout The angular timeout object. + * @param events The LBaaS v2 events object. + * @param $scope The angular scope object. * @param loadbalancer The loadbalancer object. * @param listener The listener object. * @param pool The pool object. @@ -54,7 +60,8 @@ */ function HealthMonitorDetailController( - loadbalancer, listener, pool, healthmonitor, loadBalancersService, + $timeout, events, + $scope, loadbalancer, listener, pool, healthmonitor, loadBalancersService, resourceType, typeRegistry, spinnerService, $q ) { var ctrl = this; @@ -78,6 +85,33 @@ ctrl.resultHandler = actionResultHandler; + $scope.$watch( + function() { + return ctrl.healthmonitor; + }, + function() { + $timeout.cancel($scope.loadTimeout); + $scope.loadTimeout = $timeout(function() { + ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier); + ctrl.context.loadPromise.then(loadData); + }, loadBalancersService.backoff.duration()); + } + ); + + $scope.$on( + events.ACTION_DONE, + function() { + loadBalancersService.backoff.reset(); + } + ); + + $scope.$on( + '$destroy', + function() { + $timeout.cancel($scope.loadTimeout); + } + ); + function actionResultHandler(returnValue) { return $q.when(returnValue, actionSuccessHandler); } diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js index f9237fc1..99a666b1 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.controller.spec.js @@ -52,7 +52,7 @@ loadbalancer: { id: '123' }, listener: {}, pool: { id: '123' }, - healthmonitor: { id: '123' }, + healthmonitor: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -65,7 +65,7 @@ loadbalancer: { id: '123' }, listener: { id: '123' }, pool: { id: '123' }, - healthmonitor: { id: '123' }, + healthmonitor: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -83,6 +83,30 @@ expect(ctrl.healthmonitor).toBeDefined(); }); + describe('data watchers', function() { + + var events, loadBalancersService; + beforeEach(inject(function($injector) { + events = $injector.get('horizon.dashboard.project.lbaasv2.events'); + loadBalancersService = $injector.get( + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' + ); + })); + + it('should refresh on provisioning status change', function() { + var loadFunctionDeferred = $q.defer(); + spyOn(ctrl.resourceType, 'load').and.returnValue(loadFunctionDeferred.promise); + ctrl.healthmonitor = { id: '123', provisioning_status: 'PENDING_UPDATE' }; + scope.$apply(); + $timeout.flush(); + expect(ctrl.resourceType.load).toHaveBeenCalled(); + spyOn(loadBalancersService.backoff, 'reset').and.callThrough(); + scope.$broadcast(events.ACTION_DONE); + expect(loadBalancersService.backoff.reset).toHaveBeenCalled(); + }); + + }); + describe('resultHandler', function() { it('handles empty results', function() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html index cd741cab..024170c7 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/details/detail.html @@ -7,7 +7,7 @@ - +
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.controller.js index b120648f..9edbb72b 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.controller.js @@ -21,6 +21,9 @@ .controller('L7PolicyDetailController', L7PolicyDetailController); L7PolicyDetailController.$inject = [ + '$timeout', + 'horizon.dashboard.project.lbaasv2.events', + '$scope', 'loadbalancer', 'listener', 'l7policy', @@ -38,6 +41,9 @@ * @description * Controller for the LBaaS v2 l7policy detail page. * + * @param $timeout The angular timeout object. + * @param events The LBaaS v2 events object. + * @param $scope The angular scope object. * @param loadbalancer The loadbalancer object. * @param listener The listener object. * @param l7policy The l7policy object. @@ -51,7 +57,8 @@ */ function L7PolicyDetailController( - loadbalancer, listener, l7policy, loadBalancersService, + $timeout, events, + $scope, loadbalancer, listener, l7policy, loadBalancersService, resourceType, typeRegistry, spinnerService, $q ) { var ctrl = this; @@ -73,6 +80,34 @@ ctrl.resultHandler = actionResultHandler; + $scope.$watch( + function() { + return ctrl.l7policy; + }, + function() { + $timeout.cancel($scope.loadTimeout); + $scope.loadTimeout = $timeout(function() { + ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier); + ctrl.context.loadPromise.then(loadData); + }, loadBalancersService.backoff.duration()); + } + ); + + $scope.$on( + events.ACTION_DONE, + function() { + loadBalancersService.backoff.reset(); + ctrl.l7policy = angular.copy(ctrl.l7policy); + } + ); + + $scope.$on( + '$destroy', + function() { + $timeout.cancel($scope.loadTimeout); + } + ); + function actionResultHandler(returnValue) { return $q.when(returnValue, actionSuccessHandler); } @@ -84,6 +119,11 @@ ctrl.l7policy = response.data; ctrl.l7policy.loadbalancerId = ctrl.loadbalancer.id; ctrl.l7policy.listenerId = ctrl.listener.id; + ctrl.listFunctionExtraParams = { + loadbalancerId: ctrl.loadbalancer.id, + listenerId: ctrl.listener.id, + l7policyId: ctrl.l7policy.id + }; } function actionSuccessHandler(result) { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.controller.spec.js index 92caada1..5e40decc 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.controller.spec.js @@ -50,7 +50,7 @@ $scope: scope, loadbalancer: { id: '123' }, listener: { id: '123' }, - l7policy: { id: '123' }, + l7policy: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -67,6 +67,30 @@ expect(ctrl.l7policy).toBeDefined(); }); + describe('data watchers', function() { + + var events, loadBalancersService; + beforeEach(inject(function($injector) { + events = $injector.get('horizon.dashboard.project.lbaasv2.events'); + loadBalancersService = $injector.get( + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' + ); + })); + + it('should refresh on provisioning status change', function() { + var loadFunctionDeferred = $q.defer(); + spyOn(ctrl.resourceType, 'load').and.returnValue(loadFunctionDeferred.promise); + ctrl.l7policy = { id: '123', provisioning_status: 'PENDING_UPDATE' }; + scope.$apply(); + $timeout.flush(); + expect(ctrl.resourceType.load).toHaveBeenCalled(); + spyOn(loadBalancersService.backoff, 'reset').and.callThrough(); + scope.$broadcast(events.ACTION_DONE); + expect(loadBalancersService.backoff.reset).toHaveBeenCalled(); + }); + + }); + describe('resultHandler', function() { it('handles empty results', function() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.html index b7ce90cf..d6e1ac8c 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/l7policies/details/detail.html @@ -5,14 +5,14 @@ - +
  • Action - {$ ::ctrl.l7policy.action | decode:ctrl.l7policyAction $} + {$ ctrl.l7policy.action | decode:ctrl.l7policyAction $}
  • Operating Status diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.controller.js index d1f4e09f..38185e88 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.controller.js @@ -21,6 +21,9 @@ .controller('L7RuleDetailController', L7RuleDetailController); L7RuleDetailController.$inject = [ + '$timeout', + 'horizon.dashboard.project.lbaasv2.events', + '$scope', 'loadbalancer', 'listener', 'l7policy', @@ -39,6 +42,9 @@ * @description * Controller for the LBaaS v2 l7rule detail page. * + * @param $timeout The angular timeout object. + * @param events The LBaaS v2 events object. + * @param $scope The angular scope object. * @param loadbalancer The loadbalancer object. * @param listener The listener object. * @param l7policy The l7policy object. @@ -53,7 +59,8 @@ */ function L7RuleDetailController( - loadbalancer, listener, l7policy, l7rule, loadBalancersService, + $timeout, events, + $scope, loadbalancer, listener, l7policy, l7rule, loadBalancersService, resourceType, typeRegistry, spinnerService, $q ) { var ctrl = this; @@ -79,6 +86,36 @@ ctrl.resultHandler = actionResultHandler; + $scope.$watch( + function() { + return ctrl.l7rule; + }, + function() { + $timeout.cancel($scope.loadTimeout); + $scope.loadTimeout = $timeout(function() { + ctrl.context.loadPromise = ctrl.resourceType.load( + ctrl.context.l7policyId, + ctrl.context.l7ruleId + ); + ctrl.context.loadPromise.then(loadData); + }, loadBalancersService.backoff.duration()); + } + ); + + $scope.$on( + events.ACTION_DONE, + function() { + loadBalancersService.backoff.reset(); + } + ); + + $scope.$on( + '$destroy', + function() { + $timeout.cancel($scope.loadTimeout); + } + ); + function actionResultHandler(returnValue) { return $q.when(returnValue, actionSuccessHandler); } diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.controller.spec.js index e37e256c..7e50a1af 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.controller.spec.js @@ -51,7 +51,7 @@ loadbalancer: { id: '123' }, listener: { id: '123' }, l7policy: { id: '123' }, - l7rule: { id: '123' }, + l7rule: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -69,6 +69,30 @@ expect(ctrl.l7rule).toBeDefined(); }); + describe('data watchers', function() { + + var events, loadBalancersService; + beforeEach(inject(function($injector) { + events = $injector.get('horizon.dashboard.project.lbaasv2.events'); + loadBalancersService = $injector.get( + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' + ); + })); + + it('should refresh on provisioning status change', function() { + var loadFunctionDeferred = $q.defer(); + spyOn(ctrl.resourceType, 'load').and.returnValue(loadFunctionDeferred.promise); + ctrl.l7rule = { id: '123', provisioning_status: 'PENDING_UPDATE' }; + scope.$apply(); + $timeout.flush(); + expect(ctrl.resourceType.load).toHaveBeenCalled(); + spyOn(loadBalancersService.backoff, 'reset').and.callThrough(); + scope.$broadcast(events.ACTION_DONE); + expect(loadBalancersService.backoff.reset).toHaveBeenCalled(); + }); + + }); + describe('resultHandler', function() { it('handles empty results', function() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.html index 97368df7..a60bc046 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/l7rules/details/detail.html @@ -13,7 +13,7 @@
    • Type - {$ ::ctrl.l7rule.type | decode:ctrl.l7ruleType $} + {$ ctrl.l7rule.type | decode:ctrl.l7ruleType $}
    • Operating Status diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js index e10aa289..25237bfe 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.js @@ -52,6 +52,7 @@ .constant('horizon.dashboard.project.lbaasv2.popovers', { ipAddresses: '
      • {$ addr.ip $}
      ' }) + .constant('horizon.dashboard.project.lbaasv2.events', events()) .run(['$rootScope', '$location', function ($rootScope, $location) { $rootScope.$on('$routeChangeError', function() { $location.path('project/load_balancer'); @@ -64,6 +65,12 @@ '$routeProvider' ]; + function events() { + return { + ACTION_DONE: 'horizon.dashboard.project.lbaasv2.ACTION_DONE' + }; + } + function config($provide, $windowProvider, $routeProvider) { var basePath = $windowProvider.$get().STATIC_URL + 'dashboard/project/lbaasv2/'; $provide.constant('horizon.dashboard.project.lbaasv2.basePath', basePath); @@ -81,7 +88,9 @@ $routeProvider .when(loadbalancers, { - templateUrl: basePath + 'loadbalancers/panel.html' + templateUrl: basePath + 'loadbalancers/panel.html', + controller: 'PanelController', + controllerAs: 'ctrl' }) .when(loadbalancers + '/:loadbalancerId', { templateUrl: basePath + 'loadbalancers/details/detail.html', diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js index 45e53f16..1c38d34b 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/lbaasv2.module.spec.js @@ -88,7 +88,7 @@ }); describe('LBaaS v2 Module Config', function () { - var $routeProvider, basePath; + var $routeProvider, basePath; // eslint-disable-line no-unused-vars beforeEach(function() { // Create a dummy module so that we can test $routeProvider calls in our actual @@ -105,18 +105,16 @@ inject(); }); - it('should route to loadbalancer panel', function () { - var loadbalancers = '/project/load_balancer'; - var routes = [[ - loadbalancers, { - templateUrl: basePath + 'loadbalancers/panel.html' - } - ]]; - - routes.forEach(function(route) { - expect($routeProvider.when).toHaveBeenCalledWith(route[0], route[1]); - }); - }); + it('should route resolved loadbalancer panel', + inject(function($route, $location, $rootScope, $httpBackend) { + $httpBackend.expectGET( + '/static/dashboard/project/lbaasv2/loadbalancers/panel.html' + ).respond({}); + $location.path('/project/load_balancer/'); + $rootScope.$digest(); + expect($route.current).toBeDefined(); + }) + ); it('should route resolved loadbalancer detail', inject(function($injector) { function loadbalancerAPI() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.js index f799cc38..337040dc 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.js @@ -22,6 +22,9 @@ .controller('ListenerDetailController', ListenerDetailController); ListenerDetailController.$inject = [ + '$timeout', + 'horizon.dashboard.project.lbaasv2.events', + '$scope', 'loadbalancer', 'listener', 'horizon.dashboard.project.lbaasv2.loadbalancers.service', @@ -38,6 +41,7 @@ * @description * Controller for the LBaaS v2 listener detail page. * + * @param $scope The angular scope object. * @param loadbalancer The loadbalancer object. * @param listener The listener object. * @param loadBalancersService The LBaaS v2 load balancers service. @@ -50,7 +54,8 @@ */ function ListenerDetailController( - loadbalancer, listener, loadBalancersService, resourceType, typeRegistry, + $timeout, events, + $scope, loadbalancer, listener, loadBalancersService, resourceType, typeRegistry, spinnerService, $q ) { var ctrl = this; @@ -69,6 +74,34 @@ ctrl.resultHandler = actionResultHandler; + $scope.$watch( + function() { + return ctrl.listener; + }, + function() { + $timeout.cancel($scope.loadTimeout); + $scope.loadTimeout = $timeout(function() { + ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier); + ctrl.context.loadPromise.then(loadData); + }, loadBalancersService.backoff.duration()); + } + ); + + $scope.$on( + events.ACTION_DONE, + function() { + loadBalancersService.backoff.reset(); + ctrl.listener = angular.copy(ctrl.listener); + } + ); + + $scope.$on( + '$destroy', + function() { + $timeout.cancel($scope.loadTimeout); + } + ); + function actionResultHandler(returnValue) { return $q.when(returnValue, actionSuccessHandler); } @@ -79,6 +112,10 @@ ctrl.resourceType.initActions(); ctrl.listener = response.data; ctrl.listener.loadbalancerId = ctrl.loadbalancer.id; + ctrl.listFunctionExtraParams = { + loadbalancerId: ctrl.loadbalancer.id, + listenerId: ctrl.listener.id + }; } function actionSuccessHandler(result) { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.spec.js index cb8c16c2..31e5d57f 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.controller.spec.js @@ -50,7 +50,7 @@ ctrl = $controller('ListenerDetailController', { $scope: scope, loadbalancer: { id: '123' }, - listener: { id: '123' }, + listener: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -66,6 +66,30 @@ expect(ctrl.listener).toBeDefined(); }); + describe('data watchers', function() { + + var events, loadBalancersService; + beforeEach(inject(function($injector) { + events = $injector.get('horizon.dashboard.project.lbaasv2.events'); + loadBalancersService = $injector.get( + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' + ); + })); + + it('should refresh on provisioning status change', function() { + var loadFunctionDeferred = $q.defer(); + spyOn(ctrl.resourceType, 'load').and.returnValue(loadFunctionDeferred.promise); + ctrl.listener = { id: '123', provisioning_status: 'PENDING_UPDATE' }; + scope.$apply(); + $timeout.flush(); + expect(ctrl.resourceType.load).toHaveBeenCalled(); + spyOn(loadBalancersService.backoff, 'reset').and.callThrough(); + scope.$broadcast(events.ACTION_DONE); + expect(loadBalancersService.backoff.reset).toHaveBeenCalled(); + }); + + }); + describe('resultHandler', function() { it('handles empty results', function() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.html index 9346712d..c396c9ac 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/details/detail.html @@ -4,7 +4,7 @@
    • - +
      diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.js index 74c97675..d6108ffb 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.js @@ -22,6 +22,9 @@ .controller('LoadBalancerDetailController', LoadBalancerDetailController); LoadBalancerDetailController.$inject = [ + '$timeout', + 'horizon.dashboard.project.lbaasv2.events', + '$scope', 'loadbalancer', 'horizon.dashboard.project.lbaasv2.loadbalancers.service', 'horizon.dashboard.project.lbaasv2.loadbalancers.resourceType', @@ -37,6 +40,9 @@ * @description * Controller for the LBaaS v2 load balancers detail page. * + * @param $timeout The angular timeout object. + * @param events The LBaaS v2 events object. + * @param $scope The angular scope object. * @param loadbalancer The loadbalancer object. * @param loadBalancersService The LBaaS v2 load balancers service. * @param resourceType The load balancer resource type. @@ -48,8 +54,9 @@ */ function LoadBalancerDetailController( - loadbalancer, loadBalancersService, resourceType, typeRegistry, - spinnerService, $q + $timeout, events, + $scope, loadbalancer, loadBalancersService, + resourceType, typeRegistry, spinnerService, $q ) { var ctrl = this; @@ -65,6 +72,34 @@ ctrl.resultHandler = actionResultHandler; + $scope.$watch( + function() { + return ctrl.loadbalancer; + }, + function() { + $timeout.cancel($scope.loadTimeout); + $scope.loadTimeout = $timeout(function() { + ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier); + ctrl.context.loadPromise.then(loadData); + }, loadBalancersService.backoff.duration()); + } + ); + + $scope.$on( + events.ACTION_DONE, + function() { + loadBalancersService.backoff.reset(); + ctrl.loadbalancer = angular.copy(ctrl.loadbalancer); + } + ); + + $scope.$on( + '$destroy', + function() { + $timeout.cancel($scope.loadTimeout); + } + ); + function actionResultHandler(returnValue) { return $q.when(returnValue, actionSuccessHandler); } @@ -75,6 +110,9 @@ ctrl.resourceType.initActions(); ctrl.loadbalancer = response.data; ctrl.loadbalancer.floating_ip_address = response.data.floating_ip.ip; + ctrl.listFunctionExtraParams = { + loadbalancerId: ctrl.loadbalancer.id + }; } function actionSuccessHandler(result) { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.spec.js index 50e415a5..67b444e3 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/details/detail.controller.spec.js @@ -49,7 +49,7 @@ scope = $rootScope.$new(); ctrl = $controller('LoadBalancerDetailController', { $scope: scope, - loadbalancer: { id: '123' }, + loadbalancer: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -64,6 +64,30 @@ expect(ctrl.loadbalancer).toBeDefined(); }); + describe('data watchers', function() { + + var events, loadBalancersService; + beforeEach(inject(function($injector) { + events = $injector.get('horizon.dashboard.project.lbaasv2.events'); + loadBalancersService = $injector.get( + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' + ); + })); + + it('should refresh on provisioning status change', function() { + var loadFunctionDeferred = $q.defer(); + spyOn(ctrl.resourceType, 'load').and.returnValue(loadFunctionDeferred.promise); + ctrl.loadbalancer = { id: '123', provisioning_status: 'PENDING_UPDATE' }; + scope.$apply(); + $timeout.flush(); + expect(ctrl.resourceType.load).toHaveBeenCalled(); + spyOn(loadBalancersService.backoff, 'reset').and.callThrough(); + scope.$broadcast(events.ACTION_DONE); + expect(loadBalancersService.backoff.reset).toHaveBeenCalled(); + }); + + }); + describe('resultHandler', function() { it('handles empty results', function() { @@ -97,7 +121,7 @@ var result = $q.defer(); result.resolve({some: 'thing', failed: [], deleted: [{id: 1}]}); ctrl.resultHandler(result.promise); - deferred.resolve({data: {some: 'data'}}); + deferred.resolve({data: {some: 'data', floating_ip: {}}}); $timeout.flush(); expect(ctrl.showDetails).toBe(undefined); }); diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js index 1302e1d1..a00f8488 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/loadbalancers.service.js @@ -90,6 +90,27 @@ null: gettext('None') }; + var backoff = (function() { + var min = 250; + var max = 5000; + var factor = 2; + var attempts = 0; + + function duration() { + var ms = min * Math.pow(factor, attempts++); + return Math.min(ms, max) | 0; + } + + function reset() { + attempts = 0; + } + + return { + duration: duration, + reset: reset + }; + }()); + var service = { operatingStatus: operatingStatus, provisioningStatus: provisioningStatus, @@ -120,7 +141,8 @@ getHealthMonitorPromise: getHealthMonitorPromise, getHealthMonitorsPromise: getHealthMonitorsPromise, getHealthMonitorDetailsPath: getHealthMonitorDetailsPath, - isActionable: isActionable + isActionable: isActionable, + backoff: backoff }; return service; diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.controller.js new file mode 100644 index 00000000..7fa76cee --- /dev/null +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.controller.js @@ -0,0 +1,79 @@ +/* + * Copyright 2018 Walmart. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +(function() { + 'use strict'; + + angular + .module('horizon.dashboard.project.lbaasv2.loadbalancers') + .controller('PanelController', PanelController); + + PanelController.$inject = [ + '$scope', + '$timeout', + 'horizon.dashboard.project.lbaasv2.loadbalancers.service', + 'horizon.dashboard.project.lbaasv2.events' + ]; + + /** + * @ngdoc controller + * @name PanelController + * + * @description + * Controller for the LBaaS v2 load balancers panel. + * + * @param $scope The angular scope object. + * @param $timeout The angular timeout object. + * @param loadBalancersService The LBaaS v2 load balancers service. + * @param events The LBaaS v2 events object. + * @returns undefined + */ + + function PanelController( + $scope, $timeout, loadBalancersService, events + ) { + var ctrl = this; + + ctrl.listFunctionExtraParams = {}; + + $scope.$watch( + function() { + return ctrl.listFunctionExtraParams; + }, + function() { + $timeout.cancel($scope.listTimeout); + $scope.listTimeout = $timeout(function () { + ctrl.listFunctionExtraParams = angular.copy(ctrl.listFunctionExtraParams); + }, loadBalancersService.backoff.duration()); + } + ); + + $scope.$on( + events.ACTION_DONE, + function() { + loadBalancersService.backoff.reset(); + ctrl.listFunctionExtraParams = angular.copy(ctrl.listFunctionExtraParams); + } + ); + + $scope.$on( + '$destroy', + function() { + $timeout.cancel($scope.listTimeout); + } + ); + } + +})(); diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.controller.spec.js new file mode 100644 index 00000000..1cb10f3a --- /dev/null +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.controller.spec.js @@ -0,0 +1,66 @@ +/* + * Copyright 2018 Walmart. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +(function() { + 'use strict'; + + describe('LBaaS v2 Load Balancer Panel Controller', function() { + var ctrl, scope, $timeout; + + /////////////////////// + + beforeEach(module('horizon.dashboard.project.lbaasv2')); + + beforeEach(module(function($provide) { + $provide.value('$uibModal', {}); + })); + + beforeEach(inject(function($controller, $rootScope, _$timeout_) { + $timeout = _$timeout_; + scope = $rootScope.$new(); + ctrl = $controller('PanelController', { + $scope: scope + }); + })); + + it('should create a controller', function() { + expect(ctrl).toBeDefined(); + expect(ctrl.listFunctionExtraParams).toBeDefined(); + }); + + describe('data watchers', function() { + + var events, loadBalancersService; + beforeEach(inject(function($injector) { + events = $injector.get('horizon.dashboard.project.lbaasv2.events'); + loadBalancersService = $injector.get( + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' + ); + })); + + it('should refresh on provisioning status change', function() { + ctrl.listFunctionExtraParams = {}; + scope.$apply(); + $timeout.flush(); + spyOn(loadBalancersService.backoff, 'reset').and.callThrough(); + scope.$broadcast(events.ACTION_DONE); + expect(loadBalancersService.backoff.reset).toHaveBeenCalled(); + }); + + }); + + }); + +})(); diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.html b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.html index aef6fa49..2d4ab5c7 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/panel.html @@ -5,5 +5,5 @@ + track-by="trackBy" list-function-extra-params="ctrl.listFunctionExtraParams"> diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.js index c811f1fd..6c74fa0d 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.service.js @@ -23,6 +23,8 @@ modalService); modalService.$inject = [ + '$rootScope', + 'horizon.dashboard.project.lbaasv2.events', 'horizon.dashboard.project.lbaasv2.members.resourceType', 'horizon.framework.util.actions.action-result.service', '$uibModal', @@ -39,6 +41,8 @@ * @description * Provides the service for the pool member Edit Member action. * + * @param $rootScope The angular root scope object. + * @param events The LBaaS v2 events object. * @param resourceType The member resource type. * @param actionResultService The horizon action result service. * @param $uibModal The angular bootstrap $uibModal service. @@ -51,6 +55,7 @@ */ function modalService( + $rootScope, events, resourceType, actionResultService, $uibModal, @@ -107,6 +112,7 @@ function onModalClose() { toastService.add('success', gettext('Pool member has been updated.')); + $rootScope.$broadcast(events.ACTION_DONE); return actionResultService.getActionResult() .updated(resourceType, member.id) .result; diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js index cad2730a..cef03b5f 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.js @@ -22,6 +22,9 @@ .controller('MemberDetailController', MemberDetailController); MemberDetailController.$inject = [ + '$timeout', + 'horizon.dashboard.project.lbaasv2.events', + '$scope', 'loadbalancer', 'listener', 'pool', @@ -40,6 +43,9 @@ * @description * Controller for the LBaaS v2 member detail page. * + * @param $timeout The angular timeout object. + * @param events The LBaaS v2 events object. + * @param $scope The angular scope object. * @param loadbalancer The loadbalancer object. * @param listener The listener object. * @param pool The pool object. @@ -54,7 +60,8 @@ */ function MemberDetailController( - loadbalancer, listener, pool, member, loadBalancersService, + $timeout, events, + $scope, loadbalancer, listener, pool, member, loadBalancersService, resourceType, typeRegistry, spinnerService, $q ) { var ctrl = this; @@ -79,6 +86,36 @@ ctrl.resultHandler = actionResultHandler; + $scope.$watch( + function() { + return ctrl.member; + }, + function() { + $timeout.cancel($scope.loadTimeout); + $scope.loadTimeout = $timeout(function() { + ctrl.context.loadPromise = ctrl.resourceType.load( + ctrl.context.poolId, + ctrl.context.memberId + ); + ctrl.context.loadPromise.then(loadData); + }, loadBalancersService.backoff.duration()); + } + ); + + $scope.$on( + events.ACTION_DONE, + function() { + loadBalancersService.backoff.reset(); + } + ); + + $scope.$on( + '$destroy', + function() { + $timeout.cancel($scope.loadTimeout); + } + ); + function actionResultHandler(returnValue) { return $q.when(returnValue, actionSuccessHandler); } diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js index dee5d627..7c4ccd50 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.controller.spec.js @@ -65,7 +65,7 @@ loadbalancer: { id: '123' }, listener: { id: '123' }, pool: { id: '123' }, - member: { id: '123' }, + member: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -83,6 +83,30 @@ expect(ctrl.member).toBeDefined(); }); + describe('data watchers', function() { + + var events, loadBalancersService; + beforeEach(inject(function($injector) { + events = $injector.get('horizon.dashboard.project.lbaasv2.events'); + loadBalancersService = $injector.get( + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' + ); + })); + + it('should refresh on provisioning status change', function() { + var loadFunctionDeferred = $q.defer(); + spyOn(ctrl.resourceType, 'load').and.returnValue(loadFunctionDeferred.promise); + ctrl.member = { id: '123', provisioning_status: 'PENDING_UPDATE' }; + scope.$apply(); + $timeout.flush(); + expect(ctrl.resourceType.load).toHaveBeenCalled(); + spyOn(loadBalancersService.backoff, 'reset').and.callThrough(); + scope.$broadcast(events.ACTION_DONE); + expect(loadBalancersService.backoff.reset).toHaveBeenCalled(); + }); + + }); + describe('resultHandler', function() { it('handles empty results', function() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html index 3309fc46..11d5f27c 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/details/detail.html @@ -7,7 +7,7 @@ - +
      diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js index b11bdb8d..1c69cd5c 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.js @@ -22,6 +22,9 @@ .controller('PoolDetailController', PoolDetailController); PoolDetailController.$inject = [ + '$timeout', + 'horizon.dashboard.project.lbaasv2.events', + '$scope', 'loadbalancer', 'listener', 'pool', @@ -39,6 +42,9 @@ * @description * Controller for the LBaaS v2 pool detail page. * + * @param $timeout The angular timeout object. + * @param events The LBaaS v2 events object. + * @param $scope The angular scope object. * @param loadbalancer The loadbalancer object. * @param listener The listener object. * @param pool The pool object. @@ -52,7 +58,8 @@ */ function PoolDetailController( - loadbalancer, listener, pool, loadBalancersService, + $timeout, events, + $scope, loadbalancer, listener, pool, loadBalancersService, resourceType, typeRegistry, spinnerService, $q ) { var ctrl = this; @@ -79,6 +86,34 @@ ctrl.resultHandler = actionResultHandler; + $scope.$watch( + function() { + return ctrl.pool; + }, + function() { + $timeout.cancel($scope.loadTimeout); + $scope.loadTimeout = $timeout(function() { + ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier); + ctrl.context.loadPromise.then(loadData); + }, loadBalancersService.backoff.duration()); + } + ); + + $scope.$on( + events.ACTION_DONE, + function() { + loadBalancersService.backoff.reset(); + ctrl.pool = angular.copy(ctrl.pool); + } + ); + + $scope.$on( + '$destroy', + function() { + $timeout.cancel($scope.loadTimeout); + } + ); + function actionResultHandler(returnValue) { return $q.when(returnValue, actionSuccessHandler); } @@ -90,6 +125,11 @@ ctrl.pool = response.data; ctrl.pool.loadbalancerId = ctrl.loadbalancer.id; ctrl.pool.listenerId = ctrl.listener.id; + ctrl.listFunctionExtraParams = { + loadbalancerId: ctrl.loadbalancer.id, + listenerId: ctrl.listener.id, + poolId: ctrl.pool.id + }; } function actionSuccessHandler(result) { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js index e2e4210f..423280bc 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.controller.spec.js @@ -51,7 +51,7 @@ $scope: scope, loadbalancer: { id: '123' }, listener: {}, - pool: { id: '123' }, + pool: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -63,7 +63,7 @@ $scope: scope, loadbalancer: { id: '123' }, listener: { id: '123' }, - pool: { id: '123' }, + pool: { id: '123', provisioning_status: 'ACTIVE' }, 'horizon.framework.conf.resource-type-registry.service': service, 'horizon.framework.util.actions.action-result.service': actionResultService, 'horizon.framework.widgets.modal-wait-spinner.service': { @@ -80,6 +80,30 @@ expect(ctrl.pool).toBeDefined(); }); + describe('data watchers', function() { + + var events, loadBalancersService; + beforeEach(inject(function($injector) { + events = $injector.get('horizon.dashboard.project.lbaasv2.events'); + loadBalancersService = $injector.get( + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' + ); + })); + + it('should refresh on provisioning status change', function() { + var loadFunctionDeferred = $q.defer(); + spyOn(ctrl.resourceType, 'load').and.returnValue(loadFunctionDeferred.promise); + ctrl.pool = { id: '123', provisioning_status: 'PENDING_UPDATE' }; + scope.$apply(); + $timeout.flush(); + expect(ctrl.resourceType.load).toHaveBeenCalled(); + spyOn(loadBalancersService.backoff, 'reset').and.callThrough(); + scope.$broadcast(events.ACTION_DONE); + expect(loadBalancersService.backoff.reset).toHaveBeenCalled(); + }); + + }); + describe('resultHandler', function() { it('handles empty results', function() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html index cb18e180..1b57f3d4 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/details/detail.html @@ -5,7 +5,7 @@ - +
      @@ -16,7 +16,7 @@
    • Algorithm - {$ ::ctrl.pool.lb_algorithm | decode:ctrl.loadBalancerAlgorithm $} + {$ ctrl.pool.lb_algorithm | decode:ctrl.loadBalancerAlgorithm $}
    • Operating Status diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/modal.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/modal.service.js index 6ead2e02..11364f4f 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/modal.service.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/modal.service.js @@ -21,6 +21,8 @@ .factory('horizon.dashboard.project.lbaasv2.workflow.modal', modalService); modalService.$inject = [ + '$rootScope', + 'horizon.dashboard.project.lbaasv2.events', '$uibModal', 'horizon.framework.widgets.toast.service' ]; @@ -32,12 +34,14 @@ * @description * Provides the service for opening the LBaaS create / edit modal. * + * @param $rootScope The angular root scope object. + * @param events The LBaaS v2 events object. * @param $uibModal The angular bootstrap $uibModal service. * @param toastService The horizon toast service. * @returns The modal service for the LBaaS workflow. */ - function modalService($uibModal, toastService) { + function modalService($rootScope, events, $uibModal, toastService) { var service = { init: init @@ -100,6 +104,7 @@ function onModalClose(response) { toastService.add('success', args.message); if (args.handle) { + $rootScope.$broadcast(events.ACTION_DONE); return args.handle(response); } } diff --git a/releasenotes/notes/auto-refresh-detail-pages-26166d5d9c26edee.yaml b/releasenotes/notes/auto-refresh-detail-pages-26166d5d9c26edee.yaml new file mode 100644 index 00000000..edf40b20 --- /dev/null +++ b/releasenotes/notes/auto-refresh-detail-pages-26166d5d9c26edee.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Adds the ability to auto refresh detail pages upon action.