GUI -- General GUI backend cleanup and bug fixes. Added custom formatters for existing tables, unit test for Enum Formatter, and more glyphs.
Change-Id: I956f1faf6a59e535094d45b811980f822b084be0
diff --git a/core/api/src/test/java/org/onosproject/ui/table/cell/EnumFormatterTest.java b/core/api/src/test/java/org/onosproject/ui/table/cell/EnumFormatterTest.java
new file mode 100644
index 0000000..68833c9
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/ui/table/cell/EnumFormatterTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.ui.table.cell;
+
+import org.junit.Test;
+import org.onosproject.ui.table.CellFormatter;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Unit tests for {@link EnumFormatter}.
+ */
+public class EnumFormatterTest {
+
+ enum TestEnum {
+ ADDED,
+ PENDING_ADD,
+ WAITING_AUDIT_COMPLETE
+ }
+
+ private CellFormatter fmt = EnumFormatter.INSTANCE;
+
+ @Test
+ public void nullValue() {
+ assertEquals("null value", "", fmt.format(null));
+ }
+
+ @Test
+ public void noUnderscores() {
+ assertEquals("All caps", "Added", fmt.format(TestEnum.ADDED));
+ }
+
+ @Test
+ public void underscores() {
+ assertEquals("All caps with underscores",
+ "Pending Add", fmt.format(TestEnum.PENDING_ADD));
+ }
+
+ @Test
+ public void multiUnderscores() {
+ assertEquals("All caps with underscores",
+ "Waiting Audit Complete",
+ fmt.format(TestEnum.WAITING_AUDIT_COMPLETE));
+ }
+
+}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
index 22c1723..70899bc 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
@@ -39,6 +39,8 @@
import java.util.List;
import java.util.Set;
+import static org.apache.commons.lang.WordUtils.capitalizeFully;
+
/**
* Message handler for device view related messages.
*/
@@ -157,7 +159,7 @@
ObjectNode data = MAPPER.createObjectNode();
data.put(ID, deviceId.toString());
- data.put(TYPE, device.type().toString());
+ data.put(TYPE, capitalizeFully(device.type().toString()));
data.put(TYPE_IID, getTypeIconId(device));
data.put(MFR, device.manufacturer());
data.put(HW, device.hwVersion());
@@ -190,8 +192,8 @@
LinkService ls = get(LinkService.class);
String name = p.annotations().value(AnnotationKeys.PORT_NAME);
- port.put(ID, p.number().toString());
- port.put(TYPE, p.type().toString());
+ port.put(ID, capitalizeFully(p.number().toString()));
+ port.put(TYPE, capitalizeFully(p.type().toString()));
port.put(SPEED, p.portSpeed());
port.put(ENABLED, p.isEnabled());
port.put(NAME, name != null ? name : "");
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
index 61417cd..c3e01ff 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
@@ -22,14 +22,14 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.flow.FlowEntry;
import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.table.CellFormatter;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
+import org.onosproject.ui.table.cell.EnumFormatter;
import org.onosproject.ui.table.cell.IntComparator;
import org.onosproject.ui.table.cell.LongComparator;
@@ -37,9 +37,6 @@
import java.util.List;
import java.util.Set;
-import static org.apache.commons.lang.WordUtils.capitalizeFully;
-
-
/**
* Message handler for flow view related messages.
*/
@@ -95,6 +92,10 @@
tm.setComparator(TIMEOUT, IntComparator.INSTANCE);
tm.setComparator(PACKETS, LongComparator.INSTANCE);
tm.setComparator(BYTES, LongComparator.INSTANCE);
+
+ tm.setFormatter(SELECTOR, new SelectorFormatter());
+ tm.setFormatter(TREATMENT, new TreatmentFormatter());
+ tm.setFormatter(STATE, EnumFormatter.INSTANCE);
return tm;
}
@@ -116,73 +117,50 @@
.cell(GROUP_ID, flow.groupId().id())
.cell(TABLE_ID, flow.tableId())
.cell(PRIORITY, flow.priority())
- .cell(SELECTOR, getSelectorString(flow))
- .cell(TREATMENT, getTreatmentString(flow))
+ .cell(SELECTOR, flow)
+ .cell(TREATMENT, flow)
.cell(TIMEOUT, flow.timeout())
.cell(PERMANENT, flow.isPermanent())
- .cell(STATE, capitalizeFully(flow.state().toString()))
+ .cell(STATE, flow.state())
.cell(PACKETS, flow.packets())
.cell(BYTES, flow.bytes());
}
- private String getSelectorString(FlowEntry f) {
- String result;
- TrafficSelector selector = f.selector();
- Set<Criterion> criteria = selector.criteria();
+ private final class SelectorFormatter implements CellFormatter {
+ @Override
+ public String format(Object value) {
+ FlowEntry flow = (FlowEntry) value;
+ Set<Criterion> criteria = flow.selector().criteria();
- if (criteria.isEmpty()) {
- result = "(No traffic selectors for this flow)";
- } else {
- StringBuilder sb = new StringBuilder("Criteria = ");
+ if (criteria.isEmpty()) {
+ return "(No traffic selector criteria for this flow)";
+ }
+ StringBuilder sb = new StringBuilder("Criteria: ");
for (Criterion c : criteria) {
- sb.append(capitalizeFully(c.type().toString())).append(COMMA);
- }
- result = removeTrailingComma(sb).toString();
- }
- return result;
- }
-
- private String getTreatmentString(FlowEntry f) {
- TrafficTreatment treatment = f.treatment();
- List<Instruction> deferred = treatment.deferred();
- List<Instruction> immediate = treatment.immediate();
- boolean haveDef = !deferred.isEmpty();
- boolean haveImm = !immediate.isEmpty();
- boolean both = haveDef && haveImm;
- boolean neither = !haveDef && !haveImm;
- String result;
-
- if (neither) {
- result = "(No traffic treatment instructions for this flow)";
- } else {
- StringBuilder sb = new StringBuilder();
- addDeferred(sb, deferred);
- if (both) {
- sb.append(COMMA);
- }
- addImmediate(sb, immediate);
- result = sb.toString();
- }
- return result;
- }
-
- private void addDeferred(StringBuilder sb, List<Instruction> deferred) {
- if (!deferred.isEmpty()) {
- sb.append("Deferred instructions = ");
- for (Instruction i : deferred) {
- sb.append(capitalizeFully(i.type().toString())).append(COMMA);
+ sb.append(c).append(COMMA);
}
removeTrailingComma(sb);
+
+ return sb.toString();
}
}
- private void addImmediate(StringBuilder sb, List<Instruction> immediate) {
- if (!immediate.isEmpty()) {
- sb.append("Immediate instructions = ");
- for (Instruction i : immediate) {
- sb.append(capitalizeFully(i.type().toString())).append(COMMA);
+ private final class TreatmentFormatter implements CellFormatter {
+ @Override
+ public String format(Object value) {
+ FlowEntry flow = (FlowEntry) value;
+ List<Instruction> instructions = flow.treatment().allInstructions();
+
+ if (instructions.isEmpty()) {
+ return "(No traffic treatment instructions for this flow)";
+ }
+ StringBuilder sb = new StringBuilder("Treatment Instructions: ");
+ for (Instruction i : instructions) {
+ sb.append(i).append(COMMA);
}
removeTrailingComma(sb);
+
+ return sb.toString();
}
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/GroupViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/GroupViewMessageHandler.java
index b61c1b7..17ef891 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/GroupViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/GroupViewMessageHandler.java
@@ -123,9 +123,9 @@
for (GroupBucket b : buckets) {
sb.append("Bytes: ")
- .append(Long.toString(b.bytes()))
+ .append(b.bytes())
.append(" Packets: ")
- .append(Long.toString(b.packets()))
+ .append(b.packets())
.append(" Actions: ")
.append(b.treatment().allInstructions())
.append(COMMA);
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/HostViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/HostViewMessageHandler.java
index 643fe40..a42ed90 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/HostViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/HostViewMessageHandler.java
@@ -17,16 +17,19 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Host;
import org.onosproject.net.host.HostService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.table.CellFormatter;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
import org.onosproject.ui.table.cell.HostLocationFormatter;
import java.util.Collection;
+import java.util.Set;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -72,6 +75,7 @@
protected TableModel createTableModel() {
TableModel tm = super.createTableModel();
tm.setFormatter(LOCATION, HostLocationFormatter.INSTANCE);
+ tm.setFormatter(IPS, new IpSetFormatter());
return tm;
}
@@ -97,5 +101,30 @@
return HOST_ICON_PREFIX +
(isNullOrEmpty(hostType) ? "endstation" : hostType);
}
+
+ private final class IpSetFormatter implements CellFormatter {
+ private static final String COMMA = ", ";
+
+ @Override
+ public String format(Object value) {
+ Set<IpAddress> ips = (Set<IpAddress>) value;
+ if (ips.isEmpty()) {
+ return "(No IP Addresses for this host)";
+ }
+ StringBuilder sb = new StringBuilder();
+ for (IpAddress ip : ips) {
+ sb.append(ip.toString())
+ .append(COMMA);
+ }
+ removeTrailingComma(sb);
+ return sb.toString();
+ }
+
+ private StringBuilder removeTrailingComma(StringBuilder sb) {
+ int pos = sb.lastIndexOf(COMMA);
+ sb.delete(pos, sb.length());
+ return sb;
+ }
+ }
}
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/IntentViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/IntentViewMessageHandler.java
index 2ab2f08..2af458b 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/IntentViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/IntentViewMessageHandler.java
@@ -18,6 +18,7 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.NetworkResource;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.intent.ConnectivityIntent;
@@ -32,6 +33,7 @@
import org.onosproject.net.intent.SinglePointToMultiPointIntent;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.table.CellFormatter;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
import org.onosproject.ui.table.cell.AppIdFormatter;
@@ -86,7 +88,10 @@
protected TableModel createTableModel() {
TableModel tm = super.createTableModel();
tm.setComparator(PRIORITY, IntComparator.INSTANCE);
+
tm.setFormatter(APP_ID, AppIdFormatter.INSTANCE);
+ tm.setFormatter(RESOURCES, new ResourcesFormatter());
+ tm.setFormatter(DETAILS, new DetailsFormatter());
return tm;
}
@@ -103,137 +108,168 @@
.cell(KEY, intent.key())
.cell(TYPE, intent.getClass().getSimpleName())
.cell(PRIORITY, intent.priority())
- .cell(RESOURCES, formatResources(intent))
- .cell(DETAILS, formatDetails(intent));
+ .cell(RESOURCES, intent)
+ .cell(DETAILS, intent);
}
+ private final class ResourcesFormatter implements CellFormatter {
+ private static final String COMMA = ", ";
- // == TODO: Review -- Move the following code to a helper class?
- private StringBuilder details = new StringBuilder();
+ @Override
+ public String format(Object value) {
+ Intent intent = (Intent) value;
+ Collection<NetworkResource> resources = intent.resources();
+ if (resources.isEmpty()) {
+ return "(No resources for this intent)";
+ }
+ StringBuilder sb = new StringBuilder("Resources: ");
+ for (NetworkResource nr : resources) {
+ sb.append(nr).append(COMMA);
+ }
+ removeTrailingComma(sb);
- private void appendMultiPointsDetails(Set<ConnectPoint> points) {
- for (ConnectPoint point : points) {
- details.append(point.elementId())
+ return sb.toString();
+ }
+
+ private StringBuilder removeTrailingComma(StringBuilder sb) {
+ int pos = sb.lastIndexOf(COMMA);
+ sb.delete(pos, sb.length());
+ return sb;
+ }
+ }
+
+ private final class DetailsFormatter implements CellFormatter {
+ @Override
+ public String format(Object value) {
+ return formatDetails((Intent) value, new StringBuilder()).toString();
+ }
+
+ private StringBuilder formatDetails(Intent intent, StringBuilder sb) {
+ if (intent instanceof ConnectivityIntent) {
+ buildConnectivityDetails((ConnectivityIntent) intent, sb);
+ }
+
+ if (intent instanceof HostToHostIntent) {
+ buildHostToHostDetails((HostToHostIntent) intent, sb);
+
+ } else if (intent instanceof PointToPointIntent) {
+ buildPointToPointDetails((PointToPointIntent) intent, sb);
+
+ } else if (intent instanceof MultiPointToSinglePointIntent) {
+ buildMPToSPDetails((MultiPointToSinglePointIntent) intent, sb);
+
+ } else if (intent instanceof SinglePointToMultiPointIntent) {
+ buildSPToMPDetails((SinglePointToMultiPointIntent) intent, sb);
+
+ } else if (intent instanceof PathIntent) {
+ buildPathDetails((PathIntent) intent, sb);
+
+ } else if (intent instanceof LinkCollectionIntent) {
+ buildLinkConnectionDetails((LinkCollectionIntent) intent, sb);
+ }
+
+ if (sb.length() == 0) {
+ sb.append("(No details for this intent)");
+ } else {
+ sb.insert(0, "Details: ");
+ }
+ return sb;
+ }
+
+ private void appendMultiPointsDetails(Set<ConnectPoint> points,
+ StringBuilder sb) {
+ for (ConnectPoint point : points) {
+ sb.append(point.elementId())
+ .append('/')
+ .append(point.port())
+ .append(' ');
+ }
+ }
+
+ private void buildConnectivityDetails(ConnectivityIntent intent,
+ StringBuilder sb) {
+ Set<Criterion> criteria = intent.selector().criteria();
+ List<Instruction> instructions = intent.treatment().allInstructions();
+ List<Constraint> constraints = intent.constraints();
+
+ if (!criteria.isEmpty()) {
+ sb.append("Selector: ").append(criteria);
+ }
+ if (!instructions.isEmpty()) {
+ sb.append("Treatment: ").append(instructions);
+ }
+ if (constraints != null && !constraints.isEmpty()) {
+ sb.append("Constraints: ").append(constraints);
+ }
+ }
+
+ private void buildHostToHostDetails(HostToHostIntent intent,
+ StringBuilder sb) {
+ sb.append(" Host 1: ")
+ .append(intent.one())
+ .append(", Host 2: ")
+ .append(intent.two());
+ }
+
+ private void buildPointToPointDetails(PointToPointIntent intent,
+ StringBuilder sb) {
+ ConnectPoint ingress = intent.ingressPoint();
+ ConnectPoint egress = intent.egressPoint();
+ sb.append(" Ingress: ")
+ .append(ingress.elementId())
.append('/')
- .append(point.port())
+ .append(ingress.port())
+
+ .append(", Egress: ")
+ .append(egress.elementId())
+ .append('/')
+ .append(egress.port())
.append(' ');
}
- }
- private void buildConnectivityDetails(ConnectivityIntent intent) {
- Set<Criterion> criteria = intent.selector().criteria();
- List<Instruction> instructions = intent.treatment().allInstructions();
- List<Constraint> constraints = intent.constraints();
+ private void buildMPToSPDetails(MultiPointToSinglePointIntent intent,
+ StringBuilder sb) {
+ ConnectPoint egress = intent.egressPoint();
- if (!criteria.isEmpty()) {
- details.append("selector=").append(criteria);
- }
- if (!instructions.isEmpty()) {
- details.append("treatment=").append(instructions);
- }
- if (constraints != null && !constraints.isEmpty()) {
- details.append("constraints=").append(constraints);
- }
- }
+ sb.append(" Ingress=");
+ appendMultiPointsDetails(intent.ingressPoints(), sb);
- private void buildHostToHostDetails(HostToHostIntent intent) {
- details.append(" host1=")
- .append(intent.one())
- .append(", host2=")
- .append(intent.two());
- }
-
- private void buildPointToPointDetails(PointToPointIntent intent) {
- ConnectPoint ingress = intent.ingressPoint();
- ConnectPoint egress = intent.egressPoint();
- details.append(" ingress=")
- .append(ingress.elementId())
- .append('/')
- .append(ingress.port())
-
- .append(", egress=")
- .append(egress.elementId())
- .append('/')
- .append(egress.port())
- .append(' ');
- }
-
- private void buildMPToSPDetails(MultiPointToSinglePointIntent intent) {
- ConnectPoint egress = intent.egressPoint();
-
- details.append(" ingress=");
- appendMultiPointsDetails(intent.ingressPoints());
-
- details.append(", egress=")
- .append(egress.elementId())
- .append('/')
- .append(egress.port())
- .append(' ');
- }
-
- private void buildSPToMPDetails(SinglePointToMultiPointIntent intent) {
- ConnectPoint ingress = intent.ingressPoint();
-
- details.append(" ingress=")
- .append(ingress.elementId())
- .append('/')
- .append(ingress.port())
- .append(", egress=");
-
- appendMultiPointsDetails(intent.egressPoints());
- }
-
- private void buildPathDetails(PathIntent intent) {
- details.append(" path=")
- .append(intent.path().links())
- .append(", cost=")
- .append(intent.path().cost());
- }
-
- private void buildLinkConnectionDetails(LinkCollectionIntent intent) {
- details.append(" links=")
- .append(intent.links())
- .append(", egress=");
-
- appendMultiPointsDetails(intent.egressPoints());
- }
-
- private String formatDetails(Intent intent) {
- if (intent instanceof ConnectivityIntent) {
- buildConnectivityDetails((ConnectivityIntent) intent);
+ sb.append(", Egress=")
+ .append(egress.elementId())
+ .append('/')
+ .append(egress.port())
+ .append(' ');
}
- if (intent instanceof HostToHostIntent) {
- buildHostToHostDetails((HostToHostIntent) intent);
+ private void buildSPToMPDetails(SinglePointToMultiPointIntent intent,
+ StringBuilder sb) {
+ ConnectPoint ingress = intent.ingressPoint();
- } else if (intent instanceof PointToPointIntent) {
- buildPointToPointDetails((PointToPointIntent) intent);
+ sb.append(" Ingress=")
+ .append(ingress.elementId())
+ .append('/')
+ .append(ingress.port())
+ .append(", Egress=");
- } else if (intent instanceof MultiPointToSinglePointIntent) {
- buildMPToSPDetails((MultiPointToSinglePointIntent) intent);
-
- } else if (intent instanceof SinglePointToMultiPointIntent) {
- buildSPToMPDetails((SinglePointToMultiPointIntent) intent);
-
- } else if (intent instanceof PathIntent) {
- buildPathDetails((PathIntent) intent);
-
- } else if (intent instanceof LinkCollectionIntent) {
- buildLinkConnectionDetails((LinkCollectionIntent) intent);
+ appendMultiPointsDetails(intent.egressPoints(), sb);
}
- if (details.length() == 0) {
- details.append("(No details for this intent)");
- } else {
- details.insert(0, "Details: ");
+ private void buildPathDetails(PathIntent intent, StringBuilder sb) {
+ sb.append(" path=")
+ .append(intent.path().links())
+ .append(", cost=")
+ .append(intent.path().cost());
}
- return details.toString();
- }
- private String formatResources(Intent intent) {
- return (intent.resources().isEmpty() ?
- "(No resources for this intent)" :
- "Resources: " + intent.resources());
+ private void buildLinkConnectionDetails(LinkCollectionIntent intent,
+ StringBuilder sb) {
+ sb.append(" links=")
+ .append(intent.links())
+ .append(", egress=");
+
+ appendMultiPointsDetails(intent.egressPoints(), sb);
+ }
+
}
}
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/LinkViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/LinkViewMessageHandler.java
index e361563..f594a92 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/LinkViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/LinkViewMessageHandler.java
@@ -28,6 +28,7 @@
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
import org.onosproject.ui.table.cell.ConnectPointFormatter;
+import org.onosproject.ui.table.cell.EnumFormatter;
import java.util.Collection;
import java.util.Map;
@@ -83,6 +84,7 @@
TableModel tm = super.createTableModel();
tm.setFormatter(ONE, ConnectPointFormatter.INSTANCE);
tm.setFormatter(TWO, ConnectPointFormatter.INSTANCE);
+ tm.setFormatter(TYPE, EnumFormatter.INSTANCE);
return tm;
}
@@ -113,7 +115,7 @@
if (link.two != null && link.two.type() != link.one.type()) {
sb.append(" / ").append(link.two.type());
}
- return sb.toString().toLowerCase();
+ return sb.toString();
}
private String linkState(BiLink link) {
diff --git a/web/gui/src/main/webapp/app/fw/svg/glyph.js b/web/gui/src/main/webapp/app/fw/svg/glyph.js
index 02b03ca..75a61a8 100644
--- a/web/gui/src/main/webapp/app/fw/svg/glyph.js
+++ b/web/gui/src/main/webapp/app/fw/svg/glyph.js
@@ -152,6 +152,40 @@
'4.3S57.5,83.5,55.1,83.5zM84.2,63.2c0-2.3-1.9-4.3-4.3-4.3s-4.3,' +
'1.9-4.3,4.3s1.9,4.3,4.3,4.3S84.2,65.5,84.2,63.2z',
+ portTable: 'M15.9,19.1h-8v-13h8V19.1z M90.5,6.1H75.6v13h14.9V6.1' +
+ 'z M71.9,6.1H56.9v13h14.9V6.1z M53.2,6.1H38.3v13h14.9V6.1z M34.5,' +
+ '6.1H19.6v13h14.9V6.1z M102.2,6.1h-8v13h8V6.1z M102.6,23.6v78.5H' +
+ '8.2V23.6H102.6z M85.5,37.7c0-0.7-0.4-1.3-0.9-1.3H26.2c-0.5,0-' +
+ '0.9,0.6-0.9,1.3v34.6c0,0.7,0.4,1.3,0.9,1.3h11v9.6c0,1.1,0.5,2,' +
+ '1.2,2h9.1c0,0.2,0,0.3,0,0.5v3c0,1.1,0.5,2,1.2,2h13.5c0.6,0,1.2-' +
+ '0.9,1.2-2v-3c0-0.2,0-0.3,0-0.5h9.1c0.6,0,1.2-0.9,1.2-2v-9.6h11' +
+ 'c0.5,0,0.9-0.6,0.9-1.3V37.7z M30.2,40h-1v8h1V40zM75.2,40h-2.1v8' +
+ 'h2.1V40z M67.7,40h-2.1v8h2.1V40z M60.2,40h-2.1v8h2.1V40z M52.7,' +
+ '40h-2.1v8h2.1V40z M45.2,40h-2.1v8h2.1V40zM37.7,40h-2.1v8h2.1V40' +
+ 'z M81.6,40h-1v8h1V40z',
+
+ groupTable: 'M16,19.1H8v-13h8V19.1z M90.6,6.1H75.7v13h14.9V6.1z ' +
+ 'M71.9,6.1H57v13h14.9V6.1z M53.3,6.1H38.4v13h14.9V6.1z M34.6,6.1' +
+ 'H19.7v13h14.9V6.1z M102.3,6.1h-8v13h8V6.1z M45.7,52.7c0.2-5.6,' +
+ '2.6-10.7,6.2-14.4c-2.6-1.5-5.7-2.5-8.9-2.5c-9.8,0-17.7,7.9-17.7,' +
+ '17.7c0,6.3,3.3,11.9,8.3,15C34.8,61.5,39.4,55.6,45.7,52.7z M51.9,' +
+ '68.8c-3.1-3.1-5.2-7.2-6-11.7c-4.7,2.8-7.9,7.6-8.6,13.2c1.8,0.6,' +
+ '3.6,0.9,5.6,0.9C46.2,71.2,49.3,70.3,51.9,68.8z M55.2,71.5c-3.5,' +
+ '2.4-7.7,3.7-12.2,3.7c-1.9,0-3.8-0.3-5.6-0.7C38.5,83.2,45.9,90,' +
+ '54.9,90c9,0,16.4-6.7,17.5-15.4c-1.6,0.4-3.4,0.6-5.1,0.6C62.8,' +
+ '75.2,58.6,73.8,55.2,71.5z M54.9,50.6c1.9,0,3.8,0.3,5.6,0.7c-0.5' +
+ '-4.1-2.5-7.9-5.4-10.6c-2.9,2.7-4.8,6.4-5.3,10.5C51.5,50.8,53.2,' +
+ '50.6,54.9,50.6z M49.7,55.4c0.5,4.3,2.4,8.1,5.4,10.9c2.9-2.8,4.9' +
+ '-6.6,5.4-10.8c-1.8-0.6-3.6-0.9-5.6-0.9C53.1,54.6,51.4,54.9,49.7,' +
+ '55.4z M102.3,23.6v78.5H8V23.6H102.3z M89,53.5c0-12-9.7-21.7-' +
+ '21.7-21.7c-4.5,0-8.7,1.4-12.2,3.7c-3.5-2.4-7.7-3.7-12.2-3.7c-12,' +
+ '0-21.7,9.7-21.7,21.7c0,8.5,4.9,15.9,12,19.4C33.6,84.6,43.2,94,' +
+ '54.9,94c11.7,0,21.2-9.3,21.7-20.9C84,69.7,89,62.2,89,53.5z M' +
+ '64.3,57.3c-0.8,4.4-2.9,8.4-5.9,11.5c2.6,1.5,5.7,2.5,8.9,2.5c1.8,' +
+ '0,3.6-0.3,5.2-0.8C72,64.9,68.8,60.1,64.3,57.3z M67.3,35.8c-3.3,0' +
+ '-6.3,0.9-8.9,2.5c3.7,3.8,6.1,8.9,6.2,14.6c6.1,3.1,10.6,8.9,11.7,' +
+ '15.8C81.5,65.6,85,60,85,53.5C85,43.8,77.1,35.8,67.3,35.8z',
+
// --- Topology toolbar specific glyphs ----------------------
summary: "M95.8,9.2H14.2c-2.8,0-5,2.2-5,5v81.5c0,2.8,2.2,5,5," +
diff --git a/web/gui/src/main/webapp/app/view/device/device.js b/web/gui/src/main/webapp/app/view/device/device.js
index 855f3a0..ce3eb4e 100644
--- a/web/gui/src/main/webapp/app/view/device/device.js
+++ b/web/gui/src/main/webapp/app/view/device/device.js
@@ -130,7 +130,7 @@
bns.button(
btnsDiv,
bName + '-ports',
- 'chain',
+ 'portTable',
function () {
ns.navTo(portPath, { devId: details.id });
},
@@ -142,9 +142,6 @@
var tr = tbody.append('tr');
portCols.forEach(function (col) {
- if (col === 'type' || col === 'id') {
- port[col] = fs.cap(port[col]);
- }
tr.append('td').html(port[col]);
});
}
diff --git a/web/gui/src/main/webapp/app/view/topo/topoSelect.js b/web/gui/src/main/webapp/app/view/topo/topoSelect.js
index a4e12aa..957c501 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoSelect.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoSelect.js
@@ -257,7 +257,7 @@
});
tps.addAction({
id: 'ports-table-btn',
- gid: 'chain',
+ gid: 'portTable',
cb: function () {
ns.navTo(portPath, { devId: data.props['URI'] });
},
diff --git a/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js b/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
index fda0b91..d796ae3 100644
--- a/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
@@ -20,12 +20,15 @@
describe('factory: fw/svg/glyph.js', function() {
var $log, fs, gs, d3Elem, svg;
- var numBaseGlyphs = 39,
+ var numBaseGlyphs = 41,
vbBird = '352 224 113 112',
vbGlyph = '0 0 110 110',
vbBadge = '0 0 10 10',
longPrefix = 'M95.8,9.2H14.2c-2.8,0-5,2.2-5,5v81.5c0,2.8,2.2,5,5,' +
'5h81.5c2.8,0,5-2.2,5-5V14.2C100.8,11.5,98.5,9.2,95.8,9.2z ',
+ tablePrefix = 'M15.9,19.1h-8v-13h8V19.1z M90.5,6.1H75.6v13h14.9V6.1' +
+ 'z M71.9,6.1H56.9v13h14.9V6.1z M53.2,6.1H38.3v13h14.9V6.1z M34.5,' +
+ '6.1H19.6v13h14.9V6.1z M102.2,6.1h-8v13h8V6.1z ',
prefixLookup = {
bird: 'M427.7,300.4',
unknown: 'M35,40a5',
@@ -42,7 +45,9 @@
refresh: 'M102.6,40.8L88.4',
// navigation specific glyphs
- flowTable: 'M15.9,19.1h-8v-13h',
+ flowTable: tablePrefix + 'M102.2,23.6H7.9v',
+ portTable: tablePrefix + 'M102.6,23.6v78.5H',
+ groupTable: 'M16,19.1H8v-13h',
// toolbar specific glyphs
summary: longPrefix + 'M16.7',
@@ -81,7 +86,8 @@
glyphIds = [
'unknown', 'node', 'switch', 'roadm', 'endstation', 'router',
'bgpSpeaker', 'chain', 'crown', 'lock', 'topo', 'refresh',
- 'flowTable', 'summary', 'details', 'ports', 'map', 'cycleLabels',
+ 'flowTable', 'portTable', 'groupTable',
+ 'summary', 'details', 'ports', 'map', 'cycleLabels',
'oblique', 'filters', 'resetZoom', 'relatedIntents', 'nextIntent',
'prevIntent', 'intentTraffic', 'allTraffic', 'flows', 'eqMaster'
],