From 4297ef6abf96b5fd1d6e0f1078a1ee9a76dc3f32 Mon Sep 17 00:00:00 2001 From: Daniel Malachovsky Date: Sun, 7 Feb 2016 22:07:30 +0100 Subject: Inventory rework 2 - added detail page - lot of design changes - lot of css overrides Change-Id: Ia1735272297c0913f971728acc6775cce93d4646 Signed-off-by: Daniel Malachovsky --- .../src/main/resources/vpp/assets/css/vpp.css | 104 +++++++++++++-- .../src/main/resources/vpp/assets/images/bd1.svg | 2 +- .../main/resources/vpp/assets/images/interf.svg | 2 +- .../vpp/controllers/inventory.controller.js | 141 +++++++++++++++------ .../resources/vpp/controllers/vpp.controller.js | 5 + vbd/gui/module/src/main/resources/vpp/main.js | 3 +- .../resources/vpp/services/inventory.service.js | 74 ++++++----- .../src/main/resources/vpp/views/index.tpl.html | 23 +++- .../resources/vpp/views/inventory-detail.tpl.html | 70 ++++++++++ .../resources/vpp/views/inventory-table.tpl.html | 66 ++++++---- .../main/resources/vpp/views/new-vpp-dialog.html | 4 +- .../module/src/main/resources/vpp/vpp.module.js | 2 +- 12 files changed, 374 insertions(+), 122 deletions(-) create mode 100644 vbd/gui/module/src/main/resources/vpp/views/inventory-detail.tpl.html (limited to 'vbd') diff --git a/vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css b/vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css index bd03a8baa..cd5b73d48 100644 --- a/vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css +++ b/vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css @@ -15,6 +15,15 @@ html,body { overflow: hidden; } +svg { + border: none; + border-radius: 0; + background-image: none; + background-color: rgb(66,66,66); +} + +text.node-label { fill: #FFFFFF !important; } + md-sidenav.md-locked-open { width: 550px; min-width: 550px; @@ -99,15 +108,6 @@ span.center { stroke: #FFA500 !important; } -a.md-button.md-default-theme[disabled], a.md-button[disabled], a.md-button.md-default-theme.md-raised[disabled], -a.md-button.md-raised[disabled], a.md-button.md-default-theme.md-fab[disabled], a.md-button.md-fab[disabled], -a.md-button.md-default-theme.md-accent[disabled], a.md-button.md-accent[disabled], a.md-button.md-default-theme.md-warn[disabled], -a.md-button.md-warn[disabled], .md-button.md-default-theme[disabled], .md-button[disabled], .md-button.md-default-theme.md-raised[disabled], -.md-button.md-raised[disabled], .md-button.md-default-theme.md-fab[disabled], .md-button.md-fab[disabled], .md-button.md-default-theme.md-accent[disabled], -.md-button.md-accent[disabled], .md-button.md-default-theme.md-warn[disabled], .md-button.md-warn[disabled] { - color: #FFA500 !important; -} - .st-sort-ascent:after{ content: '\25B2'; } @@ -124,8 +124,14 @@ a.md-button.md-warn[disabled], .md-button.md-default-theme[disabled], .md-button content: none; } +/*button overrides*/ button span { - color: orange !important; + color: orange; + font-weight: bold; +} + +button.md-button[disabled] span { + color: #ffc966; } button.md-raised.md-button { @@ -133,11 +139,83 @@ button.md-raised.md-button { } button.md-raised.md-button span{ - color: black !important; + color: black; +} + +a.md-button.md-default-theme.md-raised, +a.md-button.md-raised, +.md-button.md-default-theme.md-raised, +.md-button.md-raised { + background-color: #424242; +} + +a.md-button.md-default-theme[disabled], a.md-button[disabled], a.md-button.md-default-theme.md-raised[disabled], +a.md-button.md-raised[disabled], a.md-button.md-default-theme.md-fab[disabled], a.md-button.md-fab[disabled], +a.md-button.md-default-theme.md-accent[disabled], a.md-button.md-accent[disabled], a.md-button.md-default-theme.md-warn[disabled], +a.md-button.md-warn[disabled], .md-button.md-default-theme[disabled], .md-button[disabled], .md-button.md-default-theme.md-raised[disabled], +.md-button.md-raised[disabled], .md-button.md-default-theme.md-fab[disabled], .md-button.md-fab[disabled], .md-button.md-default-theme.md-accent[disabled], +.md-button.md-accent[disabled], .md-button.md-default-theme.md-warn[disabled], .md-button.md-warn[disabled] { + color: #FFA500; +} + +/*table overrides*/ +.table-striped > tbody > tr:nth-child(odd) > td, .table-striped > tbody > tr:nth-child(odd) > th { + background-color: transparent; +} + +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + vertical-align: middle; +} + +.table > thead > tr > th.interactive { + color: orange; } +/*input overrides*/ +md-input-container.md-default-theme, +md-input-container label, +md-input-container.md-default-theme, +md-input-container .md-placeholder { + text-shadow: none; + color: white; +} + +md-input-container.md-default-theme:not(.md-input-invalid).md-input-focused, +md-input-container:not(.md-input-invalid).md-input-focused label, +md-input-container.md-default-theme:not(.md-input-invalid).md-input-has-value, +md-input-container:not(.md-input-invalid).md-input-has-value label { + color: white; +} + +md-input-container.md-default-theme, +md-input-container .md-input { + text-shadow: none; +} +md-input-container.md-default-theme:not(.md-input-invalid).md-input-focused, +md-input-container:not(.md-input-invalid).md-input-focused .md-input { + border-color: orange; +} -a.md-button.md-default-theme.md-raised, a.md-button.md-raised, .md-button.md-default-theme.md-raised, .md-button.md-raised { - background-color: #424242 !important; +input:-webkit-autofill, +textarea:-webkit-autofill, +select:-webkit-autofill { + background-color: transparent !important; + text-shadow: none; + color: white !important; } + +md-select-menu.md-default-theme, +md-select-menu md-option[selected] { + color: orange; +} + +/*tab overrides*/ +md-tab.md-active { + color: orange; +} \ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/assets/images/bd1.svg b/vbd/gui/module/src/main/resources/vpp/assets/images/bd1.svg index 363d56f14..bfd05671a 100644 --- a/vbd/gui/module/src/main/resources/vpp/assets/images/bd1.svg +++ b/vbd/gui/module/src/main/resources/vpp/assets/images/bd1.svg @@ -1 +1 @@ -Device Nodes_140507 \ No newline at end of file +Device Nodes_140507 \ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/assets/images/interf.svg b/vbd/gui/module/src/main/resources/vpp/assets/images/interf.svg index ae4177b58..4ddef8038 100644 --- a/vbd/gui/module/src/main/resources/vpp/assets/images/interf.svg +++ b/vbd/gui/module/src/main/resources/vpp/assets/images/interf.svg @@ -1 +1 @@ -Device Nodes_140507 \ No newline at end of file +Device Nodes_140507 \ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js b/vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js index c579796e2..c8ca1e575 100644 --- a/vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js +++ b/vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js @@ -19,6 +19,7 @@ define(['app/vpp/vpp.module'], function(vpp) { function(data) { $scope.vppList = data; $scope.displayVppList = [].concat($scope.vppList); + dataService.vpps = $scope.vppList; $scope.$broadcast('RELOAD_VPP_TABLE'); }, @@ -34,10 +35,10 @@ define(['app/vpp/vpp.module'], function(vpp) { $scope.displayVppList = []; //setting reference for vpp access in BDM - dataService.vpps = $scope.vppList; + //dataService.vpps = $scope.vppList; }; - $scope.viewTopology = function(vpp) { + /*$scope.viewTopology = function(vpp) { $mdDialog.show({ controller: function() { var vm = this; @@ -129,7 +130,7 @@ define(['app/vpp/vpp.module'], function(vpp) { parent: angular.element(document.body), clickOutsideToClose:true }) - }; + };*/ $scope.addVppShowForm = function() { $mdDialog.show({ @@ -236,52 +237,112 @@ define(['app/vpp/vpp.module'], function(vpp) { $scope.getVppList(); }]); - vpp.register.controller('InventoryTableDefinitonController', ['$scope', function($scope) { + vpp.register.controller('InventoryDetailController', ['$scope', '$rootScope','$filter', 'toastService', 'dataService', + function($scope, $rootScope, filter, toastService, dataService) { + $scope.displayInterfaceList = [].concat($scope.selectedVpp.interfaces); + $scope.vppList = dataService.vpps; - var actionCellTemplate = - 'View Topology' + - 'Edit' + - 'Delete'; + $scope.viewTopology = function(vpp) { - $scope.gridOptions = { + var vm = this; + + $scope.topo = new nx.graphic.Topology({ + height: 400, + width: 800, + scalable: true, + theme:'blue', + enableGradualScaling:true, + nodeConfig: { + color: '#ffffff', + label: 'model.label', + scale: 'model.scale', + iconType: function(vertex) { + var type = vertex.get().type; + if (type === 'bd') { + return 'bd' + } else if (type === 'vpp') { + return 'switch' + } else { + return 'interf'; + } + } + }, + linkConfig: { + label: 'model.label', + linkType: 'parallel', + color: function(link) { + if (link.getData().type === 'tunnel') { + return '#ffffff'; + } else { + return '#ffffff'; + } + }, + width: function(link) { + if (link.getData().type === 'tunnel') { + return 5; + } + } + }, + showIcon: true, + dataProcessor: 'force', + autoLayout: true, + enableSmartNode: false, + tooltipManagerConfig: { + nodeTooltipContentClass: 'TooltipNode', + linkTooltipContentClass: 'TooltipLink' + } + }); + $scope.app = new nx.ui.Application; - expandableRowTemplate: $scope.view_path + 'inventory-table-interfaces-subgrid.tpl.html', - //subGridVariable will be available in subGrid scope - expandableRowScope: { - subGridVariable: 'subGridScopeVariable' - } + vm.vpp = vpp; + vm.vpp.type = 'vpp'; + vm.vpp.label = vm.vpp.name; - } + var nodes = [].concat(vm.vpp); + var links = []; - $scope.gridOptions.columnDefs = [ - { name: 'name' }, - { name: 'ipAddress'}, - { name: 'port'}, - { name: 'status'}, - { name:' ',cellTemplate: actionCellTemplate} - ]; + _.forEach(vm.vpp.interfaces, function(interf, index){ + interf.label = interf.name; + interf.scale = 0.5; + nodes.push(interf); + links.push({source: 0, target: index + 1}); + }); + $scope.topo.data({ + nodes: nodes, + links: links + }); - //$scope.gridOptions.data = $scope.vppList; + $scope.app.container(document.getElementById('next-vpp-topo')); + $scope.topo.attach($scope.app); - $scope.gridOptions.onRegisterApi = function(gridApi){ - $scope.gridApi = gridApi; - }; + $scope.$watch('selectedVpp', function() { + vm.vpp = vpp; + vm.vpp.type = 'vpp'; + vm.vpp.label = vm.vpp.name; - $scope.$on('RELOAD_VPP_TABLE', function(event) { - $scope.gridOptions.data = $scope.vppList.map(function(item) { - item.subGridOptions = { - columnDefs: [ - { name:"name" }, - { name:"phys-address"}, - { name:"oper-status"} - ], - data: item.interfaces - }; + var nodes = [].concat(vm.vpp); + var links = []; + + _.forEach(vm.vpp.interfaces, function(interf, index){ + interf.label = interf.name; + interf.scale = 0.5; + nodes.push(interf); + links.push({source: 0, target: index + 1}); + }); - return item; - }); - }); + $scope.topo.data({ + nodes: nodes, + links: links + }); + }); + }; + + $scope.viewTopology($scope.selectedVpp); - }]); + /*$scope.$on('RELOAD_SELECTED_VPP', function(event) { + $scope.viewTopology($scope.selectedVpp); + });*/ + + }]); }); \ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/controllers/vpp.controller.js b/vbd/gui/module/src/main/resources/vpp/controllers/vpp.controller.js index 6b2dde830..2d968f757 100644 --- a/vbd/gui/module/src/main/resources/vpp/controllers/vpp.controller.js +++ b/vbd/gui/module/src/main/resources/vpp/controllers/vpp.controller.js @@ -34,11 +34,16 @@ define(modules, function(vpp) { $scope.view_path = 'src/app/vpp/views/'; $scope.mainView = "inventory"; + $scope.selectedVpp = null; $scope.setMainView = function(viewName) { $scope.mainView = viewName; }; + $scope.selectVpp = function(vpp) { + $scope.selectedVpp = vpp; + $scope.$broadcast('RELOAD_SELECTED_VPP'); + }; }]); diff --git a/vbd/gui/module/src/main/resources/vpp/main.js b/vbd/gui/module/src/main/resources/vpp/main.js index a39513bdd..cbeb1f692 100644 --- a/vbd/gui/module/src/main/resources/vpp/main.js +++ b/vbd/gui/module/src/main/resources/vpp/main.js @@ -21,7 +21,8 @@ require.config({ 'angular-animate' : ['angular'], 'angular-aria' : ['angular'], 'angular-smart-table' : ['angular'], - 'angular-ui-grid' : ['angular'] + 'angular-ui-grid' : ['angular'], + 'lodash' : {exports: '_'} }, }); diff --git a/vbd/gui/module/src/main/resources/vpp/services/inventory.service.js b/vbd/gui/module/src/main/resources/vpp/services/inventory.service.js index a90354fb4..d6d27544f 100644 --- a/vbd/gui/module/src/main/resources/vpp/services/inventory.service.js +++ b/vbd/gui/module/src/main/resources/vpp/services/inventory.service.js @@ -29,30 +29,37 @@ define(['app/vpp/vpp.module', 'next'], function(vpp) { var restObj = VPPRestangular.one('restconf').one('operational').one('network-topology:network-topology').one('topology').one('topology-netconf'); restObj.get().then(function(data) { - //if(data.topology.length || data.topology[0].node.length) { - data.topology[0].node.forEach(function(n) { - if(n['node-id'] !== 'controller-config') { - //create new object - var vppObj = s.createObj(n['node-id'], n['netconf-node-topology:host'], n['netconf-node-topology:port'], null, null, n['netconf-node-topology:connection-status']); - // register a promise - if (vppObj.status === 'connected') { - var promise = VppInterfaceService.getInterfaceListByVppName(n['node-id'], function (interfaceList) { + data.topology[0].node.forEach(function(n) { + if(n['node-id'] !== 'controller-config') { + //create new object + var vppObj = s.createObj(n['node-id'], n['netconf-node-topology:host'], n['netconf-node-topology:port'], null, null, n['netconf-node-topology:connection-status']); + // register a promise + if (vppObj.status === 'connected') { + var promise = VppInterfaceService.getInterfaceListByVppName(n['node-id'], + function (interfaceList) { vppObj.interfaces = interfaceList; - }); - // add promise to array - promiseList.push(promise); - // when promise is resolved, push vpp into vppList - promise.then(function () { + }, + function (error) { } + ); + // add promise to array + promiseList.push(promise); + // when promise is resolved, push vpp into vppList + promise.then( + function () { vppList.push(vppObj); - }) - } - else { - vppList.push(vppObj); - } - + }, + function() { + console.warn('blabla'); + } + ) } - }); - //} + else { + vppList.push(vppObj); + } + + } + }); + // when all promises are resolved, call success callback $q.all(promiseList).then(function () { successCallback(vppList); @@ -121,20 +128,25 @@ define(['app/vpp/vpp.module', 'next'], function(vpp) { vpp.register.factory('VppInterfaceService', function(VPPRestangular, $q) { var s = {}; - s.getInterfaceListByVppName = function(vppName, successCallback) { + s.getInterfaceListByVppName = function(vppName, successCallback, errorCallback) { var interfaceList = []; var restObj = VPPRestangular.one('restconf').one('operational').one('network-topology:network-topology').one('topology').one('topology-netconf').one('node').one(vppName).one('yang-ext:mount').one('ietf-interfaces:interfaces-state'); - return restObj.get().then(function(data) { - if (data['interfaces-state'].interface) { - interfaceList = data['interfaces-state'].interface.filter(function(i) { - if (i.name != 'local0') { - return i; - } - }); + return restObj.get().then( + function(data) { + if (data['interfaces-state'].interface) { + interfaceList = data['interfaces-state'].interface.filter(function(i) { + if (i.name != 'local0') { + return i; + } + }); + } + successCallback(interfaceList); + }, + function(res) { + errorCallback(res); } - successCallback(interfaceList); - }); + ); }; return s; diff --git a/vbd/gui/module/src/main/resources/vpp/views/index.tpl.html b/vbd/gui/module/src/main/resources/vpp/views/index.tpl.html index add7f7854..72115cf7b 100644 --- a/vbd/gui/module/src/main/resources/vpp/views/index.tpl.html +++ b/vbd/gui/module/src/main/resources/vpp/views/index.tpl.html @@ -1,5 +1,19 @@
- + + + +
+
+
+
+ + +
+
+
+
+ +
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/views/inventory-detail.tpl.html b/vbd/gui/module/src/main/resources/vpp/views/inventory-detail.tpl.html new file mode 100644 index 000000000..1fc3fa617 --- /dev/null +++ b/vbd/gui/module/src/main/resources/vpp/views/inventory-detail.tpl.html @@ -0,0 +1,70 @@ +
+
+ +
+ +

Topology

+
+
+
+ + +
+ +

VPP Detail

+ + + + + + + + + + + + + + + + + + + + +
VPP Name + + {{vpp.name}} + +
IP Address{{selectedVpp.ipAddress}}
Port{{selectedVpp.port}}
Connection Status{{selectedVpp.status}}
+
+
+
+ +
+ +
+ +

Interface list

+ + + + + + + + + + + + + + + + + +
NameOper StatusAdmin StatusMAC Address
{{interface.name}}{{interface['oper-status']}}{{interface['admin-status']}}{{interface['phys-address']}}
+
+
+
+
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html b/vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html index 3335ad395..ab62c75c3 100644 --- a/vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html +++ b/vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html @@ -1,31 +1,41 @@
- Mount VPP - Reload VPPs +
+
+ +
+

VPP List

+
+
+ Mount VPP + Reload VPPs +
- - - - - - - - - - - - - - - - - - - - -
VPP NameIP AddressPortConnection StatusActions
{{vpp.name}}{{vpp.ipAddress}}{{vpp.port}}{{vpp.status}} - View Topology - Edit - Delete -
-
+ + + + + + + + + + + + + + + + + + + +
VPP NameIP AddressPortConnection StatusActions
{{vpp.name}}{{vpp.ipAddress}}{{vpp.port}}{{vpp.status}} + + Detail + Edit + Delete +
+
+
+
\ No newline at end of file diff --git a/vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html b/vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html index 39178716d..bd502b31c 100644 --- a/vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html +++ b/vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html @@ -58,8 +58,8 @@ - - Mount + + Mount diff --git a/vbd/gui/module/src/main/resources/vpp/vpp.module.js b/vbd/gui/module/src/main/resources/vpp/vpp.module.js index 712db65d5..464aa35bf 100644 --- a/vbd/gui/module/src/main/resources/vpp/vpp.module.js +++ b/vbd/gui/module/src/main/resources/vpp/vpp.module.js @@ -7,7 +7,7 @@ */ define(['angularAMD', 'app/routingConfig', 'ui-bootstrap', 'Restangular', 'angular-animate', 'angular-aria', 'angular-material', 'angular-smart-table', 'angular-translate', - 'angular-translate-loader-partial'], function() { + 'angular-translate-loader-partial', 'lodash'], function() { var vpp = angular.module('app.vpp', ['ui.router.state','app.core', 'ui.bootstrap', 'restangular', 'ngAnimate', 'ngAria', 'ngMaterial', 'smart-table', 'pascalprecht.translate']); -- cgit 1.2.3-korg