You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/02/01 18:52:11 UTC
[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 <al...@cloudsoftcorp.com>
Authored: Tue Sep 17 12:22:08 2013 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
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(
+ '<div class="navbar_main_wrapper treeloz">'+
+ '<div id="tree-list" class="navbar_main treeloz">'+
+ '<div class="lozenge-app-tree-wrapper">'+
+ '</div></div></div>');
+ 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 = $(
+ '<div class="toggler-group tree-box '+
+ (depth==0 ? "outer" : "inner "+(depth%2==1 ? "depth-odd" : "depth-even")+
+ (depth==1 ? " depth-first" : "")) + '" data-depth="'+depth+'">'+
+ '<div id="'+id+'" class="entity_tree_node_wrapper"></div>'+
+ '<div class="toggler-target hide node-children"></div>'+
+ '</div>')
+
+ $('#'+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(
- '<div class="navbar_main_wrapper treeloz">'+
- '<div id="tree-list" class="navbar_main treeloz">'+
- '<div class="lozenge-app-tree-wrapper">');
- var node = $('div.lozenge-app-tree-wrapper', that.$el);
+ _.each(this.collection.getApplications(),
+ function(appId) { that.updateNode(appId, null, true) })
- this.collection.each(function (app) {
- node.append(that.buildTree(app))
- })
+ _.each(this.collection.getNonApplications(),
+ function(id) { that.updateNode(id) })
}
+
this.highlightEntity();
// Render the details for the selected entity.
@@ -74,61 +185,15 @@ define([
return this
},
- buildTree:function (application) {
- var that = this,
- $template = $(this.template({
- id:application.get("id"),
- type:"application",
- hasChildren: application.hasChildren(),
- parentApp:application.get("id"),
- displayName:application.get("name"),
- iconUrl:application.get("iconUrl"),
- statusIconUrl: ViewUtils.computeStatusIcon(application.get("serviceUp"),application.get("serviceState")),
- depth: 0
- })),
- treeFromEntity = function (entity, depth) {
- var $entityTpl
-
- if (entity.hasChildren()) {
- $entityTpl = $(that.template({
- id:entity.get("id"),
- type:"entity",
- hasChildren: true,
- parentApp:application.get("id"),
- displayName:entity.getDisplayName(),
- iconUrl:entity.get("iconUrl"),
- statusIconUrl: ViewUtils.computeStatusIcon(entity.get("serviceUp"),entity.get("serviceState")),
- depth: depth
- }))
- var $parentTpl = $entityTpl.find("#children")
- _.each(entity.get("children"), function (childEntity) {
- $parentTpl.append(treeFromEntity(new AppTree.Model(childEntity), depth+1))
- })
- } else {
- $entityTpl = $(that.template({
- id:entity.get("id"),
- type:"leaf",
- hasChildren: false,
- parentApp:application.get("id"),
- displayName:entity.getDisplayName(),
- iconUrl:entity.get("iconUrl"),
- statusIconUrl: ViewUtils.computeStatusIcon(entity.get("serviceUp"),entity.get("serviceState")),
- depth: depth
- }))
- }
- return $entityTpl
- }
-
- // start rendering from initial children of the application
- var $tree = $template.find("#children")
- _.each(application.get("children"), function (entity) {
- $tree.append(treeFromEntity(new AppTree.Model(entity), 1))
- })
- $('a', $tree).click(function(e) { e.preventDefault(); })
+ addEventsToNode: function($node) {
+ var that = this;
+
+ // prevent default click-handling (not sure needed?)
+ $('a', $node).click(function(e) { e.preventDefault(); })
// show the "light-popup" (expand / expand all / etc) menu
// if user hovers for 500ms. surprising there is no option for this.
- $('.light-popup', $template).parent().parent().hover(
+ $('.light-popup', $node).parent().parent().hover(
function (parent) {
that.cancelHoverTimer();
that.hoverTimer = setTimeout(function() {
@@ -142,8 +207,6 @@ define([
menu.hide()
$('.light-popup').hide()
})
-
- return $template
},
cancelHoverTimer: function() {
var that = this;
@@ -157,7 +220,7 @@ define([
event.preventDefault();
var nodeSpan = $(event.currentTarget)
var nodeA = $(event.currentTarget).children('a').first()
- var entityId = nodeSpan.attr("id"),
+ var entityId = nodeSpan.parent().attr("id"),
stateId = entityId,
href = nodeA.attr('href'),
tab = (this.detailsView)
@@ -170,16 +233,14 @@ define([
this.preselectTab(tab)
}
window.history.pushState(stateId, "", href)
- this.displayEntityId(entityId, $(event.currentTarget).data("parent-app"));
+ this.displayEntityId(entityId, nodeSpan.data("app-id"));
} else {
log("no a.href in clicked target")
log(nodeSpan)
}
},
-
- displayEntityId:function (id, appName) {
+ displayEntityId:function (id, appName, afterLoad) {
var that = this;
- console.debug("Displaying entity: " + id);
this.highlightEntity(id)
var entityLoadFailed = function() {
@@ -187,14 +248,25 @@ define([
};
if (appName === undefined) {
- appName = $("span.entity_tree_node#"+id).data("parent-app")
+ appName = $("#span-"+id).data("app-id")
}
if (appName === undefined) {
- // no such app
- console.error("Couldn't find a parent application for entity: " + id);
- return entityLoadFailed();
+ if (!afterLoad) {
+ // try a reload if given an ID we don't recognise
+ this.collection.includeEntities([id]);
+ this.collection.fetch({
+ success: function() { _.defer(function() { that.displayEntityId(id, appName, true); }); },
+ error: function() { _.defer(function() { that.displayEntityId(id, appName, true); }); }
+ });
+ ViewUtils.fadeToIndicateInitialLoad($("div#details"))
+ return;
+ } else {
+ // no such app
+ entityLoadFailed();
+ return;
+ }
}
-
+
var app = new Application.Model(),
entitySummary = new EntitySummary.Model;
@@ -203,11 +275,10 @@ define([
// in case the server response time is low, fade out while it refreshes
// (since we can't show updated details until we've retrieved app + entity details)
- $("div#details").fadeTo(1000, 0.3)
+ ViewUtils.fadeToIndicateInitialLoad($("div#details"))
$.when(app.fetch(), entitySummary.fetch())
.done(function() {
- $("div#details").stop().fadeTo(200, 1)
that.showDetails(app, entitySummary);
})
.fail(entityLoadFailed);
@@ -215,6 +286,7 @@ define([
displayEntityNotFound: function(id) {
$("div#details").html(notFoundTemplate({"id": id}));
+ ViewUtils.cancelFadeOnceLoaded($("div#details"))
},
treeChange: function(event) {
@@ -230,7 +302,7 @@ define([
this.hideChildrenOf($treeBox, true)
} else {
// default - toggle
- if ($treeBox.children('#children').is(':visible')) {
+ if ($treeBox.children('.node-children').is(':visible')) {
this.hideChildrenOf($treeBox, false)
} else {
this.showChildrenOf($treeBox, false)
@@ -244,20 +316,40 @@ define([
},
hideChildrenOf: function($treeBox, recurse) {
var that = this;
- $treeBox.children('#children').slideUp(300)
- $treeBox.children('.tree-node').find('.tree-node-state').removeClass('icon-chevron-down').addClass('icon-chevron-right')
if (recurse) {
- $treeBox.children('#children').children().each(function (index, childBox) {
+ $treeBox.children('.node-children').children().each(function (index, childBox) {
that.hideChildrenOf($(childBox), recurse)
})
}
+ $treeBox.children('.node-children').slideUp(300)
+ $treeBox.children('.entity_tree_node_wrapper').find('.tree-node-state').removeClass('icon-chevron-down').addClass('icon-chevron-right')
},
showChildrenOf: function($treeBox, recurse) {
var that = this;
- $treeBox.children('#children').slideDown(300)
- $treeBox.children('.tree-node').find('.tree-node-state').removeClass('icon-chevron-right').addClass('icon-chevron-down')
+ var idToExpand = $treeBox.children('.entity_tree_node_wrapper').attr('id');
+ var model = this.collection.get(idToExpand);
+ if (model==null) {
+ // not yet loaded; parallel thread should load
+ return;
+ }
+ var childrenIds = model.get('childrenIds');
+ _.each(childrenIds, function(id) { that.updateNode(id, idToExpand) })
+ if (this.collection.includeEntities(childrenIds)) {
+ // we have to load entities before we can proceed
+ this.collection.fetch({
+ success: function() {
+ if (recurse) {
+ $treeBox.children('.node-children').children().each(function (index, childBox) {
+ _.defer( function() { that.showChildrenOf($(childBox), recurse) } );
+ })
+ }
+ }
+ })
+ }
+ $treeBox.children('.node-children').slideDown(300)
+ $treeBox.children('.entity_tree_node_wrapper').find('.tree-node-state').removeClass('icon-chevron-right').addClass('icon-chevron-down')
if (recurse) {
- $treeBox.children('#children').children().each(function (index, childBox) {
+ $treeBox.children('.node-children').children().each(function (index, childBox) {
that.showChildrenOf($(childBox), recurse)
})
}
@@ -272,6 +364,8 @@ define([
},
showDetails: function(app, entitySummary) {
+ ViewUtils.cancelFadeOnceLoaded($("div#details"))
+
var whichTab = this.currentTab
if (whichTab === undefined) {
whichTab = "summary";
@@ -295,12 +389,22 @@ define([
highlightEntity:function (id) {
if (id) this.selectedEntityId = id
else id = this.selectedEntityId
- $("span.entity_tree_node").removeClass("active")
+
+ $(".entity_tree_node_wrapper").removeClass("active")
if (id) {
- var $selectedNode = $("span.entity_tree_node#"+id);
- $selectedNode.addClass("active")
- // if we wanted to auto-expand the children of the selected node:
-// this.showChildrenOf($selectedNode.parents('#app-tree .tree-box'), false)
+ var $selectedNode = $(".entity_tree_node_wrapper#"+id);
+ // make this node active
+ $selectedNode.addClass("active")
+
+ // open the parent nodes if needed
+ var $nodeToOpenInParent = $selectedNode;
+ while ($nodeToOpenInParent.length && !$nodeToOpenInParent.is(':visible')) {
+ $nodeToOpenInParent = $nodeToOpenInParent.closest('.node-children').closest('.tree-box');
+ this.showChildrenOf($nodeToOpenInParent)
+ }
+
+ // if we want to auto-expand the children of the selected node:
+// this.showChildrenOf($selectedNode.closest('.tree-box'), false)
}
}
})
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/869239d1/usage/jsgui/src/main/webapp/assets/js/view/entity-details.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-details.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-details.js
index 11aa62e..0028b40 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-details.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-details.js
@@ -61,8 +61,8 @@ define([
},
tabSelected: function(event) {
var tabName = $(event.currentTarget).attr("href").slice(1)
- var entityId = $("#app-tree span.active").attr("id")
- var entityHref = $("#app-tree span.active a").attr("href")
+ var entityId = $("#app-tree .entity_tree_node_wrapper.active").attr("id")
+ var entityHref = $("#app-tree .entity_tree_node_wrapper.active a").attr("href")
if (entityId && entityHref) {
window.history.pushState(entityId+"/"+tabName, "",
entityHref+"/"+tabName);
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/869239d1/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js b/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js
index ae9dbb7..a30635c 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js
@@ -226,18 +226,18 @@ define([
processTooltips: function($el) {
$el.find('*[rel="tooltip"]').tooltip();
},
- fadeToIndicateInitialLoad: function($table) {
+ fadeToIndicateInitialLoad: function($el) {
// in case the server response time is low, fade out while it refreshes
// (since we can't show updated details until we've retrieved app + entity details)
try {
- $table.fadeTo(1000, 0.3);
+ $el.fadeTo(1000, 0.3);
} catch (e) {
// ignore - normal during tests
}
},
- cancelFadeOnceLoaded: function($table) {
+ cancelFadeOnceLoaded: function($el) {
try {
- $table.stop().fadeTo(200, 1);
+ $el.stop(true, false).fadeTo(200, 1);
} catch (e) {
// ignore - normal during tests
}
http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/869239d1/usage/jsgui/src/main/webapp/assets/tpl/apps/tree-item.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/tree-item.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/tree-item.html
index 82fcef3..4eb7e50 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/tree-item.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/tree-item.html
@@ -1,26 +1,34 @@
-<div class="toggler-group tree-box <%=
- depth==0 ? "outer" : "inner "+(depth%2==1 ? "depth-odd" : "depth-even")+(depth==1 ? " depth-first" : "") %>">
- <div class="tree-node">
- <span class="entity_tree_node name entity" id="<%= id %>" data-entity-type="<%= type %>" data-parent-app="<%= parentApp %>">
- <a href="#/v1/applications/<%= parentApp %>/entities/<%= id %>">
+<%
+ var isLoaded = (model ? true : false);
+ var isApp = (parentId ? false : true);
- <%
- var isApp = type == "application";
+ if (!isLoaded) {
+%>
+ <i>Loading... (<%= id %>)</i>
+<% } else {
+ var hasChildren = model.hasChildren();
+ var iconUrl = model.get('iconUrl');
+
var entityIconSize = isApp ? 40 : 30;
var statusIconSize = isApp ? 24 : 16;
- var chevronLeft = isApp ? 5.5 : 1.5;
+ var chevronLeft = (isApp ? 5.5 : 1.5);
var minHeight = hasChildren && statusIconUrl ? entityIconSize : 24;
var statusColumnWidth = hasChildren || statusIconUrl || (!isApp && !iconUrl /* for children, insert space so things line up */) ? statusIconSize : 0;
- %>
- <div style="min-width: <%= statusColumnWidth + (iconUrl ? entityIconSize : 6)%>px; min-height: <%= minHeight %>px; max-height: 40px; display: inline-block; margin-right: 4px; vertical-align: middle;">
+%>
+
+ <span class="entity_tree_node name entity" id="span-<%= id %>"
+ data-entity-type="<%= model.get('type') %>" data-parent-id="<%= parentId %>" data-app-id="<%= model.get('applicationId') %>">
+ <a href="#/v1/applications/<%= model.get('applicationId') %>/entities/<%= id %>">
+
+ <div style="min-width: <%= statusColumnWidth + (iconUrl ? entityIconSize : 6)%>px; min-height: <%= minHeight %>px; max-height: 40px; display: inline-block; margin-right: 4px; vertical-align: middle;">
<% if (statusIconUrl) { %>
<div style="position: absolute; left: 0px; margin: auto; top: <%= isApp && hasChildren ? 3 : 2 %>px;<% if (!hasChildren) { %> bottom: 0px;<% } %>">
- <img src="<%= statusIconUrl %>" style="max-width: <%= statusIconSize %>px; max-height: <%= statusIconSize %>px; margin: auto; position: absolute; top: 0px;<% if (!hasChildren) { %> bottom: 0px;<% } %>">
+ <img src="<%= statusIconUrl %>" style="max-width: <%= statusIconSize %>px; max-height: <%= statusIconSize %>px; margin: auto; position: absolute; top: -1px;<% if (!hasChildren) { %> bottom: 0px;<% } %>">
</div>
<% } %>
<% if (hasChildren) { %>
- <div style="position: absolute; left: <%= chevronLeft %>px; margin: auto; <%= statusIconUrl ? "bottom: 1px;" : isApp ? "top: 6px;" : "top: 6px;" %>">
+ <div style="position: absolute; left: <%= chevronLeft %>px; margin: auto; <%= statusIconUrl ? "bottom: -1px;" : isApp ? "top: 6px;" : "top: 6px;" %>">
<div class="toggler-icon icon-chevron-right tree-node-state tree-change">
<div class="light-popup">
<div class="light-popup-body">
@@ -34,16 +42,14 @@
</div>
</div>
<% } %>
- <% if (iconUrl) { %>
- <img src="<%= iconUrl %>" style="max-width: <%= entityIconSize %>px; max-height: <%= entityIconSize %>px; position: absolute; left: <%= statusColumnWidth %>px; top: 0; bottom: 0; margin: auto;">
- <% } %>
- </div>
+ <% if (iconUrl) { %>
+ <img src="<%= iconUrl %>" style="max-width: <%= entityIconSize %>px; max-height: <%= entityIconSize %>px; position: absolute; left: <%= statusColumnWidth %>px; top: 0; bottom: 0; margin: auto;">
+ <% } %>
+ </div>
- <span style="max-height: 18px; position: relative; margin: auto; top: 2px; bottom: 0;"><%= displayName %></span>
+ <span style="max-height: 18px; padding-right: 6px; position: relative; margin: auto; top: 2px; bottom: 0;"><%= model.get('name') %></span>
- </a>
- </span>
- </div>
- <div id="children" class="toggler-target hide">
- </div>
-</div>
+ </a>
+ </span>
+
+<% } %>
\ No newline at end of file