ONOS-3505: Basic behaviour of drivers table implemented.
- WIP -- still need to fix scrolling, styling, etc.
Change-Id: I376155ab1375ea4b4b136969b89f74c3733178b8
diff --git a/apps/drivermatrix/src/main/java/org/onosproject/drivermatrix/DriverViewMessageHandler.java b/apps/drivermatrix/src/main/java/org/onosproject/drivermatrix/DriverViewMessageHandler.java
index 8e9cdb5..148cfbe 100644
--- a/apps/drivermatrix/src/main/java/org/onosproject/drivermatrix/DriverViewMessageHandler.java
+++ b/apps/drivermatrix/src/main/java/org/onosproject/drivermatrix/DriverViewMessageHandler.java
@@ -30,24 +30,24 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
- * Message handler for device view related messages.
+ * Message handler for driver matrix view related messages.
*/
public class DriverViewMessageHandler extends UiMessageHandler {
private final Logger log = LoggerFactory.getLogger(getClass());
+ private static final int ONE = 1;
private static final String DRIVER_DATA_REQUEST = "driverDataRequest";
private static final String DRIVER_DATA_RESPONSE = "driverDataResponse";
private static final String DRIVERS = "drivers";
private static final String BEHAVIOURS = "behaviours";
+ private static final String MATRIX = "matrix";
private static final Comparator<? super Class<? extends Behaviour>> BEHAVIOUR_BY_NAME =
(o1, o2) -> o1.getSimpleName().compareTo(o2.getSimpleName());
@@ -59,11 +59,12 @@
protected Collection<RequestHandler> createRequestHandlers() {
return ImmutableSet.of(
new DataRequestHandler()
+ // TODO: for row selection, produce data for detail panel
// new DetailRequestHandler()
);
}
- // handler for device table requests
+ // handler for driver matrix requests
private final class DataRequestHandler extends RequestHandler {
private DataRequestHandler() {
@@ -72,54 +73,46 @@
@Override
public void process(long sid, ObjectNode payload) {
- // Search for drivers producing two artifacts:
- // 1) list of abstract behaviours as column listing
- // 2) sparse matrix of drivers-to-concrete behaviours
-
DriverService driverService = get(DriverService.class);
- // Collect all behaviours for all drivers
- Map<Driver, Set<Class<? extends Behaviour>>> driverBehaviours = new HashMap<>();
- driverService.getDrivers().forEach(d -> driverBehaviours.put(d, d.behaviours()));
-
- // Order all drivers
- List<Driver> drivers = orderDrivers(driverBehaviours.keySet());
+ List<Driver> drivers = new ArrayList<>(driverService.getDrivers());
+ drivers = orderDrivers(drivers);
// Produce a union of all behaviours (and order them)
- List<Class<? extends Behaviour>> behaviours = orderBehaviours(driverBehaviours.values());
+ List<Class<? extends Behaviour>> behaviours = orderBehaviours(drivers);
// Produce a JSON structure and send it
- sendMessage(DRIVER_DATA_RESPONSE, 0, driversJson(driverBehaviours, drivers, behaviours));
+ sendMessage(DRIVER_DATA_RESPONSE, 0, driversJson(drivers, behaviours));
}
- private List<Driver> orderDrivers(Set<Driver> drivers) {
+ private List<Driver> orderDrivers(List<Driver> drivers) {
// For now order by alphanumeric name of the driver
- List<Driver> ordered = new ArrayList<>(drivers);
- ordered.sort(DRIVER_BY_NAME);
- return ordered;
+ drivers.sort(DRIVER_BY_NAME);
+ return drivers;
}
- private List<Class<? extends Behaviour>>
- orderBehaviours(Collection<Set<Class<? extends Behaviour>>> behaviours) {
- // For now order by alphanumeric name of the abstract behaviour simple name
+ private List<Class<? extends Behaviour>> orderBehaviours(List<Driver> drivers) {
+ // first, produce a set-union of all behaviours from all drivers...
Set<Class<? extends Behaviour>> allBehaviours = new HashSet<>();
- behaviours.forEach(allBehaviours::addAll);
+ drivers.forEach(d -> allBehaviours.addAll(d.behaviours()));
+
+ // for now, order by alphanumeric name of the abstract behaviour simple name
List<Class<? extends Behaviour>> ordered = new ArrayList<>(allBehaviours);
ordered.sort(BEHAVIOUR_BY_NAME);
return ordered;
}
- private ObjectNode driversJson(Map<Driver, Set<Class<? extends Behaviour>>> driverBehaviours,
- List<Driver> drivers,
+ private ObjectNode driversJson(List<Driver> drivers,
List<Class<? extends Behaviour>> behaviours) {
ObjectNode root = objectNode();
addBehaviours(root, behaviours);
addDrivers(root, drivers);
- addRelationships(root, drivers, behaviours, driverBehaviours);
+ addMatrixCells(root, drivers);
return root;
}
- private void addBehaviours(ObjectNode root, List<Class<? extends Behaviour>> behaviours) {
+ private void addBehaviours(ObjectNode root,
+ List<Class<? extends Behaviour>> behaviours) {
ArrayNode array = arrayNode();
root.set(BEHAVIOURS, array);
behaviours.forEach(b -> array.add(b.getSimpleName()));
@@ -131,9 +124,19 @@
drivers.forEach(d -> array.add(d.name()));
}
- private void addRelationships(ObjectNode root,
- List<Driver> drivers, List<Class<? extends Behaviour>> behaviours,
- Map<Driver, Set<Class<? extends Behaviour>>> driverBehaviours) {
+ private void addMatrixCells(ObjectNode root, List<Driver> drivers) {
+ ObjectNode matrix = objectNode();
+ root.set(MATRIX, matrix);
+
+ drivers.forEach(d -> {
+ ObjectNode dnode = objectNode();
+ matrix.set(d.name(), dnode);
+
+ d.behaviours().forEach(b -> {
+ // TODO: can put a payload here, rather than a '1' marker
+ dnode.put(b.getSimpleName(), ONE);
+ });
+ });
}
}
diff --git a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.css b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.css
index 82ac4bb..441f129 100644
--- a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.css
+++ b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.css
@@ -1,9 +1,47 @@
-/* css for sample table view */
+/* css for driver matrix view */
#ov-driver-matrix h2 {
display: inline-block;
}
+#ov-driver-matrix table {
+ margin-left: 20px;
+}
+
+#ov-driver-matrix .table-header-rotated {
+ border-collapse: collapse;
+}
+#ov-driver-matrix .table-header-rotated td {
+ width: 30px;
+}
+#ov-driver-matrix .table-header-rotated td.xmark {
+ background-color: yellow;
+}
+#ov-driver-matrix .table-header-rotated td {
+ text-align: center;
+ padding: 2px 5px;
+ border: 1px solid #ccc;
+}
+#ov-driver-matrix .table-header-rotated th.rotate {
+ height: 140px;
+ white-space: nowrap;
+}
+#ov-driver-matrix .table-header-rotated th.rotate > div {
+ -webkit-transform: translate(25px, 51px) rotate(-45deg);
+ transform: translate(25px, 51px) rotate(-45deg);
+ width: 30px;
+}
+#ov-driver-matrix .table-header-rotated th.rotate > div > span {
+ border-bottom: 1px solid #ccc;
+ padding: 5px 10px;
+}
+#ov-driver-matrix .table-header-rotated th.row-header {
+ padding: 0 10px;
+ border-bottom: 1px solid #ccc;
+ text-align: right;
+}
+
+
/* Panel Styling */
#ov-driver-matrix-item-details-panel.floatpanel {
position: absolute;
@@ -33,3 +71,4 @@
font-style: italic;
opacity: 0.8;
}
+
diff --git a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.html b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.html
index 940a887..5df2a46 100644
--- a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.html
+++ b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.html
@@ -1,8 +1,9 @@
<!-- partial HTML -->
<div id="ov-driver-matrix">
<div class="tabular-header">
- <h2>Items ({{tableData.length}} total)</h2>
+ <h2>Driver Matrix</h2>
<div class="ctrl-btns">
+ <!-- TODO: fix (or remove) refresh button -->
<div class="refresh" ng-class="{active: autoRefresh}"
icon icon-id="refresh" icon-size="36"
tooltip tt-msg="autoRefreshTip"
@@ -10,36 +11,35 @@
</div>
</div>
- <div class="summary-list" onos-table-resize>
-
- <div class="table-header" onos-sortable-header>
- <table>
+ <!-- TODO: handle resizing / scrolling -->
+ <div class="driver-matrix">
+ <table class="table-header-rotated">
+ <thead>
<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>
+ <!-- first column header is not rotated -->
+ <th></th>
+ <!-- following headers are rotated -->
+ <th class="rotate" ng-repeat="beh in behaviours track by $index">
+ <div><span>{{beh}}</span></div>
+ </th>
</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>
+ </thead>
+ <tbody>
+ <tr ng-repeat="drv in drivers track by $index">
+ <!--ng-click="selectCallback($event, item)"-->
+ <!--ng-class="{selected: item.id === selId}">-->
+ <th class="row-header">
+ {{drv}}
+ </th>
+ <td ng-repeat="beh in behaviours track by $index"
+ ng-class="{'xmark':cellMarked(drv, beh)}">
+ {{cellValue(drv, beh)}}
+ </td>
+ </tr>
+ </tbody>
+ </table>
</div>
<ov-driver-matrix-item-details-panel></ov-driver-matrix-item-details-panel>
diff --git a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.js b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.js
index 3c77c87..80d46a3 100644
--- a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.js
+++ b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.js
@@ -1,4 +1,4 @@
-// js for sample app table view
+// js for driver view
(function () {
'use strict';
@@ -8,8 +8,8 @@
// constants
var detailsReq = 'driverDataRequest',
detailsResp = 'driverDataResponse',
+ // TODO: deal with details panel
pName = 'ov-driver-matrix-item-details-panel',
-
propOrder = ['id', 'label', 'code'],
friendlyProps = ['Item ID', 'Item Label', 'Special Code'];
@@ -40,9 +40,11 @@
}
function respDetailsCb(data) {
- $log.debug(data);
- //$scope.panelDetails = data.details;
- //$scope.$apply();
+ //$log.debug('Matrix Data', data);
+ $scope.behaviours = data.behaviours;
+ $scope.drivers = data.drivers;
+ $scope.matrix = data.matrix;
+ $scope.$apply();
}
angular.module('ovDriverMatrix', [])
@@ -57,7 +59,9 @@
wss = _wss_;
var handlers = {};
- $scope.panelDetails = {};
+ $scope.behaviours = [];
+ $scope.drivers = [];
+ $scope.matrix = {};
// details response handler
handlers[detailsResp] = respDetailsCb;
@@ -75,12 +79,17 @@
// $log.debug('Got a click on:', row);
//}
- //// TableBuilderService creating a table for us
- //tbs.buildTable({
- // scope: $scope,
- // tag: 'driverMatrix',
- // selCb: selCb
- //});
+ function cellHit(d, b) {
+ var drec = $scope.matrix[d],
+ brec = drec && drec[b];
+ return !!brec;
+ }
+
+ $scope.cellMarked = cellHit;
+
+ $scope.cellValue = function(d, b) {
+ return cellHit(d, b) ? 'x' : '';
+ };
// cleanup
$scope.$on('$destroy', function () {
@@ -91,6 +100,7 @@
$log.log('OvDriverMatrixCtrl has been created');
}])
+ // TODO: implement row selection to show details panel
.directive('ovDriverMatrixItemDetailsPanel', ['PanelService', 'KeyService',
function (ps, ks) {
return {