Committed by
Gerrit Code Review
ONOS-3505: Basic behaviour of drivers table implemented.
- WIP -- still need to fix scrolling, styling, etc. Change-Id: I376155ab1375ea4b4b136969b89f74c3733178b8
Showing
4 changed files
with
121 additions
and
69 deletions
... | @@ -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 { | ... | ... |
-
Please register or login to post a comment