blob: 0db243a5fa749bf82e8d12e20fb1ee4e67da0ae4 [file] [log] [blame]
Bri Prebilic Cole384e8dc2015-04-13 15:51:14 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Bri Prebilic Cole384e8dc2015-04-13 15:51:14 -07003 *
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/*
18 ONOS GUI -- Cluster View Module
19 */
20
21(function () {
22 'use strict';
23
Simon Hunt6b5a9412016-10-26 19:32:04 -070024 // injected references
Simon Hunt94104e72017-06-13 11:38:55 -070025 var $log, $scope, fs, ns, mast, ps, is, wss, lion;
Viswanath KSP9fcf9702016-10-23 17:13:29 +053026
Simon Hunt6b5a9412016-10-26 19:32:04 -070027 // internal state
28 var detailsPanel,
29 pStartY,
30 pHeight,
31 top,
32 topTable,
33 bottom,
34 iconDiv,
35 nameDiv,
36 wSize;
Viswanath KSP9fcf9702016-10-23 17:13:29 +053037
38
Simon Hunt6b5a9412016-10-26 19:32:04 -070039 // constants
40 var topPdg = 28,
41 ctnrPdg = 24,
42 scrollSize = 17,
43 portsTblPdg = 50,
44 htPdg = 479,
45 wtPdg = 532,
Viswanath KSP9fcf9702016-10-23 17:13:29 +053046
Simon Hunt6b5a9412016-10-26 19:32:04 -070047 pName = 'cluster-details-panel',
48 detailsReq = 'clusterDetailsRequest',
49 detailsResp = 'clusterDetailsResponse',
Viswanath KSP9fcf9702016-10-23 17:13:29 +053050
Simon Hunt6b5a9412016-10-26 19:32:04 -070051 propOrder = [
52 'id', 'ip'
53 ],
54 friendlyProps = [
55 'Node ID', 'IP Address'
Viswanath KSP116f0c12016-11-21 00:02:51 +053056 ],
57 deviceCols = [
58 'id', 'type', 'chassisid', 'mfr',
59 'hw', 'sw', 'protocol', 'serial'
60 ],
61 friendlyDeviceCols = [
62 'URI', 'Type', 'Chassis ID', 'Vendor',
63 'H/W Version', 'S/W Version', 'Protocol',
64 'Serial #'
Simon Hunt6b5a9412016-10-26 19:32:04 -070065 ];
Viswanath KSP9fcf9702016-10-23 17:13:29 +053066
Simon Hunt6b5a9412016-10-26 19:32:04 -070067 function closePanel() {
68 if (detailsPanel.isVisible()) {
69 $scope.selId = null;
Viswanath KSP9fcf9702016-10-23 17:13:29 +053070 detailsPanel.hide();
Simon Hunt6b5a9412016-10-26 19:32:04 -070071 return true;
Viswanath KSP9fcf9702016-10-23 17:13:29 +053072 }
Simon Hunt6b5a9412016-10-26 19:32:04 -070073 return false;
74 }
Viswanath KSP9fcf9702016-10-23 17:13:29 +053075
Simon Hunt6b5a9412016-10-26 19:32:04 -070076 function addCloseBtn(div) {
77 is.loadEmbeddedIcon(div, 'close', 20);
78 div.on('click', closePanel);
79 }
Viswanath KSP9fcf9702016-10-23 17:13:29 +053080
Viswanath KSP86016272016-10-27 09:49:46 +053081 function handleEscape() {
82 return closePanel();
83 }
84
Simon Hunt6b5a9412016-10-26 19:32:04 -070085 function setUpPanel() {
86 var container, closeBtn, tblDiv;
87 detailsPanel.empty();
Viswanath KSP9fcf9702016-10-23 17:13:29 +053088
Simon Hunt6b5a9412016-10-26 19:32:04 -070089 container = detailsPanel.append('div').classed('container', true);
Viswanath KSP9fcf9702016-10-23 17:13:29 +053090
Simon Hunt6b5a9412016-10-26 19:32:04 -070091 top = container.append('div').classed('top', true);
92 closeBtn = top.append('div').classed('close-btn', true);
93 addCloseBtn(closeBtn);
94 iconDiv = top.append('div').classed('dev-icon', true);
95 top.append('h2');
96 topTable = top.append('div').classed('top-content', true)
97 .append('table');
98 top.append('hr');
99
Viswanath KSP116f0c12016-11-21 00:02:51 +0530100 bottom = container.append('div').classed('bottom', true);
Simon Hunt239f09e2017-05-18 13:10:09 -0700101 bottom.append('h2').classed('devices-title', true).text('Devices');
Viswanath KSP116f0c12016-11-21 00:02:51 +0530102 bottom.append('table');
Simon Hunt6b5a9412016-10-26 19:32:04 -0700103 //ToDo add more details
104 }
105
106 function addProp(tbody, index, value) {
107 var tr = tbody.append('tr');
108
109 function addCell(cls, txt) {
Simon Hunt239f09e2017-05-18 13:10:09 -0700110 tr.append('td').attr('class', cls).text(txt);
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530111 }
Simon Hunt6b5a9412016-10-26 19:32:04 -0700112 addCell('label', friendlyProps[index] + ' :');
113 addCell('value', value);
114 }
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530115
Simon Hunt6b5a9412016-10-26 19:32:04 -0700116 function populateTop(details) {
117 is.loadEmbeddedIcon(iconDiv, 'node', 40);
Simon Hunt239f09e2017-05-18 13:10:09 -0700118 top.select('h2').text(details.id);
Simon Hunt6b5a9412016-10-26 19:32:04 -0700119
120 var tbody = topTable.append('tbody');
121
122 propOrder.forEach(function (prop, i) {
123 addProp(tbody, i, details[prop]);
124 });
125 }
126
Viswanath KSP116f0c12016-11-21 00:02:51 +0530127 function addDeviceRow(tbody, device) {
128 var tr = tbody.append('tr');
129
130 deviceCols.forEach(function (col) {
Simon Hunt239f09e2017-05-18 13:10:09 -0700131 tr.append('td').text(device[col]);
Viswanath KSP116f0c12016-11-21 00:02:51 +0530132 });
133 }
134
135 function populateBottom(devices) {
136 var table = bottom.select('table'),
137 theader = table.append('thead').append('tr'),
138 tbody = table.append('tbody'),
139 tbWidth, tbHeight;
140
141 friendlyDeviceCols.forEach(function (col) {
Simon Hunt239f09e2017-05-18 13:10:09 -0700142 theader.append('th').text(col);
Viswanath KSP116f0c12016-11-21 00:02:51 +0530143 });
144 devices.forEach(function (device) {
145 addDeviceRow(tbody, device);
146 });
147
148 tbWidth = fs.noPxStyle(tbody, 'width') + scrollSize;
149 tbHeight = pHeight
150 - (fs.noPxStyle(detailsPanel.el()
151 .select('.top'), 'height')
152 + fs.noPxStyle(detailsPanel.el()
153 .select('.devices-title'), 'height')
154 + portsTblPdg);
155
156 table.style({
157 height: tbHeight + 'px',
158 width: tbWidth + 'px',
159 overflow: 'auto',
160 display: 'block'
161 });
162
163 detailsPanel.width(tbWidth + ctnrPdg);
164 }
165
Simon Hunt6b5a9412016-10-26 19:32:04 -0700166 function createDetailsPane() {
167 detailsPanel = ps.createPanel(pName, {
168 width: wSize.width,
169 margin: 0,
170 hideMargin: 0
171 });
172 detailsPanel.el().style({
173 position: 'absolute',
174 top: pStartY + 'px'
175 });
176 $scope.hidePanel = function () { detailsPanel.hide(); };
177 detailsPanel.hide();
178 }
179
180 function populateDetails(details) {
181 setUpPanel();
Viswanath KSP116f0c12016-11-21 00:02:51 +0530182
Simon Hunt6b5a9412016-10-26 19:32:04 -0700183 populateTop(details);
Viswanath KSP116f0c12016-11-21 00:02:51 +0530184 populateBottom(details.devices);
Simon Hunt6b5a9412016-10-26 19:32:04 -0700185
186 //ToDo add more details
187 detailsPanel.height(pHeight);
Viswanath KSP116f0c12016-11-21 00:02:51 +0530188 //detailsPanel.width(wtPdg); ToDO Use this when needed!
Simon Hunt6b5a9412016-10-26 19:32:04 -0700189 }
190
191 function respDetailsCb(data) {
192 $scope.panelData = data.details;
193 $scope.$apply();
194 }
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530195
196
Bri Prebilic Cole384e8dc2015-04-13 15:51:14 -0700197 angular.module('ovCluster', [])
198 .controller('OvClusterCtrl',
Simon Hunt94104e72017-06-13 11:38:55 -0700199 ['$log', '$scope', 'FnService', 'NavService', 'MastService',
200 'PanelService', 'IconService','WebSocketService',
201 'LionService', 'TableBuilderService',
Bri Prebilic Cole384e8dc2015-04-13 15:51:14 -0700202
Simon Hunt94104e72017-06-13 11:38:55 -0700203 // var $log, $scope, fs, ns, mast, ps, is, wss, lion;
204
205 function (_$log_, _$scope_, _fs_, _ns_, _mast_, _ps_, _is_, _wss_, _lion_, tbs) {
Simon Hunt6b5a9412016-10-26 19:32:04 -0700206 var handlers = {};
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530207
Simon Hunt6b5a9412016-10-26 19:32:04 -0700208 $log = _$log_;
209 $scope = _$scope_;
210 fs = _fs_;
211 ns = _ns_;
Simon Hunt6b5a9412016-10-26 19:32:04 -0700212 mast = _mast_;
213 ps = _ps_;
Simon Hunt94104e72017-06-13 11:38:55 -0700214 is = _is_;
215 wss = _wss_;
216 lion = _lion_;
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530217
Simon Hunt6b5a9412016-10-26 19:32:04 -0700218 $scope.panelData = {};
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530219
Simon Hunt6b5a9412016-10-26 19:32:04 -0700220 tbs.buildTable({
221 scope: $scope,
222 selCb: selCb,
223 tag: 'cluster'
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530224 });
225
Simon Hunt6b5a9412016-10-26 19:32:04 -0700226 // details panel handlers
227 handlers[detailsResp] = respDetailsCb;
228 wss.bindHandlers(handlers);
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530229
Simon Hunt6b5a9412016-10-26 19:32:04 -0700230 function selCb($event, row) {
231 if ($scope.selId) {
232 wss.sendEvent(detailsReq, {id: row.id});
233 } else {
234 $scope.hidePanel();
235 }
236 $log.debug('Got a click on:', row);
237 }
238
239 $scope.$on('$destroy', function () {
240 wss.unbindHandlers(handlers);
241 });
242
Simon Hunt94104e72017-06-13 11:38:55 -0700243 // ++++ Temp test code for Localization POC ++++
244 var bun = lion.bundle('core.cluster');
245 $log.debug('Lion bundle test: computer = ', bun.computer);
246 // ++++ Temp test code for Localization POC ++++
247
Simon Hunt6b5a9412016-10-26 19:32:04 -0700248 $log.log('OvClusterCtrl has been created');
249 }])
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530250
Simon Hunta271e0a2016-10-26 10:59:14 -0700251 .directive('clusterDetailsPanel',
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530252 ['$rootScope', '$window', '$timeout', 'KeyService',
253 function ($rootScope, $window, $timeout, ks) {
254 return function (scope) {
255 var unbindWatch;
256
257 function heightCalc() {
258 pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
259 + mast.mastHeight() + topPdg;
260 wSize = fs.windowSize(pStartY);
261 pHeight = wSize.height;
262 }
263
264 function initPanel() {
265 heightCalc();
266 createDetailsPane();
267 }
268
269 // Safari has a bug where it renders the fixed-layout table wrong
270 // if you ask for the window's size too early
271 if (scope.onos.browser === 'safari') {
272 $timeout(initPanel);
273 } else {
274 initPanel();
275 }
Viswanath KSP86016272016-10-27 09:49:46 +0530276 // create key bindings to handle panel
277 ks.keyBindings({
278 esc: [handleEscape, 'Close the details panel'],
279 _helpFormat: ['esc']
280 });
281 ks.gestureNotes([
282 ['click', 'Select a row to show cluster node details'],
283 ['scroll down', 'See available cluster nodes']
284 ]);
Simon Hunta271e0a2016-10-26 10:59:14 -0700285 // if the panelData changes
286 scope.$watch('panelData', function () {
287 if (!fs.isEmptyObject(scope.panelData)) {
288 populateDetails(scope.panelData);
289 detailsPanel.show();
290 }
291 });
292
Viswanath KSP9fcf9702016-10-23 17:13:29 +0530293 // if the window size changes
294 unbindWatch = $rootScope.$watchCollection(
295 function () {
296 return {
297 h: $window.innerHeight,
298 w: $window.innerWidth
299 };
300 }, function () {
301 if (!fs.isEmptyObject(scope.panelData)) {
302 heightCalc();
303 populateDetails(scope.panelData);
304 }
305 }
306 );
307
308 scope.$on('$destroy', function () {
309 unbindWatch();
310 ps.destroyPanel(pName);
311 });
312 };
313 }]);
Bri Prebilic Cole384e8dc2015-04-13 15:51:14 -0700314}());