Return-Path: X-Original-To: apmail-ambari-commits-archive@www.apache.org Delivered-To: apmail-ambari-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2503617F89 for ; Mon, 6 Oct 2014 15:12:50 +0000 (UTC) Received: (qmail 8829 invoked by uid 500); 6 Oct 2014 15:12:49 -0000 Delivered-To: apmail-ambari-commits-archive@ambari.apache.org Received: (qmail 8737 invoked by uid 500); 6 Oct 2014 15:12:49 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 8699 invoked by uid 99); 6 Oct 2014 15:12:49 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Oct 2014 15:12:49 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 6BA34320015; Mon, 6 Oct 2014 15:12:49 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jonathanhurley@apache.org To: commits@ambari.apache.org Date: Mon, 06 Oct 2014 15:12:50 -0000 Message-Id: In-Reply-To: <216d586c16dc4829ac31e3e3905ff9f2@git.apache.org> References: <216d586c16dc4829ac31e3e3905ff9f2@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/7] git commit: AMBARI-7645. Slider View: App actions should be available in all states of an app. (onechiporenko) AMBARI-7645. Slider View: App actions should be available in all states of an app. (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/26c4cc80 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/26c4cc80 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/26c4cc80 Branch: refs/heads/branch-alerts-dev Commit: 26c4cc800dd87802e5758576629c1313bd11db3d Parents: 0e959b0 Author: Oleg Nechiporenko Authored: Mon Oct 6 13:51:00 2014 +0300 Committer: Oleg Nechiporenko Committed: Mon Oct 6 13:51:00 2014 +0300 ---------------------------------------------------------------------- .../ui/app/controllers/slider_app_controller.js | 89 ++++++++++++-------- .../main/resources/ui/app/models/slider_app.js | 33 ++++---- .../ui/test/integration/pages/index_test.js | 13 ++- .../controllers/slider_app_controller_test.js | 64 ++++++++++++++ 4 files changed, 148 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/26c4cc80/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js index 2754891..622c9f9 100644 --- a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js +++ b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js @@ -42,6 +42,49 @@ App.SliderAppController = Ember.ObjectController.extend(App.AjaxErrorHandler, { }.property('model.quickLinks.content.content.length'), /** + * List of all possible actions for slider app + * @type {Em.Object} + */ + appActions: Em.Object.create({ + stop: { + title: 'Stop', + action: 'freeze', + confirm: true + }, + flex: { + title: 'Flex', + action: 'flex', + confirm: false + }, + destroy: { + title: 'Destroy', + action: 'destroy', + customConfirm: 'confirmDestroy' + }, + start: { + title: 'Start', + action: 'thaw', + confirm: false + } + }), + + /** + * map of available action for slider app according to its status + * key - status, value - list of actions + * @type {Em.Object} + */ + statusActionsMap: Em.Object.create({ + NEW: ['stop'], + NEW_SAVING: ['stop'], + ACCEPTED: ['stop'], + RUNNING: ['stop', 'flex'], + FINISHED: ['start', 'destroy'], + FAILED: ['destroy'], + KILLED: ['destroy'], + FROZEN: ['start', 'destroy'] + }), + + /** * List of available for model actions * Based on model.status * @type {Ember.Object[]} @@ -49,40 +92,19 @@ App.SliderAppController = Ember.ObjectController.extend(App.AjaxErrorHandler, { availableActions: function() { var actions = Em.A([]), advanced = Em.A([]), + appActions = this.get('appActions'), + statusActionsMap = this.get('statusActionsMap'), status = this.get('model.status'); - if ('RUNNING' === status) { - actions.pushObject({ - title: 'Stop', - action: 'freeze', - confirm: true - }); - } - if ('RUNNING' == status) { - actions.push({ - title: 'Flex', - action: 'flex', - confirm: false - }); - } - if ('FROZEN' === status) { - actions.pushObject({ - title: 'Start', - action: 'thaw', - confirm: false - }); - advanced.pushObject({ - title: 'Destroy', - action: 'destroy', - customConfirm: 'confirmDestroy' - }); - } - if ('FAILED' === status) { - advanced.pushObject({ - title: 'Destroy', - action: 'destroy', - customConfirm: 'confirmDestroy' - }); - } + + statusActionsMap[status].forEach(function(action) { + if ('destroy' === action) { + advanced.pushObject(appActions[action]); + } + else { + actions.pushObject(appActions[action]); + } + }); + if (advanced.length) { actions.pushObject({ title: 'Advanced', @@ -405,7 +427,6 @@ App.SliderAppController = Ember.ObjectController.extend(App.AjaxErrorHandler, { this.tryDoAction(); } } - return true; } } http://git-wip-us.apache.org/repos/asf/ambari/blob/26c4cc80/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js b/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js index 3702b35..9534d98 100644 --- a/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js +++ b/contrib/views/slider/src/main/resources/ui/app/models/slider_app.js @@ -71,22 +71,22 @@ App.SliderApp = DS.Model.extend({ /** * @type {App.SliderAppComponent[]} */ - components: DS.hasMany('sliderAppComponent', {async:true}), + components: DS.hasMany('sliderAppComponent', {async: true}), /** * @type {App.QuickLink[]} */ - quickLinks: DS.hasMany('quickLink', {async:true}), + quickLinks: DS.hasMany('quickLink', {async: true}), /** * @type {App.SliderAppAlert[]} */ - alerts: DS.hasMany('sliderAppAlert', {async:true}), + alerts: DS.hasMany('sliderAppAlert', {async: true}), /** * @type {App.TypedProperty[]} */ - runtimeProperties: DS.hasMany('typedProperty', {async:true}), + runtimeProperties: DS.hasMany('typedProperty', {async: true}), /** * @type {object} @@ -117,7 +117,7 @@ App.SliderApp = DS.Model.extend({ /** * @type {boolean} */ - doNotShowComponentsAndAlerts: function(){ + doNotShowComponentsAndAlerts: function () { return this.get('status') == "FROZEN" || this.get('status') == "FAILED"; }.property('status', 'components', 'alerts'), @@ -125,7 +125,7 @@ App.SliderApp = DS.Model.extend({ * Display metrics only for running apps * @type {boolean} */ - showMetrics: function() { + showMetrics: function () { var global = this.get('configs')['global']; if (App.get('gangliaHost') != null) { return true; @@ -138,9 +138,9 @@ App.SliderApp = DS.Model.extend({ * @param {object} o * @returns {{key: string, value: *}[]} */ - mapObject: function(o) { + mapObject: function (o) { if (Ember.typeOf(o) !== 'object') return []; - return Ember.keys(o).map(function(key) { + return Ember.keys(o).map(function (key) { return { key: key, value: o[key], @@ -154,12 +154,13 @@ App.SliderApp = DS.Model.extend({ App.SliderApp.FIXTURES = []; App.SliderApp.Status = { - accepted: "ACCEPTED", - failed: "FAILED", - finished: "FINISHED", - killed: "KILLED", - new: "NEW", - new_saving: "NEW_SAVING", - running: "RUNNING" , - submitted:"SUBMITTED" + accepted: "ACCEPTED", + failed: "FAILED", + finished: "FINISHED", + killed: "KILLED", + new: "NEW", + new_saving: "NEW_SAVING", + running: "RUNNING", + submitted: "SUBMITTED", + frozen: "FROZEN" }; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/26c4cc80/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js b/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js index ecd8e6c..b684e24 100644 --- a/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js +++ b/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js @@ -44,7 +44,7 @@ test('sliderConfigs', function () { visit('/'); // configs count may be changed by adding new slider-configs - equal(App.SliderApp.store.all('sliderConfig').content.length, 2, 'slider configs should be set'); + equal(App.SliderApp.store.all('sliderConfig').content.length, 3, 'slider configs should be set'); }); @@ -59,4 +59,15 @@ test('Create-App button', function () { equal(currentURL(), '/createAppWizard/step1', 'url is valid'); }); +}); + +test('Create-App button visible/hidden', function () { + + Em.run(function () { + App.__container__.lookup('controller:application').set('hasConfigErrors', true); + }); + + visit('/'); + equal(find('.create-app').length, 0, 'Create App button should be hidden if some config errors'); + }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/26c4cc80/contrib/views/slider/src/main/resources/ui/test/unit/controllers/slider_app_controller_test.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/test/unit/controllers/slider_app_controller_test.js b/contrib/views/slider/src/main/resources/ui/test/unit/controllers/slider_app_controller_test.js new file mode 100644 index 0000000..1db72d6 --- /dev/null +++ b/contrib/views/slider/src/main/resources/ui/test/unit/controllers/slider_app_controller_test.js @@ -0,0 +1,64 @@ +/** + * 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. + */ + +moduleFor('controller:sliderApp', 'App.SliderAppController'); + +test('availableActions', function () { + + var controller = this.subject({model: Em.Object.create({status: ''})}); + controller.set('model.status', App.SliderApp.Status.accepted); + deepEqual(controller.get('availableActions').mapBy('action'), ['freeze'], 'actions for ACCEPTED'); + + Em.run(function () { + controller.set('model.status', App.SliderApp.Status.failed); + }); + deepEqual(controller.get('availableActions').findBy('title', 'Advanced').submenu.mapBy('action'), ['destroy'], 'actions for FAILED'); + + Em.run(function () { + controller.set('model.status', App.SliderApp.Status.finished); + }); + deepEqual(controller.get('availableActions').findBy('title', 'Advanced').submenu.mapBy('action'), ['destroy'], 'actions for FINISHED'); + ok(controller.get('availableActions').mapBy('action').contains('thaw'), 'actions for FINISHED (2)'); + + Em.run(function () { + controller.set('model.status', App.SliderApp.Status.killed); + }); + deepEqual(controller.get('availableActions').findBy('title', 'Advanced').submenu.mapBy('action'), ['destroy'], 'actions for KILLED'); + + Em.run(function () { + controller.set('model.status', App.SliderApp.Status.new); + }); + deepEqual(controller.get('availableActions').mapBy('action'), ['freeze'], 'actions for NEW'); + + Em.run(function () { + controller.set('model.status', App.SliderApp.Status.new_saving); + }); + deepEqual(controller.get('availableActions').mapBy('action'), ['freeze'], 'actions for NEW_SAVING'); + + Em.run(function () { + controller.set('model.status', App.SliderApp.Status.running); + }); + deepEqual(controller.get('availableActions').mapBy('action'), ['freeze', 'flex'], 'actions for RUNNING'); + + Em.run(function () { + controller.set('model.status', App.SliderApp.Status.frozen); + }); + deepEqual(controller.get('availableActions').findBy('title', 'Advanced').submenu.mapBy('action'), ['destroy'], 'actions for FROZEN'); + ok(controller.get('availableActions').mapBy('action').contains('thaw'), 'actions for FROZEN (2)'); + +});