Inventory rework 2 43/243/2
authorDaniel Malachovsky <daniel.malachovsky@pantheon.sk>
Sun, 7 Feb 2016 21:07:30 +0000 (22:07 +0100)
committerDaniel Malachovsky <daniel.malachovsky@pantheon.sk>
Mon, 8 Feb 2016 15:31:43 +0000 (15:31 +0000)
- added detail page
- lot of design changes
- lot of css overrides

Change-Id: Ia1735272297c0913f971728acc6775cce93d4646
Signed-off-by: Daniel Malachovsky <daniel.malachovsky@pantheon.sk>
12 files changed:
vbd/gui/module/src/main/resources/vpp/assets/css/vpp.css
vbd/gui/module/src/main/resources/vpp/assets/images/bd1.svg
vbd/gui/module/src/main/resources/vpp/assets/images/interf.svg
vbd/gui/module/src/main/resources/vpp/controllers/inventory.controller.js
vbd/gui/module/src/main/resources/vpp/controllers/vpp.controller.js
vbd/gui/module/src/main/resources/vpp/main.js
vbd/gui/module/src/main/resources/vpp/services/inventory.service.js
vbd/gui/module/src/main/resources/vpp/views/index.tpl.html
vbd/gui/module/src/main/resources/vpp/views/inventory-detail.tpl.html [new file with mode: 0644]
vbd/gui/module/src/main/resources/vpp/views/inventory-table.tpl.html
vbd/gui/module/src/main/resources/vpp/views/new-vpp-dialog.html
vbd/gui/module/src/main/resources/vpp/vpp.module.js

