Bri Prebilic Cole
Committed by Gerrit Code Review

GUI -- "State" is now an icon on Link and Cluster node views. - Icon mapping has…

… generic names to be reused between views - Fixed broken table unit tests - Other minor cleanup

Change-Id: I7136cba15ad4fd185095617d790940d55b9f968f
......@@ -81,7 +81,7 @@ public class ApplicationViewMessageHandler extends AbstractTabularViewMessageHan
STATE, STATE_IID, ID, VERSION, ORIGIN, DESC
};
private static final String ICON_ID_ACTIVE = "appActive";
private static final String ICON_ID_ACTIVE = "active";
private static final String ICON_ID_INACTIVE = "appInactive";
......
......@@ -76,22 +76,27 @@ public class ClusterViewMessageHandler extends AbstractTabularViewMessageHandler
private static final String ID = "id";
private static final String IP = "ip";
private static final String TCP_PORT = "tcp";
private static final String STATE = "state";
private static final String STATE_IID = "_iconid_state";
private static final String UPDATED = "updated";
private static final String[] COL_IDS = {
ID, IP, TCP_PORT, STATE, UPDATED
ID, IP, TCP_PORT, STATE_IID, UPDATED
};
private static final String ICON_ID_ONLINE = "active";
private static final String ICON_ID_OFFLINE = "inactive";
public ControllerNodeTableRow(ClusterService service, ControllerNode n) {
NodeId id = n.id();
DateTime lastUpdated = service.getLastUpdated(id);
org.joda.time.format.DateTimeFormatter format = DateTimeFormat.longTime();
String iconId = (service.getState(id) == ControllerNode.State.ACTIVE) ?
ICON_ID_ONLINE : ICON_ID_OFFLINE;
add(ID, id.toString());
add(IP, n.ip().toString());
add(TCP_PORT, Integer.toString(n.tcpPort()));
add(STATE, service.getState(id).toString());
add(STATE_IID, iconId);
add(UPDATED, format.print(lastUpdated));
}
......
......@@ -177,8 +177,8 @@ public class DeviceViewMessageHandler extends AbstractTabularViewMessageHandler
PROTOCOL, CHASSIS_ID, SERIAL
};
private static final String ICON_ID_ONLINE = "deviceOnline";
private static final String ICON_ID_OFFLINE = "deviceOffline";
private static final String ICON_ID_ONLINE = "active";
private static final String ICON_ID_OFFLINE = "inactive";
public DeviceTableRow(DeviceService service,
MastershipService ms,
......
......@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.link.LinkService;
import org.onosproject.ui.impl.TopologyViewMessageHandlerBase.BiLink;
......@@ -82,7 +83,7 @@ public class LinkViewMessageHandler extends AbstractTabularViewMessageHandler {
private static final String ONE = "one";
private static final String TWO = "two";
private static final String TYPE = "type";
private static final String STATE = "state";
private static final String STATE = "_iconid_state";
private static final String DIRECTION = "direction";
private static final String DURABLE = "durable";
......@@ -90,28 +91,32 @@ public class LinkViewMessageHandler extends AbstractTabularViewMessageHandler {
ONE, TWO, TYPE, STATE, DIRECTION, DURABLE
};
private static final String ICON_ID_ONLINE = "active";
private static final String ICON_ID_OFFLINE = "inactive";
public LinkTableRow(BiLink link) {
ConnectPoint src = link.one.src();
ConnectPoint dst = link.one.dst();
linkState(link);
add(ONE, src.elementId().toString() + "/" + src.port().toString());
add(TWO, dst.elementId().toString() + "/" + dst.port().toString());
add(TYPE, linkType(link).toLowerCase());
add(STATE, linkState(link).toLowerCase());
add(DIRECTION, link.two != null ? "A <-> B" : "A -> B");
add(STATE, linkState(link));
add(DIRECTION, link.two != null ? "A <--> B" : "A --> B");
add(DURABLE, Boolean.toString(link.one.isDurable()));
}
private String linkState(BiLink link) {
return link.two == null || link.one.state() == link.two.state() ?
link.one.state().toString() :
link.one.state().toString() + "/" + link.two.state().toString();
return (link.one.state() == Link.State.ACTIVE ||
link.two.state() == Link.State.ACTIVE) ?
ICON_ID_ONLINE : ICON_ID_OFFLINE;
}
private String linkType(BiLink link) {
return link.two == null || link.one.type() == link.two.type() ?
link.one.type().toString() :
link.one.type().toString() + "/" + link.two.type().toString();
link.one.type().toString() + " / " + link.two.type().toString();
}
@Override
......
......@@ -31,7 +31,7 @@
"devices": [{
"id": "of:0000000000000001",
"available": true,
"_iconid_available": "deviceOnline",
"_iconid_available": "active",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -44,7 +44,7 @@
{
"id": "of:0000000000000004",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -57,7 +57,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -70,7 +70,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -83,7 +83,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -96,7 +96,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -109,7 +109,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -122,7 +122,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -135,7 +135,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -148,7 +148,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -161,7 +161,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -174,7 +174,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -187,7 +187,7 @@
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"_iconid_available": "inactive",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......
......@@ -81,9 +81,9 @@
var div = d3.select('#showIcons');
// show device online and offline icons
icns.loadEmbeddedIcon(div, 'deviceOnline', 50);
icns.loadEmbeddedIcon(div, 'active', 50);
div.append('span').style('padding-left', '15px');
icns.loadEmbeddedIcon(div, 'deviceOffline', 50);
icns.loadEmbeddedIcon(div, 'inactive', 50);
var defs = d3.select('defs');
......
......@@ -41,11 +41,11 @@
fill-rule: evenodd;
}
svg .icon.deviceOnline {
svg .icon.active {
fill: green;
}
svg .icon.deviceOffline {
svg .icon.inactive {
fill: darkred;
}
......@@ -72,12 +72,12 @@
<tr> <th></th> <th>Two</th> <th>Three</th> </tr>
<tr>
<td>
<div icon icon-id="deviceOnline">
<div icon icon-id="active">
<!-- icon directive needs to inject the following structure -->
<!-- ------------------------------------------------ -->
<svg width="20" height="20" viewBox="0 0 50 50">
<g class="icon deviceOnline">
<g class="icon active">
<rect width="50" height="50" rx="10"></rect>
<use class="glyph" xlink:href="#checkmark" width="50" height="50"></use>
</g>
......@@ -91,12 +91,12 @@
</tr>
<tr>
<td>
<div icon icon-id="deviceOffline">
<div icon icon-id="inactive">
<!-- icon directive needs to inject the following structure -->
<!-- ------------------------------------------------ -->
<svg width="20" height="20" viewBox="0 0 50 50">
<g class="icon deviceOffline">
<g class="icon inactive">
<rect width="50" height="50" rx="10"></rect>
<use class="glyph" xlink:href="#xmark" width="50" height="50"></use>
</g>
......
......@@ -41,11 +41,11 @@
fill-rule: evenodd;
}
svg .icon.deviceOnline {
svg .icon.active {
fill: green;
}
svg .icon.deviceOffline {
svg .icon.inactive {
fill: darkred;
}
......@@ -72,12 +72,12 @@
<tr> <th></th> <th>Two</th> <th>Three</th> </tr>
<tr>
<td>
<div icon icon-id="deviceOnline">
<div icon icon-id="active">
<!-- icon directive needs to inject the following structure -->
<!-- ------------------------------------------------ -->
<svg width="20" height="20" viewBox="0 0 50 50">
<g class="icon deviceOnline">
<g class="icon active">
<rect width="50" height="50" rx="4"></rect>
<use class="glyph" xlink:href="#ui" width="50" height="50"></use>
</g>
......@@ -91,12 +91,12 @@
</tr>
<tr>
<td>
<div icon icon-id="deviceOffline">
<div icon icon-id="inactive">
<!-- icon directive needs to inject the following structure -->
<!-- ------------------------------------------------ -->
<svg width="20" height="20" viewBox="0 0 50 50">
<g class="icon deviceOffline">
<g class="icon inactive">
<rect width="50" height="50" rx="4"></rect>
<use class="glyph" xlink:href="#ui" width="50" height="50"></use>
</g>
......
......@@ -57,10 +57,10 @@ svg.embeddedIcon .icon.appInactive .glyph {
fill: none;
}
.light svg.embeddedIcon .icon.appActive .glyph {
.light svg.embeddedIcon .icon.active .glyph {
fill: green;
}
.dark svg.embeddedIcon .icon.appActive .glyph {
.dark svg.embeddedIcon .icon.active .glyph {
fill: #308C10;
}
......@@ -78,15 +78,15 @@ svg.embeddedIcon .icon.appInactive .glyph {
fill: #ccc;
}
.light svg.embeddedIcon .icon.deviceOnline .glyph {
.light svg.embeddedIcon .icon.active .glyph {
fill: green;
}
.light svg.embeddedIcon .icon.deviceOffline .glyph {
.light svg.embeddedIcon .icon.inactive .glyph {
fill: darkred;
}
.dark svg.embeddedIcon .icon.deviceOnline .glyph {
.dark svg.embeddedIcon .icon.active .glyph {
fill: #308C10;
}
.dark svg.embeddedIcon .icon.deviceOffline .glyph {
.dark svg.embeddedIcon .icon.inactive .glyph {
fill: #AD2D2D;
}
......
......@@ -29,28 +29,27 @@
// Maps icon ID to the glyph ID it uses.
// NOTE: icon ID maps to a CSS class for styling that icon
var glyphMapping = {
appActive: 'checkMark',
active: 'checkMark',
inactive: 'xMark',
plus: 'plus',
minus: 'minus',
play: 'play',
stop: 'stop',
upArrow: 'triangleUp',
downArrow: 'triangleDown',
appInactive: 'unknown',
appPlus: 'plus',
appMinus: 'minus',
appPlay: 'play',
appStop: 'stop',
deviceOnline: 'checkMark',
deviceOffline: 'xMark',
devIcon_SWITCH: 'switch',
devIcon_ROADM: 'roadm',
hostIcon_endstation: 'endstation',
hostIcon_router: 'router',
hostIcon_bgpSpeaker: 'bgpSpeaker',
tableColSortAsc: 'triangleUp',
tableColSortDesc: 'triangleDown'
hostIcon_bgpSpeaker: 'bgpSpeaker'
};
function ensureIconLibDefs() {
var body = d3.select('body'),
svg = body.select('svg#IconLibDefs'),
......@@ -187,13 +186,13 @@
function createSortIcon() {
function sortAsc(div) {
div.style('display', 'inline-block');
loadEmbeddedIcon(div, 'tableColSortAsc', 10);
loadEmbeddedIcon(div, 'upArrow', 10);
div.classed('tableColSort', true);
}
function sortDesc(div) {
div.style('display', 'inline-block');
loadEmbeddedIcon(div, 'tableColSortDesc', 10);
loadEmbeddedIcon(div, 'downArrow', 10);
div.classed('tableColSort', true);
}
......
......@@ -125,12 +125,12 @@
currCol.colId = thElem.attr('colId');
if (currCol.colId === prevCol.colId) {
(currCol.icon === 'tableColSortDesc') ?
currCol.icon = 'tableColSortAsc' :
currCol.icon = 'tableColSortDesc';
(currCol.icon === 'downArrow') ?
currCol.icon = 'upArrow' :
currCol.icon = 'downArrow';
prevCol.icon = currCol.icon;
} else {
currCol.icon = 'tableColSortAsc';
currCol.icon = 'upArrow';
prevCol.icon = 'tableColSortNone';
}
......@@ -138,7 +138,7 @@
api.sortNone(div);
div = thElem.append('div');
if (currCol.icon === 'tableColSortAsc') {
if (currCol.icon === 'upArrow') {
api.sortAsc(div);
} else {
api.sortDesc(div);
......@@ -156,7 +156,7 @@
function sortRequestParams() {
return {
sortCol: currCol.colId,
sortDir: (currCol.icon === 'tableColSortAsc' ? 'asc' : 'desc')
sortDir: (currCol.icon === 'upArrow' ? 'asc' : 'desc')
};
}
......
......@@ -3,10 +3,10 @@
<div>
<h2>Applications ({{ctrl.tableData.length}} total)</h2>
<div class="ctrl-btns">
<div icon icon-size="36" icon-id="appPlus"></div>
<div icon icon-size="36" icon-id="appMinus" class="disabled"></div>
<div icon icon-size="36" icon-id="appPlay" class="disabled"></div>
<div icon icon-size="36" icon-id="appStop" class="disabled"></div>
<div icon icon-size="36" icon-id="plus"></div>
<div icon icon-size="36" icon-id="minus" class="disabled"></div>
<div icon icon-size="36" icon-id="play" class="disabled"></div>
<div icon icon-size="36" icon-id="stop" class="disabled"></div>
</div>
</div>
<table class="summary-list"
......
......@@ -23,10 +23,10 @@
sort-callback="sortCallback(requestParams)">
<thead>
<tr>
<th colId="_iconid_state" class="table-icon" sortable></th>
<th colId="id" sortable>ID </th>
<th colId="ip" sortable>IP Address </th>
<th colId="tcp" sortable>TCP Port </th>
<th colId="state" sortable>State </th>
<th colId="updated" sortable>Last Updated </th>
</tr>
</thead>
......@@ -40,10 +40,12 @@
<tr ng-repeat="node in ctrl.tableData"
ng-repeat-done>
<td class="table-icon">
<div icon icon-id="{{node._iconid_state}}"></div>
</td>
<td>{{node.id}}</td>
<td>{{node.ip}}</td>
<td>{{node.tcp}}</td>
<td>{{node.state}}</td>
<td>{{node.updated}}</td>
</tr>
</tbody>
......
......@@ -42,10 +42,10 @@
top: 0;
cursor: pointer;
}
.light .close-btn svg.embeddedIcon .icon.appPlus .glyph {
.light .close-btn svg.embeddedIcon .icon.plus .glyph {
fill: #aaa;
}
.dark .close-btn svg.embeddedIcon .icon.appPlus .glyph {
.dark .close-btn svg.embeddedIcon .icon.plus .glyph {
fill: #ccc;
}
......
......@@ -21,7 +21,7 @@
<tbody>
<tr ng-hide="ctrl.tableData.length">
<td class="nodata" colspan="10">
<td class="nodata" colspan="9">
No Devices found
</td>
</tr>
......
......@@ -56,7 +56,7 @@
];
function addCloseBtn(div) {
is.loadEmbeddedIcon(div, 'appPlus', 30);
is.loadEmbeddedIcon(div, 'plus', 30);
div.select('g').attr('transform', 'translate(25, 0) rotate(45)');
div.on('click', function () {
......
......@@ -23,10 +23,10 @@
sort-callback="sortCallback(requestParams)">
<thead>
<tr>
<th colId="_iconid_state" class="table-icon" sortable></th>
<th colId="one" sortable>Port 1 </th>
<th colId="two" sortable>Port 2 </th>
<th colId="type" sortable>Type </th>
<th colId="state" sortable>State </th>
<th colId="direction" sortable>Direction </th>
<th colId="durable" sortable>Durable </th>
</tr>
......@@ -41,10 +41,12 @@
<tr ng-repeat="link in ctrl.tableData"
ng-repeat-done>
<td class="table-icon">
<div icon icon-id="{{link._iconid_state}}"></div>
</td>
<td>{{link.one}}</td>
<td>{{link.two}}</td>
<td>{{link.type}}</td>
<td>{{link.state}}</td>
<td>{{link.direction}}</td>
<td>{{link.durable}}</td>
</tr>
......
......@@ -75,26 +75,26 @@ describe('factory: fw/svg/icon.js', function() {
it('should load an icon into a div', function () {
expect(d3Elem.html()).toEqual('');
is.loadIconByClass(d3Elem, 'deviceOnline');
verifyIconStructure('deviceOnline', '#checkMark');
is.loadIconByClass(d3Elem, 'active');
verifyIconStructure('active', '#checkMark');
});
it('should allow us to specify the icon size', function () {
expect(d3Elem.html()).toEqual('');
is.loadIconByClass(d3Elem, 'deviceOffline', 32);
verifyIconStructure('deviceOffline', '#xMark', '32');
is.loadIconByClass(d3Elem, 'inactive', 32);
verifyIconStructure('inactive', '#xMark', '32');
});
it('should verify triangleUp icon', function () {
expect(d3Elem.html()).toEqual('');
is.loadIconByClass(d3Elem, 'tableColSortAsc', 10);
verifyIconStructure('tableColSortAsc', '#triangleUp', '10');
is.loadIconByClass(d3Elem, 'upArrow', 10);
verifyIconStructure('upArrow', '#triangleUp', '10');
});
it('should verify triangleDown icon', function () {
expect(d3Elem.html()).toEqual('');
is.loadIconByClass(d3Elem, 'tableColSortDesc', 10);
verifyIconStructure('tableColSortDesc', '#triangleDown', '10');
is.loadIconByClass(d3Elem, 'downArrow', 10);
verifyIconStructure('downArrow', '#triangleDown', '10');
});
it('should verify no icon is displayed', function () {
......
......@@ -39,6 +39,11 @@ describe('factory: fw/widget/table.js', function () {
'</thead>' +
'<tbody>' +
'<tr>' +
'<td colspan="4">' +
'No Devices found' +
'</td>' +
'</tr>' +
'<tr>' +
'<td class="table-icon">' +
'<div icon icon-id="{{dev._iconid_available}}">' +
'</div>' +
......@@ -147,7 +152,7 @@ describe('factory: fw/widget/table.js', function () {
function verifyColWidth() {
var winWidth = fs.windowSize().width,
colWidth, thElems, tdElem;
colWidth, thElems, tr, tdElem;
colWidth = Math.floor(winWidth / numTestElems);
......@@ -155,7 +160,8 @@ describe('factory: fw/widget/table.js', function () {
angular.forEach(thElems, function (thElem, i) {
thElem = angular.element(thElems[i]);
tdElem = angular.element(tbody.find('td').eq(i));
tr = angular.element(tbody.find('tr').eq(1));
tdElem = angular.element(tr.find('td').eq(i));
var custWidth = thElem.attr('col-width');
if (custWidth) {
......@@ -193,7 +199,7 @@ describe('factory: fw/widget/table.js', function () {
div = currentTh.find('div');
expect(div.html()).toBe('<svg class="embeddedIcon" ' +
'width="10" height="10" viewBox="0 0 50 50">' +
'<g class="icon tableColSortAsc">' +
'<g class="icon upArrow">' +
'<rect width="50" height="50" rx="5"></rect>' +
'<use width="50" height="50" class="glyph" ' +
'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
......@@ -204,7 +210,7 @@ describe('factory: fw/widget/table.js', function () {
div = currentTh.find('div');
expect(div.html()).toBe('<svg class="embeddedIcon" ' +
'width="10" height="10" viewBox="0 0 50 50">' +
'<g class="icon tableColSortDesc">' +
'<g class="icon downArrow">' +
'<rect width="50" height="50" rx="5"></rect>' +
'<use width="50" height="50" class="glyph" ' +
'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
......@@ -222,7 +228,7 @@ describe('factory: fw/widget/table.js', function () {
div = currentTh.children();
expect(div.html()).toBe('<svg class="embeddedIcon" ' +
'width="10" height="10" viewBox="0 0 50 50">' +
'<g class="icon tableColSortAsc">' +
'<g class="icon upArrow">' +
'<rect width="50" height="50" rx="5"></rect>' +
'<use width="50" height="50" class="glyph" ' +
'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
......