Add table view for Bay

Adds the table used to display bay resources

Change-Id: I455e86d75acbc21c93c40cb56a41b372e7e55dba
Implements: blueprint bay-table-view
This commit is contained in:
Bradley Jones 2015-09-11 10:51:02 +01:00
parent ce3fbb390d
commit 1fe073af8b
7 changed files with 277 additions and 4 deletions

View File

@ -98,7 +98,7 @@ def bay_delete(request, id):
def bay_list(request, limit=None, marker=None, sort_key=None,
sort_dir=None, detail=False):
sort_dir=None, detail=True):
return magnumclient(request).bays.list(limit, marker, sort_key,
sort_dir, detail)

View File

@ -81,7 +81,7 @@ class Bays(generic.View):
item under this is a Bay.
"""
result = magnum.bay_list(request)
return{'bays': [n.to_dict() for n in result]}
return{'bays': [change_to_id(n.to_dict()) for n in result]}
@rest_utils.ajax(data_required=True)
def delete(self, request):

View File

@ -3,8 +3,9 @@
{% block title %}{% trans "Bays" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Bays") %}
<hz-page-header header="'Bays' | translate"/>
{% endblock page_header %}
{% block main %}
<ng-include src="'{{ STATIC_URL }}dashboard/containers/bay/table/table.html'"></ng-include>
{% endblock %}

View File

@ -0,0 +1,80 @@
/**
* Copyright 2015 Cisco Systems, Inc.
*
* 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';
/**
* @ngdoc overview
* @name containersBayTableController
* @ngController
*
* @description
* Controller for the containers bay table
*/
angular
.module('horizon.dashboard.containers.bay')
.controller('containersBayTableController', containersBayTableController);
containersBayTableController.$inject = [
'$scope',
'horizon.app.core.openstack-service-api.magnum'
];
function containersBayTableController($scope, magnum) {
var ctrl = this;
ctrl.ibays = [];
ctrl.bays = [];
ctrl.singleDelete = singleDelete;
ctrl.batchDelete = batchDelete;
init();
function init() {
magnum.getBays().success(getBaysSuccess);
}
function getBaysSuccess(response) {
ctrl.bays = response.bays;
}
function singleDelete(bay) {
magnum.deleteBay(bay.id).success(function() {
ctrl.bays.splice(ctrl.bays.indexOf(bay), 1);
});
}
function batchDelete() {
var ids = [];
for (var id in $scope.selected) {
if ($scope.selected[id].checked) {
ids.push(id);
}
}
magnum.deleteBays(ids).success(function() {
for (var b in ids) {
var todelete = ctrl.bays.filter(function(obj) {
return obj.id == ids[b];
});
ctrl.bays.splice(ctrl.bays.indexOf(todelete[0]), 1);
}
$scope.selected = {};
});
}
}
})();

View File

@ -0,0 +1,162 @@
<table ng-controller="containersBayTableController as table"
hz-table ng-cloak
st-table="table.ibays"
st-safe-src="table.bays"
default-sort="name"
default-sort-reverse="false"
class="table-striped table-rsp table-detail modern">
<thead>
<!--
Table-batch-actions:
This is where batch actions like searching, creating, and deleting.
-->
<tr>
<th colspan="100" class="search-header">
<hz-search-bar group-classes="input-group-sm" icon-classes="fa-search">
<action-list class="btn-addon">
<action
action-classes="'btn btn-default btn-sm btn-danger'"
disabled="numSelected === 0"
callback="table.batchDelete">
<i class="fa fa-trash-o"></i>
<translate>Delete Bays</translate>
</action>
</action-list>
</hz-search-bar>
</th>
</tr>
<!--
Table-column-headers:
The headers for the table columns
-->
<tr>
<th class=select-col>
<input type="checkbox" hz-select-all="table.ibays">
</th>
<th class="expander"></th>
<th class="rsp-p1" st-sort="name" st-sort-default>
<translate>Name</translate>
</th>
<th class="rsp-p2" st-sort="id" >
<translate>ID</translate>
</th>
<th class="rsp-p1" st-sort="status" >
<translate>Status</translate>
</th>
<th class="rsp-p2" st-sort="master_count" >
<translate>Master Count</translate>
</th>
<th class="rsp-p2" st-sort="node_count" >
<translate>Node Count</translate>
</th>
<th class="action-col">
<translate>Actions</translate>
</th>
</tr>
</thead>
<tbody>
<!--
Table-rows:
This is where we declaratively define the table columns.
Include select-col if you want to select all.
Include expander if you want to inline details.
Include action-col if you want to perform actions.
rsp-p1 rsp-p2 are responsive priority as user resizes window.
-->
<tr ng-repeat-start="b in table.ibays track by b.id"
nt-class="{'st-selected': checked[b.id]}">
<td class="select-col">
<input type="checkbox"
ng-model="selected[b.id].checked"
hz-select="b">
</td>
<td class="expander">
<i class="fa fa-chevron-right"
hz-expand-detail
duration="200">
</i>
</td>
<td class="rsp-p1">{$ b.name $}</td>
<td class="rsp-p2">{$ b.id $}</td>
<td class="rsp-p1">{$ b.status $}</td>
<td class="rsp-p2">{$ b.master_count $}</td>
<td class="rsp-p2">{$ b.node_count $}</td>
<td class="action-col">
<!--
Table-row-action-column:
Actions taken here applies to a single item/row.
-->
<action-list dropdown>
<action
button-type="split-button"
action-classes="'btn btn-default btn-danger btn-sm'"
callback="table.singleDelete" item="b">
<translate>Delete</translate>
</action>
</action-list>
</td>
</tr>
<tr ng-repeat-end class="detail-row">
<!--
Table-row-details:
Provides detail view of specific view, with more information than can be
displayed in the table alone.
-->
<td class="detail" colspan="100">
<dl class=dl-horizontal>
<dt><translate>Name</translate></dt>
<dd>{$ b.name $}</dd>
<dt><translate>ID</translate></dt>
<dd>{$ b.id $}</dd>
<dt><translate>Status</translate></dt>
<dd>{$ b.status $}</dd>
<!--
TODO (bradjones): Baymodel should link to the baymodel resource in
the UI
-->
<dt><translate>BayModel</translate></dt>
<dd>{$ b.baymodel_id $}</dd>
<dt><translate>Master Count</translate></dt>
<dd>{$ b.master_count $}</dd>
<dt><translate>Node Count</translate></dt>
<dd>{$ b.node_count $}</dd>
<dt><translate>Node Addresses</translate></dt>
<dd ng-repeat="addr in b.node_addresses">{$ addr $}</dd>
</dl>
</td>
</tr>
</tbody>
<tfoot>
<td colspan="100">
<span class="display">{$ table.ibays.length|itemCount $}</span>
<div st-pagination="" st-items-by-page="10"
st-displayed-pages="10"></div>
</td>
</tfoot>
</table>

View File

@ -27,6 +27,9 @@
function MagnumAPI(apiService, toastService) {
var service = {
getBays: getBays,
deleteBay: deleteBay,
deleteBays: deleteBays,
getBayModels: getBayModels,
deleteBayModel: deleteBayModel,
deleteBayModels: deleteBayModels
@ -34,7 +37,34 @@
return service;
///////////
//////////
// Bays //
//////////
function getBays() {
return apiService.get('/api/containers/bays/')
.error(function() {
toastService.add('error', gettext('Unable to retrieve the Bays.'));
});
}
function deleteBay(id) {
return apiService.delete('/api/containers/bays/', [id])
.error(function() {
toastService.add('error', gettext('Unable to delete the Bay.'));
});
}
function deleteBays(ids) {
return apiService.delete('/api/containers/bays/', ids)
.error(function() {
toastService.add('error', gettext('Unable to delete the Bays.'));
});
}
///////////////
// BayModels //
///////////////
function getBayModels() {
return apiService.get('/api/containers/baymodels/')