improvements to add-app wizard esp use of catalog - shows templates graphically, searchable; locations in order, and misc tidies
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/c299b335 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/c299b335 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/c299b335 Branch: refs/heads/0.5.0 Commit: c299b33501e0431283722d3aeefbfe485629f038 Parents: 7e6c524 Author: Alex Heneveld <[email protected]> Authored: Tue Nov 27 11:08:08 2012 -0800 Committer: Alex Heneveld <[email protected]> Committed: Wed Nov 28 02:39:09 2012 -0800 ---------------------------------------------------------------------- .../src/main/webapp/assets/css/prettybrook.css | 155 ++++++++++++++-- .../main/webapp/assets/js/model/application.js | 27 +-- .../assets/js/model/catalog-item-summary.js | 25 +++ .../assets/js/view/application-add-wizard.js | 176 +++++++++++++++---- .../webapp/assets/js/view/application-tree.js | 2 - .../src/main/webapp/assets/js/view/catalog.js | 5 +- .../src/main/webapp/assets/js/view/home.js | 20 ++- .../tpl/app-add-wizard/create-config-entry.html | 8 - .../tpl/app-add-wizard/create-entity-entry.html | 2 +- .../create-step-template-entry.html | 13 ++ .../assets/tpl/app-add-wizard/create.html | 41 +++-- .../assets/tpl/app-add-wizard/deploy.html | 49 +++--- .../tpl/app-add-wizard/edit-config-entry.html | 8 + .../assets/tpl/app-add-wizard/preview.html | 21 ++- .../BrooklynJavascriptGuiLauncherTest.java | 2 +- .../javascript/specs/model/application-spec.js | 4 +- 16 files changed, 418 insertions(+), 140 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/css/prettybrook.css ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/css/prettybrook.css b/usage/jsgui/src/main/webapp/assets/css/prettybrook.css index d9aae39..a699234 100644 --- a/usage/jsgui/src/main/webapp/assets/css/prettybrook.css +++ b/usage/jsgui/src/main/webapp/assets/css/prettybrook.css @@ -18,7 +18,67 @@ margin-top: 40px; margin-bottom: 40px; } - +#application-content .modal-body { + padding: 0; +} +#application-content ul.nav-tabs { + margin: 15px 15px 0px 15px; +} +#application-content .deploy, +#application-content .preview { + padding: 15px; +} +#application-content .tab-content { + max-height: 500px; + overflow: scroll; +} +#application-content .template-lozenge { + cursor: hand; cursor: pointer; +} +#application-content div.template-lozenge.frame { + display: inline-block; + border: 3px solid #EEE; + border-radius: 4px; + width: 212px; + overflow: scroll; + margin: 4px; + padding: 3px; +} +#application-content div.template-lozenge div.icon { + margin: 2px 8px 2px 2px; +} +#application-content div.template-lozenge div.icon img { + max-width: 50px; + max-height: 50px; + margin-top: 15px; +} +#application-content .template-lozenge.frame:hover { + border: 3px solid #CCC; +} +#application-content .template-lozenge.frame.selected { + border: 3px solid #793; +} +#application-content .template-lozenge .icon { + float: left; +} +#application-content .template-lozenge .blurb { + overflow-y: scroll; + height: 80px; +} +#application-content .template-lozenge .title { + font-weight: 700; + font-size: 90%; +} +#application-content .template-lozenge .description { + font-size: 85%; +} +div#create-step-template-entries { + width: 472px; + margin-left: auto; + margin-right: auto; + padding-top: 12px; + padding-bottom: 36px; +} /* menu bar */ .navbar .nav>li { display: block; @@ -79,6 +139,22 @@ ul.dropdown-menu { border-radius: 5px 5px 0 0; } +li.text-filter input { + width: 10em; + margin-top: 3px; + /* taken from datatables_filter input */ + background-image: url("../img/magnifying-glass-right.png"); + background-size:12px 12px; + background-repeat: no-repeat; + background-position: 8px 5px; + font-size: 85%; + padding: 1px 4px 1px 24px; + margin-bottom: 2px; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + border-radius: 1em; +} + /* bootstrap overrides */ a { color: #382; @@ -152,6 +228,21 @@ code { } */ +textarea:focus,input[type="text"]:focus,input[type="password"]:focus, +input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus, +input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus, +input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus, +input[type="color"]:focus,.uneditable-input:focus { + border-color: rgba(120, 180, 70, 0.8); + outline: 0; + outline: thin dotted 9; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px + rgba(120, 180, 70, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px + rgba(120, 180, 70, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px + rgba(120, 180, 70, 0.6); +} /* home page squares */ @@ -312,11 +403,15 @@ code { .nav-tabs { margin-bottom: 0px; } +.tab-content-scroller { + overflow: scroll; + height: auto; +} .tab-content { - padding: 18px 12px 18px 12px; + padding: 18px 24px 18px 24px; border-right: 1px solid #DDD; border-left: 1px solid #DDD; - min-height: 500px; + min-height: 300px; } #tree-list { } @@ -560,9 +655,17 @@ div.for-empty-table { -moz-border-radius: 4px; border-radius: 4px; } -.app-add-wizard-create-entity-config input { + +.app-add-wizard-config-entry input { margin-bottom: 0px; } +.app-add-wizard-config-entry { + margin-bottom: 9px; + margin-top: 2px; +} +.app-add-wizard-config-entry button { + margin-left: 8px; +} .app-add-wizard-create-entity-label-newline { padding-left: 2px; padding-bottom: 3px; @@ -575,13 +678,6 @@ div.for-empty-table { .app-add-wizard-create-entity-input { width: 300px; } -.app-add-wizard-create-entity-config { - margin-bottom: 9px; - margin-top: 2px; -} -.app-add-wizard-create-entity-config button { - margin-left: 8px; -} #add-app-entity { float: right; } @@ -602,7 +698,16 @@ div.for-empty-table { margin-top: 6px; margin-bottom: 9px; } - +.control-group .deploy-label { + font-weight: 700; +} +.deploy .control-group { + margin-bottom: 18px; +} +.deploy input#application-name { + /** margin supplied by control group */ + margin-bottom: 0px; +} #application-explorer div#summary { padding-right: 16px; @@ -629,7 +734,7 @@ div.for-empty-table { .accordion-body { border-top: 1px dashed lightgray; padding: 8px 8px 12px 8px; - max-height: 350px;' + max-height: 400px;' overflow-x: scroll; overflow-y: scroll; background-color: white; @@ -869,14 +974,14 @@ textarea { { -webkit-border-top-right-radius: 0 0 0 13px !important; -moz-border-top-right-radius: 0 0 0 13px !important; - border-bottom-right-radius: 13px; + border-bottom-left-radius: 13px; } .table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child { -webkit-border-top-right-radius: 0 0 13px 0 !important; -moz-border-top-right-radius: 0 0 13px 0 !important; - border-bottom-left-radius: 13px; + border-bottom-right-radius: 13px; } /*HOME BODY */ @@ -968,13 +1073,20 @@ textarea { } .nav-tabs>.active>a,.nav-tabs>.active { - color: #549e2b !important; + color: #549e2b; } .nav-tabs>.active>a,.nav-tabs>.active a { background: #ffffff !important; } +.nav-tabs .dropdown-menu li > a:hover, +.nav-tabs .dropdown-menu .active > a, +.nav-tabs .dropdown-menu .active > a:hover { + color: white; + background-color: #549e2b !important; +} + .nav-tabs>li>a { color: #444444 !important; border: 1px solid #dddddd !important; @@ -988,6 +1100,17 @@ textarea { color: #549e2b !important; background: #ffffff none !important; } +.nav-tabs .dropdown-toggle .caret, .nav-pills .dropdown-toggle .caret { + opacity: 0.5; + margin-top: 6px; + border-top-color: #000; + border-bottom-color: #000; +} +.nav-tabs .dropdown-toggle:hover .caret, .nav-pills .dropdown-toggle:hover .caret { + opacity: 0.8; + border-top-color: #549e2b; + border-bottom-color: #549e2b; +} #effectors-table th { background: #ffffff !important http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/js/model/application.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/js/model/application.js b/usage/jsgui/src/main/webapp/assets/js/model/application.js index 4a7597a..3ec4fae 100644 --- a/usage/jsgui/src/main/webapp/assets/js/model/application.js +++ b/usage/jsgui/src/main/webapp/assets/js/model/application.js @@ -12,7 +12,7 @@ define([ return { name:"", type:null, - entities:[], + entities:null, locations:[] } }, @@ -55,18 +55,25 @@ define([ } this.set('locations', newLocations) }, - addEntity:function (entity) { + getEntities: function() { var entities = this.get('entities') - if (!this.hasEntityWithName(entity.get("name"))) { - entities.push(entity.toJSON()) - this.set('entities', entities) - this.trigger("change") - this.trigger("change:entities") + if (entities === undefined) return []; + return entities; + }, + addEntity:function (entity) { + var entities = this.getEntities() + if (!entities) { + entities = [] + this.set("entities", entities) } + entities.push(entity.toJSON()) + this.set('entities', entities) + this.trigger("change") + this.trigger("change:entities") }, removeEntityIndex:function (indexToRemove) { var newEntities = [], - currentEntities = this.get("entities") + currentEntities = this.getEntities() for (var index=0; index<currentEntities.length; index++) { if (index != indexToRemove) newEntities.push(currentEntities[index]) @@ -75,7 +82,7 @@ define([ }, removeEntityByName:function (name) { var newEntities = [], - currentEntities = this.get("entities") + currentEntities = this.getEntities() for (var index in currentEntities) { if (currentEntities[index].name != name) newEntities.push(currentEntities[index]) @@ -83,7 +90,7 @@ define([ this.set('entities', newEntities) }, hasEntityWithName:function (name) { - return _.any(this.get('entities'), function (entity) { + return _.any(this.getEntities(), function (entity) { return entity.name === name }) } http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/js/model/catalog-item-summary.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/js/model/catalog-item-summary.js b/usage/jsgui/src/main/webapp/assets/js/model/catalog-item-summary.js new file mode 100644 index 0000000..559a16e --- /dev/null +++ b/usage/jsgui/src/main/webapp/assets/js/model/catalog-item-summary.js @@ -0,0 +1,25 @@ +define(["underscore", "backbone"], function (_, Backbone) { + + // not used currently + + var CatalogItem = {} + + CatalogItem.Model = Backbone.Model.extend({ + defaults:function () { + return { + id:"", + name:"", + type:"", + description:"", + iconUrl:"", + } + }, + }) + + CatalogItem.Collection = Backbone.Collection.extend({ + model:CatalogItem.Model, + url:'/v1/catalog' // not used? + }) + + return CatalogItem +}) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js b/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js index f68ef29..1a7f141 100644 --- a/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js +++ b/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js @@ -6,8 +6,10 @@ define([ "underscore", "jquery", "backbone", "model/entity", "model/application", "formatJson", "model/location", "text!tpl/app-add-wizard/modal-wizard.html", - "text!tpl/app-add-wizard/create.html", - "text!tpl/app-add-wizard/create-entity-entry.html", "text!tpl/app-add-wizard/create-config-entry.html", + "text!tpl/app-add-wizard/create.html", + "text!tpl/app-add-wizard/create-step-template-entry.html", + "text!tpl/app-add-wizard/create-entity-entry.html", + "text!tpl/app-add-wizard/edit-config-entry.html", "text!tpl/app-add-wizard/deploy.html", "text!tpl/app-add-wizard/deploy-location-row.html", "text!tpl/app-add-wizard/deploy-location-option.html", @@ -18,7 +20,7 @@ define([ ], function (_, $, Backbone, Entity, Application, FormatJSON, Location, ModalHtml, CreateHtml, - CreateEntityEntryHtml, CreateConfigEntryHtml, + CreateStepTemplateEntryHtml, CreateEntityEntryHtml, EditConfigEntryHtml, DeployHtml, DeployLocationRowHtml, DeployLocationOptionHtml, PreviewHtml @@ -39,19 +41,19 @@ define([ { step_id:'what-app', title:'Create Application', - instructions:'Define how the application is built and the configuration parameters', + instructions:'Choose or build the application to deploy', view:new ModalWizard.StepCreate({ model:this.model}) }, { step_id:'name-and-locations', title:'Deploy Application', - instructions:'Enter the name of the new application and the location(s) where you wish to deploy it.', + instructions:'Specify the locations to deploy to and any additional configuration', view:new ModalWizard.StepDeploy({ model:this.model }) }, { step_id:'preview', title:'Application Preview', - instructions:'Confirm the code which will be sent to the server, optionally tweaking it or saving it for future reference.', + instructions:'Confirm the code which will be sent to the server, optionally tweaking it or saving it for future reference', view:new ModalWizard.StepPreview({ model:this.model}) } ] @@ -138,29 +140,37 @@ define([ ModalWizard.StepCreate = Backbone.View.extend({ className:'modal-body', events:{ - 'click #add-app-entity':'addEntity', + 'click #add-app-entity':'addEntityBox', 'click .editable-entity-heading':'expandEntity', 'click .remove-entity-button':'removeEntityClick', 'click .editable-entity-button':'saveEntityClick', 'click #remove-config':'removeConfigRow', - 'click #add-config':'addConfigRow' + 'click #add-config':'addConfigRow', + 'click .template-lozenge':'templateClick', + 'change .text-filter input':'applyFilter', + 'keyup .text-filter input':'applyFilter', + 'shown a[data-toggle="tab"]':'onTabChange' }, template:_.template(CreateHtml), initialize:function () { var self = this - self.catalogEntities = [] - self.catalogApplications = [] + self.catalogEntityIds = [] + self.catalogApplicationIds = [] this.$el.html(this.template({})) - this.addEntity() + + this.addEntityBox() $.get('/v1/catalog/entities', {}, function (result) { - self.catalogEntities = result - self.$(".entity-type-input").typeahead().data('typeahead').source = self.catalogEntities + self.catalogEntityItems = result + self.catalogEntityIds = _.map(result, function(item) { return item.id }) + self.$(".entity-type-input").typeahead().data('typeahead').source = self.catalogEntityIds }) $.get('/v1/catalog/applications', {}, function (result) { - self.catalogApplications = result - self.$(".application-type-input").typeahead().data('typeahead').source = self.catalogApplications + self.catalogApplicationItems = result + self.catalogApplicationIds = _.map(result, function(item) { return item.id }) + self.$("#appClassTab .application-type-input").typeahead().data('typeahead').source = self.catalogApplicationIds + self.addTemplateLozenges() }) }, beforeClose:function () { @@ -168,7 +178,7 @@ define([ renderConfiguredEntities:function () { var $configuredEntities = this.$('#entitiesAccordionish').empty() var that = this - if (this.model.get("entities").length > 0) { + if (this.model.get("entities") && this.model.get("entities").length > 0) { _.each(this.model.get("entities"), function (entity) { that.addEntityHtml($configuredEntities, entity) }) @@ -180,18 +190,65 @@ define([ this.delegateEvents() return this }, - + onTabChange: function(e) { + if (e.target.text=="Template") + $("li.text-filter").show() + else + $("li.text-filter").hide() + }, + applyFilter: function(e) { + var filter = $(e.currentTarget).val().toLowerCase() + if (!filter) { + $(".template-lozenge").show() + } else { + _.each($(".template-lozenge"), function(it) { + console.log($(it)) + console.log($(it).text()) + var viz = $(it).text().toLowerCase().indexOf(filter)>=0 + if (viz) + $(it).show() + else + $(it).hide() + }) + } + }, + addTemplateLozenges: function(event) { + var that = this + _.each(this.catalogApplicationItems, function(item) { + that.addTemplateLozenge(that, item) + }) + }, + addTemplateLozenge: function(that, item) { + var $tempel = _.template(CreateStepTemplateEntryHtml, { + id: item.id, + name: item.name, + description: item.description, + iconUrl: item.iconUrl + }) + $("#create-step-template-entries", that.$el).append($tempel) + }, + templateClick: function(event) { + var $tl = $(event.target).closest(".template-lozenge"); + var wasSelected = $tl.hasClass("selected") + $(".template-lozenge").removeClass("selected") + if (!wasSelected) { + $tl.addClass("selected") + this.selectedTemplateId = $tl.attr('id'); + } else { + this.selectedTemplateId = null; + } + }, expandEntity:function (event) { $(event.currentTarget).next().show('fast').delay(1000).prev().hide('slow') }, saveEntityClick:function (event) { - this.saveEntity($(event.currentTarget).parent().parent().parent()); + this.saveEntity($(event.currentTarget).closest(".editable-entity-group")); }, saveEntity:function ($entityGroup) { var that = this var name = $('#entity-name',$entityGroup).val() var type = $('#entity-type',$entityGroup).val() - if (type=="" || !_.contains(that.catalogEntities, type)) { + if (type=="" || !_.contains(that.catalogEntityIds, type)) { $('.entity-info-message',$entityGroup).show('slow').delay(2000).hide('slow') return false } @@ -209,33 +266,42 @@ define([ }, getConfigMap:function (root) { var map = {} - $('.app-add-wizard-create-entity-config',root).each( function (index,elt) { + $('.app-add-wizard-config-entry',root).each( function (index,elt) { map[$('#key',elt).val()] = $('#value',elt).val() }) return map; }, saveTemplate:function () { + var type = this.selectedTemplateId + if (type === undefined) return false + if (!_.contains(this.catalogApplicationIds, type)) { + $('.entity-info-message').show('slow').delay(2000).hide('slow') + return false + } + this.model.set("type", type); + return true; + }, + saveAppClass:function () { var that = this - var tab = $.find('#templateTab') - var type = $(tab).find('#entity-type').val() - if (!_.contains(this.catalogApplications, type)) { + var tab = $.find('#appClassTab') + var type = $(tab).find('#app-java-type').val() + if (!_.contains(this.catalogApplicationIds, type)) { $('.entity-info-message').show('slow').delay(2000).hide('slow') return false } this.model.set("type", type); - this.model.set("config", this.getConfigMap(tab)) return true; }, - addEntity:function () { + addEntityBox:function () { var entity = new Entity.Model this.model.addEntity( entity ) - this.addEntityHtml(this.$('#entitiesAccordionish'), entity) + this.addEntityHtml($('#entitiesAccordionish', this.$el), entity) }, addEntityHtml:function (parent, entity) { var $entity = _.template(CreateEntityEntryHtml, {}) var that = this parent.append($entity) - parent.children().last().find('.entity-type-input').typeahead({ source: that.catalogEntities }) + parent.children().last().find('.entity-type-input').typeahead({ source: that.catalogEntityIds }) }, removeEntityClick:function (event) { var $entityGroup = $(event.currentTarget).parent().parent().parent(); @@ -244,7 +310,7 @@ define([ }, addConfigRow:function (event) { - var $row = _.template(CreateConfigEntryHtml, {}) + var $row = _.template(EditConfigEntryHtml, {}) $(event.currentTarget).parent().prev().append($row) }, removeConfigRow:function (event) { @@ -258,10 +324,10 @@ define([ var allokay = true $($.find('.editable-entity-group')).each( function (i,$entityGroup) { - allokay = that.saveEntity($entityGroup) & allokay + allokay = that.saveEntity($($entityGroup)) & allokay }) if (!allokay) return false; - if (this.model.get("entities").length > 0) { + if (this.model.get("entities") && this.model.get("entities").length > 0) { this.model.set("type", null); return true; } @@ -270,7 +336,13 @@ define([ this.model.set("entities", []); return true } + } else if (tabName=='#appClassTab') { + if (this.saveAppClass()) { + this.model.set("entities", []); + return true + } } else { + console.log("NOT IMPLEMENTED YET") // other tabs not implemented yet // do nothing, show error return false below } @@ -287,7 +359,9 @@ define([ 'click #remove-app-location':'removeLocation', 'change select':'selection', 'change option':'selection', - 'blur #application-name':'updateName' + 'blur #application-name':'updateName', + 'click #remove-config':'removeConfigRow', + 'click #add-config':'addConfigRow' }, template:_.template(DeployHtml), locationRowTemplate:_.template(DeployLocationRowHtml), @@ -355,6 +429,20 @@ define([ this.model.removeLocationIndex(toBeRemoved) this.renderAddedLocations() }, + addConfigRow:function (event) { + var $row = _.template(EditConfigEntryHtml, {}) + $(event.currentTarget).parent().prev().append($row) + }, + removeConfigRow:function (event) { + $(event.currentTarget).parent().remove() + }, + getConfigMap:function() { + var map = {} + $('.app-add-wizard-config-entry').each( function (index,elt) { + map[$('#key',elt).val()] = $('#value',elt).val() + }) + return map; + }, selection:function (event) { var url = $(event.currentTarget).val(); var loc = this.locations.find(function (candidate) { @@ -364,10 +452,15 @@ define([ loc.getLinkByName("self")) }, updateName:function () { - this.model.set("name", this.$('#application-name').val()) + var name = this.$('#application-name').val() + if (name) + this.model.set("name", name) + else + this.model.set("name", "") }, validate:function () { - if (this.model.get("name") !== "" && this.model.get("locations").length !== 0) { + this.model.set("config", this.getConfigMap()) + if (this.model.get("locations").length !== 0) { return true } this.$('div.info-message').show('slow').delay(2000).hide('slow') @@ -385,15 +478,24 @@ define([ this.model.off("change", this.render) }, render:function () { + if (!this.model.get("entities") || this.model.get("entities").length==0) { + delete this.model.attributes["entities"] + } + if (!this.model.get("name")) + delete this.model.attributes["name"] + if (!this.model.get("config") || _.keys(this.model.get("config")).length==0) { + delete this.model.attributes["config"] + } + this.$('#app-summary').val(FormatJSON(this.model.toJSON())) this.delegateEvents() return this }, validate:function () { - if (this.model.get("name") != "" - && this.model.get("locations").length > 0 - && (this.model.get("type")!=null || - this.model.get("entities").length > 0)) { + // need locations, and type or entities + if ((this.model.get("locations").length > 0) && + (this.model.get("type")!=null || + this.model.getEntities().length > 0)) { return true } this.showFailure() http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/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 e5dd18e..5bde0df 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 @@ -123,8 +123,6 @@ define([ model:entitySummary, application:app }) - console.log("loading") - console.log(that.detailsView.render().el) $("div#details").html(that.detailsView.render().el) // preserve the tab selected before $("div#details").find("a[href=\"#"+whichTab+"\"]").tab('show') http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/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 a31044f..e1f5690 100644 --- a/usage/jsgui/src/main/webapp/assets/js/view/catalog.js +++ b/usage/jsgui/src/main/webapp/assets/js/view/catalog.js @@ -42,7 +42,6 @@ define([ var that = this; _.defer(function() { - console.log($("#applications div.accordion-head")) that.toggleAccordionDiv($("#applications div.accordion-head"), false) $("#details-empty").show() }) @@ -66,8 +65,8 @@ define([ }, renderGenericAccordion: function(accordion, data) { accordion.html('') - _.each(data, function (id, pos) { - accordion.append(this.entryTemplate({type:id, id:id})); + _.each(data, function (item, pos) { + accordion.append(this.entryTemplate({type:item.type, id:item.id})); }, this) accordion.find("div[id='"+this.activeItem+"']").addClass('active') }, http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/js/view/home.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/js/view/home.js b/usage/jsgui/src/main/webapp/assets/js/view/home.js index e73e58d..88a748a 100644 --- a/usage/jsgui/src/main/webapp/assets/js/view/home.js +++ b/usage/jsgui/src/main/webapp/assets/js/view/home.js @@ -57,7 +57,7 @@ define([ } this.callPeriodically(function() { - //that.refresh(that); + that.refresh(that); }, 5000) this.refresh(this) }, @@ -115,14 +115,16 @@ define([ this._modal.close() } var that = this; - var wizard = new AppAddWizard({appRouter:this.options.appRouter}) - this._modal = wizard - this.$("#modal-container").html(wizard.render().el) - this.$("#modal-container .modal") - .on("hidden",function () { - wizard.close() - that.refresh(that) - }).modal('show') + if (!this.options.offline) { + var wizard = new AppAddWizard({appRouter:this.options.appRouter}) + this._modal = wizard + this.$("#modal-container").html(wizard.render().el) + this.$("#modal-container .modal") + .on("hidden",function () { + wizard.close() + that.refresh(that) + }).modal('show') + } }, deleteApplication:function (event) { http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-config-entry.html ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-config-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-config-entry.html deleted file mode 100644 index f4a1779..0000000 --- a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-config-entry.html +++ /dev/null @@ -1,8 +0,0 @@ -<div class="controls app-add-wizard-create-entity-config"> - <input id="key" type="text" class="input-medium" name="key" placeholder="key"> - <input id="value" type="text" class="input-medium" name="value" placeholder="value"> - - <button id="remove-config" class="btn btn-info btn-mini" type="button"> - <i class="icon-minus-sign"></i> - </button> -</div> http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html index df12216..51e6aff 100644 --- a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html +++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-entity-entry.html @@ -37,7 +37,7 @@ </div> <div> <button id="add-config" class="btn btn-mini btn-info"> - Add Config Key</button> + Add Configuration</button> </div> </div> </div> http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html new file mode 100644 index 0000000..da52845 --- /dev/null +++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html @@ -0,0 +1,13 @@ +<div class="template-lozenge frame" id="<%= id %>"> + <% if (iconUrl) { %> + <div class="icon"> + <img src="<%= iconUrl %>" alt="(icon)" /> + </div> + <% } %> + <div class="blurb"> + <div class="title"><%= name %></div> + <div class="description"> + <%= description ? description : "" %> + </div> + </div> +</div> http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create.html ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create.html index 0ae2c0a..d13a486 100644 --- a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create.html +++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create.html @@ -15,32 +15,19 @@ <li><a tabindex="-1" data-toggle="tab" href="#xmlTab">XML</a></li> <li class="divider"></li> <li><a tabindex="-1" data-toggle="tab" href="#groovyTab">Groovy</a></li> - <li class="divider"></li> + <li><a tabindex="-1" data-toggle="tab" href="#appClassTab">App Class</a></li> <li><a tabindex="-1" data-toggle="tab" href="#uploadTab">JAR</a></li> - </ul></li> + </ul> + </li> + <li class="text-filter pull-right"><input type="text"/></li> </ul> - <div class="tab-content"> + <div class="tab-content-scroller"> + <div class="tab-content"> + <div class="tab-pane active" id="templateTab"> - - <div class="control-group"> - <div class="app-add-wizard-create-entity-label-newline">Type</div> - <div class="controls app-type"> - <input id="entity-type" type="text" name="type" class="input-large app-add-wizard-create-entity-input application-type-input" placeholder="type"> - </div> - </div> - - <div class="control-group"> - <div class="app-add-wizard-create-entity-label-newline">Configuration</div> - <div class="controls"> - </div> - <div> - <button id="add-config" class="btn btn-mini btn-info"> - Add Config Key</button> - </div> - </div> + <div id="create-step-template-entries"/> </div> - <div class="tab-pane" id="entitiesTab"> <div id="entitiesAccordionish"></div> @@ -59,4 +46,16 @@ <div class="tab-pane" id="uploadTab"> <br/><br/><i>coming soon!</i> </div> + + + <div class="tab-pane" id="appClassTab"> + <div class="control-group"> + <div class="app-add-wizard-create-entity-label-newline">Type</div> + <div class="controls app-type"> + <input id="app-java-type" type="text" name="type" class="input-large app-add-wizard-create-entity-input application-type-input" placeholder="type"> + </div> + </div> + </div> + + </div></div> </div> http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/deploy.html ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/deploy.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/deploy.html index b69f5ba..b5def12 100644 --- a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/deploy.html +++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/deploy.html @@ -1,28 +1,35 @@ <!-- New application wizard step 1: set name and locations --> +<div class="deploy"> -<div class="info-message label-message hide"> - <span class="label-important">Important</span> - Name and location must be specified -</div> -<div class="info-nolocs-message label-message hide"> - <span class="label-important">Important</span> - Missing or unconfigured locations -</div> + <div class="info-message label-message hide"> + <span class="label-important">Important</span> Location must be specified + </div> + <div class="info-nolocs-message label-message hide"> + <span class="label-important">Important</span> Missing or unconfigured locations + </div> + <div id="app-locations" class="control-group"> + <div class="deploy-label">Locations</div> + <div id="selector-container"></div> + <button id="add-selector-container" class="btn btn-info btn-mini"> + Add Additional Location</button> + </div> -<div class="control-group"> - <label for="application-name">Name</label> + <div class="control-group"> + <div class="application-name-label deploy-label">Name (optional)</div> + <div class="controls"> + <input id="application-name" name="name" type="text" + style="width: 80%"> + </div> + </div> - <div class="controls"> - <input id="application-name" name="name" type="text" style="width:80%"> - </div> -</div> + <div class="control-group"> + <div class="app-add-wizard-create-entity-label-newline deploy-label">Configuration</div> + <div class="controls"></div> + <div> + <button id="add-config" class="btn btn-mini btn-info"> + Add Configuration</button> + </div> + </div> -<div id="app-locations"> - <div>Locations</div> - <div id="selector-container" class="control-group"> - </div> - <button id="add-selector-container" class="btn btn-info btn-mini">Add Additional Location</button> </div> - -</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/edit-config-entry.html ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/edit-config-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/edit-config-entry.html new file mode 100644 index 0000000..366b4d7 --- /dev/null +++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/edit-config-entry.html @@ -0,0 +1,8 @@ +<div class="controls app-add-wizard-config-entry"> + <input id="key" type="text" class="input-medium" name="key" placeholder="key"> + <input id="value" type="text" class="input-medium" name="value" placeholder="value"> + + <button id="remove-config" class="btn btn-info btn-mini" type="button"> + <i class="icon-minus-sign"></i> + </button> +</div> http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/preview.html ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/preview.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/preview.html index 3b9642f..a7e5db9 100644 --- a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/preview.html +++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/preview.html @@ -1,10 +1,13 @@ <!-- New application wizard step 3: summary and submit the app --> -<div> - <h3>Application Preview</h3> - <textarea id="app-summary" readonly="readonly" rows="16" style="width:100%;"></textarea> -</div> -<dl class="dl-horizontal"></dl> -<div class="info-message hide label-message"> - <span class="label-important">ERROR</span> - Invalid spec or server failure -</div> +<div class="preview"> + <div> + <h3>Application Preview</h3> + <textarea id="app-summary" readonly="readonly" rows="16" + style="width: 100%;"></textarea> + </div> + <dl class="dl-horizontal"></dl> + <div class="info-message hide label-message"> + <span class="label-important">ERROR</span> Invalid spec or server + failure + </div> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java b/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java index fad015e..e751aee 100644 --- a/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java +++ b/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java @@ -29,7 +29,7 @@ public class BrooklynJavascriptGuiLauncherTest { @Test public void testJavascriptWithRest() throws Exception { server = BrooklynJavascriptGuiLauncher.startJavascriptAndRest(); - BrooklynRestApiLauncherTest.enableJavaClassPathUrlsForScanning(server); + BrooklynRestApiLauncherTest.forceUseOfDefaultCatalogWithJavaClassPath(server); BrooklynRestApiLauncherTest.enableAnyoneLogin(server); checkUrlContains("/index.html", "Brooklyn"); checkUrlContains("/v1/catalog/entities", "Tomcat"); http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c299b335/usage/jsgui/src/test/javascript/specs/model/application-spec.js ---------------------------------------------------------------------- diff --git a/usage/jsgui/src/test/javascript/specs/model/application-spec.js b/usage/jsgui/src/test/javascript/specs/model/application-spec.js index b005112..bb3ef7c 100644 --- a/usage/jsgui/src/test/javascript/specs/model/application-spec.js +++ b/usage/jsgui/src/test/javascript/specs/model/application-spec.js @@ -97,12 +97,12 @@ define([ expect(spec.trigger).toHaveBeenCalled() }) - it('does not allow you to add the same entity twice', function () { + it('allows you to add the same entity twice', function () { var spec = new Application.Spec, entity = new Entity.Model({ name:'test-entity'}) spec.addEntity(entity) spec.addEntity(entity) - expect(spec.get("entities").length).toEqual(1) + expect(spec.get("entities").length).toEqual(2) }) }) })
