GUI -- Added 'mask' layer to alert user of loss of websocket connection.

Change-Id: I13f4cb0176936ec1a7db4efa58e5ad0e7ac9db15
diff --git a/web/gui/src/main/webapp/topo2.css b/web/gui/src/main/webapp/topo2.css
index 2dd2a05..0dfa466 100644
--- a/web/gui/src/main/webapp/topo2.css
+++ b/web/gui/src/main/webapp/topo2.css
@@ -146,3 +146,24 @@
     border: 0;
 }
 
+/* Web Socket Closed Mask (starts hidden) */
+
+#topo-mask {
+    display: none;
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 10000px;
+    height: 8000px;
+    z-index: 5000;
+    background-color: rgba(0,0,0,0.75);
+    padding: 60px;
+}
+
+#topo-mask p {
+    margin: 8px 20px;
+    color: #ddd;
+    font-size: 14pt;
+    font-style: italic;
+}
+
diff --git a/web/gui/src/main/webapp/topo2.js b/web/gui/src/main/webapp/topo2.js
index 681562e..c831188 100644
--- a/web/gui/src/main/webapp/topo2.js
+++ b/web/gui/src/main/webapp/topo2.js
@@ -151,6 +151,7 @@
             debug: false
         },
         webSock,
+        sid = 0,
         deviceLabelIndex = 0,
         hostLabelIndex = 0,
         detailPane,
@@ -169,7 +170,8 @@
         nodeG,
         linkG,
         node,
-        link;
+        link,
+        mask;
 
     // ==============================
     // For Debugging / Development
@@ -193,10 +195,6 @@
 
     function testMe(view) {
         view.alert('test');
-        detailPane.show();
-        setTimeout(function () {
-            detailPane.hide();
-        }, 3000);
     }
 
     function abortIfLive() {
@@ -1059,6 +1057,7 @@
             webSock.ws = new WebSocket(webSockUrl());
 
             webSock.ws.onopen = function() {
+                noWebSock(false);
             };
 
             webSock.ws.onmessage = function(m) {
@@ -1070,6 +1069,7 @@
 
             webSock.ws.onclose = function(m) {
                 webSock.ws = null;
+                noWebSock(true);
             };
         },
 
@@ -1089,7 +1089,9 @@
 
     };
 
-    var sid = 0;
+    function noWebSock(b) {
+        mask.style('display',b ? 'block' : 'none');
+    }
 
     // TODO: use cache of pending messages (key = sid) to reconcile responses
 
@@ -1273,6 +1275,11 @@
 
     }
 
+
+    function para(sel, text) {
+        sel.append('p').text(text);
+    }
+
     // ==============================
     // View life-cycle callbacks
 
@@ -1367,6 +1374,12 @@
             .on('tick', tick);
 
         network.drag = d3u.createDragBehavior(network.force, selectCb, atDragEnd);
+
+        // create mask layer for when we lose connection to server.
+        mask = view.$div.append('div').attr('id','topo-mask');
+        para(mask, 'Oops!');
+        para(mask, 'Web-socket connection to server closed...');
+        para(mask, 'Try refreshing the page.');
     }
 
     function load(view, ctx, flags) {