Pushing changes for story/subtask onos-5522
Patchset-2 Fixing code based on review comments on patchset-1
Patchset-3 Fixing code based on review comments on patchset-2
Change-Id: Ib3d0773bb6d2769f0590a99161462b2fe57b4304
diff --git a/web/gui/src/main/webapp/app/view/flow/flow.css b/web/gui/src/main/webapp/app/view/flow/flow.css
index 5b59f1b..fefb7a4 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.css
+++ b/web/gui/src/main/webapp/app/view/flow/flow.css
@@ -36,3 +36,32 @@
text-align: left;
padding-left: 36px;
}
+
+/* More in generic panel.css */
+
+#flow-details-panel.floatpanel {
+ z-index: 0;
+}
+
+
+#flow-details-panel .container {
+ padding: 8px 12px;
+}
+
+#flow-details-panel .close-btn {
+ position: absolute;
+ right: 12px;
+ top: 12px;
+ cursor: pointer;
+}
+
+#flow-details-panel .dev-icon {
+ display: inline-block;
+ padding: 0 6px 0 0;
+ vertical-align: middle;
+}
+
+#flow-details-panel h2 {
+ display: inline-block;
+ margin: 8px 0;
+}
diff --git a/web/gui/src/main/webapp/app/view/flow/flow.html b/web/gui/src/main/webapp/app/view/flow/flow.html
index 89036e2..eb1e45a 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.html
+++ b/web/gui/src/main/webapp/app/view/flow/flow.html
@@ -98,6 +98,8 @@
</tr>
<tr ng-repeat-start="flow in tableData | filter:queryFilter track by $index"
+ ng-click="selectCallback($event, flow)"
+ ng-class="{selected: flow.id === selId}"
ng-repeat-complete row-id="{{flow.id}}">
<td>{{flow.id}}</td>
<td>{{flow.appId}}</td>
@@ -120,5 +122,6 @@
</div>
</div>
+ <flow-details-panel></flow-details-panel>
</div>
diff --git a/web/gui/src/main/webapp/app/view/flow/flow.js b/web/gui/src/main/webapp/app/view/flow/flow.js
index 872a2d1..445288d 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.js
+++ b/web/gui/src/main/webapp/app/view/flow/flow.js
@@ -22,21 +22,125 @@
'use strict';
// injected references
- var $log, $scope, $location, fs, tbs, ns;
+ var $log, $scope, $location, fs, tbs, ns, mast, ps, wss, is, ks;
+
+ // internal state
+ var detailsPanel,
+ pStartY,
+ pHeight,
+ top,
+ topContent,
+ bottom,
+ iconDiv,
+ nameDiv,
+ wSize;
+
+
+ // constants
+ var topPdg = 28,
+ ctnrPdg = 24,
+ scrollSize = 17,
+ portsTblPdg = 50,
+ htPdg = 479,
+ wtPdg = 532,
+
+ pName = 'flow-details-panel',
+ detailsReq = 'flowDetailsRequest',
+ detailsResp = 'flowDetailsResponse';
+
+ function closePanel() {
+ if (detailsPanel.isVisible()) {
+ $scope.selId = null;
+ detailsPanel.hide();
+ return true;
+ }
+ return false;
+ }
+
+ function addCloseBtn(div) {
+ is.loadEmbeddedIcon(div, 'close', 20);
+ div.on('click', closePanel);
+ }
+
+ function setUpPanel() {
+ var container, closeBtn, tblDiv;
+ detailsPanel.empty();
+
+ container = detailsPanel.append('div').classed('container', true);
+
+ top = container.append('div').classed('top', true);
+ closeBtn = top.append('div').classed('close-btn', true);
+ addCloseBtn(closeBtn);
+ iconDiv = top.append('div').classed('dev-icon', true);
+ top.append('h2');
+ topContent = top.append('div').classed('top-content', true);
+ top.append('hr');
+
+ //ToDo add more details
+ }
+
+ function populateTop(details) {
+ is.loadEmbeddedIcon(iconDiv, 'm_flows', 40);
+ top.select('h2').html(details.id);
+
+ //ToDo : Add more details
+ }
+
+ function createDetailsPane() {
+ detailsPanel = ps.createPanel(pName, {
+ width: wSize.width,
+ margin: 0,
+ hideMargin: 0
+ });
+ detailsPanel.el().style({
+ position: 'absolute',
+ top: pStartY + 'px'
+ });
+ $scope.hidePanel = function () { detailsPanel.hide(); };
+ detailsPanel.hide();
+ }
+
+ function populateDetails(details) {
+
+ setUpPanel();
+ populateTop(details);
+
+ //ToDo add more details
+ detailsPanel.height(pHeight);
+ detailsPanel.width(wtPdg);
+
+ //Todo : remove this when server implementation is done
+ detailsPanel.show();
+ }
+
+ function respDetailsCb(data) {
+ var details = data.details;
+ //TODO Use populateDetails() when merging server code
+ $log.debug('Get the details:', details.id);
+ }
angular.module('ovFlow', [])
.controller('OvFlowCtrl',
['$log', '$scope', '$location',
'FnService', 'TableBuilderService', 'NavService',
+ 'MastService', 'PanelService', 'KeyService', 'IconService',
+ 'WebSocketService',
- function (_$log_, _$scope_, _$location_, _fs_, _tbs_, _ns_) {
- var params;
+ function (_$log_, _$scope_, _$location_, _fs_, _tbs_, _ns_,
+ _mast_, _ps_, _ks_, _is_, _wss_) {
+ var params,
+ handlers = {};
+
$log = _$log_;
$scope = _$scope_;
$location = _$location_;
fs = _fs_;
tbs = _tbs_;
ns = _ns_;
+ is = _is_;
+ wss = _wss_;
+ mast = _mast_;
+ ps = _ps_;
$scope.deviceTip = 'Show device table';
$scope.portTip = 'Show port view for this device';
$scope.groupTip = 'Show group view for this device';
@@ -52,6 +156,7 @@
tbs.buildTable({
scope: $scope,
tag: 'flow',
+ selCb: selCb,
query: params
});
@@ -61,6 +166,22 @@
}
};
+ // details panel handlers
+ handlers[detailsResp] = respDetailsCb;
+ wss.bindHandlers(handlers);
+
+ function selCb($event, row) {
+ if ($scope.selId) {
+ wss.sendEvent(detailsReq, {flowId: row.id, appId: row.appId});
+
+ //ToDo : Remove this line when server implmentation is complete
+ populateDetails($scope.selId);
+ } else {
+ $scope.hidePanel();
+ }
+ $log.debug('Got a click on:', row);
+ }
+
$scope.briefToggle = function () {
$scope.brief = !$scope.brief;
};
@@ -74,5 +195,54 @@
});
$log.log('OvFlowCtrl has been created');
- }]);
+ }])
+
+ .directive('flowDetailsPanel',
+ ['$rootScope', '$window', '$timeout', 'KeyService',
+ function ($rootScope, $window, $timeout, ks) {
+ return function (scope) {
+ var unbindWatch;
+
+ function heightCalc() {
+ pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
+ + mast.mastHeight() + topPdg;
+ wSize = fs.windowSize(pStartY);
+ pHeight = wSize.height;
+ }
+
+ function initPanel() {
+ heightCalc();
+ createDetailsPane();
+ }
+
+ // Safari has a bug where it renders the fixed-layout table wrong
+ // if you ask for the window's size too early
+ if (scope.onos.browser === 'safari') {
+ $timeout(initPanel);
+ } else {
+ initPanel();
+ }
+
+ // if the window size changes
+ unbindWatch = $rootScope.$watchCollection(
+ function () {
+ return {
+ h: $window.innerHeight,
+ w: $window.innerWidth
+ };
+ }, function () {
+ if (!fs.isEmptyObject(scope.panelData)) {
+ heightCalc();
+ populateDetails(scope.panelData);
+ }
+ }
+ );
+
+ scope.$on('$destroy', function () {
+ unbindWatch();
+ ps.destroyPanel(pName);
+ });
+ };
+ }]);
+
}());