Skip to content
Snippets Groups Projects
Commit a1c91a27 authored by Kuang-Ching Wang's avatar Kuang-Ching Wang
Browse files

Merge pull request #336 from thewmf/webui

Various UI fixes and improvements
parents fde9ab57 f0a53bef
No related branches found
No related tags found
No related merge requests found
...@@ -91,11 +91,13 @@ var AppRouter = Backbone.Router.extend({ ...@@ -91,11 +91,13 @@ var AppRouter = Backbone.Router.extend({
var swl = new SwitchCollection(); var swl = new SwitchCollection();
var hl = new HostCollection(); var hl = new HostCollection();
var updating = true;
tpl.loadTemplates(['home', 'status', 'topology', 'header', 'switch', 'switch-list', 'switch-list-item', 'host', 'host-list', 'host-list-item', 'port-list', 'port-list-item', 'flow-list', 'flow-list-item'], tpl.loadTemplates(['home', 'status', 'topology', 'header', 'switch', 'switch-list', 'switch-list-item', 'host', 'host-list', 'host-list-item', 'port-list', 'port-list-item', 'flow-list', 'flow-list-item'],
function () { function () {
app = new AppRouter(); app = new AppRouter();
Backbone.history.start({pushState: true}); Backbone.history.start({pushState: true});
// console.log("started history") //console.log("started history")
$(document).ready(function () { $(document).ready(function () {
// trigger Backbone routing when clicking on links, thanks to Atinux and pbnv // trigger Backbone routing when clicking on links, thanks to Atinux and pbnv
...@@ -113,15 +115,16 @@ tpl.loadTemplates(['home', 'status', 'topology', 'header', 'switch', 'switch-lis ...@@ -113,15 +115,16 @@ tpl.loadTemplates(['home', 'status', 'topology', 'header', 'switch', 'switch-lis
window.addEventListener('popstate', function(e) { window.addEventListener('popstate', function(e) {
app.navigate(location.pathname.substr(1), true); app.navigate(location.pathname.substr(1), true);
}); });
// wait for the page to be rendered before loading any data
swl.fetch();
hl.fetch();
setInterval(function () {
if(updating) {
swl.fetch();
hl.fetch();
}
}, 3000);
}); });
}); });
setInterval(function () {
swl.fetch();
}, 3000);
setInterval(function () {
hl.fetch();
}, 3000);
...@@ -31,19 +31,22 @@ window.HostCollection = Backbone.Collection.extend({ ...@@ -31,19 +31,22 @@ window.HostCollection = Backbone.Collection.extend({
model:Host, model:Host,
initialize:function () { fetch:function () {
var self = this; var self = this;
//console.log("fetching host list") //console.log("fetching host list")
$.ajax({ $.ajax({
url:hackBase + "/wm/device/", url:hackBase + "/wm/device/",
dataType:"json", dataType:"json",
success:function (data) { success:function (data) {
// console.log("fetched host list: " + data.length); //console.log("fetched host list: " + data.length);
// console.log(data); // console.log(data);
// data is a list of device hashes // data is a list of device hashes
var old_ids = self.pluck('id');
//console.log("old_ids" + old_ids);
_.each(data, function(h) { _.each(data, function(h) {
h.id = h.mac[0];
old_ids = _.without(old_ids, h.id);
if (h['attachmentPoint'].length > 0) { if (h['attachmentPoint'].length > 0) {
h.id = h.mac[0];
h.swport = _.reduce(h['attachmentPoint'], function(memo, ap) { h.swport = _.reduce(h['attachmentPoint'], function(memo, ap) {
return memo + ap.switchDPID + "-" + ap.port + " "}, ""); return memo + ap.switchDPID + "-" + ap.port + " "}, "");
//console.log(h.swport); //console.log(h.swport);
...@@ -51,16 +54,18 @@ window.HostCollection = Backbone.Collection.extend({ ...@@ -51,16 +54,18 @@ window.HostCollection = Backbone.Collection.extend({
self.add(h, {silent: true}); self.add(h, {silent: true});
} }
}); });
// old_ids now holds hosts that no longer exist; remove them
//console.log("old_ids" + old_ids);
_.each(old_ids, function(h) {
console.log("---removing host " + h);
self.remove({id:h});
});
self.trigger('add'); // batch redraws self.trigger('add'); // batch redraws
} }
}); });
}, },
fetch:function () {
this.initialize();
}
/* /*
* findByName:function (key) { // TODO: Modify service to include firstName * findByName:function (key) { // TODO: Modify service to include firstName
* in search var url = (key == '') ? '/host/' : "/host/search/" + key; * in search var url = (key == '') ? '/host/' : "/host/search/" + key;
......
...@@ -38,6 +38,15 @@ window.Status = Backbone.Model.extend({ ...@@ -38,6 +38,15 @@ window.Status = Backbone.Model.extend({
// console.log(self.toJSON()); // console.log(self.toJSON());
} }
}); });
$.ajax({
url:hackBase + "/wm/core/system/uptime/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: uptime");
self.set({uptime:(Math.round(data.systemUptimeMsec / 1000) + ' s')});
// console.log(self.toJSON());
}
});
$.ajax({ $.ajax({
url:hackBase + "/wm/core/memory/json", url:hackBase + "/wm/core/memory/json",
dataType:"json", dataType:"json",
......
...@@ -74,9 +74,16 @@ window.Switch = Backbone.Model.extend({ ...@@ -74,9 +74,16 @@ window.Switch = Backbone.Model.extend({
success:function (data) { success:function (data) {
//console.log("fetched switch " + self.id + " ports"); //console.log("fetched switch " + self.id + " ports");
//console.log(data[self.id]); //console.log(data[self.id]);
var old_ids = self.ports.pluck('id');
//console.log("old_ids" + old_ids);
// create port models // create port models
_.each(data[self.id], function(p) { _.each(data[self.id], function(p) {
// workaround for REST serialization signed/unsigned bug
if(p.portNumber < 0) {p.portNumber = 65536 + p.portNumber};
p.id = self.id+'-'+p.portNumber; p.id = self.id+'-'+p.portNumber;
old_ids = _.without(old_ids, p.id);
p.dropped = p.receiveDropped + p.transmitDropped; p.dropped = p.receiveDropped + p.transmitDropped;
p.errors = p.receiveCRCErrors + p.receiveErrors + p.receiveOverrunErrors + p.errors = p.receiveCRCErrors + p.receiveErrors + p.receiveOverrunErrors +
p.receiveFrameErrors + p.transmitErrors; p.receiveFrameErrors + p.transmitErrors;
...@@ -89,6 +96,13 @@ window.Switch = Backbone.Model.extend({ ...@@ -89,6 +96,13 @@ window.Switch = Backbone.Model.extend({
} }
//console.log(p); //console.log(p);
}); });
// old_ids now holds ports that no longer exist; remove them
//console.log("old_ids" + old_ids);
_.each(old_ids, function(p) {
console.log("removing port " + p);
self.remove({id:p});
});
} }
}), }),
$.ajax({ $.ajax({
...@@ -177,7 +191,7 @@ window.Switch = Backbone.Model.extend({ ...@@ -177,7 +191,7 @@ window.Switch = Backbone.Model.extend({
f.match.dataLayerSource + "</a>, "; f.match.dataLayerSource + "</a>, ";
} }
if(!(f.match.wildcards & (1<<3))) { // dest MAC if(!(f.match.wildcards & (1<<3))) { // dest MAC
f.matchHTML =+ "dest=<a href='/host/" + f.match.dataLayerDestination + "'>" + f.matchHTML += "dest=<a href='/host/" + f.match.dataLayerDestination + "'>" +
f.match.dataLayerDestination + "</a>, "; f.match.dataLayerDestination + "</a>, ";
} }
if(!(f.match.wildcards & (1<<4))) { // Ethertype if(!(f.match.wildcards & (1<<4))) { // Ethertype
...@@ -251,7 +265,7 @@ window.SwitchCollection = Backbone.Collection.extend({ ...@@ -251,7 +265,7 @@ window.SwitchCollection = Backbone.Collection.extend({
model:Switch, model:Switch,
initialize:function () { fetch:function () {
var self = this; var self = this;
//console.log("fetching switch list") //console.log("fetching switch list")
$.ajax({ $.ajax({
...@@ -260,16 +274,22 @@ window.SwitchCollection = Backbone.Collection.extend({ ...@@ -260,16 +274,22 @@ window.SwitchCollection = Backbone.Collection.extend({
success:function (data) { success:function (data) {
//console.log("fetched switch list: " + data.length); //console.log("fetched switch list: " + data.length);
//console.log(data); //console.log(data);
_.each(data, function(sw) {self.add({id: sw['dpid'], var old_ids = self.pluck('id');
inetAddress: sw.inetAddress, //console.log("old_ids" + old_ids);
connectedSince: new Date(sw.connectedSince).toLocaleString()})});
} _.each(data, function(sw) {
old_ids = _.without(old_ids, sw['dpid']);
self.add({id: sw['dpid'], inetAddress: sw.inetAddress,
connectedSince: new Date(sw.connectedSince).toLocaleString()})});
// old_ids now holds switches that no longer exist; remove them
//console.log("old_ids" + old_ids);
_.each(old_ids, function(sw) {
console.log("removing switch " + sw);
self.remove({id:sw});
});
},
}); });
}, },
fetch:function () {
this.initialize()
}
}); });
...@@ -24,6 +24,9 @@ window.HeaderView = Backbone.View.extend({ ...@@ -24,6 +24,9 @@ window.HeaderView = Backbone.View.extend({
render:function (eventName) { render:function (eventName) {
$(this.el).html(this.template()); $(this.el).html(this.template());
$('#live-updates', this.el).change(function () {
updating = $(this).is(':checked');
})
// $('.navbar-search', this.el).append(this.searchresultsView.render().el); // $('.navbar-search', this.el).append(this.searchresultsView.render().el);
return this; return this;
}, },
......
...@@ -36,6 +36,7 @@ window.HostListView = Backbone.View.extend({ ...@@ -36,6 +36,7 @@ window.HostListView = Backbone.View.extend({
this.template = _.template(tpl.get('host-list')); this.template = _.template(tpl.get('host-list'));
this.model.bind("change", this.render, this); this.model.bind("change", this.render, this);
this.model.bind("add", this.render, this); this.model.bind("add", this.render, this);
this.model.bind("remove", this.render, this);
}, },
render:function (eventName) { render:function (eventName) {
......
...@@ -57,6 +57,7 @@ window.SwitchListView = Backbone.View.extend({ ...@@ -57,6 +57,7 @@ window.SwitchListView = Backbone.View.extend({
initialize:function () { initialize:function () {
this.template = _.template(tpl.get('switch-list')); this.template = _.template(tpl.get('switch-list'));
this.model.bind("change", this.render, this); this.model.bind("change", this.render, this);
this.model.bind("remove", this.render, this);
}, },
render:function (eventName) { render:function (eventName) {
......
...@@ -16,11 +16,18 @@ ...@@ -16,11 +16,18 @@
<li><a href="/hosts">Hosts</a></li> <li><a href="/hosts">Hosts</a></li>
<!-- <li><a href="/vlans">VLANs</a></li> --> <!-- <li><a href="/vlans">VLANs</a></li> -->
</ul> </ul>
<!--
<form id="searchForm" class="navbar-search pull-right dropdown"> <form id="searchForm" class="navbar-search pull-right dropdown">
<input id="searchText" type="text" class="search-query dropdown-toggle" <input id="searchText" type="text" class="search-query dropdown-toggle"
placeholder="Search (try an IP or MAC address)"> placeholder="Search (try an IP or MAC address)">
</form> </form>
-->
</div> <!--/.nav-collapse --> </div> <!--/.nav-collapse -->
<form class="navbar-form pull-right">
<label class="checkbox">
<input type="checkbox" id="live-updates" checked="yes">Live updates
</label>
</form>
</div> </div>
</div> </div>
</div> </div>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment