Return-Path: X-Original-To: apmail-brooklyn-commits-archive@minotaur.apache.org Delivered-To: apmail-brooklyn-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id CC673185A8 for ; Mon, 1 Feb 2016 17:52:44 +0000 (UTC) Received: (qmail 80731 invoked by uid 500); 1 Feb 2016 17:51:46 -0000 Delivered-To: apmail-brooklyn-commits-archive@brooklyn.apache.org Received: (qmail 80680 invoked by uid 500); 1 Feb 2016 17:51:46 -0000 Mailing-List: contact commits-help@brooklyn.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@brooklyn.apache.org Delivered-To: mailing list commits@brooklyn.apache.org Received: (qmail 79773 invoked by uid 99); 1 Feb 2016 17:51:45 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Feb 2016 17:51:45 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C094DE07F7; Mon, 1 Feb 2016 17:51:45 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: heneveld@apache.org To: commits@brooklyn.apache.org Date: Mon, 01 Feb 2016 17:52:11 -0000 Message-Id: <0d9aadcb8d4b40c5968556a9c86e7847@git.apache.org> In-Reply-To: <67020fe7630d456db986dadf3c5a7c21@git.apache.org> References: <67020fe7630d456db986dadf3c5a7c21@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [27/50] [abbrv] brooklyn-ui git commit: REST api supports batch-style fetch, and app tree is lazily (efficiently) loaded -- so much better for big trees -- and updates dynamically, including status icon REST api supports batch-style fetch, and app tree is lazily (efficiently) loaded -- so much better for big trees -- and updates dynamically, including status icon Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/869239d1 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/869239d1 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/869239d1 Branch: refs/heads/0.6.0 Commit: 869239d175619aa7a4152405be5dc31f13911187 Parents: e03bb7b Author: Alex Heneveld Authored: Tue Sep 17 12:22:08 2013 +0100 Committer: Alex Heneveld Committed: Wed Sep 18 09:30:06 2013 +0100 ---------------------------------------------------------------------- usage/jsgui/src/main/webapp/assets/css/base.css | 6 +- .../src/main/webapp/assets/js/model/app-tree.js | 38 ++- .../webapp/assets/js/view/activity-details.js | 6 +- .../assets/js/view/application-explorer.js | 15 +- .../webapp/assets/js/view/application-tree.js | 282 +++++++++++++------ .../webapp/assets/js/view/entity-details.js | 4 +- .../src/main/webapp/assets/js/view/viewutils.js | 8 +- .../main/webapp/assets/tpl/apps/tree-item.html | 52 ++-- 8 files changed, 278 insertions(+), 133 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/869239d1/usage/jsgui/src/main/webapp/assets/css/base.css ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/css/base.css b/usage/jsgui/src/main/webapp/assets/css/base.css index bd69c3e..5904082 100644 --- a/usage/jsgui/src/main/webapp/assets/css/base.css +++ b/usage/jsgui/src/main/webapp/assets/css/base.css @@ -539,7 +539,7 @@ ol.tree { color: #54932b !important; text-decoration: none; } -.entity_tree_node.active { +.entity_tree_node_wrapper.active .entity_tree_node { font-weight: bold; } #tree label { @@ -568,7 +568,9 @@ line-height: 18px; position: relative; float: left; } - +.entity_tree_node_wrapper { + position: relative; +} .tree-box { border: 1px solid #AAA; border-right: 0px; http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/869239d1/usage/jsgui/src/main/webapp/assets/js/model/app-tree.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/js/model/app-tree.js b/usage/jsgui/src/main/webapp/assets/js/model/app-tree.js index 91bc63d..0b2dbde 100644 --- a/usage/jsgui/src/main/webapp/assets/js/model/app-tree.js +++ b/usage/jsgui/src/main/webapp/assets/js/model/app-tree.js @@ -1,6 +1,6 @@ define([ - "backbone" -], function (Backbone) { + "underscore", "backbone" +], function (_, Backbone) { var AppTree = {} @@ -9,21 +9,47 @@ define([ return { id:"", name:"", + type:"", iconUrl:"", - children:[] + serviceUp:"", + serviceState:"", + applicationId:"", + parentId:"", + childrenIds:[] } }, getDisplayName:function () { - return this.get("name") //+ ":" + this.get("id") + return this.get("name") }, hasChildren:function () { - return this.get("children").length > 0 + return this.get("childrenIds").length > 0 } }) AppTree.Collection = Backbone.Collection.extend({ model:AppTree.Model, - url:"/v1/applications/tree" + includedEntities: [], + getApplications: function () { + var entities = []; + _.each(this.models, function(it) { if (it.get('id')==it.get('applicationId')) entities.push(it.get('id')) }); + return entities; + }, + getNonApplications: function () { + var entities = []; + _.each(this.models, function(it) { if (it.get('id')!=it.get('applicationId')) entities.push(it.get('id')) }); + return entities; + }, + includeEntities: function (entities) { + var oldLength = this.includedEntities.length; + this.includedEntities = _.uniq(this.includedEntities.concat(entities)) + return (this.includedEntities.length > oldLength); + }, + url: function() { + if (this.includedEntities.length) + return "/v1/applications/fetch?items="+this.includedEntities.join(","); + else + return "/v1/applications/fetch"; + } }) return AppTree http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/869239d1/usage/jsgui/src/main/webapp/assets/js/view/activity-details.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/js/view/activity-details.js b/usage/jsgui/src/main/webapp/assets/js/view/activity-details.js index c8079fd..1466bca 100644 --- a/usage/jsgui/src/main/webapp/assets/js/view/activity-details.js +++ b/usage/jsgui/src/main/webapp/assets/js/view/activity-details.js @@ -80,7 +80,7 @@ define([ } this.renderSubtasks() - this.callPeriodically("refreshNow", function () { + this.callPeriodically("refresh-activities-now", function () { this.refreshNow() }, 1000); @@ -158,7 +158,7 @@ define([ this.children = new TaskSummary.Collection() this.children.url = this.task.get("links").children this.children.on("reset", this.renderChildren, this) - this.callPeriodically("refreshChildren", function () { + this.callPeriodically("refresh-activity-children", function () { that.children.fetch({reset: true}); }, 3000); that.children.fetch({reset: true}); @@ -169,7 +169,7 @@ define([ that.collection = new TaskSummary.Collection() that.collection.url = entity.links.activities that.collection.on("reset", this.renderSubtasks, this) - that.callPeriodically("refreshSubmittedTasks", function () { + that.callPeriodically("refresh-activity-bgtasks", function () { that.collection.fetch({reset: true}); }, 3000); that.collection.fetch({reset: true}); http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/869239d1/usage/jsgui/src/main/webapp/assets/js/view/application-explorer.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/js/view/application-explorer.js b/usage/jsgui/src/main/webapp/assets/js/view/application-explorer.js index d6837e7..4cd2008 100644 --- a/usage/jsgui/src/main/webapp/assets/js/view/application-explorer.js +++ b/usage/jsgui/src/main/webapp/assets/js/view/application-explorer.js @@ -15,11 +15,12 @@ define([ id:'application-explorer', template:_.template(PageHtml), events:{ - 'click .application-tree-refresh': 'refreshApplications', + 'click .application-tree-refresh': 'refreshApplicationsInPlace', 'click #add-new-application':'createApplication', 'click .delete':'deleteApplication' }, initialize:function () { + var that = this; this.$el.html(this.template({})) $(".nav1").removeClass("active"); $(".nav1_apps").addClass("active"); @@ -28,8 +29,10 @@ define([ this.treeView = new ApplicationTreeView({ collection:this.collection }) - this.$('div#app-tree').html(this.treeView.render().el) - this.treeView.render() + this.$('div#app-tree').html(this.treeView.renderFull().el) + this.refreshApplications(); + that.callPeriodically("entity-tree-apps", + function() { that.refreshApplicationsInPlace() }, 3000) }, beforeClose:function () { this.collection.off("reset", this.render) @@ -43,6 +46,10 @@ define([ this.collection.fetch({reset: true}) return false }, + refreshApplicationsInPlace:function () { + this.collection.fetch() + return false + }, show: function(entityId) { this.treeView.displayEntityId(entityId) }, @@ -57,7 +64,7 @@ define([ } var wizard = new AppAddWizard({ appRouter:that.options.appRouter, - callback:function() { that.refreshApplications() } + callback:function() { that.refreshApplicationsInPlace() } }) this._modal = wizard this.$(".add-app #modal-container").html(wizard.render().el) http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/869239d1/usage/jsgui/src/main/webapp/assets/js/view/application-tree.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/js/view/application-tree.js b/usage/jsgui/src/main/webapp/assets/js/view/application-tree.js index 9e1cc73..db1c679 100644 --- a/usage/jsgui/src/main/webapp/assets/js/view/application-tree.js +++ b/usage/jsgui/src/main/webapp/assets/js/view/application-tree.js @@ -24,16 +24,130 @@ define([ }, initialize:function () { - this.collection.on('reset', this.render, this) + this.collection.on('all', this.modelEvent, this) + this.collection.on('change', this.modelChange, this) + this.collection.on('remove', this.modelRemove, this) + this.collection.on('add', this.modelAdd, this) + this.collection.on('reset', this.renderFull, this) _.bindAll(this); }, beforeClose:function () { - this.collection.off("reset", this.render) + this.collection.off("reset", this.renderFull) if (this.detailsView) this.detailsView.close() }, + + modelChange: function (child) { + this.updateNode(child.id) + }, + modelAdd: function (child) { + this.updateNode(child.id) + }, + modelRemove: function (child) { + this.removeNode(child.id) + }, + modelEvent: function (eventName, event, x) { + if (eventName == "change" || eventName == "remove" || eventName == "add" || + eventName == "reset" || + // above are handled; below is no-op + eventName == "sync" || eventName == "request") + return; + + // don't think we get other events, but just in case: + log("unhandled model event") + log(eventName) + log(event) + log(x) + }, + + removeNode: function(id) { + $('#'+id, this.$el).parent().remove() + }, + + updateNode: function(id, parentId, isApp) { + var that = this; + var nModel = that.collection.get(id); + var nEl = $('#'+id, that.$el) + + if (!isApp) { + // autodiscover whether this is an app, looking at the model and the tree + // (at least one should be available -- probably always the former, but...) + if (nModel) { isApp = (id == nModel.get('applicationId')); } + else if (!isApp && nEl && nEl.parent().data('depth')==0) isApp = true; + } - render:function () { + if (!isApp && !parentId && nModel) parentId = nModel.get('parentId'); + if (!isApp && !parentId && nEl) parentId = nEl.closest("entity_tree_node_wrapper").data('parentId'); + if (!isApp && !parentId) { + log("no parentId yet available for "+id+"; skipping;") + return false; + } + + var statusIconUrl = nModel ? ViewUtils.computeStatusIcon(nModel.get("serviceUp"),nModel.get("serviceState")) : null; + + var nEl2 = this.template({ + id:id, + parentId:parentId, + model:nModel, + statusIconUrl:statusIconUrl + }) + + if (!nEl.length) { + // node does not exist, so add it + var pElC, depth; + + if (isApp) { + pElC = $('.lozenge-app-tree-wrapper', that.$el); + if (!pElC.length) { + // entire view must be created + that.$el.html( + ''); + pElC = $('.lozenge-app-tree-wrapper', that.$el); + } + depth = 0; + } else { + var pEl = $('#'+parentId, that.$el) + if (!pEl.length) { + // see if we can load the parent + if (this.updateNode(parentId)) { + pEl = $('#'+parentId, that.$el); + if (!pEl.length) { + log("no parent element yet available for "+id+" ("+parentId+") after parent load; skipping") + return false; + } + } else { + log("no parent element yet available for "+id+" ("+parentId+"); skipping") + return false; + } + } + pElC = pEl.parent().children('.node-children') + depth = pEl.parent().data("depth")+1 + } + + // add it, with surrounding html, in parent's node-children child + var nEl3 = $( + '
'+ + '
'+ + '
'+ + '
') + + $('#'+id, nEl3).html(nEl2); + $(pElC).append(nEl3); + this.addEventsToNode($(pElC)) + } else { + // updating + $(nEl).html(nEl2) + this.addEventsToNode($(nEl)) + } + return true + }, + + renderFull:function () { var that = this this.$el.empty() @@ -41,16 +155,13 @@ define([ if (this.collection.isEmpty()) { that.$el.append(_.template(TreeEmptyHtml)) } else { - that.$el.append( - '