diff --git a/TODO b/TODO
index ca14847..5a0a9a0 100644
--- a/TODO
+++ b/TODO
@@ -1,2 +1,3 @@
- ui_relay.ml: deal with Message.Subscribe and .Unsubscribe as well as .Post in api_tap_sink
- web: add cache control information to served responses
+ - add node bound / node unbound event handlers in nodes.js to update the list as it changes
diff --git a/web/about.html b/web/about.html
index 3c2bc90..e5e0f8c 100644
--- a/web/about.html
+++ b/web/about.html
@@ -20,6 +20,7 @@
Ocamlmsg
diff --git a/web/bootstrap/nav.xml b/web/bootstrap/nav.xml
index 1ca97df..7bd32b3 100644
--- a/web/bootstrap/nav.xml
+++ b/web/bootstrap/nav.xml
@@ -1,3 +1,4 @@
Main
+ Nodes
diff --git a/web/bootstrap/templates/nodes.xml b/web/bootstrap/templates/nodes.xml
new file mode 100644
index 0000000..ae9b849
--- /dev/null
+++ b/web/bootstrap/templates/nodes.xml
@@ -0,0 +1,29 @@
+
+ Ocamlmsg
+
+
+ nodes.js
+
+
+
+ Nodes
+
+
+
diff --git a/web/index.html b/web/index.html
index 51ae838..246da84 100644
--- a/web/index.html
+++ b/web/index.html
@@ -20,6 +20,7 @@
Ocamlmsg
diff --git a/web/nodes.html b/web/nodes.html
new file mode 100644
index 0000000..c7c37ee
--- /dev/null
+++ b/web/nodes.html
@@ -0,0 +1,49 @@
+
+
+
+
+
Ocamlmsg
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/nodes.js b/web/nodes.js
new file mode 100644
index 0000000..72e5c04
--- /dev/null
+++ b/web/nodes.js
@@ -0,0 +1,37 @@
+function refresh_node_list() {
+ $.getJSON("/_/nodes", function (data) {
+ var names = data.nodes;
+ names.push("bar");
+ names.push("foo");
+ names.push("qux");
+ names.sort();
+ var column_count = 4; /* change to match nodes.xml */
+ var per_column = Math.ceil(names.length / column_count);
+ var column_index, column;
+ function set_column(i) {
+ column_index = i;
+ column = $("#nodes" + i);
+ column.html("");
+ }
+ set_column(0);
+ for (var i = 0; i < names.length; i++) {
+ if (i >= (column_index + 1) * per_column) {
+ set_column(column_index + 1);
+ }
+ var link = $("
");
+ link.text(names[i]);
+ link.attr("href", "/_/node/" + names[i]);
+ var li = $("
");
+ li.append(link);
+ column.append(li);
+ }
+ });
+}
+
+function nodes_main() {
+ Ocamlmsg.install_tap({
+ open: function (event, stream) {
+ refresh_node_list();
+ }
+ });
+}
diff --git a/web/ui.css b/web/ui.css
index e69de29..9cf1474 100644
--- a/web/ui.css
+++ b/web/ui.css
@@ -0,0 +1,5 @@
+.truncate-overflow div ul li a {
+ display: block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}