index bd03a8b..cd5b73d 100644 (file)
@@ -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
index 363d56f..bfd0567 100644 (file)
@@ -1 +1 @@
-<svg id="Layer_3" data-name="Layer 3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50.99 35.43"><defs><style>.cls-1{fill:#414040;}.cls-2{fill:#fefefe;}</style></defs><title>Device Nodes_140507</title><path class="cls-1" d="M11.59,30.62L2,30.6A10,10,0,0,0,10,34.68h2.32V30.62H11.59Z"/><path class="cls-1" d="M12.32,29.66V28.94L1,28.92c0.12,0.26.25,0.51,0.4,0.76l10.2,0h0.75Z"/><path class="cls-1" d="M10.33,22.83a7.66,7.66,0,0,0,2-4.72,1.34,1.34,0,0,1,1.41-1.46,1.21,1.21,0,0,1,1.4,1.18,9.81,9.81,0,0,0,.51,2.29,9.16,9.16,0,0,0,4.83,5.2,11,11,0,0,0,6.81,1.07,10.85,10.85,0,0,0,6.4-3.26A8.09,8.09,0,0,0,36,17.93a1.43,1.43,0,0,1,1.43-1.28,1.33,1.33,0,0,1,1.38,1.19,8.37,8.37,0,0,0,2.57,5.5,10.58,10.58,0,0,0,5.45,2.9c0.23,0,1.81.08,4,.12A10,10,0,0,0,44,15.07,12,12,0,0,0,21.25,7.38,8.51,8.51,0,0,0,6.58,15.22,10,10,0,0,0,.17,26.47c1.91,0,3.28,0,3.43-.06A10.87,10.87,0,0,0,10.33,22.83Z"/><polygon class="cls-1" points="15.16 30.66 15.16 34.68 36.03 34.68 36.05 30.66 15.16 30.66"/><path class="cls-1" d="M38.87,29.66H49.63c0.13-.23.26-0.47,0.37-0.72H38.87v0.72Z"/><path class="cls-1" d="M38.88,30.62v4.06H41a10,10,0,0,0,8-4.06H38.88Z"/><path class="cls-1" d="M15.16,29.63H36V29H15.16v0.65Z"/><polygon class="cls-2" points="12.35 35.4 15.16 35.38 15.16 34.68 12.35 34.68 12.35 35.4"/><polygon class="cls-2" points="36.03 35.43 38.88 35.38 38.88 34.68 36.03 34.68 36.03 35.43"/><path class="cls-2" d="M46.87,26.24a10.58,10.58,0,0,1-5.45-2.9,8.37,8.37,0,0,1-2.57-5.5,1.33,1.33,0,0,0-1.38-1.19A1.43,1.43,0,0,0,36,17.93a8.09,8.09,0,0,1-2.33,5.21,10.85,10.85,0,0,1-6.4,3.26,11,11,0,0,1-6.81-1.07,9.16,9.16,0,0,1-4.83-5.2,9.81,9.81,0,0,1-.51-2.29,1.21,1.21,0,0,0-1.4-1.18,1.34,1.34,0,0,0-1.41,1.46,7.66,7.66,0,0,1-2,4.72A10.87,10.87,0,0,1,3.6,26.41c-0.15,0-1.52,0-3.43.06A10,10,0,0,0,1,28.92l11.35,0v0.72H11.57l-10.2,0A10,10,0,0,0,2,30.6l9.62,0h0.77v4.06h2.8v-4h20.9l0,4h2.85V30.62H49a10,10,0,0,0,.63-1H38.87V28.94H50a9.94,9.94,0,0,0,.82-2.59C48.68,26.33,47.1,26.29,46.87,26.24ZM36,29.63H15.16V29H36v0.65Z"/></svg>
\ No newline at end of file
+<svg id="Layer_3" data-name="Layer 3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50.99 35.43"><defs><style>.cls-1{fill:#ffffff;}.cls-2{fill:#414040;}</style></defs><title>Device Nodes_140507</title><path class="cls-1" d="M11.59,30.62L2,30.6A10,10,0,0,0,10,34.68h2.32V30.62H11.59Z"/><path class="cls-1" d="M12.32,29.66V28.94L1,28.92c0.12,0.26.25,0.51,0.4,0.76l10.2,0h0.75Z"/><path class="cls-1" d="M10.33,22.83a7.66,7.66,0,0,0,2-4.72,1.34,1.34,0,0,1,1.41-1.46,1.21,1.21,0,0,1,1.4,1.18,9.81,9.81,0,0,0,.51,2.29,9.16,9.16,0,0,0,4.83,5.2,11,11,0,0,0,6.81,1.07,10.85,10.85,0,0,0,6.4-3.26A8.09,8.09,0,0,0,36,17.93a1.43,1.43,0,0,1,1.43-1.28,1.33,1.33,0,0,1,1.38,1.19,8.37,8.37,0,0,0,2.57,5.5,10.58,10.58,0,0,0,5.45,2.9c0.23,0,1.81.08,4,.12A10,10,0,0,0,44,15.07,12,12,0,0,0,21.25,7.38,8.51,8.51,0,0,0,6.58,15.22,10,10,0,0,0,.17,26.47c1.91,0,3.28,0,3.43-.06A10.87,10.87,0,0,0,10.33,22.83Z"/><polygon class="cls-1" points="15.16 30.66 15.16 34.68 36.03 34.68 36.05 30.66 15.16 30.66"/><path class="cls-1" d="M38.87,29.66H49.63c0.13-.23.26-0.47,0.37-0.72H38.87v0.72Z"/><path class="cls-1" d="M38.88,30.62v4.06H41a10,10,0,0,0,8-4.06H38.88Z"/><path class="cls-1" d="M15.16,29.63H36V29H15.16v0.65Z"/><polygon class="cls-2" points="12.35 35.4 15.16 35.38 15.16 34.68 12.35 34.68 12.35 35.4"/><polygon class="cls-2" points="36.03 35.43 38.88 35.38 38.88 34.68 36.03 34.68 36.03 35.43"/><path class="cls-2" d="M46.87,26.24a10.58,10.58,0,0,1-5.45-2.9,8.37,8.37,0,0,1-2.57-5.5,1.33,1.33,0,0,0-1.38-1.19A1.43,1.43,0,0,0,36,17.93a8.09,8.09,0,0,1-2.33,5.21,10.85,10.85,0,0,1-6.4,3.26,11,11,0,0,1-6.81-1.07,9.16,9.16,0,0,1-4.83-5.2,9.81,9.81,0,0,1-.51-2.29,1.21,1.21,0,0,0-1.4-1.18,1.34,1.34,0,0,0-1.41,1.46,7.66,7.66,0,0,1-2,4.72A10.87,10.87,0,0,1,3.6,26.41c-0.15,0-1.52,0-3.43.06A10,10,0,0,0,1,28.92l11.35,0v0.72H11.57l-10.2,0A10,10,0,0,0,2,30.6l9.62,0h0.77v4.06h2.8v-4h20.9l0,4h2.85V30.62H49a10,10,0,0,0,.63-1H38.87V28.94H50a9.94,9.94,0,0,0,.82-2.59C48.68,26.33,47.1,26.29,46.87,26.24ZM36,29.63H15.16V29H36v0.65Z"/></svg>
\ No newline at end of file
index ae4177b..4ddef80 100644 (file)
@@ -1 +1 @@
-<svg id="Layer_3" data-name="Layer 3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.34 12.6"><defs><style>.cls-1{fill:#fcfcfc;}.cls-2{fill:#414040;}</style></defs><title>Device Nodes_140507</title><rect class="cls-1" x="1.5" y="1.5" width="18.34" height="9.6" rx="2" ry="2"/><path class="cls-2" d="M17.84,12.6H3.5A3.5,3.5,0,0,1,0,9.1V3.5A3.5,3.5,0,0,1,3.5,0H17.84a3.5,3.5,0,0,1,3.5,3.5V9.1A3.5,3.5,0,0,1,17.84,12.6ZM3.5,3a0.51,0.51,0,0,0-.5.5V9.1a0.51,0.51,0,0,0,.5.5H17.84a0.51,0.51,0,0,0,.5-0.5V3.5a0.51,0.51,0,0,0-.5-0.5H3.5Z"/></svg>
\ No newline at end of file
+<svg id="Layer_3" data-name="Layer 3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.34 12.6"><defs><style>.cls-1{fill:#414040;}.cls-2{fill:#ffffff;}</style></defs><title>Device Nodes_140507</title><rect class="cls-1" x="1.5" y="1.5" width="18.34" height="9.6" rx="2" ry="2"/><path class="cls-2" d="M17.84,12.6H3.5A3.5,3.5,0,0,1,0,9.1V3.5A3.5,3.5,0,0,1,3.5,0H17.84a3.5,3.5,0,0,1,3.5,3.5V9.1A3.5,3.5,0,0,1,17.84,12.6ZM3.5,3a0.51,0.51,0,0,0-.5.5V9.1a0.51,0.51,0,0,0,.5.5H17.84a0.51,0.51,0,0,0,.5-0.5V3.5a0.51,0.51,0,0,0-.5-0.5H3.5Z"/></svg>
\ No newline at end of file
index c579796..c8ca1e5 100644 (file)
@@ -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 =
-            '<md-button ng-click="grid.appScope.viewTopology(row.entity)"><span style="color:black !important;">View Topology</span></md-button>' +
-            '<md-button ng-click="grid.appScope.editVppShowForm(row.entity)" ng-hide="row.entity.status === \'connected\'"><span style="color:black !important;">Edit</span></md-button>' +
-            '<md-button ng-click="grid.appScope.deleteVpp(row.entity)"><span style="color:black !important;">Delete</span></md-button>';
+            $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
index 6b2dde8..2d968f7 100644 (file)
@@ -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');
+            };
 
        }]);
 
