blob: 7a2dc4f995fec134027eb0f9c05c9de1de9eea6e [file] [log] [blame]
Bri Prebilic Cole7c92a3d2015-01-09 16:50:03 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
Bri Prebilic Coleaa0f0882015-02-04 15:27:55 -080018 ONOS GUI -- Device View Module
Bri Prebilic Cole7c92a3d2015-01-09 16:50:03 -080019 */
20
21(function () {
22 'use strict';
23
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070024 // injected refs
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -070025 var $log, $scope, $location, fs, mast, ps, wss, is, ns;
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070026
27 // internal state
Bri Prebilic Colee568ead2015-05-01 09:51:28 -070028 var detailsPanel,
Bri Prebilic Cole45069382015-04-14 15:21:38 -070029 pStartY, pHeight,
30 top, bottom, iconDiv,
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -070031 wSize;
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070032
33 // constants
Bri Prebilic Cole45069382015-04-14 15:21:38 -070034 var topPdg = 13,
35 ctnrPdg = 24,
Bri Prebilic Cole9cf1a8d2015-04-21 13:15:29 -070036 scrollSize = 17,
Bri Prebilic Cole45069382015-04-14 15:21:38 -070037 portsTblPdg = 50,
38
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070039 pName = 'device-details-panel',
40 detailsReq = 'deviceDetailsRequest',
41 detailsResp = 'deviceDetailsResponse',
Bri Prebilic Cole45069382015-04-14 15:21:38 -070042
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070043 propOrder = [
44 'type', 'masterid', 'chassisid',
45 'mfr', 'hw', 'sw', 'protocol', 'serial'
46 ],
47 friendlyProps = [
48 'Type', 'Master ID', 'Chassis ID',
49 'Vendor', 'H/W Version', 'S/W Version', 'Protocol', 'Serial #'
50 ],
51 portCols = [
Thomas Vachuskab52a0142015-04-21 17:48:15 -070052 'enabled', 'id', 'speed', 'type', 'elinks_dest', 'name'
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070053 ],
54 friendlyPortCols = [
Thomas Vachuskab52a0142015-04-21 17:48:15 -070055 'Enabled', 'ID', 'Speed', 'Type', 'Egress Links', 'Name'
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070056 ];
57
Bri Prebilic Cole9dcaea52015-07-21 14:39:48 -070058 function closePanel() {
59 if (detailsPanel.isVisible()) {
60 $scope.selId = null;
61 detailsPanel.hide();
62 }
63 }
64
Bri Prebilic Coleb699a162015-04-13 12:01:39 -070065 function addCloseBtn(div) {
Bri Prebilic Coleab582b82015-04-14 15:08:22 -070066 is.loadEmbeddedIcon(div, 'plus', 30);
Bri Prebilic Coleb699a162015-04-13 12:01:39 -070067 div.select('g').attr('transform', 'translate(25, 0) rotate(45)');
Bri Prebilic Cole9dcaea52015-07-21 14:39:48 -070068 div.on('click', closePanel);
Bri Prebilic Coleb699a162015-04-13 12:01:39 -070069 }
70
71 function setUpPanel() {
Bri Prebilic Cole8f07f0d2015-04-23 13:28:43 -070072 var container, closeBtn, tblDiv;
Bri Prebilic Coleb699a162015-04-13 12:01:39 -070073 detailsPanel.empty();
74
75 container = detailsPanel.append('div').classed('container', true);
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070076
77 top = container.append('div').classed('top', true);
78 closeBtn = top.append('div').classed('close-btn', true);
79 addCloseBtn(closeBtn);
Bri Prebilic Coleb699a162015-04-13 12:01:39 -070080 iconDiv = top.append('div').classed('dev-icon', true);
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070081 top.append('h2');
Bri Prebilic Cole8f07f0d2015-04-23 13:28:43 -070082
83 tblDiv = top.append('div').classed('top-tables', true);
84 tblDiv.append('div').classed('left', true).append('table');
85 tblDiv.append('div').classed('right', true).append('table');
86
Bri Prebilic Cole45069382015-04-14 15:21:38 -070087 top.append('hr');
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070088
89 bottom = container.append('div').classed('bottom', true);
Bri Prebilic Cole45069382015-04-14 15:21:38 -070090 bottom.append('h2').classed('ports-title', true).html('Ports');
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070091 bottom.append('table');
92 }
93
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -070094 function addProp(tbody, index, value) {
95 var tr = tbody.append('tr');
96
97 function addCell(cls, txt) {
98 tr.append('td').attr('class', cls).html(txt);
99 }
100 addCell('label', friendlyProps[index] + ' :');
101 addCell('value', value);
102 }
103
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700104 function populateTop(tblDiv, details) {
Bri Prebilic Cole8f07f0d2015-04-23 13:28:43 -0700105 var leftTbl = tblDiv.select('.left')
106 .select('table')
107 .append('tbody'),
108 rightTbl = tblDiv.select('.right')
109 .select('table')
110 .append('tbody');
111
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700112 is.loadEmbeddedIcon(iconDiv, details._iconid_type, 40);
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700113 top.select('h2').html(details.id);
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700114
115 propOrder.forEach(function (prop, i) {
Bri Prebilic Cole8f07f0d2015-04-23 13:28:43 -0700116 // properties are split into two tables
117 addProp(i < 3 ? leftTbl : rightTbl, i, details[prop]);
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700118 });
119 }
120
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700121 function addPortRow(tbody, port) {
122 var tr = tbody.append('tr');
123
124 portCols.forEach(function (col) {
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700125 tr.append('td').html(port[col]);
126 });
127 }
128
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700129 function populateBottom(table, ports) {
130 var theader = table.append('thead').append('tr'),
131 tbody = table.append('tbody'),
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700132 tbWidth, tbHeight;
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700133
134 friendlyPortCols.forEach(function (col) {
135 theader.append('th').html(col);
136 });
137 ports.forEach(function (port) {
138 addPortRow(tbody, port);
139 });
140
141 tbWidth = fs.noPxStyle(tbody, 'width') + scrollSize;
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700142 tbHeight = pHeight
143 - (fs.noPxStyle(detailsPanel.el()
144 .select('.top'), 'height')
145 + fs.noPxStyle(detailsPanel.el()
146 .select('.ports-title'), 'height')
147 + portsTblPdg);
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700148
149 table.style({
150 height: tbHeight + 'px',
151 width: tbWidth + 'px',
152 overflow: 'auto',
153 display: 'block'
154 });
155
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700156 detailsPanel.width(tbWidth + ctnrPdg);
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700157 }
158
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700159 function populateDetails(details) {
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700160 var topTbs, btmTbl, ports;
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700161 setUpPanel();
162
Bri Prebilic Cole8f07f0d2015-04-23 13:28:43 -0700163 topTbs = top.select('.top-tables');
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700164 btmTbl = bottom.select('table');
165 ports = details.ports;
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700166
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700167 populateTop(topTbs, details);
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700168 populateBottom(btmTbl, ports);
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700169
170 detailsPanel.height(pHeight);
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700171 }
172
173 function respDetailsCb(data) {
Bri Prebilic Colee568ead2015-05-01 09:51:28 -0700174 $scope.panelData = data.details;
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700175 $scope.$apply();
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700176 }
177
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700178 function createDetailsPane() {
179 detailsPanel = ps.createPanel(pName, {
180 width: wSize.width,
181 margin: 0,
182 hideMargin: 0
183 });
184 detailsPanel.el().style({
185 position: 'absolute',
186 top: pStartY + 'px'
187 });
Bri Prebilic Cole68844ba2015-07-22 15:41:37 -0700188 $scope.hidePanel = function () { detailsPanel.hide(); };
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700189 detailsPanel.hide();
190 }
191
Bri Prebilic Cole7c92a3d2015-01-09 16:50:03 -0800192 angular.module('ovDevice', [])
Simon Hunta89f0f92015-02-26 16:47:12 -0800193 .controller('OvDeviceCtrl',
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700194 ['$log', '$scope', '$location', 'TableBuilderService', 'FnService',
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700195 'MastService', 'PanelService', 'WebSocketService', 'IconService',
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700196 'NavService',
Simon Hunta89f0f92015-02-26 16:47:12 -0800197
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700198 function (_$log_, _$scope_, _$location_,
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700199 tbs, _fs_, _mast_, _ps_, _wss_, _is_, _ns_) {
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700200 $log = _$log_;
201 $scope = _$scope_;
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700202 $location = _$location_;
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700203 fs = _fs_;
204 mast = _mast_;
205 ps = _ps_;
206 wss = _wss_;
207 is = _is_;
Bri Prebilic Cole8f07f0d2015-04-23 13:28:43 -0700208 ns = _ns_;
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700209 var params = $location.search(),
210 handlers = {};
Bri Prebilic Cole68844ba2015-07-22 15:41:37 -0700211 $scope.panelData = {};
Bri Prebilic Coleeef67ae2015-07-01 16:26:59 -0700212 $scope.flowTip = 'Show flow view for selected device';
213 $scope.portTip = 'Show port view for selected device';
214 $scope.groupTip = 'Show group view for selected device';
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700215
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700216 // details panel handlers
217 handlers[detailsResp] = respDetailsCb;
218 wss.bindHandlers(handlers);
219
220 // query for if a certain device needs to be highlighted
221 if (params.hasOwnProperty('devId')) {
222 $scope.selId = params['devId'];
223 wss.sendEvent(detailsReq, { id: $scope.selId });
224 }
225
Bri Prebilic Coleb699a162015-04-13 12:01:39 -0700226 function selCb($event, row) {
Bri Prebilic Colebfab9c72015-06-01 14:33:18 -0700227 if ($scope.selId) {
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700228 wss.sendEvent(detailsReq, { id: row.id });
229 } else {
Bri Prebilic Cole68844ba2015-07-22 15:41:37 -0700230 $scope.hidePanel();
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700231 }
232 $log.debug('Got a click on:', row);
233 }
234
Bri Prebilic Cole864cdd62015-04-02 15:46:47 -0700235 tbs.buildTable({
Bri Prebilic Cole864cdd62015-04-02 15:46:47 -0700236 scope: $scope,
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700237 tag: 'device',
238 selCb: selCb
239 });
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700240
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700241 $scope.nav = function (path) {
242 if ($scope.selId) {
243 ns.navTo(path, { devId: $scope.selId });
244 }
245 };
246
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700247 $scope.$on('$destroy', function () {
Bri Prebilic Cole0feedc02015-04-09 14:17:37 -0700248 wss.unbindHandlers(handlers);
Simon Hunta89f0f92015-02-26 16:47:12 -0800249 });
250
Bri Prebilic Cole72eb6db2015-03-30 16:58:53 -0700251 $log.log('OvDeviceCtrl has been created');
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700252 }])
253
Bri Prebilic Cole55ee09b2015-08-04 14:34:07 -0700254 .directive('deviceDetailsPanel',
255 ['$rootScope', '$window', '$timeout', 'KeyService',
256 function ($rootScope, $window, $timeout, ks) {
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700257 return function (scope) {
Bri Prebilic Cole0bc4de22015-07-20 17:07:55 -0700258 var unbindWatch;
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700259
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700260 function heightCalc() {
261 pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
262 + mast.mastHeight() + topPdg;
263 wSize = fs.windowSize(pStartY);
264 pHeight = wSize.height;
265 }
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700266
Bri Prebilic Cole55ee09b2015-08-04 14:34:07 -0700267 function initPanel() {
268 heightCalc();
269 createDetailsPane();
270 }
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700271
Bri Prebilic Cole55ee09b2015-08-04 14:34:07 -0700272 // Safari has a bug where it renders the fixed-layout table wrong
273 // if you ask for the window's size too early
274 if (scope.onos.browser === 'safari') {
275 $timeout(initPanel);
276 } else {
277 initPanel();
278 }
Bri Prebilic Cole9dcaea52015-07-21 14:39:48 -0700279 // create key bindings to handle panel
280 ks.keyBindings({
281 esc: [closePanel, 'Close the details panel'],
282 _helpFormat: ['esc']
283 });
284 ks.gestureNotes([
285 ['click', 'Select a row to show device details'],
286 ['scroll down', 'See more devices']
287 ]);
288
Bri Prebilic Cole55ee09b2015-08-04 14:34:07 -0700289 // if the panelData changes
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700290 scope.$watch('panelData', function () {
291 if (!fs.isEmptyObject(scope.panelData)) {
292 populateDetails(scope.panelData);
293 detailsPanel.show();
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700294 }
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700295 });
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700296
Bri Prebilic Cole55ee09b2015-08-04 14:34:07 -0700297 // if the window size changes
Bri Prebilic Cole0bc4de22015-07-20 17:07:55 -0700298 unbindWatch = $rootScope.$watchCollection(
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700299 function () {
300 return {
301 h: $window.innerHeight,
302 w: $window.innerWidth
303 };
304 }, function () {
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700305 if (!fs.isEmptyObject(scope.panelData)) {
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700306 heightCalc();
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700307 populateDetails(scope.panelData);
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700308 }
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700309 }
310 );
Bri Prebilic Cole54bbfb92015-05-28 16:02:28 -0700311
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700312 scope.$on('$destroy', function () {
Bri Prebilic Cole0bc4de22015-07-20 17:07:55 -0700313 unbindWatch();
Bri Prebilic Cole9dcaea52015-07-21 14:39:48 -0700314 ks.unbindKeys();
Bri Prebilic Cole17c6d0a2015-07-16 14:56:40 -0700315 ps.destroyPanel(pName);
316 });
317 };
318 }]);
Bri Prebilic Cole7c92a3d2015-01-09 16:50:03 -0800319}());