Simplified Custom View code (ui archetype).

Change-Id: Ia9d1f1023f287653d00abc3a2f9cf7498f3875e0
diff --git a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiMessageHandler.java b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiMessageHandler.java
index e996444..d648632 100644
--- a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiMessageHandler.java
+++ b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiMessageHandler.java
@@ -22,165 +22,56 @@
 import com.google.common.collect.ImmutableSet;
 import org.onosproject.ui.RequestHandler;
 import org.onosproject.ui.UiMessageHandler;
-import org.onosproject.ui.table.TableModel;
-import org.onosproject.ui.table.TableRequestHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.lang.Override;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.List;
 
 /**
  * Skeletal ONOS UI Custom-View message handler.
  */
 public class AppUiMessageHandler extends UiMessageHandler {
-    // TODO: reduce the code down to just the custom view example
 
     private static final String SAMPLE_CUSTOM_DATA_REQ = "sampleCustomDataRequest";
     private static final String SAMPLE_CUSTOM_DATA_RESP = "sampleCustomDataResponse";
-    private static final String SAMPLE_CUSTOMS = "sampleCustoms";
 
-    private static final String SAMPLE_CUSTOM_DETAIL_REQ = "sampleCustomDetailsRequest";
-    private static final String SAMPLE_CUSTOM_DETAIL_RESP = "sampleCustomDetailsResponse";
-    private static final String DETAILS = "details";
-
-    private static final String ID = "id";
-    private static final String LABEL = "label";
-    private static final String CODE = "code";
-    private static final String COMMENT = "comment";
-    private static final String RESULT = "result";
-
-    private static final String[] COLUMN_IDS = { ID, LABEL, CODE };
+    private static final String NUMBER = "number";
+    private static final String SQUARE = "square";
+    private static final String CUBE = "cube";
+    private static final String MESSAGE = "message";
+    private static final String MSG_FORMAT = "Next incrememt is %d units";
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
+    private long someNumber = 1;
+    private long someIncrement = 1;
 
     @Override
     protected Collection<RequestHandler> createRequestHandlers() {
         return ImmutableSet.of(
-                new SampleCustomDataRequestHandler(),
-                new SampleCustomDetailRequestHandler()
+                new SampleCustomDataRequestHandler()
         );
     }
 
-    // handler for sample table requests
-    private final class SampleCustomDataRequestHandler extends TableRequestHandler {
+    // handler for sample data requests
+    private final class SampleCustomDataRequestHandler extends RequestHandler {
 
         private SampleCustomDataRequestHandler() {
-            super(SAMPLE_CUSTOM_DATA_REQ, SAMPLE_CUSTOM_DATA_RESP, SAMPLE_CUSTOMS);
-        }
-
-        @Override
-        protected String[] getColumnIds() {
-            return COLUMN_IDS;
-        }
-
-        @Override
-        protected void populateTable(TableModel tm, ObjectNode payload) {
-            // === set custom column cell formatters/comparators if need be...
-            // tm.setFormatter(CODE, new CodeFormatter());
-            // tm.setComparator(CODE, new CodeComparator());
-
-            // === retrieve table row items from some service...
-            // SomeService ss = get(SomeService.class);
-            // List<Item> items = ss.getItems()
-
-            // fake data for demonstration purposes...
-            List<Item> items = getItems();
-            for (Item item: items) {
-                populateRow(tm.addRow(), item);
-            }
-        }
-
-        private void populateRow(TableModel.Row row, Item item) {
-            row.cell(ID, item.id())
-                    .cell(LABEL, item.label())
-                    .cell(CODE, item.code());
-        }
-    }
-
-
-    // handler for sample item details requests
-    private final class SampleCustomDetailRequestHandler extends RequestHandler {
-
-        private SampleCustomDetailRequestHandler() {
-            super(SAMPLE_CUSTOM_DETAIL_REQ);
+            super(SAMPLE_CUSTOM_DATA_REQ);
         }
 
         @Override
         public void process(long sid, ObjectNode payload) {
-            String id = string(payload, ID, "(none)");
+            someIncrement++;
+            someNumber += someIncrement;
+            log.debug("Computing data for {}...", someNumber);
 
-            // SomeService ss = get(SomeService.class);
-            // Item item = ss.getItemDetails(id)
-
-            // fake data for demonstration purposes...
-            Item item = getItem(id);
-
-            ObjectNode rootNode = MAPPER.createObjectNode();
-            ObjectNode data = MAPPER.createObjectNode();
-            rootNode.set(DETAILS, data);
-
-            if (item == null) {
-                rootNode.put(RESULT, "Item with id '" + id + "' not found");
-                log.warn("attempted to get item detail for id '{}'", id);
-
-            } else {
-                rootNode.put(RESULT, "Found item with id '" + id + "'");
-
-                data.put(ID, item.id());
-                data.put(LABEL, item.label());
-                data.put(CODE, item.code());
-                data.put(COMMENT, "Some arbitrary comment");
-            }
-
-            sendMessage(SAMPLE_CUSTOM_DETAIL_RESP, 0, rootNode);
+            ObjectNode result = objectNode();
+            result.put(NUMBER, someNumber);
+            result.put(SQUARE, someNumber * someNumber);
+            result.put(CUBE, someNumber * someNumber * someNumber);
+            result.put(MESSAGE, String.format(MSG_FORMAT, someIncrement + 1));
+            sendMessage(SAMPLE_CUSTOM_DATA_RESP, 0, result);
         }
     }
-
-
-    // ===================================================================
-    // NOTE: The code below this line is to create fake data for this
-    //       sample code. Normally you would use existing services to
-    //       provide real data.
-
-    // Lookup a single item.
-    private static Item getItem(String id) {
-        // We realize this code is really inefficient, but
-        // it suffices for our purposes of demonstration...
-        for (Item item : getItems()) {
-            if (item.id().equals(id)) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    // Produce a list of items.
-    private static List<Item> getItems() {
-        List<Item> items = new ArrayList<>();
-        items.add(new Item("item-1", "foo", 42));
-        items.add(new Item("item-2", "bar", 99));
-        items.add(new Item("item-3", "baz", 65));
-        return items;
-    }
-
-    // Simple model class to provide sample data
-    private static class Item {
-        private final String id;
-        private final String label;
-        private final int code;
-
-        Item(String id, String label, int code) {
-            this.id = id;
-            this.label = label;
-            this.code = code;
-        }
-
-        String id() { return id; }
-        String label() { return label; }
-        int code() { return code; }
-    }
 }
\ No newline at end of file
diff --git a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.css b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.css
index 72b7085..ffeac0a 100644
--- a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.css
+++ b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.css
@@ -1,35 +1,48 @@
-/* css for sample app view */
+/* css for sample app custom view */
 
-#ov-sample h2 {
-    display: inline-block;
+#ov-sample-custom {
+    padding: 20px;
+}
+.light #ov-sample-custom {
+    color: navy;
+}
+.dark #ov-sample-custom {
+    color: #88f;
 }
 