index a39513b..cbeb1f6 100644 (file)
@@ -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: '_'}
   },
 
 });
index a90354f..d6d2754 100644 (file)
@@ -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;
index add7f78..72115cf 100644 (file)
@@ -1,5 +1,19 @@
 <div ng-controller="vppCtrl">
-    <md-toolbar>
+    <md-tabs md-dynamic-height md-border-bottom>
+        <md-tab label="Inventory" md-on-select="setMainView('inventory')">
+            <md-content class="md-padding">
+                <section ng-if="mainView === 'inventory'" ng-include src="view_path+'inventory-table.tpl.html'"></section>
+                <section ng-if="mainView === 'inventoryDetail'" ng-include src="view_path+'inventory-detail.tpl.html'"></section>
+            </md-content>
+        </md-tab>
+        <md-tab label="Bridge Domains" md-on-select="setMainView('bridgeDomains')">
+            <md-content class="md-padding">
+                <section ng-if="mainView === 'bridgeDomains'" ng-include src="view_path+'bridge-domains.tpl.html'"></section>
+            </md-content>
+        </md-tab>
+    </md-tabs>
+
+    <!--<md-toolbar>
         <div class="md-toolbar-tools float-left">
             <span flex></span>
             <md-button ng-click="setMainView('inventory')">Inventory</md-button>
