blob: be5d6dc0115987b544bc05a1575b4d0956a6a734 [file] [log] [blame]
Bri Prebilic Coleac829e42015-05-05 13:42:06 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Bri Prebilic Coleac829e42015-05-05 13:42:06 -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 -- Port View Module
19 */
20
21(function () {
22 'use strict';
23
24 // injected references
Simon Huntc9e83212017-10-09 16:52:07 -070025 var $log, $scope, $location, tbs, fs, mast, wss, ns, prefs, dps, is, ps;
Viswanath KSPd25440b2017-07-21 13:48:06 +053026
27 var nz = 'nzFilter',
28 del = 'showDelta';
Bri Prebilic Coleac829e42015-05-05 13:42:06 -070029
Simon Hunt105bc4e2017-07-21 11:07:01 -070030 // internal state
31 var nzFilter = true,
Simon Huntc9e83212017-10-09 16:52:07 -070032 showDelta = false,
33 detailsPanel,
34 pStartY,
35 pHeight,
36 wSize,
37 port;
38
39 // constants
40 var topPdg = 28,
41 dPanelWidth = 480,
42
43 pName = 'port-details-panel',
44 detailsReq = 'portDetailsRequest',
45 detailsResp = 'portDetailsResponse';
46
47
48 var keyBindings = {
49 esc: [closePanel, 'Close the details panel'],
50 _helpFormat: ['esc'],
51 };
52
53 function closePanel() {
54 if (detailsPanel.isVisible()) {
55 $scope.selId = null;
56 detailsPanel.hide();
57 return true;
58 }
59 return false;
60 }
Simon Hunt105bc4e2017-07-21 11:07:01 -070061
Viswanath KSPd25440b2017-07-21 13:48:06 +053062 var defaultPortPrefsState = {
Steven Burrows1c2a9682017-07-14 16:52:46 +010063 nzFilter: 1,
64 showDelta: 0,
Viswanath KSPd25440b2017-07-21 13:48:06 +053065 };
66
67 var prefsState = {};
68
69 function updatePrefsState(what, b) {
70 prefsState[what] = b ? 1 : 0;
Simon Huntc9e83212017-10-09 16:52:07 -070071 prefs.setPrefs('port_prefs', prefsState);
Viswanath KSPd25440b2017-07-21 13:48:06 +053072 }
73
74 function toggleNZState(b) {
75 if (b === undefined) {
76 nzFilter = !nzFilter;
77 } else {
78 nzFilter = b;
79 }
80 updatePrefsState(nz, nzFilter);
81 }
82
83 function toggleDeltaState(b) {
84 if (b === undefined) {
85 showDelta = !showDelta;
86 } else {
87 showDelta = b;
88 }
89 updatePrefsState(del, b);
90 }
91
92 function restoreConfigFromPrefs() {
Simon Huntc9e83212017-10-09 16:52:07 -070093 prefsState = prefs.asNumbers(
94 prefs.getPrefs('port_prefs', defaultPortPrefsState)
Viswanath KSPd25440b2017-07-21 13:48:06 +053095 );
96
97 $log.debug('Port - Prefs State:', prefsState);
98 toggleDeltaState(prefsState.showDelta);
99 toggleNZState(prefsState.nzFilter);
100 }
Simon Hunt105bc4e2017-07-21 11:07:01 -0700101
Simon Huntc9e83212017-10-09 16:52:07 -0700102 function createDetailsPanel() {
103 detailsPanel = dps.create(pName, {
104 width: wSize.width,
105 margin: 0,
106 hideMargin: 0,
107 scope: $scope,
108 keyBindings: keyBindings,
109 });
110
111 dps.setResponse(detailsResp, respDetailsCb);
112
113 $scope.hidePanel = function () { detailsPanel.hide(); };
114 }
115
116 function setUpPanel() {
117 dps.empty();
118 dps.addContainers();
119 dps.addCloseButton(closePanel);
120
121 var top = dps.top();
122
123 dps.addHeading('port-icon');
124 top.append('div').classed('top-content', true);
125
126 top.append('hr');
127 }
128
129 function friendlyPropsList(details) {
130 return {
131 'ID': details['id'],
132 'Device': details['devId'],
133 'Type': details['type'],
134 'Speed': details['speed'],
135 'Enabled': details['enabled'],
136 };
137 }
138
139
140 function populateTop(tblDiv, details) {
141 is.loadEmbeddedIcon(dps.select('.iconDiv'), details._iconid_type, 40);
142 dps.top().select('h2').text(details.devId + ' port ' + details.id);
143 dps.addPropsList(tblDiv, friendlyPropsList(details));
144 }
145
146 function populateDetails(details) {
147 setUpPanel();
148 populateTop(dps.select('.top-content'), details);
149 detailsPanel.height(pHeight);
150 detailsPanel.width(dPanelWidth);
151
152 }
153
154 function respDetailsCb(data) {
155 $scope.panelData = data.details;
156 port = data.port;
157 $scope.$apply();
158 }
159
Bri Prebilic Coleac829e42015-05-05 13:42:06 -0700160 angular.module('ovPort', [])
Steven Burrows1c2a9682017-07-14 16:52:46 +0100161 .controller('OvPortCtrl', [
162 '$log', '$scope', '$location',
Simon Huntc9e83212017-10-09 16:52:07 -0700163 'TableBuilderService', 'FnService', 'MastService', 'WebSocketService',
164 'NavService', 'PrefsService', 'DetailsPanelService', 'IconService',
165 'PanelService',
Bri Prebilic Coleac829e42015-05-05 13:42:06 -0700166
Simon Huntc9e83212017-10-09 16:52:07 -0700167 function (_$log_, _$scope_, _$location_,
168 _tbs_, _fs_, _mast_, _wss_,
169 _ns_, _prefs_, _dps_, _is_, _ps_) {
Steven Burrows1c2a9682017-07-14 16:52:46 +0100170 var params;
171 var tableApi;
172 $log = _$log_;
173 $scope = _$scope_;
174 $location = _$location_;
175 tbs = _tbs_;
Simon Huntc9e83212017-10-09 16:52:07 -0700176 fs = _fs_;
177 mast = _mast_;
178 wss = _wss_;
Steven Burrows1c2a9682017-07-14 16:52:46 +0100179 ns = _ns_;
Simon Huntc9e83212017-10-09 16:52:07 -0700180 prefs = _prefs_;
181 dps = _dps_;
182 is = _is_;
Steven Burrows1c2a9682017-07-14 16:52:46 +0100183 ps = _ps_;
Viswanath KSPd25440b2017-07-21 13:48:06 +0530184
Simon Huntc9e83212017-10-09 16:52:07 -0700185 params = $location.search();
186
Steven Burrows1c2a9682017-07-14 16:52:46 +0100187 $scope.deviceTip = 'Show device table';
188 $scope.flowTip = 'Show flow view for this device';
189 $scope.groupTip = 'Show group view for this device';
190 $scope.meterTip = 'Show meter view for selected device';
Yi Tsenga87b40c2017-09-10 00:59:03 -0700191 $scope.pipeconfTip = 'Show pipeconf view for selected device';
Steven Burrows1c2a9682017-07-14 16:52:46 +0100192 $scope.toggleDeltaTip = 'Toggle port delta statistics';
193 $scope.toggleNZTip = 'Toggle non zero port statistics';
Bri Prebilic Coleac829e42015-05-05 13:42:06 -0700194
Steven Burrows1c2a9682017-07-14 16:52:46 +0100195 if (params.hasOwnProperty('devId')) {
196 $scope.devId = params['devId'];
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700197 }
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700198
Steven Burrows1c2a9682017-07-14 16:52:46 +0100199 $scope.payloadParams = {
200 nzFilter: nzFilter,
201 showDelta: showDelta,
202 };
Viswanath KSPd25440b2017-07-21 13:48:06 +0530203
Simon Huntc9e83212017-10-09 16:52:07 -0700204 function selCb($event, row) {
205 if ($scope.selId) {
206 wss.sendEvent(detailsReq, {
207 id: row.id,
208 devId: $scope.devId,
209 });
210 } else {
211 $scope.hidePanel();
212 }
213 $log.debug('Got a click on:', row);
214 }
215
Steven Burrows1c2a9682017-07-14 16:52:46 +0100216 tableApi = tbs.buildTable({
217 scope: $scope,
218 tag: 'port',
219 query: params,
Simon Huntc9e83212017-10-09 16:52:07 -0700220 selCb: selCb,
Steven Burrows1c2a9682017-07-14 16:52:46 +0100221 });
Viswanath KSPd25440b2017-07-21 13:48:06 +0530222
Steven Burrows1c2a9682017-07-14 16:52:46 +0100223 function filterToggleState() {
224 return {
225 nzFilter: nzFilter,
226 showDelta: showDelta,
227 };
228 }
Viswanath KSPd25440b2017-07-21 13:48:06 +0530229
Steven Burrows1c2a9682017-07-14 16:52:46 +0100230 $scope.nav = function (path) {
231 if ($scope.devId) {
232 ns.navTo(path, { devId: $scope.devId });
233 }
234 };
Viswanath KSPd25440b2017-07-21 13:48:06 +0530235
Steven Burrows1c2a9682017-07-14 16:52:46 +0100236 $scope.toggleNZ = function () {
237 toggleNZState();
238 $scope.payloadParams = filterToggleState();
239 tableApi.forceRefesh();
240 };
kalagesa1101dbb2016-12-20 23:34:28 +0530241
Steven Burrows1c2a9682017-07-14 16:52:46 +0100242 $scope.toggleDelta = function () {
243 toggleDeltaState();
244 $scope.payloadParams = filterToggleState();
245 tableApi.forceRefesh();
246 };
247
248 $scope.isDelta = function () {
249 return showDelta;
250 };
251
252 $scope.isNZ = function () {
253 return nzFilter;
254 };
255
Steven Burrows33872882017-10-09 17:17:37 +0100256 function getOperatorFromQuery(query) {
257
258 var operator = query.split(' '),
259 opFunc = null;
260
261 if (operator[0] === '>') {
262 opFunc = _.gt;
263 } else if (operator[0] === '>=') {
264 opFunc = _.gte;
265 } else if (operator[0] === '<') {
266 opFunc = _.lt;
267 } else if (operator[0] === '<=') {
268 opFunc = _.lte;
269 } else {
270 return {
271 operator: opFunc,
272 searchText: query,
273 };
274 }
275
276 return {
277 operator: opFunc,
278 searchText: operator[1],
279 };
280 }
281
282 $scope.customFilter = function (prop, val) {
283 if (!val) {
284 return;
285 }
286
287 var search = getOperatorFromQuery(val),
288 operator = search.operator,
289 searchText = search.searchText;
290
291 if (operator) {
292 return function (row) {
293 var queryBy = $scope.queryBy || '$';
294
295 if (queryBy !== '$') {
296 var rowValue = parseInt(row[$scope.queryBy].replace(/,/g, ''));
297 return operator(rowValue, parseInt(searchText)) ? row : null;
298 } else {
299 var keys = _.keysIn(row);
300
301 for (var i = 0, l = keys.length; i < l; i++) {
302 var rowValue = parseInt(row[keys[i]].replace(/,/g, ''));
303 if (operator(rowValue, parseInt(searchText))) {
304 return row;
305 }
306 }
307 }
308 };
309 } else {
Steven Burrows1c2a9682017-07-14 16:52:46 +0100310 var out = {};
311 out[$scope.queryBy || '$'] = $scope.query;
312 return out;
Steven Burrows33872882017-10-09 17:17:37 +0100313 }
314 };
Steven Burrows1c2a9682017-07-14 16:52:46 +0100315
316 restoreConfigFromPrefs();
Simon Huntc9e83212017-10-09 16:52:07 -0700317
318 $scope.$on('$destroy', function () {
319 dps.destroy();
320 });
321
Steven Burrows1c2a9682017-07-14 16:52:46 +0100322 $log.log('OvPortCtrl has been created');
Simon Huntc9e83212017-10-09 16:52:07 -0700323 }])
324 .directive('portDetailsPanel',
325 ['$rootScope', '$window', '$timeout', 'KeyService',
326 function ($rootScope, $window, $timeout, ks) {
327 return function (scope) {
328 var unbindWatch;
329
330 function heightCalc() {
331 pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
332 + mast.mastHeight() + topPdg;
333 wSize = fs.windowSize(pStartY);
334 pHeight = wSize.height;
335 }
336
337 function initPanel() {
338 heightCalc();
339 createDetailsPanel();
340 }
341
342 // Safari has a bug where it renders the fixed-layout table wrong
343 // if you ask for the window's size too early
344 if (scope.onos.browser === 'safari') {
345 $timeout(initPanel);
346 } else {
347 initPanel();
348 }
349 // create key bindings to handle panel
350 ks.keyBindings(keyBindings);
351
352 ks.gestureNotes([
353 ['click', 'Select a row to show port details'],
354 ['scroll down', 'See more ports'],
355 ]);
356
357 // if the panelData changes
358 scope.$watch('panelData', function () {
359 if (!fs.isEmptyObject(scope.panelData)) {
360 populateDetails(scope.panelData);
361 detailsPanel.show();
362 }
363 });
364
365 // if the window size changes
366 unbindWatch = $rootScope.$watchCollection(
367 function () {
368 return {
369 h: $window.innerHeight,
370 w: $window.innerWidth,
371 };
372 }, function () {
373 if (!fs.isEmptyObject(scope.panelData)) {
374 heightCalc();
375 populateDetails(scope.panelData);
376 }
377 }
378 );
379
380 scope.$on('$destroy', function () {
381 unbindWatch();
382 ks.unbindKeys();
383 ps.destroyPanel(pName);
384 });
385 };
Steven Burrows1c2a9682017-07-14 16:52:46 +0100386 }]);
Bri Prebilic Coleac829e42015-05-05 13:42:06 -0700387}());