-/* Panel Styling */
-#ov-sample-custom-item-details-panel.floatpanel {
-    position: absolute;
-    top: 115px;
+#ov-sample-custom .button-panel {
+    margin: 10px;
+    width: 200px;
 }
 
-.light #ov-sample-custom-item-details-panel.floatpanel {
-    background-color: rgb(229, 234, 237);
+.light #ov-sample-custom .button-panel {
+    background-color: #ccf;
 }
-.dark #ov-sample-custom-item-details-panel.floatpanel {
-    background-color: #3A4042;
+.dark #ov-sample-custom .button-panel {
+    background-color: #444;
 }
 
-#ov-sample-custom-item-details-panel h3 {
-    margin: 0;
-    font-size: large;
+#ov-sample-custom .my-button {
+    cursor: pointer;
+    padding: 4px;
+    text-align: center;
 }
 
-#ov-sample-custom-item-details-panel h4 {
-    margin: 0;
+.light #ov-sample-custom .my-button {
+    color: white;
+    background-color: #99d;
+}
+.dark #ov-sample-custom .my-button {
+    color: black;
+    background-color: #aaa;
 }
 
-#ov-sample-custom-item-details-panel td {
-    padding: 5px;
+#ov-sample-custom .number {
+    font-size: 140%;
+    text-align: right;
 }
-#ov-sample-custom-item-details-panel td.label {
+
+#ov-sample-custom .quote {
+    margin: 10px 20px;
     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/sampleCustom/sampleCustom.html b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.html
index 05f6d58..a0ccfb3 100644
--- a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.html
+++ b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.html
@@ -1,46 +1,32 @@
 <!-- partial HTML -->
 <div id="ov-sample-custom">
-    <div class="tabular-header">
-        <h2>Items ({{tableData.length}} total)</h2>
-        <div class="ctrl-btns">
-            <div class="refresh" ng-class="{active: autoRefresh}"
-                 icon icon-id="refresh" icon-size="36"
-                 tooltip tt-msg="autoRefreshTip"
-                 ng-click="toggleRefresh()"></div>
+    <div class="button-panel">
+        <div class="my-button" ng-click="getData()">
+            Fetch Data
         </div>
     </div>
 
