Simon Hunt
Committed by Gerrit Code Review

ONOS-3505: Basic behaviour of drivers table implemented.

- WIP -- still need to fix scrolling, styling, etc.

Change-Id: I376155ab1375ea4b4b136969b89f74c3733178b8
...@@ -30,24 +30,24 @@ import org.slf4j.LoggerFactory; ...@@ -30,24 +30,24 @@ import org.slf4j.LoggerFactory;
30 import java.util.ArrayList; 30 import java.util.ArrayList;
31 import java.util.Collection; 31 import java.util.Collection;
32 import java.util.Comparator; 32 import java.util.Comparator;
33 -import java.util.HashMap;
34 import java.util.HashSet; 33 import java.util.HashSet;
35 import java.util.List; 34 import java.util.List;
36 -import java.util.Map;
37 import java.util.Set; 35 import java.util.Set;
38 36
39 /** 37 /**
40 - * Message handler for device view related messages. 38 + * Message handler for driver matrix view related messages.
41 */ 39 */
42 public class DriverViewMessageHandler extends UiMessageHandler { 40 public class DriverViewMessageHandler extends UiMessageHandler {
43 41
44 private final Logger log = LoggerFactory.getLogger(getClass()); 42 private final Logger log = LoggerFactory.getLogger(getClass());
45 43
44 + private static final int ONE = 1;
46 private static final String DRIVER_DATA_REQUEST = "driverDataRequest"; 45 private static final String DRIVER_DATA_REQUEST = "driverDataRequest";
47 private static final String DRIVER_DATA_RESPONSE = "driverDataResponse"; 46 private static final String DRIVER_DATA_RESPONSE = "driverDataResponse";
48 47
49 private static final String DRIVERS = "drivers"; 48 private static final String DRIVERS = "drivers";
50 private static final String BEHAVIOURS = "behaviours"; 49 private static final String BEHAVIOURS = "behaviours";
50 + private static final String MATRIX = "matrix";
51 51
52 private static final Comparator<? super Class<? extends Behaviour>> BEHAVIOUR_BY_NAME = 52 private static final Comparator<? super Class<? extends Behaviour>> BEHAVIOUR_BY_NAME =
53 (o1, o2) -> o1.getSimpleName().compareTo(o2.getSimpleName()); 53 (o1, o2) -> o1.getSimpleName().compareTo(o2.getSimpleName());
...@@ -59,11 +59,12 @@ public class DriverViewMessageHandler extends UiMessageHandler { ...@@ -59,11 +59,12 @@ public class DriverViewMessageHandler extends UiMessageHandler {
59 protected Collection<RequestHandler> createRequestHandlers() { 59 protected Collection<RequestHandler> createRequestHandlers() {
60 return ImmutableSet.of( 60 return ImmutableSet.of(
61 new DataRequestHandler() 61 new DataRequestHandler()
62 + // TODO: for row selection, produce data for detail panel
62 // new DetailRequestHandler() 63 // new DetailRequestHandler()
63 ); 64 );
64 } 65 }
65 66
66 - // handler for device table requests 67 + // handler for driver matrix requests
67 private final class DataRequestHandler extends RequestHandler { 68 private final class DataRequestHandler extends RequestHandler {
68 69
69 private DataRequestHandler() { 70 private DataRequestHandler() {
...@@ -72,54 +73,46 @@ public class DriverViewMessageHandler extends UiMessageHandler { ...@@ -72,54 +73,46 @@ public class DriverViewMessageHandler extends UiMessageHandler {
72 73
73 @Override 74 @Override
74 public void process(long sid, ObjectNode payload) { 75 public void process(long sid, ObjectNode payload) {
75 - // Search for drivers producing two artifacts:
76 - // 1) list of abstract behaviours as column listing
77 - // 2) sparse matrix of drivers-to-concrete behaviours
78 -
79 DriverService driverService = get(DriverService.class); 76 DriverService driverService = get(DriverService.class);
80 77
81 - // Collect all behaviours for all drivers 78 + List<Driver> drivers = new ArrayList<>(driverService.getDrivers());
82 - Map<Driver, Set<Class<? extends Behaviour>>> driverBehaviours = new HashMap<>(); 79 + drivers = orderDrivers(drivers);
83 - driverService.getDrivers().forEach(d -> driverBehaviours.put(d, d.behaviours()));
84 -
85 - // Order all drivers
86 - List<Driver> drivers = orderDrivers(driverBehaviours.keySet());
87 80
88 // Produce a union of all behaviours (and order them) 81 // Produce a union of all behaviours (and order them)
89 - List<Class<? extends Behaviour>> behaviours = orderBehaviours(driverBehaviours.values()); 82 + List<Class<? extends Behaviour>> behaviours = orderBehaviours(drivers);
90 83
91 // Produce a JSON structure and send it 84 // Produce a JSON structure and send it
92 - sendMessage(DRIVER_DATA_RESPONSE, 0, driversJson(driverBehaviours, drivers, behaviours)); 85 + sendMessage(DRIVER_DATA_RESPONSE, 0, driversJson(drivers, behaviours));
93 } 86 }
94 87
95 - private List<Driver> orderDrivers(Set<Driver> drivers) { 88 + private List<Driver> orderDrivers(List<Driver> drivers) {
96 // For now order by alphanumeric name of the driver 89 // For now order by alphanumeric name of the driver
97 - List<Driver> ordered = new ArrayList<>(drivers); 90 + drivers.sort(DRIVER_BY_NAME);
98 - ordered.sort(DRIVER_BY_NAME); 91 + return drivers;
99 - return ordered;
100 } 92 }
101 93
102 - private List<Class<? extends Behaviour>> 94 + private List<Class<? extends Behaviour>> orderBehaviours(List<Driver> drivers) {
103 - orderBehaviours(Collection<Set<Class<? extends Behaviour>>> behaviours) { 95 + // first, produce a set-union of all behaviours from all drivers...
104 - // For now order by alphanumeric name of the abstract behaviour simple name
105 Set<Class<? extends Behaviour>> allBehaviours = new HashSet<>(); 96 Set<Class<? extends Behaviour>> allBehaviours = new HashSet<>();
106 - behaviours.forEach(allBehaviours::addAll); 97 + drivers.forEach(d -> allBehaviours.addAll(d.behaviours()));
98 +
99 + // for now, order by alphanumeric name of the abstract behaviour simple name
107 List<Class<? extends Behaviour>> ordered = new ArrayList<>(allBehaviours); 100 List<Class<? extends Behaviour>> ordered = new ArrayList<>(allBehaviours);
108 ordered.sort(BEHAVIOUR_BY_NAME); 101 ordered.sort(BEHAVIOUR_BY_NAME);
109 return ordered; 102 return ordered;
110 } 103 }
111 104
112 - private ObjectNode driversJson(Map<Driver, Set<Class<? extends Behaviour>>> driverBehaviours, 105 + private ObjectNode driversJson(List<Driver> drivers,
113 - List<Driver> drivers,
114 List<Class<? extends Behaviour>> behaviours) { 106 List<Class<? extends Behaviour>> behaviours) {
115 ObjectNode root = objectNode(); 107 ObjectNode root = objectNode();
116 addBehaviours(root, behaviours); 108 addBehaviours(root, behaviours);
117 addDrivers(root, drivers); 109 addDrivers(root, drivers);
118 - addRelationships(root, drivers, behaviours, driverBehaviours); 110 + addMatrixCells(root, drivers);
119 return root; 111 return root;
120 } 112 }
121 113
122 - private void addBehaviours(ObjectNode root, List<Class<? extends Behaviour>> behaviours) { 114 + private void addBehaviours(ObjectNode root,
115 + List<Class<? extends Behaviour>> behaviours) {
123 ArrayNode array = arrayNode(); 116 ArrayNode array = arrayNode();
124 root.set(BEHAVIOURS, array); 117 root.set(BEHAVIOURS, array);
125 behaviours.forEach(b -> array.add(b.getSimpleName())); 118 behaviours.forEach(b -> array.add(b.getSimpleName()));
...@@ -131,9 +124,19 @@ public class DriverViewMessageHandler extends UiMessageHandler { ...@@ -131,9 +124,19 @@ public class DriverViewMessageHandler extends UiMessageHandler {
131 drivers.forEach(d -> array.add(d.name())); 124 drivers.forEach(d -> array.add(d.name()));
132 } 125 }
133 126
134 - private void addRelationships(ObjectNode root, 127 + private void addMatrixCells(ObjectNode root, List<Driver> drivers) {
135 - List<Driver> drivers, List<Class<? extends Behaviour>> behaviours, 128 + ObjectNode matrix = objectNode();
136 - Map<Driver, Set<Class<? extends Behaviour>>> driverBehaviours) { 129 + root.set(MATRIX, matrix);
130 +
131 + drivers.forEach(d -> {
132 + ObjectNode dnode = objectNode();
133 + matrix.set(d.name(), dnode);
134 +
135 + d.behaviours().forEach(b -> {
136 + // TODO: can put a payload here, rather than a '1' marker
137 + dnode.put(b.getSimpleName(), ONE);
138 + });
139 + });
137 } 140 }
138 } 141 }
139 142
......
1 -/* css for sample table view */ 1 +/* css for driver matrix view */
2 2
3 #ov-driver-matrix h2 { 3 #ov-driver-matrix h2 {
4 display: inline-block; 4 display: inline-block;
5 } 5 }
6 6
7 +#ov-driver-matrix table {
8 + margin-left: 20px;
9 +}
10 +
11 +#ov-driver-matrix .table-header-rotated {
12 + border-collapse: collapse;
13 +}
14 +#ov-driver-matrix .table-header-rotated td {
15 + width: 30px;
16 +}
17 +#ov-driver-matrix .table-header-rotated td.xmark {
18 + background-color: yellow;
19 +}
20 +#ov-driver-matrix .table-header-rotated td {
21 + text-align: center;
22 + padding: 2px 5px;
23 + border: 1px solid #ccc;
24 +}
25 +#ov-driver-matrix .table-header-rotated th.rotate {
26 + height: 140px;
27 + white-space: nowrap;
28 +}
29 +#ov-driver-matrix .table-header-rotated th.rotate > div {
30 + -webkit-transform: translate(25px, 51px) rotate(-45deg);
31 + transform: translate(25px, 51px) rotate(-45deg);
32 + width: 30px;
33 +}
34 +#ov-driver-matrix .table-header-rotated th.rotate > div > span {
35 + border-bottom: 1px solid #ccc;
36 + padding: 5px 10px;
37 +}
38 +#ov-driver-matrix .table-header-rotated th.row-header {
39 + padding: 0 10px;
40 + border-bottom: 1px solid #ccc;
41 + text-align: right;
42 +}
43 +
44 +
7 /* Panel Styling */ 45 /* Panel Styling */
8 #ov-driver-matrix-item-details-panel.floatpanel { 46 #ov-driver-matrix-item-details-panel.floatpanel {
9 position: absolute; 47 position: absolute;
...@@ -33,3 +71,4 @@ ...@@ -33,3 +71,4 @@
33 font-style: italic; 71 font-style: italic;
34 opacity: 0.8; 72 opacity: 0.8;
35 } 73 }
74 +
......
1 <!-- partial HTML --> 1 <!-- partial HTML -->
2 <div id="ov-driver-matrix"> 2 <div id="ov-driver-matrix">
3 <div class="tabular-header"> 3 <div class="tabular-header">
4 - <h2>Items ({{tableData.length}} total)</h2> 4 + <h2>Driver Matrix</h2>
5 <div class="ctrl-btns"> 5 <div class="ctrl-btns">
6 + <!-- TODO: fix (or remove) refresh button -->
6 <div class="refresh" ng-class="{active: autoRefresh}" 7 <div class="refresh" ng-class="{active: autoRefresh}"
7 icon icon-id="refresh" icon-size="36" 8 icon icon-id="refresh" icon-size="36"
8 tooltip tt-msg="autoRefreshTip" 9 tooltip tt-msg="autoRefreshTip"
...@@ -10,37 +11,36 @@ ...@@ -10,37 +11,36 @@
10 </div> 11 </div>
11 </div> 12 </div>
12 13
13 - <div class="summary-list" onos-table-resize> 14 + <!-- TODO: handle resizing / scrolling -->
14 - 15 + <div class="driver-matrix">
15 - <div class="table-header" onos-sortable-header> 16 + <table class="table-header-rotated">
16 - <table> 17 + <thead>
17 <tr> 18 <tr>
18 - <td colId="id" sortable>Item ID </td> 19 + <!-- first column header is not rotated -->
19 - <td colId="label" sortable>Label </td> 20 + <th></th>
20 - <td colId="code" sortable>Code </td> 21 + <!-- following headers are rotated -->
22 + <th class="rotate" ng-repeat="beh in behaviours track by $index">
23 + <div><span>{{beh}}</span></div>
24 + </th>
21 </tr> 25 </tr>
22 - </table>
23 - </div>
24 26
25 - <div class="table-body"> 27 + </thead>
26 - <table>
27 - <tr ng-if="!tableData.length" class="no-data">
28 - <td colspan="3">
29 - No Items found
30 - </td>
31 - </tr>
32 28
33 - <tr ng-repeat="item in tableData track by $index" 29 + <tbody>
34 - ng-click="selectCallback($event, item)" 30 + <tr ng-repeat="drv in drivers track by $index">
35 - ng-class="{selected: item.id === selId}"> 31 + <!--ng-click="selectCallback($event, item)"-->
36 - <td>{{item.id}}</td> 32 + <!--ng-class="{selected: item.id === selId}">-->
37 - <td>{{item.label}}</td> 33 + <th class="row-header">
38 - <td>{{item.code}}</td> 34 + {{drv}}
35 + </th>
36 + <td ng-repeat="beh in behaviours track by $index"
37 + ng-class="{'xmark':cellMarked(drv, beh)}">
38 + {{cellValue(drv, beh)}}
39 + </td>
39 </tr> 40 </tr>
41 + </tbody>
40 </table> 42 </table>
41 </div> 43 </div>
42 44
43 - </div>
44 -
45 <ov-driver-matrix-item-details-panel></ov-driver-matrix-item-details-panel> 45 <ov-driver-matrix-item-details-panel></ov-driver-matrix-item-details-panel>
46 </div> 46 </div>
......
1 -// js for sample app table view 1 +// js for driver view
2 (function () { 2 (function () {
3 'use strict'; 3 'use strict';
4 4
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
8 // constants 8 // constants
9 var detailsReq = 'driverDataRequest', 9 var detailsReq = 'driverDataRequest',
10 detailsResp = 'driverDataResponse', 10 detailsResp = 'driverDataResponse',
11 + // TODO: deal with details panel
11 pName = 'ov-driver-matrix-item-details-panel', 12 pName = 'ov-driver-matrix-item-details-panel',
12 -
13 propOrder = ['id', 'label', 'code'], 13 propOrder = ['id', 'label', 'code'],
14 friendlyProps = ['Item ID', 'Item Label', 'Special Code']; 14 friendlyProps = ['Item ID', 'Item Label', 'Special Code'];
15 15
...@@ -40,9 +40,11 @@ ...@@ -40,9 +40,11 @@
40 } 40 }
41 41
42 function respDetailsCb(data) { 42 function respDetailsCb(data) {
43 - $log.debug(data); 43 + //$log.debug('Matrix Data', data);
44 - //$scope.panelDetails = data.details; 44 + $scope.behaviours = data.behaviours;
45 - //$scope.$apply(); 45 + $scope.drivers = data.drivers;
46 + $scope.matrix = data.matrix;
47 + $scope.$apply();
46 } 48 }
47 49
48 angular.module('ovDriverMatrix', []) 50 angular.module('ovDriverMatrix', [])
...@@ -57,7 +59,9 @@ ...@@ -57,7 +59,9 @@
57 wss = _wss_; 59 wss = _wss_;
58 60
59 var handlers = {}; 61 var handlers = {};
60 - $scope.panelDetails = {}; 62 + $scope.behaviours = [];
63 + $scope.drivers = [];
64 + $scope.matrix = {};
61 65
62 // details response handler 66 // details response handler
63 handlers[detailsResp] = respDetailsCb; 67 handlers[detailsResp] = respDetailsCb;
...@@ -75,12 +79,17 @@ ...@@ -75,12 +79,17 @@
75 // $log.debug('Got a click on:', row); 79 // $log.debug('Got a click on:', row);
76 //} 80 //}
77 81
78 - //// TableBuilderService creating a table for us 82 + function cellHit(d, b) {
79 - //tbs.buildTable({ 83 + var drec = $scope.matrix[d],
80 - // scope: $scope, 84 + brec = drec && drec[b];
81 - // tag: 'driverMatrix', 85 + return !!brec;
82 - // selCb: selCb 86 + }
83 - //}); 87 +
88 + $scope.cellMarked = cellHit;
89 +
90 + $scope.cellValue = function(d, b) {
91 + return cellHit(d, b) ? 'x' : '';
92 + };
84 93
85 // cleanup 94 // cleanup
86 $scope.$on('$destroy', function () { 95 $scope.$on('$destroy', function () {
...@@ -91,6 +100,7 @@ ...@@ -91,6 +100,7 @@
91 $log.log('OvDriverMatrixCtrl has been created'); 100 $log.log('OvDriverMatrixCtrl has been created');
92 }]) 101 }])
93 102
103 + // TODO: implement row selection to show details panel
94 .directive('ovDriverMatrixItemDetailsPanel', ['PanelService', 'KeyService', 104 .directive('ovDriverMatrixItemDetailsPanel', ['PanelService', 'KeyService',
95 function (ps, ks) { 105 function (ps, ks) {
96 return { 106 return {
......