Commit 85029d2d authored by Zuul's avatar Zuul Committed by Gerrit Code Review

Merge "Allow detail pages to auto refresh upon action"

parents 9a4c7523 bb0cb864
......@@ -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);
}
......
......@@ -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() {
......
......@@ -7,7 +7,7 @@
<li class="breadcrumb-item-truncate" ng-style="ctrl.withListenerStyle"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}/listeners/{$ :: ctrl.listener.id $}">{$ :: (ctrl.listener.name || ctrl.listener.id) $}</a></li>
<li class="breadcrumb-item-truncate" ng-style="ctrl.withListenerStyle"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}/listeners/{$ :: ctrl.listener.id $}/pools/{$ ::ctrl.pool.id $}">{$ ::(ctrl.pool.name || ctrl.pool.id) $}</a></li>
<li class="breadcrumb-item-truncate" ng-style="ctrl.withoutListenerStyle"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}/pools/{$ ::ctrl.pool.id $}">{$ ::(ctrl.pool.name || ctrl.pool.id) $}</a></li>
<li class="breadcrumb-item-truncate active">{$ ::(ctrl.healthmonitor.name || ctrl.healthmonitor.id) $}</li>
<li class="breadcrumb-item-truncate active">{$ (ctrl.healthmonitor.name || ctrl.healthmonitor.id) $}</li>
</ol>
<div class="row">
<div class="col-xs-12 col-sm-9 text-left">
......
......@@ -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) {
......
......@@ -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() {
......
......@@ -5,14 +5,14 @@
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/"><translate>Load Balancers</translate></a></li>
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}">{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</a></li>
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}/listeners/{$ ::ctrl.listener.id $}">{$ ::(ctrl.listener.name || ctrl.listener.id) $}</a></li>
<li class="breadcrumb-item-truncate active">{$ ::(ctrl.l7policy.name || ctrl.l7policy.id) $}</li>
<li class="breadcrumb-item-truncate active">{$ (ctrl.l7policy.name || ctrl.l7policy.id) $}</li>
</ol>
<div class="row">
<div class="col-xs-12 col-sm-9 text-left">
<ul class="list-inline">
<li>
<strong translate>Action</strong>
{$ ::ctrl.l7policy.action | decode:ctrl.l7policyAction $}
{$ ctrl.l7policy.action | decode:ctrl.l7policyAction $}
</li>
<li>
<strong translate>Operating Status</strong>
......
......@@ -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);
}
......
......@@ -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() {
......
......@@ -13,7 +13,7 @@
<ul class="list-inline">
<li>
<strong translate>Type</strong>
{$ ::ctrl.l7rule.type | decode:ctrl.l7ruleType $}
{$ ctrl.l7rule.type | decode:ctrl.l7ruleType $}
</li>
<li>
<strong translate>Operating Status</strong>
......
......@@ -52,6 +52,7 @@
.constant('horizon.dashboard.project.lbaasv2.popovers', {
ipAddresses: '<ul><li ng-repeat="addr in member.addresses">{$ addr.ip $}</li></ul>'
})
.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',
......
......@@ -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() {
......
......@@ -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) {
......
......@@ -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() {
......
......@@ -4,7 +4,7 @@
<li class="breadcrumb-item-truncate"><translate>Network</translate></li>
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/"><translate>Load Balancers</translate></a></li>
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}">{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</a></li>
<li class="breadcrumb-item-truncate active">{$ ::(ctrl.listener.name || ctrl.listener.id) $}</li>
<li class="breadcrumb-item-truncate active">{$ (ctrl.listener.name || ctrl.listener.id) $}</li>
</ol>
<div class="row">
<div class="col-xs-12 col-sm-9 text-left">
......
......@@ -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) {
......
......@@ -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'
);