-    <div class="summary-list" onos-table-resize>
+    <div class="data-panel">
+        <table>
+            <tr>
+                <td> Number </td>
+                <td class="number"> {{data.number}} </td>
+            </tr>
+            <tr>
+                <td> Square </td>
+                <td class="number"> {{data.square}} </td>
+            </tr>
+            <tr>
+                <td> Cube </td>
+                <td class="number"> {{data.cube}} </td>
+            </tr>
+        </table>
 
-        <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>
-                </tr>
-            </table>
-        </div>
-
-        <div class="table-body">
-            <table>
-                <tr ng-if="!tableData.length" class="no-data">
-                    <td colspan="3">
-                        No Items found
-                    </td>
-                </tr>
-
-                <tr ng-repeat="item in tableData track by $index"
-                    ng-click="selectCallback($event, item)"
-                    ng-class="{selected: item.id === selId}">
-                    <td>{{item.id}}</td>
-                    <td>{{item.label}}</td>
-                    <td>{{item.code}}</td>
-                </tr>
-            </table>
-        </div>
-
+        <p>
+            A message from our sponsors:
+        </p>
+        <p>
+            <span class="quote">{{data.message}} </span>
+        </p>
     </div>
-
-    <ov-sample-custom-item-details-panel></ov-sample-custom-item-details-panel>
 </div>
diff --git a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.js b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.js
index 7f37c5d..df5b93a 100644
--- a/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.js
+++ b/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sampleCustom/sampleCustom.js
@@ -3,139 +3,67 @@
     'use strict';
 
     // injected refs
-    var $log, $scope, fs, wss;
+    var $log, $scope, wss, ks;
 
     // constants
-    var detailsReq = 'sampleCustomDetailsRequest',
-        detailsResp = 'sampleCustomDetailsResponse',
-        pName = 'ov-sample-custom-item-details-panel',
+    var dataReq = 'sampleCustomDataRequest',
+        dataResp = 'sampleCustomDataResponse';
 
-        propOrder = ['id', 'label', 'code'],
-        friendlyProps = ['Item ID', 'Item Label', 'Special Code'];
+    function addKeyBindings() {
+        var map = {
+            space: [getData, 'Fetch data from server'],
 
+            _helpFormat: [
+                ['space']
+            ]
+        };
 
-    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);
+        ks.keyBindings(map);
     }
 
-    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 getData() {
+        wss.sendEvent(dataReq);
     }
 
-    function respDetailsCb(data) {
-        $scope.panelDetails = data.details;
+    function respDataCb(data) {
+        $scope.data = data;
         $scope.$apply();
     }
 
+
     angular.module('ovSampleCustom', [])
         .controller('OvSampleCustomCtrl',
-        ['$log', '$scope', 'TableBuilderService',
-            'FnService', 'WebSocketService',
+        ['$log', '$scope', 'WebSocketService', 'KeyService',
 
-            function (_$log_, _$scope_, tbs, _fs_, _wss_) {
+            function (_$log_, _$scope_, _wss_, _ks_) {
                 $log = _$log_;
                 $scope = _$scope_;
-                fs = _fs_;
                 wss = _wss_;
+                ks = _ks_;
 
                 var handlers = {};
-                $scope.panelDetails = {};
+                $scope.data = {};
 
-                // details response handler
-                handlers[detailsResp] = respDetailsCb;
+                // data response handler
+                handlers[dataResp] = respDataCb;
                 wss.bindHandlers(handlers);
 
-                // custom selection callback
-                function selCb($event, row) {
-                    if ($scope.selId) {
-                        wss.sendEvent(detailsReq, { id: row.id });
-                    } else {
-                        $scope.hidePanel();
-                    }
-                    $log.debug('Got a click on:', row);
-                }
+                addKeyBindings();
 
-                // TableBuilderService creating a table for us
-                tbs.buildTable({
-                    scope: $scope,
-                    tag: 'sampleCustom',
-                    selCb: selCb
-                });
+                // custom click handler
+                $scope.getData = getData;
+
+                // get data the first time...
+                getData();
 
                 // cleanup
                 $scope.$on('$destroy', function () {
                     wss.unbindHandlers(handlers);
+                    ks.unbindKeys();
                     $log.log('OvSampleCustomCtrl has been destroyed');
                 });
 
                 $log.log('OvSampleCustomCtrl has been created');
-            }])
+            }]);
 
-        .directive('ovSampleCustomItemDetailsPanel', ['PanelService', 'KeyService',
-            function (ps, ks) {
-            return {
-                restrict: 'E',
-                link: function (scope, element, attrs) {
-                    // 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();
-                            return true;
-                        }
-                        return false;
-                    }
-
-                    // 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);
-                    });
-                }
-            };
-        }]);
 }());