Simon Hunt

GUI -- Added TopoPanelService to encapsulate summary, detail and instance panels.

- Rudimentary handling of 'showSummary' event implemented.
- Fixed resize behavior of topo SVG.
- Created 'migrate' mock-server scenario.
- Added 'restart' command to mock-server.

Change-Id: I90ac93dbc9efb8f17ef95825d3159030145267a2
......@@ -76,6 +76,7 @@
<script src="view/topo/topo.js"></script>
<script src="view/topo/topoEvent.js"></script>
<script src="view/topo/topoForce.js"></script>
<script src="view/topo/topoPanel.js"></script>
<script src="view/device/device.js"></script>
<!-- TODO: inject javascript refs server-side -->
......
......@@ -28,7 +28,7 @@
];
// references to injected services etc.
var $log, fs, ks, zs, gs, ms, ps, tes, tfs;
var $log, fs, ks, zs, gs, ms, tes, tfs, tps;
// DOM elements
var ovtopo, svg, defs, zoomLayer, mapG, forceG;
......@@ -101,9 +101,9 @@
// callback invoked when the SVG view has been resized..
function svgResized(w, h) {
$log.debug('TopoView just resized... ' + w + 'x' + h);
tfs.resize(w, h);
function svgResized(dim) {
//$log.debug('TopoView just resized... ', dim);
tfs.resize(dim);
}
// --- Background Map ------------------------------------------------
......@@ -137,6 +137,10 @@
tfs.initForce(forceG, svg.attr('width'), svg.attr('height'));
}
function setUpPanels() {
tps.initPanels();
}
// --- Controller Definition -----------------------------------------
......@@ -146,10 +150,10 @@
'$scope', '$log', '$location', '$timeout',
'FnService', 'MastService',
'KeyService', 'ZoomService', 'GlyphService', 'MapService',
'PanelService', 'TopoEventService', 'TopoForceService',
'TopoEventService', 'TopoForceService', 'TopoPanelService',
function ($scope, _$log_, $loc, $timeout, _fs_, mast,
_ks_, _zs_, _gs_, _ms_, _ps_, _tes_, _tfs_) {
_ks_, _zs_, _gs_, _ms_, _tes_, _tfs_, _tps_) {
var self = this;
$log = _$log_;
fs = _fs_;
......@@ -157,12 +161,12 @@
zs = _zs_;
gs = _gs_;
ms = _ms_;
ps = _ps_;
tes = _tes_;
tfs = _tfs_;
tps = _tps_;
self.notifyResize = function () {
svgResized(svg.attr('width'), svg.attr('height'));
svgResized(fs.windowSize(mast.mastHeight()));
};
// Cleanup on destroyed scope..
......@@ -186,16 +190,11 @@
setUpZoom();
setUpMap();
setUpForce();
setUpPanels();
// open up a connection to the server...
tes.openSock();
// TODO: remove this temporary code....
var p = ps.createPanel('topo-p-summary');
p.append('h1').text('Hello World');
p.show();
$timeout(function () { p.hide(); }, 2000);
$log.log('OvTopoCtrl has been created');
}]);
}());
......
......@@ -23,7 +23,7 @@
'use strict';
// injected refs
var $log, wss, wes;
var $log, wss, wes, tps;
// internal state
var wsock;
......@@ -42,11 +42,12 @@
// === Event Handlers ===
function showSummary(ev) {
$log.log(' **** Show Summary **** ', ev.payload);
$log.debug(' **** Show Summary **** ', ev.payload);
tps.showSummary(ev.payload);
}
function addInstance(ev) {
$log.log(' *** We got an ADD INSTANCE event: ', ev);
$log.debug(' *** We got an ADD INSTANCE event: ', ev);
}
// ==========================
......@@ -86,11 +87,13 @@
angular.module('ovTopo')
.factory('TopoEventService',
['$log', '$location', 'WebSocketService', 'WsEventService',
'TopoPanelService',
function (_$log_, $loc, _wss_, _wes_) {
function (_$log_, $loc, _wss_, _wes_, _tps_) {
$log = _$log_;
wss = _wss_;
wes = _wes_;
tps = _tps_;
function bindDispatcher(TopoDomElementsPassedHere) {
// TODO: store refs to topo DOM elements...
......
......@@ -124,8 +124,8 @@
selectCb, atDragEnd, dragEnabled, clickEnabled);
}
function resize(w, h) {
force.size([w, h]);
function resize(dim) {
force.size([dim.width, dim.height]);
// Review -- do we need to nudge the layout ?
}
......
/*
* 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.
*/
/*
ONOS GUI -- Topology Panel Module.
Defines functions for manipulating the summary, detail, and instance panels.
*/
(function () {
'use strict';
// injected refs
var $log, ps;
// internal state
var settings;
// SVG elements;
var fooPane;
// D3 selections;
var summaryPanel,
detailPanel,
instancePanel;
// default settings for force layout
var defaultSettings = {
foo: 2
};
// ==========================
angular.module('ovTopo')
.factory('TopoPanelService',
['$log', 'PanelService',
function (_$log_, _ps_) {
$log = _$log_;
ps = _ps_;
function initPanels() {
summaryPanel = ps.createPanel('topo-p-summary');
// TODO: set up detail and instance panels..
}
function showSummary(payload) {
summaryPanel.empty();
summaryPanel.append('h2').text(payload.id);
// TODO: complete the formatting...
summaryPanel.show();
}
return {
initPanels: initPanels,
showSummary: showSummary
};
}]);
}());
......@@ -20,7 +20,7 @@
describe('factory: view/topo/topoEvent.js', function() {
var $log, fs, tes;
beforeEach(module('ovTopo', 'onosUtil'));
beforeEach(module('ovTopo', 'onosUtil', 'onosLayer'));
beforeEach(inject(function (_$log_, FnService, TopoEventService) {
$log = _$log_;
......
/*
* 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.
*/
/*
ONOS GUI -- Topo View -- Topo Panel Service - Unit Tests
*/
describe('factory: view/topo/topoPanel.js', function() {
var $log, fs, tps;
beforeEach(module('ovTopo', 'onosUtil', 'onosLayer'));
beforeEach(inject(function (_$log_, FnService, TopoPanelService) {
$log = _$log_;
fs = FnService;
tps = TopoPanelService;
}));
it('should define TopoPanelService', function () {
expect(tps).toBeDefined();
});
it('should define api functions', function () {
expect(fs.areFunctions(tps, [
'initPanels'
])).toBeTruthy();
});
// TODO: more tests...
});
{
"event": "showSummary",
"sid": 1,
"payload": {
"id": "ONOS Summary",
"type": "node",
"propOrder": [
"Devices",
"Links",
"Hosts",
"Topology SCCs",
"-",
"Intents",
"Flows",
"Version"
],
"props": {
"Devices": "25",
"Links": "112",
"Hosts": "0",
"Topology SCCs": "1",
"-": "",
"Intents": "0",
"Flows": "125",
"Version": "1.0.0*"
}
}
}
{
"comments": [
"Used during the migration of old GUI (topo.js==3.1KLOC) to Angular"
],
"title": "Migration Helper",
"params": {
"lastAuto": 0
},
"description": [
"Do what you need to..."
]
}
......@@ -34,7 +34,7 @@ server.listen(port, function() {
});
server.on('listening', function () {
console.log('ok, server is running');
console.log('OK, server is running');
});
var wsServer = new WebSocketServer({
......@@ -110,6 +110,7 @@ function doCli() {
case 'm': customMessage(str); break;
case 's': setScenario(str); break;
case 'n': nextEvent(); break;
case 'r': restartScenario(); break;
case 'q': quit(); break;
case '?': showHelp(); break;
default: console.log('Say what?! (? for help)'); break;
......@@ -126,10 +127,11 @@ function doCli() {
var helptext = '\n' +
'c - show connection status\n' +
'm {text} - send custom message to client\n' +
's {id} - set scenario\n' +
's {id} - load scenario {id}\n' +
's - show scenario staus\n' +
//'a - auto-send events\n' +
'n - send next event\n' +
'r - restart the scenario\n' +
'q - exit the server\n' +
'? - display this help text\n';
......@@ -146,13 +148,13 @@ function connStatus() {
}
function quit() {
console.log('quitting...');
console.log('Quitting...');
process.exit(0);
}
function customMessage(m) {
if (connection) {
console.log('sending message: ' + m);
console.log('Sending message: ' + m);
connection.sendUTF(m);
} else {
console.warn('No current connection.');
......@@ -162,7 +164,7 @@ function customMessage(m) {
function showScenarioStatus() {
var msg;
if (!scenario) {
console.log('No scenario selected.');
console.log('No scenario loaded.');
} else {
msg = 'Scenario: "' + scenario + '", ' +
(scdone ? 'DONE' : 'next event: ' + evno);
......@@ -189,7 +191,7 @@ function setScenario(id) {
} else {
evdata = JSON.parse(data);
console.log(); // get past prompt
console.log('setting scenario to "' + id + '"');
console.log('Loading scenario "' + id + '"');
console.log(evdata.title);
evdata.description.forEach(function (d) {
console.log(' ' + d);
......@@ -201,11 +203,27 @@ function setScenario(id) {
});
}
function restartScenario() {
if (!scenario) {
console.log('No scenario loaded.');
} else {
console.log();
console.log('Restarting scenario "' + scenario + '"');
console.log(evdata.title);
evdata.description.forEach(function (d) {
console.log(' ' + d);
});
evno = 1;
scdone = false;
}
rl.prompt();
}
function nextEvent() {
var path;
if (!scenario) {
console.log('No scenario selected.');
console.log('No scenario loaded.');
rl.prompt();
} else if (!connection) {
console.warn('No current connection.');
......@@ -220,7 +238,7 @@ function nextEvent() {
} else {
evdata = JSON.parse(data);
console.log(); // get past prompt
console.log('sending event #' + evno + ' [' + evdata.event + ']');
console.log('Sending event #' + evno + ' [' + evdata.event + ']');
connection.sendUTF(data);
evno++;
}
......