ONOS-303 Added ability to add mult-source intent from GUI.
Fixed treatment of selection & hover modes.
Change-Id: Idf47b6a15b56ea96b9edaeeb034fad0f205af6e3
diff --git a/web/gui/src/main/webapp/topo2.js b/web/gui/src/main/webapp/topo2.js
index d58de15..cd30334 100644
--- a/web/gui/src/main/webapp/topo2.js
+++ b/web/gui/src/main/webapp/topo2.js
@@ -72,9 +72,9 @@
topo: {
linkBaseColor: '#666',
linkInColor: '#66f',
- linkInWidth: 14,
+ linkInWidth: 12,
linkOutColor: '#f00',
- linkOutWidth: 14
+ linkOutWidth: 10
},
icons: {
w: 30,
@@ -148,8 +148,7 @@
P: togglePorts,
U: [unpin, 'Unpin node'],
R: [resetZoomPan, 'Reset zoom/pan'],
- H: [cycleHoverMode, 'Cycle hover mode'],
- V: [showTrafficAction, 'Show traffic'],
+ V: [showTrafficAction, 'Show related traffic'],
A: [showAllTrafficAction, 'Show all traffic'],
F: [showDeviceLinkFlowsAction, 'Show device link flows'],
esc: handleEscape
@@ -191,10 +190,13 @@
onosOrder = [],
oiBox,
oiShowMaster = false,
- hoverModes = [ 'none', 'intents', 'flows'],
- hoverMode = 0,
portLabelsOn = false;
+ var hoverModeAll = 1,
+ hoverModeFlows = 2,
+ hoverModeIntents = 3,
+ hoverMode = hoverModeFlows;
+
// D3 selections
var svg,
zoomPanContainer,
@@ -327,14 +329,6 @@
});
}
- function cycleHoverMode(view) {
- hoverMode++;
- if (hoverMode === hoverModes.length) {
- hoverMode = 0;
- }
- view.flash('Mode: ' + hoverModes[hoverMode]);
- }
-
function togglePorts(view) {
view.alert('togglePorts() callback')
}
@@ -829,6 +823,14 @@
function getSelId(idx) {
return getSel(idx).obj.id;
}
+ function getSelIds(start, endOffset) {
+ var end = selectOrder.length - endOffset;
+ var ids = [];
+ selectOrder.slice(start, end).forEach(function (d) {
+ ids.push(getSelId(d));
+ });
+ return ids;
+ }
function allSelectionsClass(cls) {
for (var i=0, n=nSel(); i<n; i++) {
if (getSel(i).obj.class !== cls) {
@@ -876,69 +878,92 @@
sendMessage('requestDetails', payload);
}
- function addIntentAction() {
+ function addHostIntentAction() {
sendMessage('addHostIntent', {
- one: getSelId(0),
- two: getSelId(1),
- ids: [ getSelId(0), getSelId(1) ]
+ one: selectOrder[0],
+ two: selectOrder[1],
+ ids: selectOrder
});
- network.view.flash('Host-to-Host connectivity added');
+ network.view.flash('Host-to-Host flow added');
}
- function showTrafficAction() {
- cancelTraffic();
- hoverMode = 1;
- showSelectTraffic();
- network.view.flash('Related Traffic');
+ function addMultiSourceIntentAction() {
+ sendMessage('addMultiSourceIntent', {
+ src: selectOrder.slice(0, selectOrder.length - 1),
+ dst: selectOrder[selectOrder.length - 1],
+ ids: selectOrder
+ });
+ network.view.flash('Multi-Source flow added');
}
+
function cancelTraffic() {
sendMessage('cancelTraffic', {});
}
- function showSelectTraffic() {
- // if nothing is hovered over, and nothing selected, send cancel request
- if (!hovered && nSel() === 0) {
- cancelTraffic();
- return;
+ function requestTrafficForMode() {
+ if (hoverMode === hoverModeAll) {
+ requestAllTraffic();
+ } else if (hoverMode === hoverModeFlows) {
+ requestDeviceLinkFlows();
+ } else if (hoverMode === hoverModeIntents) {
+ requestSelectTraffic();
}
+ }
- // NOTE: hover is only populated if "show traffic on hover" is
- // toggled on, and the item hovered is a host or a device...
- var hoverId = (trafficHover() && hovered &&
- (hovered.class === 'host' || hovered.class === 'device'))
+ function showTrafficAction() {
+ hoverMode = hoverModeIntents;
+ requestSelectTraffic();
+ network.view.flash('Related Traffic');
+ }
+
+ function requestSelectTraffic() {
+ if (validateSelectionContext()) {
+ var hoverId = (hoverMode === hoverModeIntents && hovered &&
+ (hovered.class === 'host' || hovered.class === 'device'))
? hovered.id : '';
- sendMessage('requestTraffic', {
- ids: selectOrder,
- hover: hoverId
- });
+ sendMessage('requestTraffic', {
+ ids: selectOrder,
+ hover: hoverId
+ });
+ }
}
- function showAllTrafficAction() {
- cancelTraffic();
- sendMessage('requestAllTraffic', {});
- network.view.flash('All Traffic');
- }
function showDeviceLinkFlowsAction() {
- cancelTraffic();
- hoverMode = 2;
- showDeviceLinkFlows();
+ hoverMode = hoverModeFlows;
+ requestDeviceLinkFlows();
network.view.flash('Device Flows');
}
- function showDeviceLinkFlows() {
- // if nothing is hovered over, and nothing selected, send cancel request
+ function requestDeviceLinkFlows() {
+ if (validateSelectionContext()) {
+ var hoverId = (hoverMode === hoverModeFlows && hovered &&
+ (hovered.class === 'device')) ? hovered.id : '';
+ sendMessage('requestDeviceLinkFlows', {
+ ids: selectOrder,
+ hover: hoverId
+ });
+ }
+ }
+
+
+ function showAllTrafficAction() {
+ hoverMode = hoverModeAll;
+ requestAllTraffic();
+ network.view.flash('All Traffic');
+ }
+
+ function requestAllTraffic() {
+ sendMessage('requestAllTraffic', {});
+ }
+
+ function validateSelectionContext() {
if (!hovered && nSel() === 0) {
cancelTraffic();
- return;
+ return false;
}
- var hoverId = (flowsHover() && hovered && hovered.class === 'device') ?
- hovered.id : '';
- sendMessage('requestDeviceLinkFlows', {
- ids: selectOrder,
- hover: hoverId
- });
+ return true;
}
// TODO: these should be moved out to utility module.
@@ -1547,20 +1572,12 @@
function nodeMouseOver(d) {
hovered = d;
- if (trafficHover() && (d.class === 'host' || d.class === 'device')) {
- showSelectTraffic();
- } else if (flowsHover() && (d.class === 'device')) {
- showDeviceLinkFlows();
- }
+ requestTrafficForMode();
}
function nodeMouseOut(d) {
hovered = null;
- if (trafficHover() && (d.class === 'host' || d.class === 'device')) {
- showSelectTraffic();
- } else if (flowsHover() && (d.class === 'device')) {
- showDeviceLinkFlows();
- }
+ requestTrafficForMode();
}
function addHostIcon(node, radius, iid) {
@@ -2002,22 +2019,29 @@
function updateDetailPane() {
var nSel = selectOrder.length;
if (!nSel) {
- detailPane.hide();
- cancelTraffic();
+ emptySelect();
} else if (nSel === 1) {
singleSelect();
+ requestTrafficForMode();
} else {
multiSelect();
}
}
+ function emptySelect() {
+ detailPane.hide();
+ cancelTraffic();
+ }
+
function singleSelect() {
+ // NOTE: detail is shown from showDetails event callback
requestDetails();
- // NOTE: detail pane will be shown from showDetails event callback
+ requestTrafficForMode();
}
function multiSelect() {
populateMultiSelect();
+ requestTrafficForMode();
}
function addSep(tbody) {
@@ -2127,7 +2151,9 @@
addAction(detailPane, 'Show Related Traffic', showTrafficAction);
// if exactly two hosts are selected, also want 'add host intent'
if (nSel() === 2 && allSelectionsClass('host')) {
- addAction(detailPane, 'Add Host-to-Host Intent', addIntentAction);
+ addAction(detailPane, 'Create Host-to-Host Flow', addHostIntentAction);
+ } else if (nSel() >= 2 && allSelectionsClass('host')) {
+ addAction(detailPane, 'Create Multi-Source Flow', addMultiSourceIntentAction);
}
}
@@ -2239,14 +2265,6 @@
return false;
}
- function trafficHover() {
- return hoverModes[hoverMode] === 'intents';
- }
-
- function flowsHover() {
- return hoverModes[hoverMode] === 'flows';
- }
-
function loadGlyphs(svg) {
var defs = svg.append('defs');
gly.defBird(defs);