Updated GUI Archetype to implement a simple table view.
Change-Id: I1e4faa457d7407f81b1926949a09e8c4570399e2
Showing
4 changed files
with
294 additions
and
35 deletions
tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiComponent.java
| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | #set( $symbol_dollar = '$' ) | 2 | #set( $symbol_dollar = '$' ) |
| 3 | #set( $symbol_escape = '\' ) | 3 | #set( $symbol_escape = '\' ) |
| 4 | /* | 4 | /* |
| 5 | - * Copyright 2014 Open Networking Laboratory | 5 | + * Copyright 2014,2015 Open Networking Laboratory |
| 6 | * | 6 | * |
| 7 | * Licensed under the Apache License, Version 2.0 (the "License"); | 7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | * you may not use this file except in compliance with the License. | 8 | * you may not use this file except in compliance with the License. |
| ... | @@ -18,25 +18,19 @@ | ... | @@ -18,25 +18,19 @@ |
| 18 | */ | 18 | */ |
| 19 | package ${package}; | 19 | package ${package}; |
| 20 | 20 | ||
| 21 | -import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 22 | import com.google.common.collect.ImmutableList; | 21 | import com.google.common.collect.ImmutableList; |
| 23 | -import com.google.common.collect.ImmutableSet; | ||
| 24 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
| 25 | import org.apache.felix.scr.annotations.Component; | 23 | import org.apache.felix.scr.annotations.Component; |
| 26 | import org.apache.felix.scr.annotations.Deactivate; | 24 | import org.apache.felix.scr.annotations.Deactivate; |
| 27 | -import org.apache.felix.scr.annotations.Service; | ||
| 28 | import org.apache.felix.scr.annotations.Reference; | 25 | import org.apache.felix.scr.annotations.Reference; |
| 29 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 26 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 30 | -import org.onosproject.ui.RequestHandler; | ||
| 31 | import org.onosproject.ui.UiExtension; | 27 | import org.onosproject.ui.UiExtension; |
| 32 | import org.onosproject.ui.UiExtensionService; | 28 | import org.onosproject.ui.UiExtensionService; |
| 33 | -import org.onosproject.ui.UiMessageHandler; | ||
| 34 | import org.onosproject.ui.UiMessageHandlerFactory; | 29 | import org.onosproject.ui.UiMessageHandlerFactory; |
| 35 | import org.onosproject.ui.UiView; | 30 | import org.onosproject.ui.UiView; |
| 36 | import org.slf4j.Logger; | 31 | import org.slf4j.Logger; |
| 37 | import org.slf4j.LoggerFactory; | 32 | import org.slf4j.LoggerFactory; |
| 38 | 33 | ||
| 39 | -import java.util.Collection; | ||
| 40 | import java.util.List; | 34 | import java.util.List; |
| 41 | 35 | ||
| 42 | /** | 36 | /** |
| ... | @@ -62,7 +56,8 @@ public class AppUiComponent { | ... | @@ -62,7 +56,8 @@ public class AppUiComponent { |
| 62 | ); | 56 | ); |
| 63 | 57 | ||
| 64 | // Application UI extension | 58 | // Application UI extension |
| 65 | - protected UiExtension extension = new UiExtension(uiViews, messageHandlerFactory, | 59 | + protected UiExtension extension = |
| 60 | + new UiExtension(uiViews, messageHandlerFactory, | ||
| 66 | getClass().getClassLoader()); | 61 | getClass().getClassLoader()); |
| 67 | 62 | ||
| 68 | @Activate | 63 | @Activate |
| ... | @@ -77,24 +72,4 @@ public class AppUiComponent { | ... | @@ -77,24 +72,4 @@ public class AppUiComponent { |
| 77 | log.info("Stopped"); | 72 | log.info("Stopped"); |
| 78 | } | 73 | } |
| 79 | 74 | ||
| 80 | - // Application UI message handler | ||
| 81 | - private class AppUiMessageHandler extends UiMessageHandler { | ||
| 82 | - | ||
| 83 | - @Override | ||
| 84 | - protected Collection<RequestHandler> createRequestHandlers() { | ||
| 85 | - return ImmutableSet.of(new SampleRequest()); | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | - private class SampleRequest extends RequestHandler { | ||
| 89 | - public SampleRequest() { | ||
| 90 | - super("sampleRequest"); | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - @Override | ||
| 94 | - public void process(long sid, ObjectNode objectNode) { | ||
| 95 | - log.info("We got a message: {}", objectNode); | ||
| 96 | - } | ||
| 97 | - } | ||
| 98 | - } | ||
| 99 | - | ||
| 100 | } | 75 | } | ... | ... |
| 1 | +#set( $symbol_pound = '#' ) | ||
| 2 | +#set( $symbol_dollar = '$' ) | ||
| 3 | +#set( $symbol_escape = '\' ) | ||
| 4 | +/* | ||
| 5 | + * Copyright 2014,2015 Open Networking Laboratory | ||
| 6 | + * | ||
| 7 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 8 | + * you may not use this file except in compliance with the License. | ||
| 9 | + * You may obtain a copy of the License at | ||
| 10 | + * | ||
| 11 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 12 | + * | ||
| 13 | + * Unless required by applicable law or agreed to in writing, software | ||
| 14 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 15 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 16 | + * See the License for the specific language governing permissions and | ||
| 17 | + * limitations under the License. | ||
| 18 | + */ | ||
| 19 | +package ${package}; | ||
| 20 | + | ||
| 21 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 22 | +import com.google.common.collect.ImmutableSet; | ||
| 23 | +import org.onosproject.ui.RequestHandler; | ||
| 24 | +import org.onosproject.ui.UiMessageHandler; | ||
| 25 | +import org.onosproject.ui.table.TableModel; | ||
| 26 | +import org.onosproject.ui.table.TableRequestHandler; | ||
| 27 | +import org.slf4j.Logger; | ||
| 28 | +import org.slf4j.LoggerFactory; | ||
| 29 | + | ||
| 30 | +import java.lang.Override; | ||
| 31 | +import java.util.ArrayList; | ||
| 32 | +import java.util.Collection; | ||
| 33 | +import java.util.List; | ||
| 34 | + | ||
| 35 | +/** | ||
| 36 | + * Skeletal ONOS UI message handler. | ||
| 37 | + * <p> | ||
| 38 | + * This example specifically supporting a "table" view. | ||
| 39 | + */ | ||
| 40 | +public class AppUiMessageHandler extends UiMessageHandler { | ||
| 41 | + | ||
| 42 | + private static final String SAMPLE_DATA_REQ = "sampleDataRequest"; | ||
| 43 | + private static final String SAMPLE_DATA_RESP = "sampleDataResponse"; | ||
| 44 | + private static final String SAMPLES = "samples"; | ||
| 45 | + | ||
| 46 | + private static final String SAMPLE_DETAIL_REQ = "sampleDetailsRequest"; | ||
| 47 | + private static final String SAMPLE_DETAIL_RESP = "sampleDetailsResponse"; | ||
| 48 | + private static final String DETAILS = "details"; | ||
| 49 | + | ||
| 50 | + private static final String ID = "id"; | ||
| 51 | + private static final String LABEL = "label"; | ||
| 52 | + private static final String CODE = "code"; | ||
| 53 | + private static final String COMMENT = "comment"; | ||
| 54 | + private static final String RESULT = "result"; | ||
| 55 | + | ||
| 56 | + private static final String[] COLUMN_IDS = { ID, LABEL, CODE }; | ||
| 57 | + | ||
| 58 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
| 59 | + | ||
| 60 | + | ||
| 61 | + @Override | ||
| 62 | + protected Collection<RequestHandler> createRequestHandlers() { | ||
| 63 | + return ImmutableSet.of( | ||
| 64 | + new SampleDataRequestHandler(), | ||
| 65 | + new SampleDetailRequestHandler() | ||
| 66 | + ); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + // handler for sample table requests | ||
| 70 | + private final class SampleDataRequestHandler extends TableRequestHandler { | ||
| 71 | + | ||
| 72 | + private SampleDataRequestHandler() { | ||
| 73 | + super(SAMPLE_DATA_REQ, SAMPLE_DATA_RESP, SAMPLES); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + // if necessary, override defaultColumnId() -- if it isn't "id" | ||
| 77 | + | ||
| 78 | + @Override | ||
| 79 | + protected String[] getColumnIds() { | ||
| 80 | + return COLUMN_IDS; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + @Override | ||
| 84 | + protected void populateTable(TableModel tm, ObjectNode payload) { | ||
| 85 | + // === set custom column cell formatters/comparators if need be... | ||
| 86 | + // tm.setFormatter(CODE, new CodeFormatter()); | ||
| 87 | + // tm.setComparator(CODE, new CodeComparator()); | ||
| 88 | + | ||
| 89 | + // === retrieve table row items from some service... | ||
| 90 | + // SomeService ss = get(SomeService.class); | ||
| 91 | + // List<Item> items = ss.getItems() | ||
| 92 | + | ||
| 93 | + // fake data for demonstration purposes... | ||
| 94 | + List<Item> items = getItems(); | ||
| 95 | + for (Item item: items) { | ||
| 96 | + populateRow(tm.addRow(), item); | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + private void populateRow(TableModel.Row row, Item item) { | ||
| 101 | + row.cell(ID, item.id()) | ||
| 102 | + .cell(LABEL, item.label()) | ||
| 103 | + .cell(CODE, item.code()); | ||
| 104 | + } | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + | ||
| 108 | + // handler for sample item details requests | ||
| 109 | + private final class SampleDetailRequestHandler extends RequestHandler { | ||
| 110 | + | ||
| 111 | + private SampleDetailRequestHandler() { | ||
| 112 | + super(SAMPLE_DETAIL_REQ); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + @Override | ||
| 116 | + public void process(long sid, ObjectNode payload) { | ||
| 117 | + String id = string(payload, ID, "(none)"); | ||
| 118 | + | ||
| 119 | + // SomeService ss = get(SomeService.class); | ||
| 120 | + // Item item = ss.getItemDetails(id) | ||
| 121 | + | ||
| 122 | + // fake data for demonstration purposes... | ||
| 123 | + Item item = getItem(id); | ||
| 124 | + | ||
| 125 | + ObjectNode rootNode = MAPPER.createObjectNode(); | ||
| 126 | + ObjectNode data = MAPPER.createObjectNode(); | ||
| 127 | + rootNode.set(DETAILS, data); | ||
| 128 | + | ||
| 129 | + if (item == null) { | ||
| 130 | + rootNode.put(RESULT, "Item with id '" + id + "' not found"); | ||
| 131 | + log.warn("attempted to get item detail for id '{}'", id); | ||
| 132 | + | ||
| 133 | + } else { | ||
| 134 | + rootNode.put(RESULT, "Found item with id '" + id + "'"); | ||
| 135 | + | ||
| 136 | + data.put(ID, item.id()); | ||
| 137 | + data.put(LABEL, item.label()); | ||
| 138 | + data.put(CODE, item.code()); | ||
| 139 | + data.put(COMMENT, "Some arbitrary comment"); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + sendMessage(SAMPLE_DETAIL_RESP, 0, rootNode); | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + | ||
| 147 | + // =================================================================== | ||
| 148 | + // NOTE: The code below this line is to create fake data for this | ||
| 149 | + // sample code. Normally you would use existing services to | ||
| 150 | + // provide real data. | ||
| 151 | + | ||
| 152 | + // Lookup a single item. | ||
| 153 | + private static Item getItem(String id) { | ||
| 154 | + // We realize this code is really inefficient, but | ||
| 155 | + // it suffices for our purposes of demonstration... | ||
| 156 | + for (Item item : getItems()) { | ||
| 157 | + if (item.id().equals(id)) { | ||
| 158 | + return item; | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + return null; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + // Produce a list of items. | ||
| 165 | + private static List<Item> getItems() { | ||
| 166 | + List<Item> items = new ArrayList<>(); | ||
| 167 | + items.add(new Item("item-1", "foo", 42)); | ||
| 168 | + items.add(new Item("item-2", "bar", 99)); | ||
| 169 | + items.add(new Item("item-3", "baz", 65)); | ||
| 170 | + return items; | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + // Simple model class to provide sample data | ||
| 174 | + private static class Item { | ||
| 175 | + private final String id; | ||
| 176 | + private final String label; | ||
| 177 | + private final int code; | ||
| 178 | + | ||
| 179 | + Item(String id, String label, int code) { | ||
| 180 | + this.id = id; | ||
| 181 | + this.label = label; | ||
| 182 | + this.code = code; | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + String id() { return id; } | ||
| 186 | + String label() { return label; } | ||
| 187 | + int code() { return code; } | ||
| 188 | + } | ||
| 189 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | - | ||
| 2 | <!-- partial HTML --> | 1 | <!-- partial HTML --> |
| 3 | <div id="ov-sample"> | 2 | <div id="ov-sample"> |
| 4 | - <h2>Sample App View</h2> | 3 | + <div class="tabular-header"> |
| 4 | + <h2>Items ({{tableData.length}} total)</h2> | ||
| 5 | + <div class="ctrl-btns"> | ||
| 6 | + <div class="refresh" ng-class="{active: autoRefresh}" | ||
| 7 | + icon icon-id="refresh" icon-size="36" | ||
| 8 | + tooltip tt-msg="autoRefreshTip" | ||
| 9 | + ng-click="toggleRefresh()"></div> | ||
| 10 | + </div> | ||
| 11 | + </div> | ||
| 12 | + | ||
| 13 | + <div class="summary-list" onos-table-resize> | ||
| 14 | + | ||
| 15 | + <div class="table-header" onos-sortable-header> | ||
| 16 | + <table> | ||
| 17 | + <tr> | ||
| 18 | + <td colId="id" sortable> Item ID </td> | ||
| 19 | + <td colId="label" sortable> Label </td> | ||
| 20 | + <td colId="code" sortable> Code </td> | ||
| 21 | + </tr> | ||
| 22 | + </table> | ||
| 23 | + </div> | ||
| 24 | + | ||
| 25 | + <div class="table-body"> | ||
| 26 | + <table> | ||
| 27 | + <tr ng-if="!tableData.length" class="no-data"> | ||
| 28 | + <td colspan="3"> | ||
| 29 | + No Items found | ||
| 30 | + </td> | ||
| 31 | + </tr> | ||
| 32 | + | ||
| 33 | + <tr ng-repeat="item in tableData track by $index" | ||
| 34 | + ng-click="selectCallback($event, item)" | ||
| 35 | + ng-class="{selected: item.id === selId}"> | ||
| 36 | + <td>{{item.id}}</td> | ||
| 37 | + <td>{{item.label}}</td> | ||
| 38 | + <td>{{item.code}}</td> | ||
| 39 | + </tr> | ||
| 40 | + </table> | ||
| 41 | + </div> | ||
| 42 | + | ||
| 43 | + </div> | ||
| 5 | 44 | ||
| 6 | - <p> {{ctrl.msg}} </p> | 45 | + <item-details-panel></item-details-panel> |
| 7 | </div> | 46 | </div> | ... | ... |
| ... | @@ -2,14 +2,70 @@ | ... | @@ -2,14 +2,70 @@ |
| 2 | (function () { | 2 | (function () { |
| 3 | 'use strict'; | 3 | 'use strict'; |
| 4 | 4 | ||
| 5 | + // injected refs | ||
| 6 | + var $log, $scope, fs, mast, ps, wss; | ||
| 7 | + | ||
| 8 | + // internal state | ||
| 9 | + var selRow, | ||
| 10 | + detailsPanel, | ||
| 11 | + pStartY, pHeight, | ||
| 12 | + wSize; | ||
| 13 | + | ||
| 14 | + // constants | ||
| 15 | + var topPadding = 20, | ||
| 16 | + | ||
| 17 | + detailsReq = 'sampleDetailsRequest', | ||
| 18 | + detailsResp = 'sampleDetailsResponse', | ||
| 19 | + pName = 'item-details-panel', | ||
| 20 | + | ||
| 21 | + propOrder = [ 'id', 'label', 'code'], | ||
| 22 | + friendlyProps = [ 'Item ID', 'Item Label', 'Special Code' ]; | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + function respDetailsCb(data) { | ||
| 26 | + $scope.panelData = data.details; | ||
| 27 | + $scope.$apply(); | ||
| 28 | + } | ||
| 29 | + | ||
| 5 | angular.module('ovSample', []) | 30 | angular.module('ovSample', []) |
| 6 | .controller('OvSampleCtrl', | 31 | .controller('OvSampleCtrl', |
| 7 | - ['$log', '$scope', | 32 | + ['$log', '$scope', 'TableBuilderService', |
| 33 | + 'FnService', 'WebSocketService', | ||
| 34 | + | ||
| 35 | + function (_$log_, _$scope_, tbs, _fs_, _wss_) { | ||
| 36 | + $log = _$log_; | ||
| 37 | + $scope = _$scope_; | ||
| 38 | + fs = _fs_; | ||
| 39 | + wss = _wss_; | ||
| 40 | + | ||
| 41 | + var handlers = {}; | ||
| 42 | + | ||
| 43 | + $scope.panelData = []; | ||
| 44 | + | ||
| 45 | + function selCb($event, row) { | ||
| 46 | + selRow = angular.element($event.currentTarget); | ||
| 47 | + if ($scope.selId) { | ||
| 48 | + wss.sendEvent(detailsReq, { id: row.id }); | ||
| 49 | + } else { | ||
| 50 | + $log.debug('need to hide details panel'); | ||
| 51 | + //detailsPanel.hide() | ||
| 52 | + } | ||
| 53 | + $log.debug('Got a click on:', row); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + tbs.buildTable({ | ||
| 57 | + scope: $scope, | ||
| 58 | + tag: 'sample', | ||
| 59 | + selCb: selCb | ||
| 60 | + }); | ||
| 8 | 61 | ||
| 9 | - function ($log, $scope) { | 62 | + // details response handler |
| 10 | - var self = this; | 63 | + handlers[detailsResp] = respDetailsCb; |
| 64 | + wss.bindHandlers(handlers); | ||
| 11 | 65 | ||
| 12 | - self.msg = 'A message from our app...'; | 66 | + $scope.$on('$destroy', function () { |
| 67 | + wss.unbindHandlerse(handlers); | ||
| 68 | + }); | ||
| 13 | 69 | ||
| 14 | $log.log('OvSampleCtrl has been created'); | 70 | $log.log('OvSampleCtrl has been created'); |
| 15 | }]); | 71 | }]); | ... | ... |
-
Please register or login to post a comment