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 2015/10/08 13:28:31 UTC
[1/7] incubator-brooklyn git commit: Prevent infinite expand-all of
recursive group members.
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master 7b89b6644 -> fa131b105
Prevent infinite expand-all of recursive group members.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/5ada3e21
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/5ada3e21
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/5ada3e21
Branch: refs/heads/master
Commit: 5ada3e2135bcd0f175bf5c251c4b3f35b28c32fb
Parents: c9f45a3
Author: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Authored: Wed Oct 7 11:35:09 2015 +0100
Committer: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Committed: Wed Oct 7 14:33:57 2015 +0100
----------------------------------------------------------------------
.../webapp/assets/js/view/application-tree.js | 29 ++++++++++++++------
1 file changed, 21 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5ada3e21/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 1d31953..2f7a3d0 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
@@ -282,10 +282,11 @@ define([
return false;
},
- showChildrenOf: function($treeBox, recurse) {
+ showChildrenOf: function($treeBox, recurse, excludedEntityIds) {
+ excludedEntityIds = excludedEntityIds || [];
+ var idToExpand = $treeBox.data('entityId');
var $wrapper = $treeBox.children('.entity_tree_node_wrapper');
var $childContainer = $treeBox.children('.node-children');
- var idToExpand = $treeBox.data('entityId');
var model = this.collection.get(idToExpand);
if (model == null) {
// not yet loaded; parallel thread should load
@@ -311,16 +312,28 @@ define([
}
});
+ // Avoid infinite recursive expansion using a "taboo list" of indirect entities already expanded in this
+ // operation. Example: a group that contains itself or one of its own ancestors. Such cycles can only
+ // originate via "indirect" subordinates.
+ var expandIfNotExcluded = function($treebox, excludedEntityIds, defer) {
+ if ($treebox.hasClass('indirect')) {
+ var id = $treebox.data('entityId');
+ if (_.contains(excludedEntityIds, id))
+ return;
+ excludedEntityIds.push(id);
+ }
+ var doExpand = function() { that.showChildrenOf($treebox, recurse, excludedEntityIds); };
+ if (defer) _.defer(doExpand);
+ else doExpand();
+ };
+
if (this.collection.includeEntities(_.union(children, members))) {
// we have to load entities before we can proceed
this.collection.fetch({
success: function() {
if (recurse) {
$childContainer.children('.tree-box').each(function () {
- var $treebox = $(this);
- _.defer(function() {
- that.showChildrenOf($treebox, recurse);
- });
+ expandIfNotExcluded($(this), excludedEntityIds, true);
});
}
}
@@ -331,8 +344,8 @@ define([
$wrapper.find('.tree-node-state').removeClass('icon-chevron-right').addClass('icon-chevron-down');
if (recurse) {
$childContainer.children('.tree-box').each(function () {
- that.showChildrenOf($(this), recurse);
- })
+ expandIfNotExcluded($(this), excludedEntityIds, false);
+ });
}
},
[4/7] incubator-brooklyn git commit: Decouple application-tree view
from entity-details view.
Posted by he...@apache.org.
Decouple application-tree view from entity-details view.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/c9f45a32
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/c9f45a32
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/c9f45a32
Branch: refs/heads/master
Commit: c9f45a32f8a85665abd8f8f5fcf7610d7f25f10a
Parents: 345daaa
Author: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Authored: Thu Oct 1 11:39:12 2015 +0100
Committer: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Committed: Wed Oct 7 14:33:57 2015 +0100
----------------------------------------------------------------------
.../assets/js/view/application-explorer.js | 120 +++++++++++++--
.../webapp/assets/js/view/application-tree.js | 154 +++----------------
2 files changed, 129 insertions(+), 145 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c9f45a32/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 45160cb..e9c23bc 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
@@ -23,21 +23,24 @@
*/
define([
"underscore", "jquery", "backbone", "view/viewutils",
- "./application-add-wizard", "model/app-tree", "./application-tree",
- "text!tpl/apps/page.html"
-], function (_, $, Backbone, ViewUtils, AppAddWizard, AppTree, ApplicationTreeView, PageHtml) {
+ "./application-add-wizard", "model/application", "model/entity-summary", "model/app-tree", "./application-tree", "./entity-details",
+ "text!tpl/apps/details.html", "text!tpl/apps/entity-not-found.html", "text!tpl/apps/page.html"
+], function (_, $, Backbone, ViewUtils,
+ AppAddWizard, Application, EntitySummary, AppTree, ApplicationTreeView, EntityDetailsView,
+ EntityDetailsEmptyHtml, EntityNotFoundHtml, PageHtml) {
var ApplicationExplorerView = Backbone.View.extend({
tagName:"div",
className:"container container-fluid",
id:'application-explorer',
template:_.template(PageHtml),
+ notFoundTemplate: _.template(EntityNotFoundHtml),
events:{
'click .application-tree-refresh': 'refreshApplicationsInPlace',
'click #add-new-application':'createApplication',
'click .delete':'deleteApplication'
},
- initialize:function () {
+ initialize: function () {
this.$el.html(this.template({}))
$(".nav1").removeClass("active");
$(".nav1_apps").addClass("active");
@@ -46,7 +49,12 @@ define([
collection:this.collection,
appRouter:this.options.appRouter
})
+ this.treeView.on('entitySelected', function(e) {
+ this.displayEntityId(e.id, e.get('applicationId'), false);
+ }, this);
this.$('div#app-tree').html(this.treeView.renderFull().el)
+ this.$('div#details').html(EntityDetailsEmptyHtml);
+
ViewUtils.fetchRepeatedlyWithDelay(this, this.collection)
},
refreshApplicationsInPlace: function() {
@@ -54,9 +62,11 @@ define([
// (not a full visual recompute, which reset does - both in application-tree.js)
this.collection.fetch();
},
- beforeClose:function () {
- this.collection.off("reset", this.render)
- this.treeView.close()
+ beforeClose: function () {
+ this.collection.off("reset", this.render);
+ this.treeView.close();
+ if (this.detailsView)
+ this.detailsView.close();
},
show: function(entityId) {
var tab = "";
@@ -79,10 +89,6 @@ define([
}
this.treeView.selectEntity(entityId)
},
- preselectTab: function(tab, tabDetails) {
- this.treeView.preselectTab(tab, tabDetails)
- },
-
createApplication:function () {
var that = this;
if (this._modal) {
@@ -102,7 +108,97 @@ define([
deleteApplication:function (event) {
// call Backbone destroy() which does HTTP DELETE on the model
this.collection.get(event.currentTarget['id']).destroy({wait:true})
- }
+ },
+ /**
+ * Causes the tab with the given name to be selected automatically when
+ * the view is next rendered.
+ */
+ preselectTab: function(tab, tabDetails) {
+ this.currentTab = tab;
+ this.currentTabDetails = tabDetails;
+ },
+ showDetails: function(app, entitySummary) {
+ var that = this;
+ ViewUtils.cancelFadeOnceLoaded($("div#details"));
+
+ var whichTab = this.currentTab;
+ if (!whichTab) {
+ whichTab = "summary";
+ if (this.detailsView) {
+ whichTab = this.detailsView.$el.find(".tab-pane.active").attr("id");
+ this.detailsView.close();
+ }
+ }
+ if (this.detailsView) {
+ this.detailsView.close();
+ }
+ this.detailsView = new EntityDetailsView({
+ model: entitySummary,
+ application: app,
+ appRouter: this.options.appRouter,
+ preselectTab: whichTab,
+ preselectTabDetails: this.currentTabDetails,
+ });
+
+ this.detailsView.on("entity.expunged", function() {
+ that.preselectTab("summary");
+ var id = that.selectedEntityId;
+ var model = that.collection.get(id);
+ if (model && model.get("parentId")) {
+ that.displayEntityId(model.get("parentId"));
+ } else if (that.collection) {
+ that.displayEntityId(that.collection.first().id);
+ } else if (id) {
+ that.displayEntityNotFound(id);
+ } else {
+ that.displayEntityNotFound("?");
+ }
+ that.collection.fetch();
+ });
+ this.detailsView.render( $("div#details") );
+ },
+ displayEntityId: function (id, appName, afterLoad) {
+ var that = this;
+ var entityLoadFailed = function() {
+ return that.displayEntityNotFound(id);
+ };
+ if (appName === undefined) {
+ 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();
+ var entitySummary = new EntitySummary.Model;
+
+ app.url = "/v1/applications/" + appName;
+ entitySummary.url = "/v1/applications/" + appName + "/entities/" + id;
+
+ // 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)
+ ViewUtils.fadeToIndicateInitialLoad($("div#details"));
+
+ $.when(app.fetch(), entitySummary.fetch())
+ .done(function() {
+ that.showDetails(app, entitySummary);
+ })
+ .fail(entityLoadFailed);
+ },
+ displayEntityNotFound: function(id) {
+ $("div#details").html(this.notFoundTemplate({"id": id}));
+ ViewUtils.cancelFadeOnceLoaded($("div#details"))
+ },
})
return ApplicationExplorerView
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c9f45a32/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 be21e40..1d31953 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
@@ -22,14 +22,12 @@
*/
define([
"underscore", "jquery", "backbone", "view/viewutils",
- "model/app-tree", "./entity-details", "model/entity-summary", "model/application",
- "text!tpl/apps/tree-item.html", "text!tpl/apps/tree-empty.html", "text!tpl/apps/details.html", "text!tpl/apps/entity-not-found.html"
+ "model/app-tree", "text!tpl/apps/tree-item.html", "text!tpl/apps/tree-empty.html"
], function (_, $, Backbone, ViewUtils,
- AppTree, EntityDetailsView, EntitySummary, Application,
- TreeItemHtml, TreeEmptyHtml, EntityDetailsEmptyHtml, EntityNotFoundHtml) {
+ AppTree, TreeItemHtml, EmptyTreeHtml) {
- var treeViewTemplate = _.template(TreeItemHtml);
- var notFoundTemplate = _.template(EntityNotFoundHtml);
+ var emptyTreeTemplate = _.template(EmptyTreeHtml);
+ var treeItemTemplate = _.template(TreeItemHtml);
var findAllTreeboxes = function(id, $scope) {
return $('.tree-box[data-entity-id="' + id + '"]', $scope);
@@ -43,8 +41,8 @@ define([
return $parentTreebox.children('.node-children').children('.tree-box[data-entity-id="' + id + '"]');
};
- var findMasterTreebox = function(id) {
- return $('.tree-box[data-entity-id="' + id + '"]:not(.indirect)');
+ var findMasterTreebox = function(id, $scope) {
+ return $('.tree-box[data-entity-id="' + id + '"]:not(.indirect)', $scope);
};
var createEntityTreebox = function(id, name, $domParent, depth, indirect) {
@@ -153,13 +151,13 @@ define([
var entity = treeView.collection.get(id);
if (entity) {
treeView.selectedEntityId = id;
- treeView.displayEntityId(entity.id, entity.get('applicationId'), false);
+ treeView.trigger('entitySelected', entity);
}
};
return Backbone.View.extend({
- template: treeViewTemplate,
+ template: treeItemTemplate,
hoverTimer: null,
events: {
@@ -177,7 +175,6 @@ define([
beforeClose: function() {
this.collection.off("reset", this.renderFull);
- if (this.detailsView) this.detailsView.close();
},
entityAdded: function(entity) {
@@ -187,7 +184,11 @@ define([
// If the new entity is an application, we must create its placeholder in the DOM.
if (!entity.get('parentId')) {
- getOrCreateApplicationTreebox(entity.id, entity.get('name'), this);
+ var $treebox = getOrCreateApplicationTreebox(entity.id, entity.get('name'), this);
+
+ // Select the new app if there's no current selection.
+ if (!this.selectedEntityId)
+ selectTreebox(entity.id, $treebox, this);
}
this.entityChanged(entity);
@@ -219,7 +220,7 @@ define([
},
selectEntity: function(id) {
- var $treebox = findMasterTreebox(id);
+ var $treebox = findMasterTreebox(id, this.$el);
selectTreebox(id, $treebox, this);
},
@@ -229,7 +230,8 @@ define([
// Display tree and highlight the selected entity.
if (this.collection.getApplications().length == 0) {
- that.$el.append(_.template(TreeEmptyHtml));
+ this.$el.append(emptyTreeTemplate());
+
} else {
_.each(this.collection.getApplications(), function(appId) {
var entity = that.collection.get(appId);
@@ -238,24 +240,11 @@ define([
});
}
- // this.highlightEntity();
-
- // Render the details for the selected entity.
- if (this.detailsView) {
- this.detailsView.render();
- } else {
- // if nothing selected, select the first application
- if (!this.collection.isEmpty()) {
- var app0 = this.collection.first().id;
- _.defer(function () {
- that.selectEntity(app0);
- });
- } else {
- _.defer(function() {
- $("div#details").html(_.template(EntityDetailsEmptyHtml));
- $("div#details").find("a[href='#summary']").tab('show');
- });
- }
+ // Select the first app if there's no current selection.
+ if (!this.selectedEntityId) {
+ var firstApp = _.first(this.collection.getApplications());
+ if (firstApp)
+ this.selectEntity(firstApp);
}
return this;
},
@@ -267,57 +256,6 @@ define([
}
},
- displayEntityId: function (id, appName, afterLoad) {
- var that = this;
- //this.highlightEntity(id);
-
- var entityLoadFailed = function() {
- return that.displayEntityNotFound(id);
- };
-
- if (appName === undefined) {
- var $treebox = findMasterTreebox(id);
- appName = $treebox.children(".entity_tree_node").data("app-id");
- }
- if (appName === undefined) {
- 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();
- var entitySummary = new EntitySummary.Model;
-
- app.url = "/v1/applications/" + appName;
- entitySummary.url = "/v1/applications/" + appName + "/entities/" + id;
-
- // 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)
- ViewUtils.fadeToIndicateInitialLoad($("div#details"));
-
- $.when(app.fetch(), entitySummary.fetch())
- .done(function() {
- that.showDetails(app, entitySummary);
- })
- .fail(entityLoadFailed);
- },
-
- displayEntityNotFound: function(id) {
- $("div#details").html(notFoundTemplate({"id": id}));
- ViewUtils.cancelFadeOnceLoaded($("div#details"))
- },
-
treeChange: function(event) {
var $target = $(event.currentTarget);
var $treeBox = $target.closest('.tree-box');
@@ -411,56 +349,6 @@ define([
$wrapper.find('.tree-node-state').removeClass('icon-chevron-down').addClass('icon-chevron-right');
},
- /**
- * Causes the tab with the given name to be selected automatically when
- * the view is next rendered.
- */
- preselectTab: function(tab, tabDetails) {
- this.currentTab = tab;
- this.currentTabDetails = tabDetails;
- },
-
- showDetails: function(app, entitySummary) {
- var that = this;
- ViewUtils.cancelFadeOnceLoaded($("div#details"));
-
- var whichTab = this.currentTab;
- if (whichTab === undefined) {
- whichTab = "summary";
- if (this.detailsView) {
- whichTab = this.detailsView.$el.find(".tab-pane.active").attr("id");
- this.detailsView.close();
- }
- }
- if (this.detailsView) {
- this.detailsView.close();
- }
- this.detailsView = new EntityDetailsView({
- model: entitySummary,
- application: app,
- appRouter: this.options.appRouter,
- preselectTab: whichTab,
- preselectTabDetails: this.currentTabDetails,
- });
-
- this.detailsView.on("entity.expunged", function() {
- that.preselectTab("summary");
- var id = that.selectedEntityId;
- var model = that.collection.get(id);
- if (model && model.get("parentId")) {
- that.displayEntityId(model.get("parentId"));
- } else if (that.collection) {
- that.displayEntityId(that.collection.first().id);
- } else if (id) {
- that.displayEntityNotFound(id);
- } else {
- that.displayEntityNotFound("?");
- }
- that.collection.fetch();
- });
- this.detailsView.render( $("div#details") );
- },
-
});
});
[7/7] incubator-brooklyn git commit: This closes #942
Posted by he...@apache.org.
This closes #942
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/fa131b10
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/fa131b10
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/fa131b10
Branch: refs/heads/master
Commit: fa131b1055398f4caa7479d42ed8d3e3679ba9ea
Parents: e23889c b02bd17
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Oct 8 12:28:06 2015 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Oct 8 12:28:06 2015 +0100
----------------------------------------------------------------------
.../webapp/assets/tpl/app-add-wizard/required-config-entry.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
[6/7] incubator-brooklyn git commit: This closes #929
Posted by he...@apache.org.
This closes #929
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/e23889cc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/e23889cc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/e23889cc
Branch: refs/heads/master
Commit: e23889cc63745b3f542b2397272a86307ce1894c
Parents: 7b89b66 5ada3e2
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Oct 8 12:27:57 2015 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Oct 8 12:27:57 2015 +0100
----------------------------------------------------------------------
usage/jsgui/src/main/webapp/assets/css/base.css | 9 +
.../src/main/webapp/assets/js/model/app-tree.js | 62 +-
.../assets/js/view/application-explorer.js | 122 +++-
.../webapp/assets/js/view/application-tree.js | 700 ++++++++-----------
.../webapp/assets/js/view/entity-summary.js | 2 +-
.../main/webapp/assets/tpl/apps/summary.html | 6 +-
.../main/webapp/assets/tpl/apps/tree-item.html | 26 +-
7 files changed, 448 insertions(+), 479 deletions(-)
----------------------------------------------------------------------
[2/7] incubator-brooklyn git commit: Show group members as ‘indirect’ subordinates in tree.
Posted by he...@apache.org.
Show group members as ‘indirect’ subordinates in tree.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/345daaa0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/345daaa0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/345daaa0
Branch: refs/heads/master
Commit: 345daaa0050b1dbe2fea536a566f6552227294fc
Parents: 99c0119
Author: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Authored: Thu Oct 1 08:49:51 2015 +0100
Committer: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Committed: Wed Oct 7 14:33:57 2015 +0100
----------------------------------------------------------------------
usage/jsgui/src/main/webapp/assets/css/base.css | 9 +
.../assets/js/view/application-explorer.js | 2 +-
.../webapp/assets/js/view/application-tree.js | 506 +++++++++----------
.../main/webapp/assets/tpl/apps/tree-item.html | 12 +-
4 files changed, 246 insertions(+), 283 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/345daaa0/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 04a488d..a80f35b 100644
--- a/usage/jsgui/src/main/webapp/assets/css/base.css
+++ b/usage/jsgui/src/main/webapp/assets/css/base.css
@@ -580,6 +580,15 @@ ol.tree {
.entity_tree_node_wrapper.active .entity_tree_node {
font-weight: bold;
}
+.entity_tree_node_wrapper .indirection-icon {
+ opacity: 0.7;
+ margin-left: -5px;
+}
+.tree-box.indirect > .entity_tree_node_wrapper a {
+ font-style: italic !important;
+ color: #666;
+}
+
#tree label {
/* remove the folder, and align with + - icons */
background: none;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/345daaa0/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 b7d6f70..45160cb 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
@@ -77,7 +77,7 @@ define([
}
this.preselectTab(tab, tabDetails);
}
- this.treeView.displayEntityId(entityId)
+ this.treeView.selectEntity(entityId)
},
preselectTab: function(tab, tabDetails) {
this.treeView.preselectTab(tab, tabDetails)
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/345daaa0/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 8a5175a..be21e40 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
@@ -31,22 +31,147 @@ define([
var treeViewTemplate = _.template(TreeItemHtml);
var notFoundTemplate = _.template(EntityNotFoundHtml);
+ var findAllTreeboxes = function(id, $scope) {
+ return $('.tree-box[data-entity-id="' + id + '"]', $scope);
+ };
+
+ var findRootTreebox = function(id) {
+ return $('.lozenge-app-tree-wrapper').children('.tree-box[data-entity-id="' + id + '"]', this.$el);
+ };
+
+ var findChildTreebox = function(id, $parentTreebox) {
+ return $parentTreebox.children('.node-children').children('.tree-box[data-entity-id="' + id + '"]');
+ };
+
+ var findMasterTreebox = function(id) {
+ return $('.tree-box[data-entity-id="' + id + '"]:not(.indirect)');
+ };
+
+ var createEntityTreebox = function(id, name, $domParent, depth, indirect) {
+ // Tildes in sort key force entities with no name to bottom of list (z < ~).
+ var sortKey = (name ? name.toLowerCase() : "~~~") + " " + id.toLowerCase();
+
+ // Create the wrapper.
+ var $treebox = $(
+ '<div data-entity-id="'+id+'" data-sort-key="'+sortKey+'" data-depth="'+depth+'" ' +
+ 'class="tree-box toggler-group' +
+ (indirect ? " indirect" : "") +
+ (depth == 0 ? " outer" : " inner " + (depth % 2 ? " depth-odd" : " depth-even")+
+ (depth == 1 ? " depth-first" : "")) + '">'+
+ '<div class="entity_tree_node_wrapper"></div>'+
+ '<div class="node-children toggler-target hide"></div>'+
+ '</div>');
+
+ // Insert into the passed DOM parent, maintaining sort order relative to siblings: name then id.
+ var placed = false;
+ var contender = $(".toggler-group", $domParent).first();
+ while (contender.length && !placed) {
+ var contenderKey = contender.data("sort-key");
+ if (sortKey < contenderKey) {
+ contender.before($treebox);
+ placed = true;
+ } else {
+ contender = contender.next(".toggler-group", $domParent);
+ }
+ }
+ if (!placed) {
+ $domParent.append($treebox);
+ }
+ return $treebox;
+ };
+
+ var getOrCreateApplicationTreebox = function(id, name, treeView) {
+ var $treebox = findRootTreebox(id);
+ if (!$treebox.length) {
+ var $insertionPoint = $('.lozenge-app-tree-wrapper', treeView.$el);
+ if (!$insertionPoint.length) {
+ // entire view must be created
+ treeView.$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>');
+ $insertionPoint = $('.lozenge-app-tree-wrapper', treeView.$el);
+ }
+ $treebox = createEntityTreebox(id, name, $insertionPoint, 0, false);
+ }
+ return $treebox;
+ };
+
+ var getOrCreateChildTreebox = function(id, name, isIndirect, $parentTreebox) {
+ var $treebox = findChildTreebox(id, $parentTreebox);
+ if (!$treebox.length) {
+ $treebox = createEntityTreebox(id, name, $parentTreebox.children('.node-children'), $parentTreebox.data("depth") + 1, isIndirect);
+ }
+ return $treebox;
+ };
+
+ var updateTreeboxContent = function(entity, $treebox, treeView) {
+ var $newContent = $(treeView.template({
+ id: entity.get('id'),
+ parentId: entity.get('parentId'),
+ model: entity,
+ statusIconUrl: ViewUtils.computeStatusIconInfo(entity.get("serviceUp"), entity.get("serviceState")).url,
+ indirect: $treebox.hasClass('indirect'),
+ }));
+
+ var $wrapper = $treebox.children('.entity_tree_node_wrapper');
+
+ // Preserve old display status (just chevron direction at present).
+ if ($wrapper.find('.tree-node-state').hasClass('icon-chevron-down')) {
+ $newContent.find('.tree-node-state').removeClass('icon-chevron-right').addClass('icon-chevron-down');
+ }
+
+ $wrapper.html($newContent);
+ addEventsToNode($treebox, treeView);
+ };
+
+ var addEventsToNode = function($node, treeView) {
+ // show the "light-popup" (expand / expand all / etc) menu
+ // if user hovers for 500ms. surprising there is no option for this (hover delay).
+ // also, annoyingly, clicks around the time the animation starts don't seem to get handled
+ // if the click is in an overlapping reason; this is why we position relative top: 12px in css
+ $('.light-popup', $node).parent().parent().hover(
+ function(parent) {
+ treeView.cancelHoverTimer();
+ treeView.hoverTimer = setTimeout(function() {
+ var menu = $(parent.currentTarget).find('.light-popup');
+ menu.show();
+ }, 500);
+ },
+ function(parent) {
+ treeView.cancelHoverTimer();
+ $('.light-popup').hide();
+ }
+ );
+ };
- var ApplicationTreeView = Backbone.View.extend({
+ var selectTreebox = function(id, $treebox, treeView) {
+ $('.entity_tree_node_wrapper').removeClass('active');
+ $treebox.children('.entity_tree_node_wrapper').addClass('active');
+
+ var entity = treeView.collection.get(id);
+ if (entity) {
+ treeView.selectedEntityId = id;
+ treeView.displayEntityId(entity.id, entity.get('applicationId'), false);
+ }
+ };
+
+
+ return Backbone.View.extend({
template: treeViewTemplate,
hoverTimer: null,
events: {
- 'click span.entity_tree_node .tree-change':'treeChange',
- 'click span.entity_tree_node':'displayEntity'
+ 'click span.entity_tree_node .tree-change': 'treeChange',
+ 'click span.entity_tree_node': 'nodeClicked'
},
- 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)
initialize: function() {
+ this.collection.on('add', this.entityAdded, this);
+ this.collection.on('change', this.entityChanged, this);
+ this.collection.on('remove', this.entityRemoved, this);
+ this.collection.on('reset', this.renderFull, this);
_.bindAll(this);
},
@@ -54,171 +179,48 @@ define([
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 (/^change/i.test(eventName) || eventName == "remove" || eventName == "add" ||
- eventName == "reset" ||
- // above are handled; below is no-op
- eventName == "sync" || eventName == "request")
- return;
+ entityAdded: function(entity) {
+ // Called when the full entity model is fetched into our collection, at which time we can replace
+ // the empty contents of any placeholder tree nodes (.tree-box) that were created earlier.
+ // The entity may have multiple 'treebox' views (in the case of group members).
- if (eventName == "error") {
- log("model error in application-tree - has the internet vanished?")
- // ignore; app-explorer should clear the view
- return;
+ // If the new entity is an application, we must create its placeholder in the DOM.
+ if (!entity.get('parentId')) {
+ getOrCreateApplicationTreebox(entity.id, entity.get('name'), this);
}
- // don't think we get other events, but just in case:
- log("unhandled model event");
- log(eventName);
- log(event);
- log(x);
+ this.entityChanged(entity);
},
- removeNode: function(id) {
- $('#'+id, this.$el).parent().remove()
- // collection seems sometimes to have children nodes;
- // not sure why, but that's okay for now
- if (this.collection.getApplications().length==0)
- this.renderFull();
- },
-
- updateNode: function(id, parentId, isApp) {
+ entityChanged: function(entity) {
+ // The entity may have multiple 'treebox' views (in the case of group members).
var that = this;
- var nModel = that.collection.get(id);
- var node = $('#'+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 && node && node.parent().data('depth')==0) isApp = true;
- }
+ findAllTreeboxes(entity.id).each(function() {
+ var $treebox = $(this);
+ updateTreeboxContent(entity, $treebox, that);
+ });
+ },
- if (!isApp && !parentId && nModel)
- parentId = nModel.get('parentId');
- if (!isApp && !parentId && node)
- parentId = node.closest("entity_tree_node_wrapper").data('parentId');
- if (!isApp && !parentId) {
- log("no parentId yet available for "+id+"; skipping;")
- return false;
- }
-
- var statusIconUrl = nModel
- ? ViewUtils.computeStatusIconInfo(nModel.get("serviceUp"),nModel.get("serviceState")).url
- : null;
-
- var newNode = this.template({
- id:id,
- parentId:parentId,
- model:nModel,
- statusIconUrl:statusIconUrl
- })
-
- if (!node.length) {
- // node does not exist, so add it
- var parentsChildren, depth;
-
- if (isApp) {
- parentsChildren = $('.lozenge-app-tree-wrapper', that.$el);
- if (!parentsChildren.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>');
- parentsChildren = $('.lozenge-app-tree-wrapper', that.$el);
- }
- depth = 0;
- } else {
- var parent = $('#'+parentId, that.$el)
- if (!parent.length) {
- // see if we can load the parent
- if (this.updateNode(parentId)) {
- parent = $('#'+parentId, that.$el);
- if (!parent.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;
- }
- }
- parentsChildren = $(parent.parent().children('.node-children'));
- depth = parent.parent().data("depth")+1
- }
+ entityRemoved: function(entity) {
+ // The entity may have multiple 'treebox' views (in the case of group members).
+ findAllTreeboxes(entity.id, this.$el).remove();
+ // Collection seems sometimes to retain children of the removed node;
+ // not sure why, but that's okay for now.
+ if (this.collection.getApplications().length == 0)
+ this.renderFull();
+ },
- // add it, with surrounding html, in parent's node-children child
- // tildes in sortKey force entities with no name to bottom of list (z < ~).
- var entityName = nModel && nModel.get("name")
- ? nModel.get("name")
- : this.collection.getEntityNameFromId(id);
- var sortKey = (entityName ? entityName.toLowerCase() : "~~~") + " " + id.toLowerCase();
- var newNodeWrapper = $(
- '<div data-sort-key="'+sortKey+'" 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, newNodeWrapper).html(newNode);
-
- // Maintain entities sorted by name, then id.
- var placed = false;
- var contender = $(".toggler-group", parentsChildren).first();
- while (contender.length && !placed) {
- var contenderKey = contender.data("sort-key");
- if (sortKey < contenderKey) {
- contender.before(newNodeWrapper);
- placed = true;
- } else {
- contender = contender.next(".toggler-group", parentsChildren);
- }
- }
- if (!placed) {
- parentsChildren.append(newNodeWrapper);
- }
- this.addEventsToNode(parentsChildren)
- } else {
- // updating
- var $node = $(node),
- $newNode = $(newNode);
-
- // preserve old display status (just chevron direction at present)
- if ($node.find('.tree-node-state').hasClass('icon-chevron-down')) {
- $newNode.find('.tree-node-state').removeClass('icon-chevron-right').addClass('icon-chevron-down')
- // and if visible, see if any children have been added
- var children = nModel.get("children");
- var newChildren = []
- _.each(children, function(child) {
- var childId = child.id;
- if (!that.collection.get(childId)) {
- newChildren.push(childId);
- }
- })
- if (newChildren.length) {
- // reload if new child ID we don't recognise
- this.collection.includeEntities(newChildren);
- this.collection.fetch()
- }
- }
+ nodeClicked: function(event) {
+ var $treebox = $(event.currentTarget).closest('.tree-box');
+ var id = $treebox.data('entityId');
+ selectTreebox(id, $treebox, this);
+ return false;
+ },
- $(node).html($newNode)
- this.addEventsToNode($(node))
- }
- return true;
+ selectEntity: function(id) {
+ var $treebox = findMasterTreebox(id);
+ selectTreebox(id, $treebox, this);
},
renderFull: function() {
@@ -230,15 +232,13 @@ define([
that.$el.append(_.template(TreeEmptyHtml));
} else {
_.each(this.collection.getApplications(), function(appId) {
- that.updateNode(appId, null, true);
- });
-
- _.each(this.collection.getNonApplications(), function(id) {
- that.updateNode(id);
+ var entity = that.collection.get(appId);
+ var $treebox = getOrCreateApplicationTreebox(entity.id, entity.name, that);
+ updateTreeboxContent(entity, $treebox, that);
});
}
- this.highlightEntity();
+ // this.highlightEntity();
// Render the details for the selected entity.
if (this.detailsView) {
@@ -248,8 +248,7 @@ define([
if (!this.collection.isEmpty()) {
var app0 = this.collection.first().id;
_.defer(function () {
- if (!that.selectedEntityId)
- that.displayEntityId(app0, app0);
+ that.selectEntity(app0);
});
} else {
_.defer(function() {
@@ -261,30 +260,6 @@ define([
return this;
},
- addEventsToNode: function($node) {
- var that = this;
-
- // show the "light-popup" (expand / expand all / etc) menu
- // if user hovers for 500ms. surprising there is no option for this (hover delay).
- // also, annoyingly, clicks around the time the animation starts don't seem to get handled
- // if the click is in an overlapping reason; this is why we position relative top: 12px in css
- $('.light-popup', $node).parent().parent().hover(
- function(parent) {
- that.cancelHoverTimer();
- that.hoverTimer = setTimeout(function() {
- var menu = $(parent.currentTarget).find('.light-popup')
- menu.show()
- }, 500);
- },
- function(parent) {
- that.cancelHoverTimer();
- var menu = $(parent.currentTarget).find('.light-popup')
- menu.hide()
- // hide all others too
- $('.light-popup').hide()
- });
- },
-
cancelHoverTimer: function() {
if (this.hoverTimer != null) {
clearTimeout(this.hoverTimer);
@@ -292,42 +267,17 @@ define([
}
},
- displayEntity: function(event) {
- if (event.metaKey || event.shiftKey)
- // trying to open in a new tab, do not act on it here!
- return;
- event.preventDefault();
- var $nodeSpan = $(event.currentTarget);
- var $nodeA = $nodeSpan.children('a').first();
- var entityId = $nodeSpan.closest('.tree-box').data("entityId");
- var href = $nodeA.attr('href');
- var tab = (this.detailsView)
- ? this.detailsView.$el.find(".tab-pane.active").attr("id")
- : undefined;
- if (href) {
- if (tab) {
- href = href+"/"+tab;
- stateId = entityId+"/"+tab;
- this.preselectTab(tab);
- }
- Backbone.history.navigate(href);
- this.displayEntityId(entityId, $nodeSpan.data("app-id"));
- } else {
- log("no a.href in clicked target");
- log($nodeSpan);
- }
- },
-
displayEntityId: function (id, appName, afterLoad) {
var that = this;
- this.highlightEntity(id);
+ //this.highlightEntity(id);
var entityLoadFailed = function() {
return that.displayEntityNotFound(id);
};
if (appName === undefined) {
- appName = $("#span-"+id).data("app-id")
+ var $treebox = findMasterTreebox(id);
+ appName = $treebox.children(".entity_tree_node").data("app-id");
}
if (appName === undefined) {
if (!afterLoad) {
@@ -391,56 +341,76 @@ define([
this.cancelHoverTimer();
$('.light-popup').hide();
// don't let other events interfere
- return false
- },
-
- hideChildrenOf: function($treeBox, recurse) {
- var that = this;
- if (recurse) {
- $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');
+ return false;
},
showChildrenOf: function($treeBox, recurse) {
- var that = this;
- var idToExpand = $treeBox.children('.entity_tree_node_wrapper').attr('id');
+ var $wrapper = $treeBox.children('.entity_tree_node_wrapper');
+ var $childContainer = $treeBox.children('.node-children');
+ var idToExpand = $treeBox.data('entityId');
var model = this.collection.get(idToExpand);
if (model == null) {
// not yet loaded; parallel thread should load
return;
}
- var children = model.get('children');
+
+ var that = this;
+ var children = model.get('children'); // entity summaries: {id: ..., name: ...}
+ var renderChildrenAsIndirect = $treeBox.hasClass("indirect");
_.each(children, function(child) {
- var id = child.id;
- if (!$('#'+id, that.$el).length)
- // load, but only if necessary
- that.updateNode(id, idToExpand)
- })
- if (this.collection.includeEntities(children)) {
+ var $treebox = getOrCreateChildTreebox(child.id, child.name, renderChildrenAsIndirect, $treeBox);
+ var model = that.collection.get(child.id);
+ if (model) {
+ updateTreeboxContent(model, $treebox, that);
+ }
+ });
+ var members = model.get('members'); // entity summaries: {id: ..., name: ...}
+ _.each(members, function(member) {
+ var $treebox = getOrCreateChildTreebox(member.id, member.name, true, $treeBox);
+ var model = that.collection.get(member.id);
+ if (model) {
+ updateTreeboxContent(model, $treebox, that);
+ }
+ });
+
+ if (this.collection.includeEntities(_.union(children, members))) {
// 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) } );
+ $childContainer.children('.tree-box').each(function () {
+ var $treebox = $(this);
+ _.defer(function() {
+ that.showChildrenOf($treebox, 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');
+
+ $childContainer.slideDown(300);
+ $wrapper.find('.tree-node-state').removeClass('icon-chevron-right').addClass('icon-chevron-down');
if (recurse) {
- $treeBox.children('.node-children').children().each(function (index, childBox) {
- that.showChildrenOf($(childBox), recurse);
+ $childContainer.children('.tree-box').each(function () {
+ that.showChildrenOf($(this), recurse);
})
}
},
+ hideChildrenOf: function($treeBox, recurse) {
+ var $wrapper = $treeBox.children('.entity_tree_node_wrapper');
+ var $childContainer = $treeBox.children('.node-children');
+ if (recurse) {
+ var that = this;
+ $childContainer.children('.tree-box').each(function () {
+ that.hideChildrenOf($(this), recurse);
+ });
+ }
+ $childContainer.slideUp(300);
+ $wrapper.find('.tree-node-state').removeClass('icon-chevron-down').addClass('icon-chevron-right');
+ },
+
/**
* Causes the tab with the given name to be selected automatically when
* the view is next rendered.
@@ -466,11 +436,11 @@ define([
this.detailsView.close();
}
this.detailsView = new EntityDetailsView({
- model:entitySummary,
- application:app,
- appRouter:this.options.appRouter,
- preselectTab:whichTab,
- preselectTabDetails:this.currentTabDetails,
+ model: entitySummary,
+ application: app,
+ appRouter: this.options.appRouter,
+ preselectTab: whichTab,
+ preselectTabDetails: this.currentTabDetails,
});
this.detailsView.on("entity.expunged", function() {
@@ -491,28 +461,6 @@ define([
this.detailsView.render( $("div#details") );
},
- highlightEntity: function(id) {
- if (id) this.selectedEntityId = id;
- else id = this.selectedEntityId;
-
- $(".entity_tree_node_wrapper").removeClass("active");
- if (id) {
- 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)
- }
- }
});
- return ApplicationTreeView;
-})
+});
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/345daaa0/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 88e671a..d1a3d74 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
@@ -22,11 +22,14 @@ under the License.
var isLoaded = (model ? true : false);
var isApp = (parentId ? false : true);
+ // Only emphasise applications at the top level, not as indirect references.
+ isApp &= !indirect;
+
if (!isLoaded) {
%>
<i>Loading... (<%= id %>)</i>
<% } else {
- var hasChildren = model.hasChildren();
+ var hasChildren = model.hasChildren() || model.hasMembers();
var iconUrl = model.get('iconUrl');
var entityIconSize = isApp ? 40 : 30;
@@ -38,7 +41,7 @@ under the License.
%>
<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') %>">
+ data-entity-id="<%= 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;">
@@ -68,7 +71,10 @@ under the License.
<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 (indirect) { %>
+ <i class="indirection-icon icon-share-alt"></i>
+ <% } %>
<span style="max-height: 18px; padding-right: 6px; position: relative; margin: auto; top: 2px; bottom: 0;"><%= model.get('name') %></span>
</a>
[3/7] incubator-brooklyn git commit: Sanitise JS.
Posted by he...@apache.org.
Sanitise JS.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/99c01191
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/99c01191
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/99c01191
Branch: refs/heads/master
Commit: 99c01191fe1aa078838e1e71da5274be6f332d9c
Parents: e948978
Author: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Authored: Tue Sep 29 18:05:39 2015 +0100
Committer: Alasdair Hodge <gi...@alasdairhodge.co.uk>
Committed: Wed Oct 7 14:33:57 2015 +0100
----------------------------------------------------------------------
.../src/main/webapp/assets/js/model/app-tree.js | 62 +++---
.../webapp/assets/js/view/application-tree.js | 213 +++++++++----------
.../webapp/assets/js/view/entity-summary.js | 2 +-
.../main/webapp/assets/tpl/apps/summary.html | 6 +-
.../main/webapp/assets/tpl/apps/tree-item.html | 14 +-
5 files changed, 153 insertions(+), 144 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/99c01191/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 2cf6c54..67efd91 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
@@ -20,27 +20,31 @@ define([
"underscore", "backbone"
], function (_, Backbone) {
- var AppTree = {}
+ var AppTree = {};
AppTree.Model = Backbone.Model.extend({
- defaults:function () {
+ defaults: function() {
return {
- id:"",
- name:"",
- type:"",
- iconUrl:"",
- serviceUp:"",
- serviceState:"",
- applicationId:"",
- parentId:"",
- children:[]
- }
+ id: "",
+ name: "",
+ type: "",
+ iconUrl: "",
+ serviceUp: "",
+ serviceState: "",
+ applicationId: "",
+ parentId: "",
+ children: [],
+ members: []
+ };
+ },
+ getDisplayName: function() {
+ return this.get("name");
},
- getDisplayName:function () {
- return this.get("name")
+ hasChildren: function() {
+ return this.get("children").length > 0;
},
- hasChildren:function () {
- return this.get("children").length > 0
+ hasMembers: function() {
+ return this.get("members").length > 0;
}
})
@@ -48,7 +52,7 @@ define([
model: AppTree.Model,
includedEntities: [],
- getApplications: function () {
+ getApplications: function() {
var entities = [];
_.each(this.models, function(it) {
if (it.get('id') == it.get('applicationId'))
@@ -56,7 +60,8 @@ define([
});
return entities;
},
- getNonApplications: function () {
+
+ getNonApplications: function() {
var entities = [];
_.each(this.models, function(it) {
if (it.get('id') != it.get('applicationId'))
@@ -64,20 +69,22 @@ define([
});
return entities;
},
- includeEntities: function (entities) {
+
+ includeEntities: function(entities) {
// accepts id as string or object with id field
var oldLength = this.includedEntities.length;
- var newList = [].concat(this.includedEntities)
+ var newList = [].concat(this.includedEntities);
for (entityId in entities) {
- var entity = entities[entityId]
+ var entity = entities[entityId];
if (typeof entity === 'string')
- newList.push(entity)
+ newList.push(entity);
else
- newList.push(entity.id)
+ newList.push(entity.id);
}
- this.includedEntities = _.uniq(newList)
+ this.includedEntities = _.uniq(newList);
return (this.includedEntities.length > oldLength);
},
+
/**
* Depth-first search of entries in this.models for the first entity whose ID matches the
* function's argument. Includes each entity's children.
@@ -88,7 +95,7 @@ define([
for (var i = 0, l = this.models.length; i < l; i++) {
var model = this.models[i];
if (model.get("id") === id) {
- return model.getDisplayName()
+ return model.getDisplayName();
} else {
// slice(0) makes a shallow clone of the array
var queue = model.get("children").slice(0);
@@ -109,6 +116,7 @@ define([
// a string they'll get "stringundefined", whereas this way they'll just get "string".
return "";
},
+
url: function() {
if (this.includedEntities.length) {
var ids = this.includedEntities.join(",");
@@ -116,7 +124,7 @@ define([
} else
return "/v1/applications/fetch";
}
- })
+ });
- return AppTree
+ return AppTree;
})
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/99c01191/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 6c1c972..8a5175a 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
@@ -28,31 +28,31 @@ define([
AppTree, EntityDetailsView, EntitySummary, Application,
TreeItemHtml, TreeEmptyHtml, EntityDetailsEmptyHtml, EntityNotFoundHtml) {
- var treeViewTemplate = _.template(TreeItemHtml),
- notFoundTemplate = _.template(EntityNotFoundHtml);
+ var treeViewTemplate = _.template(TreeItemHtml);
+ var notFoundTemplate = _.template(EntityNotFoundHtml);
+
-
var ApplicationTreeView = Backbone.View.extend({
template: treeViewTemplate,
hoverTimer: null,
- events:{
+ events: {
'click span.entity_tree_node .tree-change':'treeChange',
'click span.entity_tree_node':'displayEntity'
},
-
- initialize:function () {
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)
+
+ initialize: function() {
_.bindAll(this);
},
- beforeClose:function () {
- this.collection.off("reset", this.renderFull)
- if (this.detailsView) this.detailsView.close()
+ beforeClose: function() {
+ this.collection.off("reset", this.renderFull);
+ if (this.detailsView) this.detailsView.close();
},
modelChange: function (child) {
@@ -64,7 +64,8 @@ define([
modelRemove: function (child) {
this.removeNode(child.id)
},
- modelEvent: function (eventName, event, x) {
+
+ modelEvent: function(eventName, event, x) {
if (/^change/i.test(eventName) || eventName == "remove" || eventName == "add" ||
eventName == "reset" ||
// above are handled; below is no-op
@@ -76,12 +77,12 @@ define([
// ignore; app-explorer should clear the view
return;
}
-
+
// don't think we get other events, but just in case:
- log("unhandled model event")
- log(eventName)
- log(event)
- log(x)
+ log("unhandled model event");
+ log(eventName);
+ log(event);
+ log(x);
},
removeNode: function(id) {
@@ -89,7 +90,6 @@ define([
// collection seems sometimes to have children nodes;
// not sure why, but that's okay for now
if (this.collection.getApplications().length==0)
-// if (this.collection.isEmpty() || $('lozenge-app-tree-wrapper').length==0)
this.renderFull();
},
@@ -111,7 +111,7 @@ define([
parentId = node.closest("entity_tree_node_wrapper").data('parentId');
if (!isApp && !parentId) {
log("no parentId yet available for "+id+"; skipping;")
- return false;
+ return false;
}
var statusIconUrl = nModel
@@ -218,16 +218,16 @@ define([
$(node).html($newNode)
this.addEventsToNode($(node))
}
- return true
+ return true;
},
-
- renderFull:function () {
- var that = this
- this.$el.empty()
+
+ renderFull: function() {
+ var that = this;
+ this.$el.empty();
// Display tree and highlight the selected entity.
- if (this.collection.getApplications().length==0) {
- that.$el.append(_.template(TreeEmptyHtml))
+ if (this.collection.getApplications().length == 0) {
+ that.$el.append(_.template(TreeEmptyHtml));
} else {
_.each(this.collection.getApplications(), function(appId) {
that.updateNode(appId, null, true);
@@ -237,63 +237,59 @@ define([
that.updateNode(id);
});
}
-
+
this.highlightEntity();
// Render the details for the selected entity.
if (this.detailsView) {
- this.detailsView.render()
+ this.detailsView.render();
} else {
// if nothing selected, select the first application
if (!this.collection.isEmpty()) {
var app0 = this.collection.first().id;
_.defer(function () {
if (!that.selectedEntityId)
- that.displayEntityId(app0, app0)
+ that.displayEntityId(app0, app0);
});
} else {
_.defer(function() {
$("div#details").html(_.template(EntityDetailsEmptyHtml));
- $("div#details").find("a[href='#summary']").tab('show')
- })
+ $("div#details").find("a[href='#summary']").tab('show');
+ });
}
}
- return this
+ return this;
},
addEventsToNode: function($node) {
var that = this;
-
- // prevent default click-handling
- // don't think this is needed, 18 Sep 2013; but leaving for a few weeks just in case
-// $('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 (hover delay).
// also, annoyingly, clicks around the time the animation starts don't seem to get handled
// if the click is in an overlapping reason; this is why we position relative top: 12px in css
$('.light-popup', $node).parent().parent().hover(
- function (parent) {
+ function(parent) {
that.cancelHoverTimer();
that.hoverTimer = setTimeout(function() {
var menu = $(parent.currentTarget).find('.light-popup')
menu.show()
}, 500);
},
- function (parent) {
+ function(parent) {
that.cancelHoverTimer();
var menu = $(parent.currentTarget).find('.light-popup')
menu.hide()
// hide all others too
$('.light-popup').hide()
- })
+ });
},
+
cancelHoverTimer: function() {
- var that = this;
- if (that.hoverTimer!=null) {
- clearTimeout(that.hoverTimer);
- that.hoverTimer = null;
- }
+ if (this.hoverTimer != null) {
+ clearTimeout(this.hoverTimer);
+ this.hoverTimer = null;
+ }
},
displayEntity: function(event) {
@@ -301,29 +297,30 @@ define([
// trying to open in a new tab, do not act on it here!
return;
event.preventDefault();
- var nodeSpan = $(event.currentTarget)
- var nodeA = $(event.currentTarget).children('a').first()
- var entityId = nodeSpan.parent().attr("id"),
- href = nodeA.attr('href'),
- tab = (this.detailsView)
+ var $nodeSpan = $(event.currentTarget);
+ var $nodeA = $nodeSpan.children('a').first();
+ var entityId = $nodeSpan.closest('.tree-box').data("entityId");
+ var href = $nodeA.attr('href');
+ var tab = (this.detailsView)
? this.detailsView.$el.find(".tab-pane.active").attr("id")
: undefined;
if (href) {
if (tab) {
- href = href+"/"+tab
- stateId = entityId+"/"+tab
- this.preselectTab(tab)
+ href = href+"/"+tab;
+ stateId = entityId+"/"+tab;
+ this.preselectTab(tab);
}
Backbone.history.navigate(href);
- this.displayEntityId(entityId, nodeSpan.data("app-id"));
+ this.displayEntityId(entityId, $nodeSpan.data("app-id"));
} else {
- log("no a.href in clicked target")
- log(nodeSpan)
+ log("no a.href in clicked target");
+ log($nodeSpan);
}
},
- displayEntityId:function (id, appName, afterLoad) {
+
+ displayEntityId: function (id, appName, afterLoad) {
var that = this;
- this.highlightEntity(id)
+ this.highlightEntity(id);
var entityLoadFailed = function() {
return that.displayEntityNotFound(id);
@@ -348,17 +345,17 @@ define([
return;
}
}
-
- var app = new Application.Model(),
- entitySummary = new EntitySummary.Model;
- app.url = "/v1/applications/" + appName
+ var app = new Application.Model();
+ var entitySummary = new EntitySummary.Model;
+
+ app.url = "/v1/applications/" + appName;
entitySummary.url = "/v1/applications/" + appName + "/entities/" + id;
// 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)
- ViewUtils.fadeToIndicateInitialLoad($("div#details"))
-
+ ViewUtils.fadeToIndicateInitialLoad($("div#details"));
+
$.when(app.fetch(), entitySummary.fetch())
.done(function() {
that.showDetails(app, entitySummary);
@@ -375,42 +372,44 @@ define([
var $target = $(event.currentTarget);
var $treeBox = $target.closest('.tree-box');
if ($target.hasClass('tr-expand')) {
- this.showChildrenOf($treeBox, false)
+ this.showChildrenOf($treeBox, false);
} else if ($target.hasClass('tr-expand-all')) {
- this.showChildrenOf($treeBox, true)
+ this.showChildrenOf($treeBox, true);
} else if ($target.hasClass('tr-collapse')) {
- this.hideChildrenOf($treeBox, false)
+ this.hideChildrenOf($treeBox, false);
} else if ($target.hasClass('tr-collapse-all')) {
- this.hideChildrenOf($treeBox, true)
+ this.hideChildrenOf($treeBox, true);
} else {
// default - toggle
if ($treeBox.children('.node-children').is(':visible')) {
- this.hideChildrenOf($treeBox, false)
+ this.hideChildrenOf($treeBox, false);
} else {
- this.showChildrenOf($treeBox, false)
+ this.showChildrenOf($treeBox, false);
}
}
// hide the popup menu
this.cancelHoverTimer();
- $('.light-popup').hide()
+ $('.light-popup').hide();
// don't let other events interfere
return false
},
+
hideChildrenOf: function($treeBox, recurse) {
var that = this;
if (recurse) {
$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')
+ $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;
var idToExpand = $treeBox.children('.entity_tree_node_wrapper').attr('id');
var model = this.collection.get(idToExpand);
- if (model==null) {
+ if (model == null) {
// not yet loaded; parallel thread should load
return;
}
@@ -428,43 +427,43 @@ define([
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')
+ $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('.node-children').children().each(function (index, childBox) {
- that.showChildrenOf($(childBox), recurse)
+ that.showChildrenOf($(childBox), recurse);
})
}
},
-
+
/**
* Causes the tab with the given name to be selected automatically when
* the view is next rendered.
*/
preselectTab: function(tab, tabDetails) {
- this.currentTab = tab
+ this.currentTab = tab;
this.currentTabDetails = tabDetails;
},
showDetails: function(app, entitySummary) {
- var self = this;
- ViewUtils.cancelFadeOnceLoaded($("div#details"))
-
- var whichTab = this.currentTab
+ var that = this;
+ ViewUtils.cancelFadeOnceLoaded($("div#details"));
+
+ var whichTab = this.currentTab;
if (whichTab === undefined) {
whichTab = "summary";
if (this.detailsView) {
whichTab = this.detailsView.$el.find(".tab-pane.active").attr("id");
- this.detailsView.close()
+ this.detailsView.close();
}
}
if (this.detailsView) {
- this.detailsView.close()
+ this.detailsView.close();
}
this.detailsView = new EntityDetailsView({
model:entitySummary,
@@ -473,47 +472,47 @@ define([
preselectTab:whichTab,
preselectTabDetails:this.currentTabDetails,
});
-
+
this.detailsView.on("entity.expunged", function() {
- self.preselectTab("summary");
- var id = self.selectedEntityId;
- var model = self.collection.get(id);
+ that.preselectTab("summary");
+ var id = that.selectedEntityId;
+ var model = that.collection.get(id);
if (model && model.get("parentId")) {
- self.displayEntityId(model.get("parentId"));
- } else if (self.collection) {
- self.displayEntityId(self.collection.first().id);
+ that.displayEntityId(model.get("parentId"));
+ } else if (that.collection) {
+ that.displayEntityId(that.collection.first().id);
} else if (id) {
- self.displayEntityNotFound(id);
+ that.displayEntityNotFound(id);
} else {
- self.displayEntityNotFound("?");
+ that.displayEntityNotFound("?");
}
- self.collection.fetch();
+ that.collection.fetch();
});
this.detailsView.render( $("div#details") );
},
- highlightEntity:function (id) {
- if (id) this.selectedEntityId = id
- else id = this.selectedEntityId
-
- $(".entity_tree_node_wrapper").removeClass("active")
+ highlightEntity: function(id) {
+ if (id) this.selectedEntityId = id;
+ else id = this.selectedEntityId;
+
+ $(".entity_tree_node_wrapper").removeClass("active");
if (id) {
var $selectedNode = $(".entity_tree_node_wrapper#"+id);
// make this node active
- $selectedNode.addClass("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)
+ this.showChildrenOf($nodeToOpenInParent);
}
-
+
// if we want to auto-expand the children of the selected node:
// this.showChildrenOf($selectedNode.closest('.tree-box'), false)
}
}
- })
+ });
- return ApplicationTreeView
+ return ApplicationTreeView;
})
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/99c01191/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js
index c102a67..51a7c33 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-summary.js
@@ -43,7 +43,7 @@ define([
this.$("div.catalogItemId").show();
else
this.$("div.catalogItemId").hide();
-
+
this.options.tabView.configView = new EntityConfigView({
model:this.options.model,
tabView:this.options.tabView,
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/99c01191/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html
index 0965068..ed90c75 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/summary.html
@@ -73,9 +73,9 @@ under the License.
<div class="additional-info-on-problem hide" style="margin-top: 12px;">
</div>
-
- <div id="status-icon" style="display: inline-block; padding-top: 12px; padding-bottom: 18px; padding-right: 8px; position: absolute; right: 0; top: 0;"></div>
-
+
+ <div id="status-icon" style="display: inline-block; padding-top: 12px; padding-bottom: 18px; padding-right: 8px; position: absolute; right: 0; top: 0;"></div>
+
</div>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/99c01191/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 3109230..88e671a 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
@@ -21,32 +21,33 @@ under the License.
<%
var isLoaded = (model ? true : false);
var isApp = (parentId ? false : true);
-
+
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 minHeight = hasChildren && statusIconUrl ? entityIconSize : 24;
var statusColumnWidth = hasChildren || statusIconUrl || (!isApp && !iconUrl /* for children, insert space so things line up */) ? statusIconSize : 0;
%>
-
+
<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: -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 class="toggler-icon icon-chevron-right tree-node-state tree-change">
@@ -62,13 +63,14 @@ under the License.
</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>
<span style="max-height: 18px; padding-right: 6px; position: relative; margin: auto; top: 2px; bottom: 0;"><%= model.get('name') %></span>
-
+
</a>
</span>
[5/7] incubator-brooklyn git commit: Fix add-app-wizard for enums
Posted by he...@apache.org.
Fix add-app-wizard for enums
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/b02bd177
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/b02bd177
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/b02bd177
Branch: refs/heads/master
Commit: b02bd17710d20104e2f4559c17a91769b7f36126
Parents: d2a5d4b
Author: Aled Sage <al...@gmail.com>
Authored: Wed Oct 7 21:04:35 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Oct 7 21:04:35 2015 +0100
----------------------------------------------------------------------
.../webapp/assets/tpl/app-add-wizard/required-config-entry.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b02bd177/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html
index 1478963..b802624 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html
@@ -34,7 +34,7 @@ under the License.
element = null;
for (var i = 0; i < length; i++) {
element = data.possibleValues[i]; %>
- <option value="<%= element.value %>"><% if (data.defaultValue == element.value) { %> selected="selected"<% } %>><%= element.description %></option>
+ <option value="<%= element.value %>"<% if (data.defaultValue == element.value) { %> selected="selected"<% } %>><%= element.description %></option>
<% } %>
</select>
<% } else { %>