diff --git a/htrace-core/src/web/app/setup.js b/htrace-core/src/web/app/setup.js index 12bd691..ec6c0ab 100644 --- a/htrace-core/src/web/app/setup.js +++ b/htrace-core/src/web/app/setup.js @@ -16,12 +16,68 @@ * specific language governing permissions and limitations * under the License. */ - -$(function() { - var spansCollection = spans.clone(); - $("*[role='main']").append(new App.SpanView({"collection": spansCollection, "id": "span-list"}).$el); - spansCollection.trigger('change'); +var Router = Backbone.Router.extend({ + + routes: { + "": "search", + "spans/:span": "span" + }, + + initialize: function() { + this.spansCollection = spans.clone(); + this.spanViews = {}; + + this.spansView = new App.SpansView({ + "collection": this.spansCollection, + "id": "span-list" + }); + this.searchView = new App.SearchView({ + "collection": this.spansCollection, + "el": $("#list").find("[role='form']") + }); + + + this.spansCollection.trigger('change'); + }, + + search: function() { + var root = $("#list"); + + $("*[role='application']").css('display', 'none'); + + root.find("*[role='main']").append(this.spansView.$el); - var search = new App.SearchView({"collection": spansCollection, "el": $("*[role='form']")}); -}) \ No newline at end of file + root.show(); + }, + + span: function(span) { + var root = $("#span"); + + // Cache views to avoid leaks + if (!(span in this.spanViews)) { + this.spanViews[span] = new App.SpanView({ + "model": this.spansCollection.findWhere({ + "spanId": parseInt(span) + }), + "id": "span-details" + }); + } + + var view = this.spanViews[span]; + + $("*[role='application']").css('display', 'none'); + + view.render(); + root.find("*[role='main']").empty(); + root.find("*[role='main']").append(view.$el); + + root.show(); + } +}); + +window.urlconf = new Router(); + +$(function() { + Backbone.history.start(); +}); diff --git a/htrace-core/src/web/app/views/span.js b/htrace-core/src/web/app/views/span.js index 81cf59c..813d446 100644 --- a/htrace-core/src/web/app/views/span.js +++ b/htrace-core/src/web/app/views/span.js @@ -17,10 +17,13 @@ * under the License. */ -App.SpanView = Backbone.View.extend({ +App.SpansView = Backbone.View.extend({ "tagName": "ul", "className": "spans", - "template": _.template($("#span-template").html()), + "template": _.template($("#list-span-template").html()), + "events": { + "click li": "spanClicked" + }, initialize: function() { _.bindAll(this, "render"); @@ -30,9 +33,44 @@ App.SpanView = Backbone.View.extend({ }, "render": function() { + if (this.rendered) { + $(this.el).empty(); + } + + $(this.el).append( + this.template({ + "spans": this.collection.toJSON() + })); + + this.rendered = true; + + return this; + }, + + "spanClicked": function(e) { + e.preventDefault(); + var spanId = $(e.currentTarget).data("id"); + window.urlconf.navigate("/spans/" + spanId, true); + } +}); + +App.SpanView = Backbone.View.extend({ + "tagName": "div", + "className": "span", + "template": _.template($("#span-details-template").html()), + + initialize: function() { + _.bindAll(this, "render"); + this.model.bind('change', this.render); + + this.rendered = false; + }, + + "render": function() { var context = { - "spans": this.collection.toJSON() + "span": this.model.toJSON() }; + context["span"]["duration"] = this.model.duration(); if (this.rendered) { $(this.el).empty(); diff --git a/htrace-core/src/web/index.html b/htrace-core/src/web/index.html index 443116e..efb8ff0 100644 --- a/htrace-core/src/web/index.html +++ b/htrace-core/src/web/index.html @@ -40,7 +40,14 @@ -
+ +
+
+
+
+
+ +
@@ -83,26 +90,62 @@
+
- + + @@ -118,8 +161,5 @@ -