Add routing and load balancer detail page
This adds the routing to allow navigating between angular pages as well as the beginning of the load balancer detail page. The detail page is very basic but is based on both the existing angular Images detail page and the designs from invision. It includes two empty tabs that will eventually hold the tables for Pools and Members. Partially-Implements: blueprint horizon-lbaas-v2-ui Change-Id: Icbf4396238036b20712ca643e635dd84fe66a86e
This commit is contained in:
parent
75fc881f7f
commit
3d99fc5544
|
@ -39,3 +39,20 @@ class LoadBalancers(generic.View):
|
|||
tenant_id = request.user.project_id
|
||||
result = neutronclient(request).list_loadbalancers(tenant_id=tenant_id)
|
||||
return {'items': result.get('loadbalancers')}
|
||||
|
||||
|
||||
@urls.register
|
||||
class LoadBalancer(generic.View):
|
||||
"""API for retrieving a single load balancer.
|
||||
|
||||
"""
|
||||
url_regex = r'lbaas/loadbalancers/(?P<loadbalancer_id>[^/]+)/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request, loadbalancer_id):
|
||||
"""Get a specific load balancer.
|
||||
|
||||
http://localhost/api/lbaas/loadbalancers/cc758c90-3d98-4ea1-af44-aab405c9c915
|
||||
"""
|
||||
lb = neutronclient(request).show_loadbalancer(loadbalancer_id)
|
||||
return lb.get('loadbalancer')
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Load Balancers" %}{% endblock %}
|
||||
{% block page_header %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
<hz-page-header header="'{% trans "Load Balancers" %}'"></hz-page-header>
|
||||
{% endblock page_header %}
|
||||
{% block ng_route_base %}
|
||||
<base href="/"></base>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<ng-include src="'{{ STATIC_URL }}dashboard/project/lbaasv2/loadbalancers/table.html'"></ng-include>
|
||||
<div ng-view></div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -20,5 +20,5 @@ from neutron_lbaas_dashboard.dashboards.project.ngloadbalancersv2 import views
|
|||
|
||||
urlpatterns = patterns(
|
||||
'neutron_lbaas_dashboard.dashboards.project.ngloadbalancersv2.views',
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url('', views.IndexView.as_view(), name='index'),
|
||||
)
|
||||
|
|
|
@ -35,6 +35,7 @@ ADD_JS_FILES = [
|
|||
'dashboard/project/lbaasv2/lbaasv2.module.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/table.controller.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/detail.controller.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/filters.js',
|
||||
]
|
||||
|
||||
|
@ -43,9 +44,10 @@ ADD_JS_SPEC_FILES = [
|
|||
'dashboard/project/lbaasv2/lbaasv2.module.spec.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.spec.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/table.controller.spec.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/detail.controller.spec.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/filters.spec.js',
|
||||
]
|
||||
#
|
||||
# ADD_SCSS_FILES = [
|
||||
#
|
||||
# ]
|
||||
|
||||
ADD_SCSS_FILES = [
|
||||
'dashboard/project/lbaasv2/lbaasv2.scss',
|
||||
]
|
||||
|
|
|
@ -69,6 +69,7 @@ module.exports = function (config) {
|
|||
// from jasmine.html
|
||||
xstaticPath + 'jquery/data/jquery.js',
|
||||
xstaticPath + 'angular/data/angular.js',
|
||||
xstaticPath + 'angular/data/angular-route.js',
|
||||
xstaticPath + 'angular/data/angular-mocks.js',
|
||||
xstaticPath + 'angular/data/angular-cookies.js',
|
||||
xstaticPath + 'angular_bootstrap/data/angular-bootstrap.js',
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
*/
|
||||
function lbaasv2API(apiService, toastService) {
|
||||
var service = {
|
||||
getLoadBalancers: getLoadBalancers
|
||||
getLoadBalancers: getLoadBalancers,
|
||||
getLoadBalancer: getLoadBalancer
|
||||
};
|
||||
|
||||
return service;
|
||||
|
@ -56,5 +57,19 @@
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.getLoadBalancer
|
||||
* @description
|
||||
* Get a single load balancer by ID
|
||||
* @param {string} id
|
||||
* Specifies the id of the load balancer to request.
|
||||
*/
|
||||
function getLoadBalancer(id) {
|
||||
return apiService.get('/api/lbaas/loadbalancers/' + id)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve load balancer.'));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}());
|
||||
|
|
|
@ -41,6 +41,15 @@
|
|||
"method": "get",
|
||||
"path": "/api/lbaas/loadbalancers/",
|
||||
"error": "Unable to retrieve load balancers."
|
||||
},
|
||||
{
|
||||
"func": "getLoadBalancer",
|
||||
"method": "get",
|
||||
"path": "/api/lbaas/loadbalancers/1234",
|
||||
"error": "Unable to retrieve load balancer.",
|
||||
"testInput": [
|
||||
'1234'
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -27,6 +27,31 @@
|
|||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2', [
|
||||
'ngRoute',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers'
|
||||
]);
|
||||
])
|
||||
.config(config);
|
||||
|
||||
config.$inject = [
|
||||
'$windowProvider',
|
||||
'$routeProvider',
|
||||
'$locationProvider'
|
||||
];
|
||||
|
||||
function config($windowProvider, $routeProvider, $locationProvider) {
|
||||
$locationProvider.html5Mode({
|
||||
enabled: true
|
||||
}).hashPrefix('!');
|
||||
|
||||
var base = '/project/ngloadbalancersv2/';
|
||||
var path = $windowProvider.$get().STATIC_URL + 'dashboard/project/lbaasv2/';
|
||||
|
||||
$routeProvider
|
||||
.when(base, {
|
||||
templateUrl: path + 'loadbalancers/table.html'
|
||||
})
|
||||
.when(base + 'detail/:loadbalancerId', {
|
||||
templateUrl: path + 'loadbalancers/detail.html'
|
||||
})
|
||||
}
|
||||
}());
|
||||
|
|
|
@ -22,4 +22,52 @@
|
|||
});
|
||||
});
|
||||
|
||||
describe('LBaaS v2 Module Config', function () {
|
||||
var $routeProvider, $locationProvider, path;
|
||||
|
||||
beforeEach(function() {
|
||||
// Create a dummy module so that we can test $routeProvider and $locationProvider calls
|
||||
// in our actual config block.
|
||||
angular.module('configTest', [])
|
||||
.config(function(_$routeProvider_, _$locationProvider_, $windowProvider) {
|
||||
$routeProvider = _$routeProvider_;
|
||||
$locationProvider = _$locationProvider_;
|
||||
path = $windowProvider.$get().STATIC_URL + 'dashboard/project/lbaasv2/';
|
||||
spyOn($routeProvider, 'when').and.callThrough();
|
||||
spyOn($locationProvider, 'html5Mode').and.callThrough();
|
||||
});
|
||||
module('ngRoute')
|
||||
module('configTest');
|
||||
module('horizon.dashboard.project.lbaasv2')
|
||||
inject();
|
||||
});
|
||||
|
||||
it('should use html5 mode', function () {
|
||||
expect($locationProvider.html5Mode).toHaveBeenCalledWith({enabled: true});
|
||||
});
|
||||
|
||||
it('should route URLs', function () {
|
||||
var base = '/ngloadbalancersv2/';
|
||||
var routes = [
|
||||
[
|
||||
base,
|
||||
{
|
||||
templateUrl: path + 'loadbalancers/table.html'
|
||||
}
|
||||
],
|
||||
[
|
||||
base + 'detail/:loadbalancerId',
|
||||
{
|
||||
templateUrl: path + 'loadbalancers/detail.html'
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
expect($routeProvider.when.calls.count()).toBe(2);
|
||||
angular.forEach($routeProvider.when.calls.all(), function(call, i) {
|
||||
expect(call.args).toEqual(routes[i]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@import "/app/app";
|
||||
|
||||
/*
|
||||
* TODO(jpomero): This detail page styling should become common with the following patch:
|
||||
* https://review.openstack.org/158881
|
||||
*/
|
||||
.detail-page {
|
||||
position: relative;
|
||||
|
||||
p {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.detail-statuses {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
div {
|
||||
display: inline;
|
||||
margin-right: 20px;
|
||||
|
||||
> b {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.tab-pane > dl {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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('LoadBalancerDetailController', LoadBalancerDetailController);
|
||||
|
||||
LoadBalancerDetailController.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.basePath',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
'$routeParams'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name LoadBalancerDetailController
|
||||
*
|
||||
* @description
|
||||
* Controller for the LBaaS v2 load balancers detail page.
|
||||
*/
|
||||
function LoadBalancerDetailController(basepath, api, $routeParams) {
|
||||
|
||||
var ctrl = this;
|
||||
ctrl.loadbalancer = {};
|
||||
ctrl.path = basepath;
|
||||
|
||||
var loadbalancerId = $routeParams.loadbalancerId;
|
||||
|
||||
init();
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
function init() {
|
||||
api.getLoadBalancer(loadbalancerId).success(success);
|
||||
}
|
||||
|
||||
function success(response) {
|
||||
ctrl.loadbalancer = response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})();
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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 Detail Controller', function() {
|
||||
var controller, lbaasv2API, staticUrl, loadbalancer;
|
||||
|
||||
function fakeAPI() {
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback(loadbalancer);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
|
||||
beforeEach(module('horizon.framework.util.http'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2.loadbalancers'));
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
loadbalancer = { id: '1234' };
|
||||
lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
|
||||
controller = $injector.get('$controller');
|
||||
staticUrl = $injector.get('$window').STATIC_URL;
|
||||
spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(fakeAPI);
|
||||
}));
|
||||
|
||||
function createController() {
|
||||
return controller('LoadBalancerDetailController', {
|
||||
api: lbaasv2API,
|
||||
$routeParams: { loadbalancerId: '1234' }
|
||||
});
|
||||
}
|
||||
|
||||
it('should set path properly', function() {
|
||||
var path = staticUrl + 'dashboard/project/lbaasv2/loadbalancers/';
|
||||
expect(createController().path).toEqual(path);
|
||||
});
|
||||
|
||||
it('should invoke lbaasv2 apis', function() {
|
||||
createController();
|
||||
expect(lbaasv2API.getLoadBalancer).toHaveBeenCalledWith('1234');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
|
@ -0,0 +1,58 @@
|
|||
<div class="content" ng-controller="LoadBalancerDetailController as ctrl">
|
||||
<div class='page-header'>
|
||||
<h1>{$ ::ctrl.loadbalancer.name $}</h1>
|
||||
<p ng-if="::ctrl.loadbalancer.description">{$ ::ctrl.loadbalancer.description $}</p>
|
||||
</div>
|
||||
<div class="detail-page">
|
||||
<div class="detail-statuses">
|
||||
<div>
|
||||
<strong translate>IP Address</strong>
|
||||
{$ ::ctrl.loadbalancer.vip_address $}
|
||||
</div>
|
||||
<div>
|
||||
<strong translate>Operating Status</strong>
|
||||
{$ ::ctrl.loadbalancer.operating_status | operatingStatus $}
|
||||
</div>
|
||||
<div>
|
||||
<strong translate>Provisioning Status</strong>
|
||||
{$ ::ctrl.loadbalancer.provisioning_status | provisioningStatus $}
|
||||
</div>
|
||||
</div>
|
||||
<tabset>
|
||||
<tab heading="{$ 'Overview' | translate $}">
|
||||
<dl class="dl-horizontal">
|
||||
<div>
|
||||
<dt translate>Provider</dt>
|
||||
<dd>{$ ::ctrl.loadbalancer.provider $}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt translate>Admin State Up</dt>
|
||||
<dd>{$ ::ctrl.loadbalancer.admin_state_up | yesno $}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt translate>Load Balancer ID</dt>
|
||||
<dd>{$ ::ctrl.loadbalancer.id $}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt translate>Subnet ID</dt>
|
||||
<dd>
|
||||
<a ng-href="/project/networks/subnets/{$ ::ctrl.loadbalancer.vip_subnet_id $}/detail">{$ ::ctrl.loadbalancer.vip_subnet_id $}</a>
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt translate>Port ID</dt>
|
||||
<dd>
|
||||
<a ng-href="/project/networks/ports/{$ ::ctrl.loadbalancer.vip_port_id $}/detail">{$ ::ctrl.loadbalancer.vip_port_id $}</a>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</tab>
|
||||
<tab heading="{$ 'Pools' | translate $}">
|
||||
<!-- TODO(jpomero) ng-include the table of pools for this load balancer -->
|
||||
</tab>
|
||||
<tab heading="{$ 'Members' | translate $}">
|
||||
<!-- TODO(jpomero) ng-include the table of members for this load balancer -->
|
||||
</tab>
|
||||
</tabset>
|
||||
</div>
|
||||
</div>
|
|
@ -25,8 +25,6 @@
|
|||
describe('LBaaS v2 Load Balancers Module Base Path', function () {
|
||||
var basePath, staticUrl;
|
||||
|
||||
beforeEach(module('horizon.dashboard.project'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2.loadbalancers'));
|
||||
beforeEach(inject(function ($injector) {
|
||||
basePath = $injector.get('horizon.dashboard.project.lbaasv2.loadbalancers.basePath');
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<hz-page-header header="{$ 'Load Balancers' | translate $}"></hz-page-header>
|
||||
|
||||
<table ng-controller="loadBalancersTableController as table"
|
||||
hz-table ng-cloak
|
||||
st-table="table.items"
|
||||
|
@ -63,12 +65,12 @@
|
|||
hz-select="item">
|
||||
</td>
|
||||
<td class="expander">
|
||||
<i class="fa fa-chevron-right"
|
||||
<span class="fa fa-chevron-right"
|
||||
hz-expand-detail
|
||||
duration="200">
|
||||
</i>
|
||||
</span>
|
||||
</td>
|
||||
<td class="rsp-p1">{$ item.name $}</td>
|
||||
<td class="rsp-p1"><a ng-href="/project/ngloadbalancersv2/detail/{$ item.id $}">{$ item.name $}</a></td>
|
||||
<td class="rsp-p1">{$ item.description | noValue $}</td>
|
||||
<td class="rsp-p1">{$ item.operating_status | operatingStatus $}</td>
|
||||
<td class="rsp-p1">{$ item.provisioning_status | provisioningStatus $}</td>
|
||||
|
@ -135,4 +137,4 @@
|
|||
-->
|
||||
<tfoot hz-table-footer items="table.items"></tfoot>
|
||||
|
||||
</table>
|
||||
</table>
|
Loading…
Reference in New Issue