Merge pull request #326 from pgreyson/master

Bug fixes
diff --git a/web/ons-demo/RELEASE_NOTES.txt b/web/ons-demo/RELEASE_NOTES.txt
index 8649e9b..916a965 100644
--- a/web/ons-demo/RELEASE_NOTES.txt
+++ b/web/ons-demo/RELEASE_NOTES.txt
@@ -1,3 +1,11 @@
+** April 4, 2013 **
+Fix issues:
+	305 - "close x" now unselects flow. double click to delete a flow
+	323 - gui now recovers on timeout errors and polls again
+	324 - fixed problem with added flows not displaying
+	325 - fixed logic displaying flows in topology view
+
+
 ** March 28, 2013 **
 - add and delete flow implemented
 - to add flow
diff --git a/web/ons-demo/css/skin.default.css b/web/ons-demo/css/skin.default.css
index d88814e..1ce4897 100644
--- a/web/ons-demo/css/skin.default.css
+++ b/web/ons-demo/css/skin.default.css
@@ -366,6 +366,6 @@
 	-webkit-animation-duration: .5s;
 	-webkit-animation-direction: alternate;
 	-webkit-animation-timing-function: ease-in-out;
-	-webkit-animation-iteration-count: 24;
+	-webkit-animation-iteration-count: 70;
 }
 
diff --git a/web/ons-demo/js/app.js b/web/ons-demo/js/app.js
index e342213..695e4bb 100644
--- a/web/ons-demo/js/app.js
+++ b/web/ons-demo/js/app.js
@@ -20,7 +20,7 @@
 var pendingLinks = {};
 var selectedFlows = [];
 
-var pendingTimeout = 10000;
+var pendingTimeout = 30000;
 
 var colors = [
 	'color1',
@@ -70,7 +70,14 @@
 
 function updateSelectedFlowsTopology() {
 	// DRAW THE FLOWS
-	var flows = d3.select('svg').selectAll('.flow').data(selectedFlows);
+	var topologyFlows = [];
+	selectedFlows.forEach(function (flow) {
+		if (flow) {
+			topologyFlows.push(flow);
+		}
+	});
+
+	var flows = d3.select('svg').selectAll('.flow').data(topologyFlows);
 
 	flows.enter().append("svg:path").attr('class', 'flow')
 		.attr('stroke-dasharray', '4, 10')
@@ -82,13 +89,14 @@
 		.attr('dur', '20s')
 		.attr('repeatCount', 'indefinite');
 
+	flows.exit().remove();
 
 	flows.attr('d', function (d) {
 			if (!d) {
 				return;
 			}
 			var pts = [];
-			if (!d.dataPath.flowEntries) {
+			if (!d.dataPath.flowEntries || !d.dataPath.flowEntries.length) {
 				// create a temporary vector to indicate the pending flow
 				var s1 = d3.select(document.getElementById(d.dataPath.srcPort.dpid.value));
 				var s2 = d3.select(document.getElementById(d.dataPath.dstPort.dpid.value));
@@ -162,6 +170,10 @@
 	function rowUpdate(d) {
 		var row = d3.select(this);
 		row.select('.deleteFlow').on('click', function () {
+			selectedFlows[selectedFlows.indexOf(d)] = null;
+			updateSelectedFlows();
+		});
+		row.on('dblclick', function () {
 			if (d) {
 				var prompt = 'Delete flow ' + d.flowId.value + '?';
 				if (confirm(prompt)) {
@@ -187,7 +199,9 @@
 					}
 				}
 			})
-			.classed('pending', d && (d.deletePending || d.createPending));
+			.classed('pending', function (d) {
+				return d && (d.createPending || d.deletePending);
+			});
 
 		row.select('.srcDPID')
 			.text(function (d) {
@@ -238,8 +252,6 @@
 				} else if (flow.createPending) {
 					newSelectedFlows.push(flow);
 				}
-			} else {
-				newSelectedFlows.push(null);
 			}
 		});
 		selectedFlows = newSelectedFlows;
@@ -1059,21 +1071,23 @@
 	updateModel(function (newModel) {
 //		console.log('Update time: ' + (Date.now() - d)/1000 + 's');
 
-		var modelChanged = false;
-		if (!model || JSON.stringify(model) != JSON.stringify(newModel)) {
-			modelChanged = true;
-			model = newModel;
-		} else {
-//			console.log('no change');
-		}
+		if (newModel) {
+			var modelChanged = false;
+			if (!model || JSON.stringify(model) != JSON.stringify(newModel)) {
+				modelChanged = true;
+				model = newModel;
+			} else {
+	//			console.log('no change');
+			}
 
-		if (modelChanged) {
-			updateControllers();
-			updateSelectedFlows();
-			updateTopology();
-		}
+			if (modelChanged) {
+				updateControllers();
+				updateSelectedFlows();
+				updateTopology();
+			}
 
-		updateHeader(newModel);
+			updateHeader(newModel);
+		}
 
 		// do it again in 1s
 		setTimeout(function () {
diff --git a/web/ons-demo/js/model.js b/web/ons-demo/js/model.js
index 29859a6..5026bd4 100644
--- a/web/ons-demo/js/model.js
+++ b/web/ons-demo/js/model.js
@@ -126,7 +126,8 @@
 			var model = toD3(results);
 			cb(model);
 		} else {
-			alert(JSON.stringify(err));
+			console.log(JSON.stringify(err));
+			cb(null);
 		}
 	});
 }