Repository: ambari Updated Branches: refs/heads/trunk 67f3ed342 -> d8724c077
AMBARI-12071 Disabled webpage elements allow user to perform attached actions in IE 9-10. (ababiichuk) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d8724c07 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d8724c07 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d8724c07 Branch: refs/heads/trunk Commit: d8724c0770618a3318e85c4c3b135671b02dcea9 Parents: 67f3ed3 Author: aBabiichuk <[email protected]> Authored: Mon Jun 22 19:42:08 2015 +0300 Committer: aBabiichuk <[email protected]> Committed: Mon Jun 22 19:47:23 2015 +0300 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 1 + ambari-web/app/controllers/main/host/details.js | 6 + .../wizard/wizardProgressPageController.js | 3 + ambari-web/app/models/operating_system.js | 3 +- ambari-web/app/styles/stack_versions.less | 7 - .../main/host/details/host_component.hbs | 2 +- ambari-web/app/templates/wizard/step1.hbs | 4 +- ambari-web/app/views/main/host.js | 6 + .../test/controllers/main/host/details_test.js | 112 ++++++++++++--- ambari-web/test/models/operating_system_test.js | 42 ++++++ ambari-web/test/views/main/host_test.js | 135 ++++++++++++++----- 11 files changed, 252 insertions(+), 69 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index 8dd1086..45f6df9 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -282,6 +282,7 @@ var files = ['test/init_model_test', 'test/models/host_test', 'test/models/host_component_test', 'test/models/hosts_test', + 'test/models/operating_system_test', 'test/models/repository_test', 'test/models/stack_service_component_test', 'test/models/service_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/app/controllers/main/host/details.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js index e23c052..b61cbfb 100644 --- a/ambari-web/app/controllers/main/host/details.js +++ b/ambari-web/app/controllers/main/host/details.js @@ -216,6 +216,9 @@ App.MainHostDetailsController = Em.Controller.extend({ * @method deleteComponent */ deleteComponent: function (event) { + if ($(event.target).closest('li').hasClass('disabled')) { + return; + } var self = this; var component = event.context; var componentName = component.get('componentName'); @@ -2085,6 +2088,9 @@ App.MainHostDetailsController = Em.Controller.extend({ * @method moveComponent */ moveComponent: function (event) { + if ($(event.target).closest('li').hasClass('disabled')) { + return; + } return App.showConfirmationPopup(function () { var component = event.context; var reassignMasterController = App.router.get('reassignMasterController'); http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/app/mixins/wizard/wizardProgressPageController.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/wizard/wizardProgressPageController.js b/ambari-web/app/mixins/wizard/wizardProgressPageController.js index 49bcae6..e061811 100644 --- a/ambari-web/app/mixins/wizard/wizardProgressPageController.js +++ b/ambari-web/app/mixins/wizard/wizardProgressPageController.js @@ -656,6 +656,9 @@ App.wizardProgressPageControllerMixin = Em.Mixin.create({ }, showHostProgressPopup: function (event) { + if (!['IN_PROGRESS', 'FAILED', 'COMPLETED'].contains(Em.get(event.context, 'status')) || !this.get('content.requestIds.length')) { + return; + } var popupTitle = event.contexts[0].title; var requestIds = event.contexts[0].requestIds; var stageId = event.contexts[0].stageId; http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/app/models/operating_system.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/operating_system.js b/ambari-web/app/models/operating_system.js index 9fa221a..31f8922 100644 --- a/ambari-web/app/models/operating_system.js +++ b/ambari-web/app/models/operating_system.js @@ -26,7 +26,8 @@ App.OperatingSystem = DS.Model.extend({ stackVersion: DS.attr('string'), repositories: DS.hasMany('App.Repository'), stack: DS.belongsTo('App.Stack'), - isSelected: DS.attr('boolean', {defaultValue: true}) + isSelected: DS.attr('boolean', {defaultValue: true}), + isDeselected: Em.computed.not('isSelected') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/app/styles/stack_versions.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/stack_versions.less b/ambari-web/app/styles/stack_versions.less index cbe4151..4ec60cb 100644 --- a/ambari-web/app/styles/stack_versions.less +++ b/ambari-web/app/styles/stack_versions.less @@ -111,13 +111,6 @@ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } - .disabled-textfield input { - color: #808080; - disabled: disabled; - pointer-events: none; - cursor: default; - background: #E4E4E4; - } .disabled-label { color: #808080; } http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/app/templates/main/host/details/host_component.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/host/details/host_component.hbs b/ambari-web/app/templates/main/host/details/host_component.hbs index 419d794..c9c6069 100644 --- a/ambari-web/app/templates/main/host/details/host_component.hbs +++ b/ambari-web/app/templates/main/host/details/host_component.hbs @@ -112,7 +112,7 @@ </li> {{/unless}} {{#if view.isInit}} - <li {{bindAttr class="view."}}> + <li> <a href="javascript:void(null)" data-toggle="modal" {{action "installComponent" view.content target="controller"}}> {{t common.reinstall}} </a> http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/app/templates/wizard/step1.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step1.hbs b/ambari-web/app/templates/wizard/step1.hbs index eca7b52..478e459 100644 --- a/ambari-web/app/templates/wizard/step1.hbs +++ b/ambari-web/app/templates/wizard/step1.hbs @@ -69,8 +69,8 @@ {{view view.popoverView repositoryBinding="repository"}} {{/if}} </div> - <div {{bindAttr class=":url-td operatingSystem.osType repository.repoId operatingSystem.isSelected::disabled-textfield repository.invalidFormatError:textfield-error repository.invalidError:textfield-error"}}> - {{view Ember.TextField valueBinding="repository.baseUrl"}} + <div {{bindAttr class=":url-td operatingSystem.osType repository.repoId repository.invalidFormatError:textfield-error repository.invalidError:textfield-error"}}> + {{view Ember.TextField valueBinding="repository.baseUrl" disabledBinding="operatingSystem.isDeselected"}} </div> <div class="clear-td"> {{#if repository.clearAll}} http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/app/views/main/host.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/host.js b/ambari-web/app/views/main/host.js index a39dc2e..bfd668d 100644 --- a/ambari-web/app/views/main/host.js +++ b/ambari-web/app/views/main/host.js @@ -548,6 +548,9 @@ App.MainHostView = App.TableView.extend(App.TableServerViewMixin, { }, displayComponents: function () { + if (this.get('hasNoComponents')) { + return; + } var header = Em.I18n.t('common.components'), hostName = this.get('content.hostName'), items = this.get('content.hostComponents').getEach('displayName'); @@ -555,6 +558,9 @@ App.MainHostView = App.TableView.extend(App.TableServerViewMixin, { }, displayVersions: function () { + if (this.get('hasSingleVersion')) { + return; + } var header = Em.I18n.t('common.versions'), hostName = this.get('content.hostName'), items = this.get('content.stackVersions').filterProperty('isVisible').map(function (stackVersion) { http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/test/controllers/main/host/details_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js index 3824a20..2d19316 100644 --- a/ambari-web/test/controllers/main/host/details_test.js +++ b/ambari-web/test/controllers/main/host/details_test.js @@ -314,20 +314,56 @@ describe('App.MainHostDetailsController', function () { }); describe('#deleteComponent()', function () { - it('confirm popup should be displayed', function () { - var event = { - context: Em.Object.create({}) - }; - sinon.spy(App.ModalPopup, "show"); + + var jQueryMock, + cases = [ + { + isDisabled: false, + showCallCount: 1, + title: 'confirm popup should be displayed' + }, + { + isDisabled: true, + showCallCount: 0, + title: 'confirm popup shouldn\'t be displayed' + } + ]; + + beforeEach(function () { + jQueryMock = sinon.stub(window, '$'); + sinon.spy(App.ModalPopup, 'show'); sinon.stub(controller, '_doDeleteHostComponent', Em.K); + }); - var popup = controller.deleteComponent(event); - expect(App.ModalPopup.show.calledOnce).to.be.true; - popup.onPrimary(); - expect(controller._doDeleteHostComponent.calledWith(Em.Object.create({}))).to.be.true; + afterEach(function () { + window.$.restore(); App.ModalPopup.show.restore(); controller._doDeleteHostComponent.restore(); }); + + cases.forEach(function (item) { + it(item.title, function () { + jQueryMock.returns({ + closest: function () { + return { + hasClass: function () { + return item.isDisabled; + } + } + } + }); + var event = { + context: Em.Object.create({}) + }, + popup = controller.deleteComponent(event); + expect(App.ModalPopup.show.callCount).to.equal(item.showCallCount); + if (item.showCallCount) { + popup.onPrimary(); + expect(controller._doDeleteHostComponent.calledWith(Em.Object.create({}))).to.be.true; + } + }); + }); + }); describe('#mimicWorkStatusChange()', function () { @@ -1794,36 +1830,70 @@ describe('App.MainHostDetailsController', function () { }); describe('#moveComponent()', function () { - it('popup should be displayed', function () { - var mock = { + + var jQueryMock, + mock = { saveComponentToReassign: Em.K, getSecurityStatus: Em.K, setCurrentStep: Em.K - }; + }, + cases = [ + { + isDisabled: false, + showConfirmationPopupCallCount: 1, + title: 'popup should be displayed' + }, + { + isDisabled: true, + showConfirmationPopupCallCount: 0, + title: 'popup shouldn\'t be displayed' + } + ]; + + beforeEach(function () { + jQueryMock = sinon.stub(window, '$'); sinon.spy(App, "showConfirmationPopup"); sinon.stub(App.router, 'get').withArgs('reassignMasterController').returns(mock); sinon.stub(App.router, 'transitionTo', Em.K); sinon.spy(mock, "saveComponentToReassign"); sinon.spy(mock, "getSecurityStatus"); sinon.spy(mock, "setCurrentStep"); + }); - var popup = controller.moveComponent({context: {}}); - expect(App.showConfirmationPopup.calledOnce).to.be.true; - popup.onPrimary(); - expect(App.router.get.calledWith('reassignMasterController')).to.be.true; - expect(mock.saveComponentToReassign.calledWith({})).to.be.true; - expect(mock.getSecurityStatus.calledOnce).to.be.true; - expect(mock.setCurrentStep.calledWith('1')).to.be.true; - expect(App.router.transitionTo.calledWith('reassign')).to.be.true; - + afterEach(function () { + window.$.restore(); App.showConfirmationPopup.restore(); App.router.get.restore(); App.router.transitionTo.restore(); mock.saveComponentToReassign.restore(); mock.getSecurityStatus.restore(); mock.setCurrentStep.restore(); + }); + cases.forEach(function (item) { + it(item.title, function () { + jQueryMock.returns({ + closest: function () { + return { + hasClass: function () { + return item.isDisabled; + } + } + } + }); + var popup = controller.moveComponent({context: {}}); + expect(App.showConfirmationPopup.callCount).to.equal(item.showConfirmationPopupCallCount); + if (item.showConfirmationPopupCallCount) { + popup.onPrimary(); + expect(App.router.get.calledWith('reassignMasterController')).to.be.true; + expect(mock.saveComponentToReassign.calledWith({})).to.be.true; + expect(mock.getSecurityStatus.calledOnce).to.be.true; + expect(mock.setCurrentStep.calledWith('1')).to.be.true; + expect(App.router.transitionTo.calledWith('reassign')).to.be.true; + } + }); }); + }); describe('#refreshConfigs()', function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/test/models/operating_system_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/models/operating_system_test.js b/ambari-web/test/models/operating_system_test.js new file mode 100644 index 0000000..097c0ca --- /dev/null +++ b/ambari-web/test/models/operating_system_test.js @@ -0,0 +1,42 @@ +/** + * 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. + */ + +var App = require('app'); + +require('models/operating_system'); + +describe('App.OperatingSystem', function () { + + var os; + + beforeEach(function () { + os = App.OperatingSystem.createRecord(); + }); + + describe('#isDeselected', function () { + + it('should be opposite to isSelected', function () { + os.set('isSelected', true); + expect(os.get('isDeselected')).to.be.false; + os.set('isSelected', false); + expect(os.get('isDeselected')).to.be.true; + }); + + }); + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/d8724c07/ambari-web/test/views/main/host_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/host_test.js b/ambari-web/test/views/main/host_test.js index b438b60..4f9766a 100644 --- a/ambari-web/test/views/main/host_test.js +++ b/ambari-web/test/views/main/host_test.js @@ -120,17 +120,8 @@ describe('App.MainHostView', function () { describe('#displayComponents', function () { - beforeEach(function () { - sinon.stub(App, 'showHostsTableListPopup', Em.K); - }); - - afterEach(function () { - App.showHostsTableListPopup.restore(); - }); - - it('should display host components in modal popup', function () { - hostView.set('content', { - hostName: 'h', + var cases = [ + { hostComponents: [ { displayName: 'c0' @@ -138,16 +129,16 @@ describe('App.MainHostView', function () { { displayName: 'c1' } - ] - }); - hostView.displayComponents(); - expect(App.showHostsTableListPopup.calledOnce).to.be.true; - expect(App.showHostsTableListPopup.calledWith(Em.I18n.t('common.components'), 'h', ['c0', 'c1'])).to.be.true; - }); - - }); - - describe('#displayVersions', function () { + ], + showHostsTableListPopupCallCount: 1, + title: 'should display host components in modal popup' + }, + { + hostComponents: [], + showHostsTableListPopupCallCount: 0, + title: 'should not display modal popup' + } + ]; beforeEach(function () { sinon.stub(App, 'showHostsTableListPopup', Em.K); @@ -157,9 +148,26 @@ describe('App.MainHostView', function () { App.showHostsTableListPopup.restore(); }); - it('should display stack versions in modal popup', function () { - hostView.set('content', { - hostName: 'h', + cases.forEach(function (item) { + it(item.title, function () { + hostView.set('content', { + hostName: 'h', + hostComponents: item.hostComponents + }); + hostView.displayComponents(); + expect(App.showHostsTableListPopup.callCount).to.equal(item.showHostsTableListPopupCallCount); + if (item.showHostsTableListPopupCallCount) { + expect(App.showHostsTableListPopup.calledWith(Em.I18n.t('common.components'), 'h', ['c0', 'c1'])).to.be.true; + } + }); + }); + + }); + + describe('#displayVersions', function () { + + var cases = [ + { stackVersions: [ Em.Object.create({ displayName: 'v0', @@ -176,20 +184,73 @@ describe('App.MainHostView', function () { status: 'INSTALL_FAILED', isVisible: false }) - ] - }); - hostView.displayVersions(); - expect(App.showHostsTableListPopup.calledOnce).to.be.true; - expect(App.showHostsTableListPopup.calledWith(Em.I18n.t('common.versions'), 'h', [ - { - name: 'v0', - status: 'Current' - }, - { - name: 'v1', - status: 'Out Of Sync' + ], + showHostsTableListPopupCallCount: 1, + title: 'should display stack versions in modal popup' + }, + { + stackVersions: [ + Em.Object.create({ + displayName: 'v0', + status: 'CURRENT', + isVisible: true + }), + Em.Object.create({ + displayName: 'v2', + status: 'INSTALL_FAILED', + isVisible: false + }) + ], + showHostsTableListPopupCallCount: 0, + title: 'should not display modal popup if there\'s only one visible stack version' + }, + { + stackVersions: [ + Em.Object.create({ + displayName: 'v2', + status: 'INSTALL_FAILED', + isVisible: false + }) + ], + showHostsTableListPopupCallCount: 0, + title: 'should not display modal popup if there are no visible stack versions available' + }, + { + stackVersions: [], + showHostsTableListPopupCallCount: 0, + title: 'should not display modal popup if there are no stack versions available' + } + ]; + + beforeEach(function () { + sinon.stub(App, 'showHostsTableListPopup', Em.K); + }); + + afterEach(function () { + App.showHostsTableListPopup.restore(); + }); + + cases.forEach(function (item) { + it('should display stack versions in modal popup', function () { + hostView.set('content', { + hostName: 'h', + stackVersions: item.stackVersions + }); + hostView.displayVersions(); + expect(App.showHostsTableListPopup.callCount).to.equal(item.showHostsTableListPopupCallCount); + if (item.showHostsTableListPopupCallCount) { + expect(App.showHostsTableListPopup.calledWith(Em.I18n.t('common.versions'), 'h', [ + { + name: 'v0', + status: 'Current' + }, + { + name: 'v1', + status: 'Out Of Sync' + } + ])).to.be.true; } - ])).to.be.true; + }); }); });
