blob: a48c63eb3c0ea750fa19d17b20518fdb89bbe863 [file] [log] [blame]
Simon Hunt1002cd82015-04-23 14:44:03 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Simon Hunt1002cd82015-04-23 14:44:03 -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 -- Flow View Module
19 */
20
21(function () {
22 'use strict';
23
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070024 // injected references
Viswanath KSP7bdc9172016-10-19 20:19:17 +053025 var $log, $scope, $location, fs, tbs, ns, mast, ps, wss, is, ks;
26
27 // internal state
28 var detailsPanel,
29 pStartY,
30 pHeight,
31 top,
Viswanath KSP70e0d142016-10-28 21:58:32 +053032 topTable,
Viswanath KSPed55ecf2016-12-22 18:15:45 +053033 trmtDiv,
34 selDiv,
35 topSelTable,
36 topTrmtTable,
Viswanath KSP7bdc9172016-10-19 20:19:17 +053037 bottom,
38 iconDiv,
39 nameDiv,
40 wSize;
41
42
43 // constants
44 var topPdg = 28,
45 ctnrPdg = 24,
46 scrollSize = 17,
47 portsTblPdg = 50,
48 htPdg = 479,
49 wtPdg = 532,
50
51 pName = 'flow-details-panel',
52 detailsReq = 'flowDetailsRequest',
Viswanath KSP70e0d142016-10-28 21:58:32 +053053 detailsResp = 'flowDetailsResponse',
54
55 propOrder = [
Viswanath KSPed55ecf2016-12-22 18:15:45 +053056 'flowId', 'priority', 'groupId', 'appId', 'tableId',
57 'timeout', 'permanent'
Viswanath KSP70e0d142016-10-28 21:58:32 +053058 ],
59 friendlyProps = [
Viswanath KSPed55ecf2016-12-22 18:15:45 +053060 'Flow ID', 'Flow Priority', 'Group ID', 'Application ID',
61 'Table ID', 'Timeout', 'Permanent'
Viswanath KSP70e0d142016-10-28 21:58:32 +053062 ];
Viswanath KSP7bdc9172016-10-19 20:19:17 +053063
64 function closePanel() {
65 if (detailsPanel.isVisible()) {
66 $scope.selId = null;
67 detailsPanel.hide();
68 return true;
69 }
70 return false;
71 }
72
73 function addCloseBtn(div) {
74 is.loadEmbeddedIcon(div, 'close', 20);
75 div.on('click', closePanel);
76 }
77
Viswanath KSP70e0d142016-10-28 21:58:32 +053078 function handleEscape() {
79 return closePanel();
80 }
81
Viswanath KSP7bdc9172016-10-19 20:19:17 +053082 function setUpPanel() {
83 var container, closeBtn, tblDiv;
84 detailsPanel.empty();
85
86 container = detailsPanel.append('div').classed('container', true);
Viswanath KSP7bdc9172016-10-19 20:19:17 +053087 top = container.append('div').classed('top', true);
Viswanath KSPed55ecf2016-12-22 18:15:45 +053088 trmtDiv = container.append('div').classed('top', true);
89 selDiv = container.append('div').classed('top', true);
Viswanath KSP7bdc9172016-10-19 20:19:17 +053090 closeBtn = top.append('div').classed('close-btn', true);
91 addCloseBtn(closeBtn);
92 iconDiv = top.append('div').classed('dev-icon', true);
93 top.append('h2');
Viswanath KSP70e0d142016-10-28 21:58:32 +053094 topTable = top.append('div').classed('top-content', true)
95 .append('table');
Viswanath KSP7bdc9172016-10-19 20:19:17 +053096 top.append('hr');
Simon Hunt239f09e2017-05-18 13:10:09 -070097 trmtDiv.append('h2').text('Treatment');
Viswanath KSPed55ecf2016-12-22 18:15:45 +053098 topTrmtTable = trmtDiv.append('div').classed('top-content', true)
99 .append('table');
100 trmtDiv.append('hr');
Simon Hunt239f09e2017-05-18 13:10:09 -0700101 selDiv.append('h2').text('Selector');
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530102 topSelTable = selDiv.append('div').classed('top-content', true)
103 .append('table');
104
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530105
106 //ToDo add more details
107 }
108
Viswanath KSP70e0d142016-10-28 21:58:32 +0530109 function addProp(tbody, index, value) {
110 var tr = tbody.append('tr');
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530111
Viswanath KSP70e0d142016-10-28 21:58:32 +0530112 function addCell(cls, txt) {
Simon Hunt239f09e2017-05-18 13:10:09 -0700113 tr.append('td').attr('class', cls).text(txt);
Viswanath KSP70e0d142016-10-28 21:58:32 +0530114 }
115 addCell('label', friendlyProps[index] + ' :');
116 addCell('value', value);
117 }
118
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530119 function populateTable(tbody, label, value) {
120 var tr = tbody.append('tr');
121
122 function addCell(cls, txt) {
Simon Hunt239f09e2017-05-18 13:10:09 -0700123 tr.append('td').attr('class', cls).text(txt);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530124 }
125 addCell('label', label + ' :');
126 addCell('value', value);
127 }
128
Viswanath KSP70e0d142016-10-28 21:58:32 +0530129 function populateTop(details) {
130 is.loadEmbeddedIcon(iconDiv, 'flowTable', 40);
Simon Hunt239f09e2017-05-18 13:10:09 -0700131 top.select('h2').text(details.flowId);
Viswanath KSP70e0d142016-10-28 21:58:32 +0530132
133 var tbody = topTable.append('tbody');
134
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530135 var topSelTablebody = topSelTable.append('tbody');
136 var selectorString = details['selector'];
137 var selectors = selectorString.split(',');
138
139 var topTrmtTablebody = topTrmtTable.append('tbody');
140 var treatmentString = details['treatment'];
141 var treatment = treatmentString.split(',');
142
Viswanath KSP70e0d142016-10-28 21:58:32 +0530143 propOrder.forEach(function (prop, i) {
144 addProp(tbody, i, details[prop]);
145 });
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530146
147 selectors.forEach(function (sel) {
Jian Li70c460a2017-05-11 02:26:07 +0900148 var selArray = sel.match(/^([^:]*):([\s\S]*)/);
149 populateTable(topSelTablebody, selArray[1], selArray[2]);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530150 });
151
152 treatment.forEach(function (sel) {
Jian Li70c460a2017-05-11 02:26:07 +0900153 var selArray = sel.match(/^([^:]*):([\s\S]*)/);
154 populateTable(topTrmtTable, selArray[1], selArray[2]);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530155 });
156
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530157 }
158
159 function createDetailsPane() {
160 detailsPanel = ps.createPanel(pName, {
161 width: wSize.width,
162 margin: 0,
163 hideMargin: 0
164 });
165 detailsPanel.el().style({
166 position: 'absolute',
167 top: pStartY + 'px'
168 });
169 $scope.hidePanel = function () { detailsPanel.hide(); };
170 detailsPanel.hide();
171 }
172
173 function populateDetails(details) {
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530174 setUpPanel();
175 populateTop(details);
176
177 //ToDo add more details
178 detailsPanel.height(pHeight);
179 detailsPanel.width(wtPdg);
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530180 }
181
182 function respDetailsCb(data) {
Viswanath KSP70e0d142016-10-28 21:58:32 +0530183 $log.debug("Got response from server :", data);
184 $scope.panelData = data.details;
185 $scope.$apply();
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530186 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700187
Simon Hunt1002cd82015-04-23 14:44:03 -0700188 angular.module('ovFlow', [])
189 .controller('OvFlowCtrl',
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700190 ['$log', '$scope', '$location',
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700191 'FnService', 'TableBuilderService', 'NavService',
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530192 'MastService', 'PanelService', 'KeyService', 'IconService',
193 'WebSocketService',
Simon Hunt1002cd82015-04-23 14:44:03 -0700194
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530195 function (_$log_, _$scope_, _$location_, _fs_, _tbs_, _ns_,
196 _mast_, _ps_, _ks_, _is_, _wss_) {
197 var params,
198 handlers = {};
199
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700200 $log = _$log_;
201 $scope = _$scope_;
202 $location = _$location_;
203 fs = _fs_;
204 tbs = _tbs_;
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700205 ns = _ns_;
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530206 is = _is_;
207 wss = _wss_;
208 mast = _mast_;
209 ps = _ps_;
Simon Hunt20856ec2015-11-16 15:58:14 -0800210 $scope.deviceTip = 'Show device table';
Bri Prebilic Coleeef67ae2015-07-01 16:26:59 -0700211 $scope.portTip = 'Show port view for this device';
212 $scope.groupTip = 'Show group view for this device';
Jian Li1f544732015-12-30 23:36:37 -0800213 $scope.meterTip = 'Show meter view for selected device';
Kavitha Alagesaneaf614c2016-08-22 23:46:05 -0700214 $scope.briefTip = 'Switch to brief view';
215 $scope.detailTip = 'Switch to detailed view';
216 $scope.brief = true;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700217 params = $location.search();
218 if (params.hasOwnProperty('devId')) {
Bri Prebilic Colee568ead2015-05-01 09:51:28 -0700219 $scope.devId = params['devId'];
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700220 }
221
222 tbs.buildTable({
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700223 scope: $scope,
224 tag: 'flow',
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530225 selCb: selCb,
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700226 query: params
227 });
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700228
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700229 $scope.nav = function (path) {
230 if ($scope.devId) {
231 ns.navTo(path, { devId: $scope.devId });
232 }
233 };
234
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530235 // details panel handlers
236 handlers[detailsResp] = respDetailsCb;
237 wss.bindHandlers(handlers);
238
239 function selCb($event, row) {
240 if ($scope.selId) {
241 wss.sendEvent(detailsReq, {flowId: row.id, appId: row.appId});
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530242 } else {
243 $scope.hidePanel();
244 }
245 $log.debug('Got a click on:', row);
246 }
247
Viswanath KSP70e0d142016-10-28 21:58:32 +0530248 $scope.$on('$destroy', function () {
249 wss.unbindHandlers(handlers);
250 });
251
Kavitha Alagesaneaf614c2016-08-22 23:46:05 -0700252 $scope.briefToggle = function () {
253 $scope.brief = !$scope.brief;
254 };
255
sisubram9ada8d72016-09-02 13:54:40 +0530256 Object.defineProperty($scope, "queryFilter", {
257 get: function() {
Simon Huntc8f06d92016-09-28 17:28:26 -0700258 var out = {};
259 out[$scope.queryBy || "$"] = $scope.queryTxt;
260 return out;
sisubram9ada8d72016-09-02 13:54:40 +0530261 }
262 });
263
Simon Hunt1002cd82015-04-23 14:44:03 -0700264 $log.log('OvFlowCtrl has been created');
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530265 }])
266
267 .directive('flowDetailsPanel',
268 ['$rootScope', '$window', '$timeout', 'KeyService',
269 function ($rootScope, $window, $timeout, ks) {
270 return function (scope) {
271 var unbindWatch;
272
273 function heightCalc() {
274 pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
275 + mast.mastHeight() + topPdg;
276 wSize = fs.windowSize(pStartY);
277 pHeight = wSize.height;
278 }
279
280 function initPanel() {
281 heightCalc();
282 createDetailsPane();
283 }
284
285 // Safari has a bug where it renders the fixed-layout table wrong
286 // if you ask for the window's size too early
287 if (scope.onos.browser === 'safari') {
288 $timeout(initPanel);
289 } else {
290 initPanel();
291 }
Viswanath KSP70e0d142016-10-28 21:58:32 +0530292 // create key bindings to handle panel
293 ks.keyBindings({
294 esc: [handleEscape, 'Close the details panel'],
295 _helpFormat: ['esc']
296 });
297 ks.gestureNotes([
298 ['click', 'Select a row to show cluster node details'],
299 ['scroll down', 'See available cluster nodes']
300 ]);
301 // if the panelData changes
302 scope.$watch('panelData', function () {
303 if (!fs.isEmptyObject(scope.panelData)) {
304 populateDetails(scope.panelData);
305 detailsPanel.show();
306 }
307 });
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530308 // if the window size changes
309 unbindWatch = $rootScope.$watchCollection(
310 function () {
311 return {
312 h: $window.innerHeight,
313 w: $window.innerWidth
314 };
315 }, function () {
316 if (!fs.isEmptyObject(scope.panelData)) {
317 heightCalc();
318 populateDetails(scope.panelData);
319 }
320 }
321 );
322
323 scope.$on('$destroy', function () {
324 unbindWatch();
325 ps.destroyPanel(pName);
326 });
327 };
328 }]);
329
Simon Hunt1002cd82015-04-23 14:44:03 -0700330}());