Added changes for onos-5523
Fixed code as per review

Change-Id: Ie8e59e3be2a2d762a125e34852abb39548addfea
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
index 4e0c939..f55c6e8 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
@@ -70,6 +70,8 @@
     private static final String BYTES = "bytes";
 
     private static final String COMMA = ", ";
+    private static final String OX = "0x";
+    private static final String EMPTY = "";
 
     private static final String[] COL_IDS = {
             ID, APP_ID, GROUP_ID, TABLE_ID, PRIORITY, SELECTOR,
@@ -202,13 +204,14 @@
         }
 
         private FlowRule findFlowById(String appIdText, String flowId) {
+            String strippedFlowId = flowId.replaceAll(OX, EMPTY);
             FlowRuleService fs = get(FlowRuleService.class);
             int appIdInt = Integer.parseInt(appIdText);
-            ApplicationId appId = new DefaultApplicationId(appIdInt, "details");
+            ApplicationId appId = new DefaultApplicationId(appIdInt, DETAILS);
             Iterable<FlowRule> flows = fs.getFlowRulesById(appId);
 
             for (FlowRule flow : flows) {
-                if (flow.id().toString().equals(flowId)) {
+                if (flow.id().toString().equals(strippedFlowId)) {
                     return flow;
                 }
             }
@@ -216,22 +219,28 @@
             return null;
         }
 
+        private String decorateFlowId(FlowRule flow) {
+            return OX + flow.id();
+        }
+
         @Override
         public void process(long sid, ObjectNode payload) {
 
             String flowId = string(payload, FLOW_ID);
             String appId = string(payload, APP_ID);
             FlowRule flow = findFlowById(appId, flowId);
-            ObjectNode data = objectNode();
+            if (flow != null) {
+                ObjectNode data = objectNode();
 
-            data.put(FLOW_ID, flow.id().toString());
-            data.put(FLOW_PRIORITY, flow.priority());
+                data.put(FLOW_ID, decorateFlowId(flow));
+                data.put(FLOW_PRIORITY, flow.priority());
 
-            //TODO put more detail info to data
+                //TODO put more detail info to data
 
-            ObjectNode rootNode = objectNode();
-            rootNode.set(DETAILS, data);
-            sendMessage(FLOW_DETAILS_RESP, rootNode);
+                ObjectNode rootNode = objectNode();
+                rootNode.set(DETAILS, data);
+                sendMessage(FLOW_DETAILS_RESP, rootNode);
+            }
         }
     }
 }
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 fefb7a4..ba87df0 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.css
+++ b/web/gui/src/main/webapp/app/view/flow/flow.css
@@ -65,3 +65,13 @@
     display: inline-block;
     margin: 8px 0;
 }
+
+#flow-details-panel .top-content table {
+    font-size: 12pt;
+}
+
+#flow-details-panel td.label {
+    font-weight: bold;
+    text-align: right;
+    padding-right: 6px;
+}
\ No newline at end of file
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 445288d..6f862fb 100644
--- a/web/gui/src/main/webapp/app/view/flow/flow.js
+++ b/web/gui/src/main/webapp/app/view/flow/flow.js
@@ -29,7 +29,7 @@
         pStartY,
         pHeight,
         top,
-        topContent,
+        topTable,
         bottom,
         iconDiv,
         nameDiv,
@@ -46,7 +46,14 @@
 
         pName = 'flow-details-panel',
         detailsReq = 'flowDetailsRequest',
-        detailsResp = 'flowDetailsResponse';
+        detailsResp = 'flowDetailsResponse',
+
+        propOrder = [
+            'flowId', 'priority'
+        ],
+        friendlyProps = [
+            'Flow ID', 'Flow Priority'
+        ];
 
     function closePanel() {
         if (detailsPanel.isVisible()) {
@@ -62,6 +69,10 @@
         div.on('click', closePanel);
     }
 
+    function handleEscape() {
+        return closePanel();
+    }
+
     function setUpPanel() {
         var container, closeBtn, tblDiv;
         detailsPanel.empty();
@@ -73,17 +84,32 @@
         addCloseBtn(closeBtn);
         iconDiv = top.append('div').classed('dev-icon', true);
         top.append('h2');
-        topContent = top.append('div').classed('top-content', true);
+        topTable = top.append('div').classed('top-content', true)
+            .append('table');
         top.append('hr');
 
         //ToDo add more details
     }
 
-    function populateTop(details) {
-        is.loadEmbeddedIcon(iconDiv, 'm_flows', 40);
-        top.select('h2').html(details.id);
+    function addProp(tbody, index, value) {
+        var tr = tbody.append('tr');
 
-        //ToDo : Add more details
+        function addCell(cls, txt) {
+            tr.append('td').attr('class', cls).html(txt);
+        }
+        addCell('label', friendlyProps[index] + ' :');
+        addCell('value', value);
+    }
+
+    function populateTop(details) {
+        is.loadEmbeddedIcon(iconDiv, 'flowTable', 40);
+        top.select('h2').html(details.flowId);
+
+        var tbody = topTable.append('tbody');
+
+        propOrder.forEach(function (prop, i) {
+            addProp(tbody, i, details[prop]);
+        });
     }
 
     function createDetailsPane() {
@@ -101,22 +127,18 @@
     }
 
     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);
+        $log.debug("Got response from server :", data);
+        $scope.panelData = data.details;
+        $scope.$apply();
     }
 
     angular.module('ovFlow', [])
@@ -173,15 +195,16 @@
             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.$on('$destroy', function () {
+                 wss.unbindHandlers(handlers);
+             });
+
             $scope.briefToggle = function () {
                 $scope.brief = !$scope.brief;
             };
@@ -222,7 +245,22 @@
             } else {
                 initPanel();
             }
-
+            // create key bindings to handle panel
+            ks.keyBindings({
+                esc: [handleEscape, 'Close the details panel'],
+                _helpFormat: ['esc']
+            });
+            ks.gestureNotes([
+                ['click', 'Select a row to show cluster node details'],
+                ['scroll down', 'See available cluster nodes']
+            ]);
+            // if the panelData changes
+            scope.$watch('panelData', function () {
+                if (!fs.isEmptyObject(scope.panelData)) {
+                    populateDetails(scope.panelData);
+                    detailsPanel.show();
+                }
+            });
             // if the window size changes
             unbindWatch = $rootScope.$watchCollection(
                 function () {