@@ -10,7 +24,8 @@
     </md-toolbar>
 
     <div ng-view style="height: 100%">
-        <section ng-if="mainView === 'inventory'" ng-include src="view_path+'inventory-table.tpl.html'"></section>
-        <section ng-if="mainView === 'bridgeDomains'" ng-include src="view_path+'bridge-domains.tpl.html'"></section>
-    </div>
+
+
+
+    </div>-->
 </div>
\ 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 (file)
index 0000000..1fc3fa6
--- /dev/null
@@ -0,0 +1,70 @@
+<div ng-controller="InventoryDetailController">
+    <div layout="row" layout-xs="column">
+        <!-- Topology -->
+        <div class="md-whiteframe-z2" flex="60" layout-margin>
+            <md-content layout-padding>
+                <h3>Topology</h3>
+                <div id="next-vpp-topo"></div>
+            </md-content>
+        </div>
+
+        <!-- right aligned detail -->
+        <div class="md-sidenav-left md-whiteframe-z2" flex layout-margin>
+            <md-content layout-padding>
+                <h3>VPP Detail</h3>
+
+                <table class="table table-striped">
+                    <tbody>
+                    <tr>
+                        <td><b>VPP Name</b></td>
+                        <td>
+                            <md-select ng-model='selectedVpp' placeholder="Select VPP" ng-change="selectVpp(vpp)">
+                                <md-option ng-repeat="vpp in vppList" ng-value="vpp">{{vpp.name}}</md-option>
+                            </md-select>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td><b>IP Address</b></td>
+                        <td>{{selectedVpp.ipAddress}}</td>
+                    </tr>
+                    <tr>
+                        <td><b>Port</b></td>
+                        <td>{{selectedVpp.port}}</td>
+                    </tr>
+                    <tr>
+                        <td><b>Connection Status</b></td>
+                        <td>{{selectedVpp.status}}</td>
+                    </tr>
+                    </tbody>
+                </table>
+            </md-content>
+        </div>
+    </div>
+
+    <div layout="row" flex="100" layout-margin>
+        <!-- interfaces list -->
+        <div class="md-whiteframe-z2" flex="100">
+            <md-content layout-padding>
+                <h3>Interface list</h3>
+                <table st-table="displayInterfaceList" st-safe-src="selectedVpp.interfaces" class="table table-striped">
+                    <thead>
+                        <tr>
+                            <th st-sort="name" class="interactive">Name</th>
+                            <th st-sort="oper-status" class="interactive" >Oper Status</th>
+                            <th st-sort="admin-status" class="interactive">Admin Status</th>
+                            <th st-sort="phys-address" class="interactive">MAC Address</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        <tr ng-repeat="interface in displayInterfaceList">
+                            <td>{{interface.name}}</td>
+                            <td>{{interface['oper-status']}}</td>
+                            <td>{{interface['admin-status']}}</td>
+                            <td>{{interface['phys-address']}}</td>
+                        </tr>
+                    </tbody>
+                </table>
+            </md-content>
+        </div>
+    </div>
+</div>
\ No newline at end of file
index 3335ad3..ab62c75 100644 (file)
@@ -1,31 +1,41 @@
 <div ng-controller="InventoryTableController">
