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 2014/09/03 18:15:29 UTC
[02/11] git commit: jsgui: re-support adding locations to the
catalogue
jsgui: re-support adding locations to the catalogue
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/17f04a0a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/17f04a0a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/17f04a0a
Branch: refs/heads/master
Commit: 17f04a0ade20890c52ad50003adfa0aa1b862c76
Parents: e0e56f4
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Tue Aug 12 15:13:14 2014 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Tue Sep 2 11:26:50 2014 +0100
----------------------------------------------------------------------
.../webapp/assets/js/libs/brooklyn-utils.js | 16 +++
.../main/webapp/assets/js/libs/brooklyn-view.js | 24 +++-
.../src/main/webapp/assets/js/model/location.js | 7 +-
.../js/view/catalog-add-location-modal.js | 115 -------------------
.../src/main/webapp/assets/js/view/catalog.js | 69 +++++++++--
.../assets/tpl/catalog/add-catalog-entry.html | 1 +
.../assets/tpl/catalog/add-location-modal.html | 66 -----------
.../webapp/assets/tpl/catalog/add-location.html | 37 ++++++
.../assets/tpl/catalog/details-entity.html | 26 ++---
.../assets/tpl/catalog/details-location.html | 8 +-
.../assets/tpl/catalog/location-config.html | 24 ----
.../webapp/assets/tpl/catalog/nav-entry.html | 2 +-
.../src/test/javascript/specs/brooklyn-spec.js | 4 +-
.../javascript/specs/brooklyn-utils-spec.js | 18 +++
14 files changed, 170 insertions(+), 247 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js b/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
index 1fc8905..acd8135 100644
--- a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
+++ b/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
@@ -109,6 +109,22 @@ define([
return model;
};
+ /**
+ * Parses xhrResponse.responseText as JSON and returns its message. Returns
+ * alternate message if parsing fails or the parsed object has no message.
+ * @param {jqXHR} xhrResponse
+ * @param {string} alternateMessage
+ * @returns {*}
+ */
+ Util.extractError = function (xhrResponse, alternateMessage) {
+ try {
+ var response = JSON.parse(xhrResponse.responseText);
+ return response.message ? response.message : alternateMessage;
+ } catch (e) {
+ return alternateMessage;
+ }
+ };
+
return Util;
});
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-view.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-view.js b/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-view.js
index 5bc2bc7..3511b61 100644
--- a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-view.js
+++ b/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-view.js
@@ -84,6 +84,8 @@ define([
/**
* A form that listens to modifications to its inputs, maintaining a model that is
* submitted when a button with class 'submit' is clicked.
+ *
+ * Expects a body view or a template function to render.
*/
module.Form = Backbone.View.extend({
events: {
@@ -92,20 +94,30 @@ define([
},
initialize: function() {
- if (!this.options.template) {
- throw new Error("template required by GenericForm");
+ if (!this.options.body && !this.options.template) {
+ throw new Error("body view or template function required by GenericForm");
} else if (!this.options.onSubmit) {
throw new Error("onSubmit function required by GenericForm");
}
this.onSubmitCallback = this.options.onSubmit;
- this.template = _.template(this.options.template);
this.model = new (this.options.model || Backbone.Model);
_.bindAll(this, "onSubmit", "onChange");
this.render();
},
+ beforeClose: function() {
+ if (this.options.body) {
+ this.options.body.close();
+ }
+ },
+
render: function() {
- this.$el.html(this.template());
+ if (this.options.body) {
+ this.options.body.render();
+ this.$el.html(this.options.body.$el);
+ } else {
+ this.$el.html(this.options.template());
+ }
// Initialise the model with existing values
Util.bindModelFromForm(this.model, this.$el);
return this;
@@ -119,8 +131,8 @@ define([
onSubmit: function(e) {
e.preventDefault();
- // TODO: Could validate model
- this.onSubmitCallback(this.model);
+ // Could validate model
+ this.onSubmitCallback(this.model.clone());
return false;
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/js/model/location.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/model/location.js b/usage/jsgui/src/main/webapp/assets/js/model/location.js
index cf38bad..6d45478 100644
--- a/usage/jsgui/src/main/webapp/assets/js/model/location.js
+++ b/usage/jsgui/src/main/webapp/assets/js/model/location.js
@@ -24,13 +24,9 @@ define(["underscore", "backbone"], function (_, Backbone) {
urlRoot:'/v1/locations',
defaults:function () {
return {
- id:'',
name:'',
spec:'',
- config:{},
- links:{
- self:''
- }
+ config:{}
}
},
idFromSelfLink:function () {
@@ -79,6 +75,7 @@ define(["underscore", "backbone"], function (_, Backbone) {
Location.Collection = Backbone.Collection.extend({
model:Location.Model,
+ comparator: "name",
url:'/v1/locations'
})
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/js/view/catalog-add-location-modal.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/catalog-add-location-modal.js b/usage/jsgui/src/main/webapp/assets/js/view/catalog-add-location-modal.js
deleted file mode 100644
index b54ff49..0000000
--- a/usage/jsgui/src/main/webapp/assets/js/view/catalog-add-location-modal.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
-*/
-/**
- * Modal dialog to add a new location.
- */
-define([
- "underscore", "jquery", "backbone",
- "text!tpl/catalog/add-location-modal.html", "text!tpl/catalog/location-config.html",
- "bootstrap"
-], function (_, $, Backbone, LocationModalHtml, LocationConfigHtml) {
-
- var LocationModalView = Backbone.View.extend({
- tagName:'div',
- className:'modal hide fade',
- id:'new-location-modal',
- events:{
- 'click #add-location-config':'addLocationConfig',
- 'click .remove':'removeLocationConfig',
- 'click #new-location-submit':'newLocationSubmit',
- 'click #show-config-form':'showConfigForm',
- 'blur #provider':'updateLocationName'
- },
- template:_.template(LocationModalHtml),
- addedConfigTemplate:_.template(LocationConfigHtml),
-
- initialize:function () {
- _.bindAll(this, 'render')
- },
- render:function (eventName) {
- this.$el.html(this.template({}))
- this.renderLocationName()
- this.renderAddedConfigs()
- return this
- },
- renderLocationName:function () {
- this.$('#provider').val(this.model.get("provider"))
- },
- renderAddedConfigs:function () {
- var $addedConfigs = this.$('#added-configs ul').empty(),
- that = this
- _.each(this.model.get("config"), function (theValue, theKey) {
- $addedConfigs.append(that.addedConfigTemplate({ key:theKey, value:theValue}))
- })
- },
- removeLocationConfig:function (event) {
- var key = $(event.currentTarget).parent().find('span.key').html()
- this.model.removeConfig(key)
- this.render()
- },
- newLocationSubmit:function (event) {
- event.preventDefault()
- if (this.isNewLocationValid()) {
- var self = this
- Backbone.sync('create', this.model, {
- success:function () {
- self.options.appRouter.navigate("v1/locations")
- }
-
- })
- this.$el.modal('hide')
- this.$el.empty()
- } else {
- this.showMessage('A location must have a non-empty name and at least one configuration.')
- }
- },
- updateLocationName:function (eventName) {
- this.model.set("provider", this.$('#provider').val())
- this.render()
- },
- isNewLocationValid:function () {
- if (this.model.get("provider").length == 0 || _.isEmpty(this.model.get("config"))) {
- return false
- }
- return true
- },
- addLocationConfig:function (event) {
- // add a new key-value option to the new location form
- var key = $.trim(this.$('input#key').val())
- if (key.length != 0) {
- this.model.addConfig(key, this.$('input#value').val())
- this.render()
- } else {
- this.showMessage('Key must not be empty!')
- }
- return false
- },
- showConfigForm:function () {
- this.$('#config-form').show()
- },
- showMessage:function (message) {
- var $div = this.$('div.info-message')
- $div.find('span#message').html(message)
- $div.show('slow').delay(2000).hide('slow')
- return false
- }
- })
-
- return LocationModalView
-})
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/js/view/catalog.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/catalog.js b/usage/jsgui/src/main/webapp/assets/js/view/catalog.js
index 06ba9ac..24389d9 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/catalog.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/catalog.js
@@ -25,13 +25,14 @@ define([
"text!tpl/catalog/details-location.html",
"text!tpl/catalog/add-catalog-entry.html",
"text!tpl/catalog/add-entity.html",
+ "text!tpl/catalog/add-location.html",
"text!tpl/catalog/nav-entry.html",
"bootstrap", "jquery-form"
], function(_, $, Backbone, FormatJSON, Brooklyn,
Location, Entity,
CatalogPageHtml, DetailsEntityHtml, DetailsGenericHtml, LocationDetailsHtml,
- AddCatalogEntryHtml, AddEntityHtml, EntryHtml) {
+ AddCatalogEntryHtml, AddEntityHtml, AddLocationHtml, EntryHtml) {
// Holds the currently active details type, e.g. applications, policies. Bit of a workaround
// to share the active view with all instances of AccordionItemView, so clicking the 'reload
@@ -39,7 +40,6 @@ define([
// more than one element.
var activeDetailsView;
- // TODO: Loading item's details should perform page navigation
var CatalogItemDetailsView = Backbone.View.extend({
events: {
@@ -154,6 +154,8 @@ define([
this.context = type;
if (type == "entity") {
this.contextView = newEntityForm(this.options.parent);
+ } else if (type == "location") {
+ this.contextView = newLocationForm(this.options.parent);
} else if (type !== undefined) {
console.log("unknown catalog type " + type);
this.showFormForType("entity");
@@ -166,7 +168,7 @@ define([
function newEntityForm(parent) {
return new Brooklyn.view.Form({
- template: AddEntityHtml,
+ template: _.template(AddEntityHtml),
onSubmit: function (model) {
console.log("Submit entity", model.get("yaml"));
var submitButton = this.$(".catalog-submit-button");
@@ -186,20 +188,59 @@ define([
parent.loadAccordionItem("entities", data.id);
})
.fail(function (xhr, status, error) {
- var message;
- try {
- message = JSON.parse(xhr.responseText).message;
- } catch (e) {
- message = "Error adding catalog item: " + error;
- }
submitButton.button("reset");
self.$(".catalog-save-error")
.removeClass("hide")
.find(".catalog-error-message")
- .html(message);
+ .html(Brooklyn.util.extractError(xhr, "Error adding catalog item: " + error));
+ });
+ }
+ });
+ }
+
+ // Could adapt to edit existing locations too.
+ function newLocationForm(parent) {
+ // Renders with config key list
+ var body = new (Backbone.View.extend({
+ beforeClose: function() {
+ if (this.configKeyList) {
+ this.configKeyList.close();
+ }
+ },
+ render: function() {
+ this.configKeyList = new Brooklyn.view.ConfigKeyInputPairList().render();
+ var template = _.template(AddLocationHtml);
+ this.$el.html(template);
+ this.$("#new-location-config").html(this.configKeyList.$el);
+ },
+ showError: function (message) {
+ self.$(".catalog-save-error")
+ .removeClass("hide")
+ .find(".catalog-error-message")
+ .html(message);
+ }
+ }));
+ var form = new Brooklyn.view.Form({
+ body: body,
+ model: Location.Model,
+ onSubmit: function (location) {
+ var configKeys = body.configKeyList.getConfigKeys();
+ if (!configKeys.displayName) {
+ configKeys.displayName = location.get("name");
+ }
+ location.set("config", configKeys);
+ location.save()
+ .done(function (newModel) {
+ newModel = new Location.Model(newModel);
+ parent.loadAccordionItem("locations", newModel.id);
+ })
+ .fail(function (response) {
+ body.showError(Brooklyn.util.extractError(response));
});
}
});
+
+ return form;
}
var Catalog = Backbone.Collection.extend({
@@ -342,12 +383,14 @@ define([
this.accordion = this.options.accordion || {
"applications": new AccordionItemView({
name: "applications",
+ singular: "application",
onItemSelected: _.partial(this.showCatalogItem, DetailsEntityHtml),
model: Entity.Model,
autoOpen: !this.options.kind || this.options.kind == "applications"
}),
"entities": new AccordionItemView({
name: "entities",
+ singular: "entity",
onItemSelected: _.partial(this.showCatalogItem, DetailsEntityHtml),
model: Entity.Model,
autoOpen: this.options.kind == "entities"
@@ -355,10 +398,12 @@ define([
"policies": new AccordionItemView({
onItemSelected: _.partial(this.showCatalogItem, DetailsEntityHtml),
name: "policies",
+ singular: "policy",
autoOpen: this.options.kind == "policies"
}),
"locations": new AccordionItemView({
name: "locations",
+ singular: "location",
onItemSelected: _.partial(this.showCatalogItem, LocationDetailsHtml),
collection: this.options.locations,
autoOpen: this.options.kind == "locations",
@@ -420,11 +465,13 @@ define([
console.error("No accordion for: " + kind);
} else {
var accordion = this.accordion[kind];
+ var self = this;
accordion.collection.fetch()
.then(function() {
var model = accordion.collection.get(id);
if (!model) {
- console.log("Accordion for " + kind + " has no element with id " + id);
+ self.setDetailsView(new CatalogItemDetailsView().renderEmpty(
+ "No " + accordion.options.singular + " with id: " + id));
} else {
activeDetailsView = kind;
accordion.activeCid = model.cid;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-catalog-entry.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-catalog-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-catalog-entry.html
index 16fb9ee..6bd8c00 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-catalog-entry.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-catalog-entry.html
@@ -23,6 +23,7 @@ under the License.
<div data-toggle="buttons-radio">
<button class="btn btn-large show-context" data-context="entity">Entity</button>
+ <button class="btn btn-large show-context" data-context="location">Location</button>
</div>
<hr/>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-location-modal.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-location-modal.html b/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-location-modal.html
deleted file mode 100644
index cadd6fc..0000000
--- a/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-location-modal.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-<!-- Modal window for adding a new location to the catalog -->
-<div class="modal-header">
- <button type="button" class="close" data-dismiss="modal">x</button>
- <h3>Add a new Location</h3>
-</div>
-<div class="modal-body">
- <div class="row">
- <div class="span5">
-
- <label for="provider" class="control-label">Provider name:</label>
-
- <div class="control-group">
- <div class="controls">
- <input id="provider" name="provider" type="text" placeholder="Provider"
- class="input-large">
- </div>
- </div>
-
- <div id="added-configs">
- <h4>Location configuration</h4>
- <ul/>
- </div>
- <dl class="dl-horizontal"></dl>
- <button id="show-config-form" class="btn btn-info btn-mini">Add configuration key-value</button>
- <dl class="dl-horizontal"></dl>
- <div id="config-form" class="hide">
- <input id="key" type="text" class="input-medium" placeholder="key">
- <input id="value" type="text" class="input-medium" placeholder="value">
- <button id="add-location-config" class="btn btn-inverted btn-mini" type="button">
- <i class="icon-br-plus-sign"></i>
- </button>
- </div>
- </div>
- </div>
- <dl class="dl-horizontal"></dl>
- <div class="info-message hide">
- <p>
- <span class="label-important">Important</span>
- <span id="message">A location must have at least one config.</span>
- </p>
- </div>
-</div>
-
-<div class="modal-footer">
- <button class="btn" data-dismiss="modal" type="button">Close</button>
- <button id="new-location-submit" class="btn btn-primary" type="button">Save</button>
-</div>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-location.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-location.html b/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-location.html
new file mode 100644
index 0000000..e57b83a
--- /dev/null
+++ b/usage/jsgui/src/main/webapp/assets/tpl/catalog/add-location.html
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<form>
+ <label for="name" class="control-label">Name</label>
+ <input id="name" name="name" type="text" placeholder="e.g. My Cloud Region #3" class="input-xlarge">
+
+ <label for="spec" class="control-label">Spec</label>
+ <input id="spec" name="spec" type="text" placeholder="e.g. jclouds:cloud:region" class="input-xlarge">
+
+ <h4>Configuration</h4>
+ <div id="new-location-config"></div>
+
+ <button class='catalog-submit-button btn' data-loading-text='Saving...'>Submit</button>
+
+ <p class="catalog-save-error hide">
+ <span class="alert-error">
+ <strong>Error:</strong><br/>
+ <span class="catalog-error-message"></span>
+ </span>
+ </p>
+</form>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-entity.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-entity.html b/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-entity.html
index fda1da1..60768d5 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-entity.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-entity.html
@@ -18,9 +18,9 @@ under the License.
-->
<div class="catalog-details">
- <h2><%= model.get("name") %></h2>
- <p><%= model.get("id") %></p>
- <p><%= model.get("description") %></p>
+ <h2><%- model.get("name") %></h2>
+ <p><%- model.get("id") %></p>
+ <p><%- model.get("description") %></p>
<div id="catalog-details-accordion" class="accordion">
<div class="accordion-group">
@@ -32,7 +32,7 @@ under the License.
<div id="collapseYaml" class="accordion-body collapse">
<div class="accordion-inner">
<% if (model.get("planYaml")) { %>
- <textarea rows="15" readonly><%= model.get("planYaml") %></textarea>
+ <textarea rows="15" readonly><%- model.get("planYaml") %></textarea>
<% } else { %>
<p>No plan</p>
<% } %>
@@ -63,14 +63,14 @@ under the License.
'reconfigurable'
]; %>
<% _.each(model.get("config"), function(object, index) { %>
- <p><strong><%= object.name %></strong>: <%= object.description %></p>
+ <p><strong><%- object.name %></strong>: <%- object.description %></p>
<table class="table table-striped table-condensed nonDatatables">
<tbody>
<% _.each(object, function(value, key) { %>
<% if (!_.contains(skip, key)) { %>
<tr>
- <td><%= key %></td>
- <td><%= value %></td>
+ <td><%- key %></td>
+ <td><%- value %></td>
</tr>
<% } %>
<% }); %>
@@ -107,9 +107,9 @@ under the License.
<tbody>
<% _.each(model.get("sensors"), function(object, index) { %>
<tr>
- <td><%= object.name %></td>
- <td><%= object.type %></td>
- <td><%= object.description %></td>
+ <td><%- object.name %></td>
+ <td><%- object.type %></td>
+ <td><%- object.description %></td>
</tr>
<% }); %>
</tbody>
@@ -134,7 +134,7 @@ under the License.
<p>No effectors</p>
<% } else { %>
<% _.each(model.get("effectors"), function(object, index) { %>
- <p><strong><%= object.name %></strong>: <%= object.description %></p>
+ <p><strong><%- object.name %></strong>: <%- object.description %></p>
<% if (!object.parameters || _.isEmpty(object.parameters)) { %>
<p>No parameters</p>
<% } else { %>
@@ -143,8 +143,8 @@ under the License.
<% _.each(object.parameters, function(parameter, index) { %>
<% _.each(parameter, function(value, key) { %>
<tr>
- <td><%= key %></td>
- <td><%= value %></td>
+ <td><%- key %></td>
+ <td><%- value %></td>
</tr>
<% }); %>
<% }); %>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-location.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-location.html b/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-location.html
index 4d93207..27fe3e2 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-location.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/catalog/details-location.html
@@ -18,7 +18,7 @@ under the License.
-->
<div class="catalog-details">
- <h3><%= model.getPrettyName() %></h3>
+ <h3><%- model.getPrettyName() %></h3>
<div class="float-right">
<button data-name="<%= model.getPrettyName() %>" class="btn btn-danger delete">Delete</button>
@@ -30,9 +30,9 @@ under the License.
<br/>
<table>
- <tr><td><strong>ID:</strong> </td><td><%= model.get("id") || "" %></td></tr>
- <tr><td><strong>Name:</strong> </td><td><%= model.get("name") || "" %></td></tr>
- <tr><td><strong>Spec:</strong> </td><td><%= model.get("spec") || "" %></td></tr>
+ <tr><td><strong>ID:</strong> </td><td><%- model.get("id") || "" %></td></tr>
+ <tr><td><strong>Name:</strong> </td><td><%- model.get("name") || "" %></td></tr>
+ <tr><td><strong>Spec:</strong> </td><td><%- model.get("spec") || "" %></td></tr>
</table>
<br/>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/tpl/catalog/location-config.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/catalog/location-config.html b/usage/jsgui/src/main/webapp/assets/tpl/catalog/location-config.html
deleted file mode 100644
index 91c980f..0000000
--- a/usage/jsgui/src/main/webapp/assets/tpl/catalog/location-config.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-<!-- Template for rendering a key-value configuration inside the new location form -->
-<li>
- <span class="key"><%= key %></span> : <span class="value"><%= value %></span>
- <span class="icon-remove-sign remove" style="margin-left:10px;"></span>
-</li>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/main/webapp/assets/tpl/catalog/nav-entry.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/catalog/nav-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/catalog/nav-entry.html
index 9c6dcbf..36a8588 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/catalog/nav-entry.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/catalog/nav-entry.html
@@ -16,4 +16,4 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
-<div data-cid="<%= cid %>" class="accordion-nav-row <%= extraClasses %>"><%= type %></div>
+<div data-cid="<%= cid %>" class="accordion-nav-row <%= extraClasses %>"><%- type %></div>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/test/javascript/specs/brooklyn-spec.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/test/javascript/specs/brooklyn-spec.js b/usage/jsgui/src/test/javascript/specs/brooklyn-spec.js
index 8c9642d..3f301a4 100644
--- a/usage/jsgui/src/test/javascript/specs/brooklyn-spec.js
+++ b/usage/jsgui/src/test/javascript/specs/brooklyn-spec.js
@@ -22,11 +22,11 @@ define([
describe("view", function () {
describe("form", function() {
- var formTemplate = '<form>' +
+ var formTemplate = _.template('<form>' +
'<input name="id" type="text"/>' +
'<input name="initialvalue" type="text" value="present"/>' +
'<button type="submit" class="submit">Submit</button>' +
- '</form>';
+ '</form>');
it("should set existing values on the model", function() {
var form = new B.view.Form({template: formTemplate, onSubmit: function() {}});
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/17f04a0a/usage/jsgui/src/test/javascript/specs/brooklyn-utils-spec.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/test/javascript/specs/brooklyn-utils-spec.js b/usage/jsgui/src/test/javascript/specs/brooklyn-utils-spec.js
index ab9566d..4c21f50 100644
--- a/usage/jsgui/src/test/javascript/specs/brooklyn-utils-spec.js
+++ b/usage/jsgui/src/test/javascript/specs/brooklyn-utils-spec.js
@@ -130,4 +130,22 @@ define([
expect(inputs.initialAttribute).toBe("xyz");
});
});
+
+ describe("extractError", function () {
+ it("should extract the response message", function () {
+ var m = Util.extractError({ responseText: '{"message": "hello"}'}, "default");
+ expect(m).toBe("hello");
+ });
+
+ it("should return the default on invalid JSON", function () {
+ var m = Util.extractError({ responseText: "<html></html>"}, "default");
+ expect(m).toBe("default");
+ });
+
+ it("should return the default if the response has no message", function () {
+ var m = Util.extractError({ a: '{"b": "c"}'}, "default");
+ expect(m).toBe("default");
+ });
+ });
+
});