ONOS-2422 - GUI -- Sample client side code for maven archetypes updated.

Change-Id: I3ce65ab83b24cd04498913cf1fabf8eabb67ba14
diff --git a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.css b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.css
index 9e4e761..c492e20 100644
--- a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.css
+++ b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.css
@@ -1,16 +1,35 @@
 /* css for sample app view */
 
-#ov-sample p {
-    margin: 0 30px;
-    padding: 10px;
-    border: 2px solid;
+#ov-sample h2 {
+    display: inline-block;
 }
 
-.light #ov-sample p {
-    color: darkblue;
-    border-color: #88c;
+/* Panel Styling */
+#item-details-panel.floatpanel {
+    position: absolute;
+    top: 115px;
 }
-.dark #ov-sample p {
-    color: #aac;
-    border-color: #448;
+
+.light #item-details-panel.floatpanel {
+    background-color: rgb(229, 234, 237);
+}
+.dark #item-details-panel.floatpanel {
+    background-color: #3A4042;
+}
+
+#item-details-panel h3 {
+    margin: 0;
+    font-size: large;
+}
+
+#item-details-panel h4 {
+    margin: 0;
+}
+
+#item-details-panel td {
+    padding: 5px;
+}
+#item-details-panel td.label {
+    font-style: italic;
+    opacity: 0.8;
 }
\ No newline at end of file
diff --git a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.html b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.html
index de67585..03a7383 100644
--- a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.html
+++ b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.html
@@ -15,9 +15,9 @@
         <div class="table-header" onos-sortable-header>
             <table>
                 <tr>
-                    <td colId="id" sortable> Item ID </td>
-                    <td colId="label" sortable> Label </td>
-                    <td colId="code" sortable> Code </td>
+                    <td colId="id" sortable>Item ID </td>
+                    <td colId="label" sortable>Label </td>
+                    <td colId="code" sortable>Code </td>
                 </tr>
             </table>
         </div>
diff --git a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.js b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.js
index 37b8988..2d4aed4 100644
--- a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.js
+++ b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.js
@@ -3,27 +3,44 @@
     'use strict';
 
     // injected refs
-    var $log, $scope, fs, mast, ps, wss;
-
-    // internal state
-    var selRow,
-        detailsPanel,
-        pStartY, pHeight,
-        wSize;
+    var $log, $scope, fs, wss, ps;
 
     // constants
-    var topPadding = 20,
-
-        detailsReq = 'sampleDetailsRequest',
+    var detailsReq = 'sampleDetailsRequest',
         detailsResp = 'sampleDetailsResponse',
         pName = 'item-details-panel',
 
-        propOrder = [ 'id', 'label', 'code'],
-        friendlyProps = [ 'Item ID', 'Item Label', 'Special Code' ];
+        propOrder = ['id', 'label', 'code'],
+        friendlyProps = ['Item ID', 'Item Label', 'Special Code'];
 
 
+    function addProp(tbody, index, value) {
+        var tr = tbody.append('tr');
+
+        function addCell(cls, txt) {
+            tr.append('td').attr('class', cls).html(txt);
+        }
+        addCell('label', friendlyProps[index] + ' :');
+        addCell('value', value);
+    }
+
+    function populatePanel(panel) {
+        var title = panel.append('h3'),
+            tbody = panel.append('table').append('tbody');
+
+        title.text('Item Details');
+
+        propOrder.forEach(function (prop, i) {
+            addProp(tbody, i, $scope.panelDetails[prop]);
+        });
+
+        panel.append('hr');
+        panel.append('h4').text('Comments');
+        panel.append('p').text($scope.panelDetails.comment);
+    }
+
     function respDetailsCb(data) {
-        $scope.panelData = data.details;
+        $scope.panelDetails = data.details;
         $scope.$apply();
     }
 
@@ -39,34 +56,84 @@
                 wss = _wss_;
 
                 var handlers = {};
+                $scope.panelDetails = {};
 
-                $scope.panelData = [];
+                // details response handler
+                handlers[detailsResp] = respDetailsCb;
+                wss.bindHandlers(handlers);
 
+                // custom selection callback
                 function selCb($event, row) {
-                    selRow = angular.element($event.currentTarget);
                     if ($scope.selId) {
                         wss.sendEvent(detailsReq, { id: row.id });
                     } else {
-                        $log.debug('need to hide details panel');
-                        //detailsPanel.hide()
+                        $scope.hidePanel();
                     }
                     $log.debug('Got a click on:', row);
                 }
 
+                // TableBuilderService creating a table for us
                 tbs.buildTable({
                     scope: $scope,
                     tag: 'sample',
                     selCb: selCb
                 });
 
-                // details response handler
-                handlers[detailsResp] = respDetailsCb;
-                wss.bindHandlers(handlers);
-
+                // cleanup
                 $scope.$on('$destroy', function () {
-                    wss.unbindHandlerse(handlers);
+                    wss.unbindHandlers(handlers);
                 });
 
                 $log.log('OvSampleCtrl has been created');
-            }]);
+            }])
+
+        .directive('itemDetailsPanel', ['PanelService', 'KeyService',
+            function (_ps_, ks) {
+            return {
+                restrict: 'E',
+                link: function (scope, element, attrs) {
+                    ps = _ps_;
+                    // insert details panel with PanelService
+                    // create the panel
+                    var panel = ps.createPanel(pName, {
+                        width: 200,
+                        margin: 20,
+                        hideMargin: 0
+                    });
+                    panel.hide();
+                    scope.hidePanel = function () { panel.hide(); };
+
+                    function closePanel() {
+                        if (panel.isVisible()) {
+                            $scope.selId = null;
+                            panel.hide();
+                        }
+                    }
+
+                    // create key bindings to handle panel
+                    ks.keyBindings({
+                        esc: [closePanel, 'Close the details panel'],
+                        _helpFormat: ['esc']
+                    });
+                    ks.gestureNotes([
+                        ['click', 'Select a row to show item details']
+                    ]);
+
+                    // update the panel's contents when the data is changed
+                    scope.$watch('panelDetails', function () {
+                        if (!fs.isEmptyObject(scope.panelDetails)) {
+                            panel.empty();
+                            populatePanel(panel);
+                            panel.show();
+                        }
+                    });
+
+                    // cleanup on destroyed scope
+                    scope.$on('$destroy', function () {
+                        ks.unbindKeys();
+                        ps.destroyPanel(pName);
+                    });
+                }
+            };
+        }]);
 }());
diff --git a/web/gui/src/main/webapp/app/view/device/device.js b/web/gui/src/main/webapp/app/view/device/device.js
index 1f2a8ca..d376fe9 100644
--- a/web/gui/src/main/webapp/app/view/device/device.js
+++ b/web/gui/src/main/webapp/app/view/device/device.js
@@ -185,6 +185,7 @@
             position: 'absolute',
             top: pStartY + 'px'
         });
+        $scope.hidePanel = function () { detailsPanel.hide(); };
         detailsPanel.hide();
     }
 
@@ -207,7 +208,7 @@
             ns = _ns_;
             var params = $location.search(),
                 handlers = {};
-            $scope.panelData = [];
+            $scope.panelData = {};
             $scope.flowTip = 'Show flow view for selected device';
             $scope.portTip = 'Show port view for selected device';
             $scope.groupTip = 'Show group view for selected device';
@@ -226,7 +227,7 @@
                 if ($scope.selId) {
                     wss.sendEvent(detailsReq, { id: row.id });
                 } else {
-                    detailsPanel.hide();
+                    $scope.hidePanel();
                 }
                 $log.debug('Got a click on:', row);
             }