-       <md-button ng-click="addVppShowForm()">Mount VPP</md-button>
-       <md-button ng-click="getVppList()">Reload VPPs</md-button>
+    <div layout="row" flex="100" layout-margin>
+        <div class="md-whiteframe-z2 flex">
+            <md-content layout-padding>
+                <div style="float: left">
+                    <h3>VPP List</h3>
+                </div>
+                <div style="float: right">
+                    <md-button ng-click="addVppShowForm()" class="md-raised">Mount VPP</md-button>
+                    <md-button ng-click="getVppList()" class="md-raised">Reload VPPs</md-button>
+                </div>
 
-    <md-content layout-padding>
-        <table st-table="displayVppList" st-safe-src="vppList" class="table table-striped">
-            <thead>
-            <tr>
-                <th st-sort="name">VPP Name</th>
-                <th st-sort="ipAddress">IP Address</th>
-                <th st-sort="port">Port</th>
-                <th st-sort="status">Connection Status</th>
-                <th>Actions</th>
-            </tr>
-            </thead>
-            <tbody>
-            <tr ng-repeat="vpp in displayVppList">
-                <td>{{vpp.name}}</td>
-                <td>{{vpp.ipAddress}}</td>
-                <td>{{vpp.port}}</td>
-                <td>{{vpp.status}}</td>
-                <td>
-                    <md-button ng-click="viewTopology(vpp)">View Topology</md-button>
-                    <md-button ng-click="editVppShowForm(vpp)" ng-hide="vpp.status === 'connected'">Edit</md-button>
-                    <md-button ng-click="deleteVpp(vpp)" >Delete</md-button>
-                </td>
-            </tr>
-            </tbody>
-        </table>
-    </md-content>
+                <table st-table="displayVppList" st-safe-src="vppList" class="table table-striped">
+                    <thead>
+                    <tr>
+                        <th st-sort="name" class="interactive">VPP Name</th>
+                        <th st-sort="ipAddress" class="interactive">IP Address</th>
+                        <th st-sort="port" class="interactive">Port</th>
+                        <th st-sort="status" class="interactive">Connection Status</th>
+                        <th>Actions</th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    <tr ng-repeat="vpp in displayVppList">
+                        <td>{{vpp.name}}</td>
+                        <td>{{vpp.ipAddress}}</td>
+                        <td>{{vpp.port}}</td>
+                        <td>{{vpp.status}}</td>
+                        <td>
+                            <!--<md-button ng-click="viewTopology(vpp)" class="md-accent">View Topology</md-button>-->
+                            <md-button ng-click="selectVpp(vpp); setMainView('inventoryDetail')" >Detail</md-button>
+                            <md-button ng-click="editVppShowForm(vpp)" ng-disabled="vpp.status === 'connected'" class="md-accent">Edit</md-button>
+                            <md-button ng-click="deleteVpp(vpp)" class="md-accent">Delete</md-button>
+                        </td>
+                    </tr>
+                    </tbody>
+                </table>
+            </md-content>
+        </div>
+    </div>
 </div>
\ No newline at end of file
index 3917871..bd502b3 100644 (file)
@@ -58,8 +58,8 @@
         <md-progress-linear md-mode="indeterminate" ng-show="NewVppDialogCtrl.waiting"></md-progress-linear>
         <md-dialog-actions layout="row">
             <span flex></span>
-            <md-button ng-click="NewVppDialogCtrl.updateConfig();" style="margin-right:20px;" class="md-accent">
-                <span style="color: black">Mount</span>
+            <md-button ng-click="NewVppDialogCtrl.updateConfig();" style="margin-right:20px;" class="md-raised">
+                <span>Mount</span>
             </md-button>
         </md-dialog-actions>
     </form>
index 712db65..464aa35 100644 (file)
@@ -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']);