AMBARI-16983. Installer/ASW: Next and Back button should be disabled once its clicked (onechiporenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fb69fb6f Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fb69fb6f Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fb69fb6f Branch: refs/heads/branch-2.4 Commit: fb69fb6f1b5435ef00ea3f2216b89e13c1aae167 Parents: 3148759 Author: Oleg Nechiporenko <onechipore...@apache.org> Authored: Wed Jun 1 15:05:59 2016 +0300 Committer: Oleg Nechiporenko <onechipore...@apache.org> Committed: Thu Jun 2 09:49:32 2016 +0300 ---------------------------------------------------------------------- ambari-web/app/controllers/wizard.js | 2 +- .../app/controllers/wizard/step0_controller.js | 5 + .../app/controllers/wizard/step2_controller.js | 2 +- .../app/controllers/wizard/step3_controller.js | 22 ++- .../app/controllers/wizard/step4_controller.js | 7 +- .../app/controllers/wizard/step5_controller.js | 10 +- .../app/controllers/wizard/step6_controller.js | 19 +-- .../app/controllers/wizard/step7_controller.js | 71 +++++----- .../app/controllers/wizard/step9_controller.js | 2 +- .../mixins/wizard/assign_master_components.js | 29 ++-- ambari-web/app/router.js | 129 ++++++++++++++++-- ambari-web/app/routes/add_host_routes.js | 22 +-- ambari-web/app/routes/add_service_routes.js | 86 ++++++------ ambari-web/app/routes/installer.js | 76 ++++++----- .../common/assign_master_components.hbs | 14 +- .../app/templates/main/host/addHost/step4.hbs | 14 +- ambari-web/app/templates/wizard/step0.hbs | 7 +- ambari-web/app/templates/wizard/step1.hbs | 14 +- ambari-web/app/templates/wizard/step10.hbs | 7 +- ambari-web/app/templates/wizard/step2.hbs | 13 +- ambari-web/app/templates/wizard/step3.hbs | 14 +- ambari-web/app/templates/wizard/step4.hbs | 14 +- ambari-web/app/templates/wizard/step6.hbs | 17 ++- ambari-web/app/templates/wizard/step7.hbs | 18 ++- ambari-web/app/templates/wizard/step8.hbs | 20 ++- ambari-web/app/templates/wizard/step9.hbs | 8 +- ambari-web/app/views/wizard/step1_view.js | 2 +- ambari-web/app/views/wizard/step4_view.js | 5 +- ambari-web/app/views/wizard/step7_view.js | 5 +- .../test/controllers/wizard/step0_test.js | 4 +- .../test/controllers/wizard/step2_test.js | 2 +- .../test/controllers/wizard/step3_test.js | 17 +-- .../test/controllers/wizard/step4_test.js | 21 --- .../test/controllers/wizard/step5_test.js | 17 +-- .../test/controllers/wizard/step7_test.js | 4 +- ambari-web/test/router_test.js | 135 ++++++++++++++++--- ambari-web/test/views/wizard/step1_view_test.js | 2 +- ambari-web/test/views/wizard/step4_view_test.js | 21 --- ambari-web/test/views/wizard/step7_view_test.js | 23 ---- 39 files changed, 553 insertions(+), 347 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js index d5e946c..41837d2 100644 --- a/ambari-web/app/controllers/wizard.js +++ b/ambari-web/app/controllers/wizard.js @@ -60,7 +60,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM connectOutlet:function(name) { if (name !== 'loading') this.set('isStepDisabled.isLocked', false); App.router.setProperties({ - transitionInProgress: false, + backBtnClickInProgress: false, nextBtnClickInProgress: false }); return this._super.apply(this,arguments); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard/step0_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step0_controller.js b/ambari-web/app/controllers/wizard/step0_controller.js index b816bd0..1ddb4fc 100644 --- a/ambari-web/app/controllers/wizard/step0_controller.js +++ b/ambari-web/app/controllers/wizard/step0_controller.js @@ -65,6 +65,11 @@ App.WizardStep0Controller = Em.Controller.extend({ }, /** + * @type {boolean} + */ + isSubmitDisabled: Em.computed.or('invalidClusterName', 'App.router.btnClickInProgress'), + + /** * Onclick handler for <code>next</code> button * Disable 'Next' button while it is already under process. (using Router's property 'nextBtnClickInProgress') * @method submit http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard/step2_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step2_controller.js b/ambari-web/app/controllers/wizard/step2_controller.js index 1ed3f69..7bbb2dd 100644 --- a/ambari-web/app/controllers/wizard/step2_controller.js +++ b/ambari-web/app/controllers/wizard/step2_controller.js @@ -167,7 +167,7 @@ App.WizardStep2Controller = Em.Controller.extend({ * is Submit button disabled * @type {bool} */ - isSubmitDisabled: Em.computed.or('hostsError', 'sshKeyError', 'sshUserError', 'sshPortError', 'agentUserError'), + isSubmitDisabled: Em.computed.or('hostsError', 'sshKeyError', 'sshUserError', 'sshPortError', 'agentUserError', 'App.router.btnClickInProgress'), installedHostNames: function () { var installedHostsName = []; http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard/step3_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step3_controller.js b/ambari-web/app/controllers/wizard/step3_controller.js index e8108ef..03912ed 100644 --- a/ambari-web/app/controllers/wizard/step3_controller.js +++ b/ambari-web/app/controllers/wizard/step3_controller.js @@ -113,7 +113,7 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { * @return {bool} */ isBackDisabled: function () { - return (this.get('isRegistrationInProgress') || !this.get('isWarningsLoaded')) && !this.get('isBootstrapFailed'); + return (this.get('isRegistrationInProgress') || !this.get('isWarningsLoaded')) && !this.get('isBootstrapFailed') || App.get('router.btnClickInProgress'); }.property('isRegistrationInProgress', 'isWarningsLoaded', 'isBootstrapFailed'), /** @@ -1660,33 +1660,31 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { } }, + _submitProceed: function () { + this.set('confirmedHosts', this.get('bootHosts')); + App.get('router').send('next'); + }, + /** * Submit-click handler * Disable 'Next' button while it is already under process. (using Router's property 'nextBtnClickInProgress') - * @return {App.ModalPopup|null} + * @return {App.ModalPopup?} * @method submit */ submit: function () { var self = this; - if(App.get('router.nextBtnClickInProgress')){ + if(App.get('router.nextBtnClickInProgress')) { return; } if (this.get('isHostHaveWarnings')) { return App.showConfirmationPopup( function () { - self.set('confirmedHosts', self.get('bootHosts')); - App.set('router.nextBtnClickInProgress', true); - App.get('router').send('next'); + self._submitProceed(); }, Em.I18n.t('installer.step3.hostWarningsPopup.hostHasWarnings')); } - else { - this.set('confirmedHosts', this.get('bootHosts')); - App.set('router.nextBtnClickInProgress', true); - App.get('router').send('next'); - } - return null; + this._submitProceed(); }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard/step4_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step4_controller.js b/ambari-web/app/controllers/wizard/step4_controller.js index 3513a1a..04e6784 100644 --- a/ambari-web/app/controllers/wizard/step4_controller.js +++ b/ambari-web/app/controllers/wizard/step4_controller.js @@ -47,8 +47,8 @@ App.WizardStep4Controller = Em.ArrayController.extend({ * @type {bool} */ isSubmitDisabled: function () { - return this.filterProperty('isSelected', true).filterProperty('isInstalled', false).length === 0; - }.property("@each.isSelected"), + return this.filterProperty('isSelected', true).filterProperty('isInstalled', false).length === 0 || App.get('router.btnClickInProgress'); + }.property('@each.isSelected', 'App.router.btnClickInProgress'), /** * List of validation errors. Look to #createError method for information @@ -137,14 +137,13 @@ App.WizardStep4Controller = Em.ArrayController.extend({ * @method submit */ submit: function () { - if(App.get('router.nextBtnClickInProgress')){ + if(App.get('router.nextBtnClickInProgress')) { return; } if (!this.get('isSubmitDisabled')) { this.unSelectServices(); this.setGroupedServices(); if (this.validate()) { - App.set('router.nextBtnClickInProgress', true); this.set('errorStack', []); App.router.send('next'); } http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard/step5_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step5_controller.js b/ambari-web/app/controllers/wizard/step5_controller.js index f800d09..5597165 100644 --- a/ambari-web/app/controllers/wizard/step5_controller.js +++ b/ambari-web/app/controllers/wizard/step5_controller.js @@ -20,5 +20,13 @@ var App = require('app'); App.WizardStep5Controller = Em.Controller.extend(App.BlueprintMixin, App.AssignMasterComponents, { - name: "wizardStep5Controller" + name: "wizardStep5Controller", + + _goNextStepIfValid: function () { + App.set('router.nextBtnClickInProgress', false); + if (!this.get('submitDisabled')) { + App.router.send('next'); + } + }, + }); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard/step6_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step6_controller.js b/ambari-web/app/controllers/wizard/step6_controller.js index 9e1dce9..e1d3953 100644 --- a/ambari-web/app/controllers/wizard/step6_controller.js +++ b/ambari-web/app/controllers/wizard/step6_controller.js @@ -69,7 +69,7 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { * Define state for submit button * @type {bool} */ - submitDisabled: Em.computed.alias('validationInProgress'), + submitDisabled: Em.computed.or('validationInProgress', 'App.router.btnClickInProgress'), /** * timer for validation request @@ -144,7 +144,7 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { anyGeneralIssues: Em.computed.or('anyGeneralErrors', 'anyGeneralWarnings'), anyHostErrors: function () { - return this.get('hosts').some(function(h) { return h.errorMessages ? (h.errorMessages.length > 0) : false;}); + return this.get('hosts').some(function(h) { return h.errorMessages ? h.errorMessages.length > 0 : false;}); }.property('hosts.@each.errorMessages'), /** @@ -153,7 +153,7 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { anyErrors: Em.computed.or('anyGeneralErrors', 'anyHostErrors'), anyHostWarnings: function () { - return this.get('hosts').some(function(h) { return h.warnMessages ? (h.warnMessages.length > 0) : false;}); + return this.get('hosts').some(function(h) { return h.warnMessages ? h.warnMessages.length > 0 : false;}); }.property('hosts.@each.warnMessages'), /** @@ -631,7 +631,7 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { }). then(function () { self.set('validationInProgress', false); - if (!self.get('submitDisabled') && successCallback) { + if (App.get('router.btnClickInProgress') && successCallback) { successCallback(); } } @@ -645,7 +645,6 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { */ updateValidationsSuccessCallback: function (data) { var self = this; - //data = JSON.parse(data); // temporary fix var clientComponents = App.get('components.clients'); @@ -658,7 +657,6 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { host.checkboxes.setEach('hasWarnMessage', false); host.checkboxes.setEach('hasErrorMessage', false); }); - var anyErrors = false; var anyGeneralClientErrors = false; // any error/warning for any client component (under "CLIENT" alias) var validationData = validationUtils.filterNotInstalledComponents(data); @@ -673,16 +671,14 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { if (checkbox.component === item['component-name'] || isClientComponent) { checkboxWithIssue = checkbox; return true; - } else { - return false; } + return false; }); }); if (host) { Em.set(host, 'anyMessage', true); if (item.level === 'ERROR') { - anyErrors = true; host.errorMessages.pushObject(item.message); Em.set(checkboxWithIssue, 'hasErrorMessage', true); } @@ -711,7 +707,6 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { } if (item.level === 'ERROR') { - anyErrors = true; self.get('generalErrorMessages').push(item.message + details); } else @@ -721,10 +716,6 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { } } }); - - // use this.set('submitDisabled', anyErrors); is validation results should block next button - // It's because showValidationIssuesAcceptBox allow use accept validation issues and continue - // this.set('submitDisabled', false); }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard/step7_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js index 57a993f..5b28cfa 100644 --- a/ambari-web/app/controllers/wizard/step7_controller.js +++ b/ambari-web/app/controllers/wizard/step7_controller.js @@ -143,8 +143,9 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E isSubmitDisabled: function () { if (!this.get('stepConfigs.length')) return true; if (this.get('submitButtonClicked')) return true; + if (App.get('router.btnClickInProgress')) return true; return !this.get('stepConfigs').filterProperty('showConfig', true).everyProperty('errorCount', 0) || this.get("miscModalVisible"); - }.property('stepConfigs.@each.errorCount', 'miscModalVisible', 'submitButtonClicked'), + }.property('stepConfigs.@each.errorCount', 'miscModalVisible', 'submitButtonClicked', 'App.router.btnClickInProgress'), /** * List of selected to install service names @@ -250,15 +251,20 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E Em.I18n.t('installer.step7.showingPropertiesWithIssues') : ''; }.property('isSubmitDisabled', 'submitButtonClicked', 'filterColumns.@each.selected'), + /** + * @type {string} + */ issuesFilterLinkText: function () { - if (this.get('filterColumns').findProperty('attributeName', 'hasIssues').get('selected')) { + var issuesAttrSelected = this.get('filterColumns').findProperty('attributeName', 'hasIssues').get('selected'); + if (issuesAttrSelected) { return Em.I18n.t('installer.step7.showAllProperties'); } - return this.get('isSubmitDisabled') && !this.get('submitButtonClicked') ? - this.get('filterColumns').findProperty('attributeName', 'hasIssues').get('selected') ? - Em.I18n.t('installer.step7.showAllProperties') : Em.I18n.t('installer.step7.showPropertiesWithIssues') - : ''; + if (this.get('isSubmitDisabled') && !this.get('submitButtonClicked')) { + return issuesAttrSelected ? + Em.I18n.t('installer.step7.showAllProperties') : Em.I18n.t('installer.step7.showPropertiesWithIssues'); + } + return ''; }.property('isSubmitDisabled', 'submitButtonClicked', 'filterColumns.@each.selected'), /** @@ -281,7 +287,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E * <li>stepConfigs</li> * <li>filter</li> * </ul> - * and desect all <code>filterColumns</code> + * and deselect all <code>filterColumns</code> * @method clearStep */ clearStep: function () { @@ -353,7 +359,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E serviceConfigs = stepConfig.get('configs'), configGroup = App.ServiceConfigGroup.find().filterProperty('serviceName', group.service_name).findProperty('name', group.group_name); - var isEditable = self.get('canEdit') && configGroup.get('name') == stepConfig.get('selectedConfigGroup.name'); + var isEditable = self.get('canEdit') && configGroup.get('name') === stepConfig.get('selectedConfigGroup.name'); group.configurations.forEach(function (config) { for (var prop in config.properties) { @@ -464,7 +470,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E var storedConfigs = this.get('content.serviceConfigProperties'); - var configs = (storedConfigs && storedConfigs.length) ? storedConfigs : App.configsCollection.getAll(); + var configs = storedConfigs && storedConfigs.length ? storedConfigs : App.configsCollection.getAll(); this.set('groupsToDelete', this.get('wizardController').getDBProperty('groupsToDelete') || []); if (this.get('wizardController.name') === 'addServiceController' && !this.get('content.serviceConfigProperties.length')) { @@ -974,19 +980,17 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E if (Em.isNone(mappedConfigValue)) { //for now ranger plugin properties are not sending by recommendations if they are missed - it should be added return _config.serviceName === 'MISC' || /^ranger-/.test(_config.filename); - } else { - if (_config.savedValue != mappedConfigValue) { - _config.savedValue = App.config.formatPropertyValue(_config, mappedConfigValue); - } - _config.value = App.config.formatPropertyValue(_config, mappedConfigValue); - _config.hasInitialValue = true; - this.updateDependencies(_config); - delete configsMap[type][_config.name]; - return true; } - } else { + if (_config.savedValue != mappedConfigValue) { + _config.savedValue = App.config.formatPropertyValue(_config, mappedConfigValue); + } + _config.value = App.config.formatPropertyValue(_config, mappedConfigValue); + _config.hasInitialValue = true; + this.updateDependencies(_config); + delete configsMap[type][_config.name]; return true; } + return true; }, this); //add user properties Em.keys(configsMap).forEach(function (filename) { @@ -1007,10 +1011,14 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E * @param config */ updateDependencies: function(config) { - if (config.name === 'hive.metastore.uris' && config.filename === 'hive-site.xml') { - this.get('configDependencies')['hive.metastore.uris'] = config.savedValue; - } else if (config.name === 'clientPort' && config.filename === 'hive-site.xml') { - this.get('configDependencies').clientPort = config.savedValue; + if (config.filename === 'hive-site.xml') { + if (config.name === 'hive.metastore.uris') { + this.get('configDependencies')['hive.metastore.uris'] = config.savedValue; + } + else + if (config.name === 'clientPort') { + this.get('configDependencies').clientPort = config.savedValue; + } } }, @@ -1050,7 +1058,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E this.set('configGroups', serviceGroups); this.set('selectedConfigGroup', serviceGroups.findProperty('isDefault')); } - }.observes('selectedService.configGroups.@each'), + }.observes('selectedService.configGroups.[]'), /** * load default groups for each service in case of initial load @@ -1301,12 +1309,11 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E * that using MySql database too. * * @method resolveHiveMysqlDatabase - **/ + */ resolveHiveMysqlDatabase: function () { var hiveService = this.get('content.services').findProperty('serviceName', 'HIVE'); if (!hiveService || !hiveService.get('isSelected') || hiveService.get('isInstalled')) { - this.moveNext(); - return; + return this.moveNext(); } var hiveDBType = this.get('stepConfigs').findProperty('serviceName', 'HIVE').configs.findProperty('name', 'hive_database').value; if (hiveDBType === 'New MySQL Database') { @@ -1315,9 +1322,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E self.mySQLWarningHandler(); }); } - else { - this.moveNext(); - } + return this.moveNext(); }, /** @@ -1366,9 +1371,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E } }); } - else { - return this.moveNext(); - } + return this.moveNext(); }, checkDatabaseConnectionTest: function () { @@ -1490,7 +1493,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E * Proceed to the next step **/ moveNext: function () { - App.set('router.nextBtnClickInProgress', true); + App.set('router.nextBtnClickInProgress', false); App.router.send('next'); this.set('submitButtonClicked', false); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/controllers/wizard/step9_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step9_controller.js b/ambari-web/app/controllers/wizard/step9_controller.js index 916f9dc..015cb84 100644 --- a/ambari-web/app/controllers/wizard/step9_controller.js +++ b/ambari-web/app/controllers/wizard/step9_controller.js @@ -111,7 +111,7 @@ App.WizardStep9Controller = Em.Controller.extend(App.ReloadPopupMixin, { if (controllerName == 'addHostController' || controllerName == 'addServiceController') { validStates.push('INSTALL FAILED'); } - return !validStates.contains(this.get('content.cluster.status')); + return !validStates.contains(this.get('content.cluster.status')) || App.get('router.btnClickInProgress'); }.property('content.cluster.status'), /** http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/mixins/wizard/assign_master_components.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/wizard/assign_master_components.js b/ambari-web/app/mixins/wizard/assign_master_components.js index 0e4a23d..a8b0caf 100644 --- a/ambari-web/app/mixins/wizard/assign_master_components.js +++ b/ambari-web/app/mixins/wizard/assign_master_components.js @@ -1144,6 +1144,14 @@ App.AssignMasterComponents = Em.Mixin.create({ }, true); }, + _goNextStepIfValid: function () { + if (!this.get('submitDisabled')) { + App.router.send('next'); + }else{ + App.set('router.nextBtnClickInProgress', false); + } + }, + /** * Submit button click handler * Disable 'Next' button while it is already under process. (using Router's property 'nextBtnClickInProgress') @@ -1154,26 +1162,19 @@ App.AssignMasterComponents = Em.Mixin.create({ if (this.get('submitDisabled')) { return; } - if (!this.get('submitButtonClicked') && !App.router.get('nextBtnClickInProgress')) { + if (!this.get('submitButtonClicked') && !App.get('router.nextBtnClickInProgress')) { this.set('submitButtonClicked', true); App.router.set('nextBtnClickInProgress', true); - var goNextStepIfValid = function () { - if (!self.get('submitDisabled')) { - App.router.send('next'); - }else{ - App.router.set('nextBtnClickInProgress', false); - } - }; - if (this.get('useServerValidation')) { self.recommendAndValidate(function () { - self.showValidationIssuesAcceptBox(goNextStepIfValid); + self.showValidationIssuesAcceptBox(self._goNextStepIfValid.bind(self)); }); - } else { - self.updateIsSubmitDisabled(); - goNextStepIfValid(); - self.set('submitButtonClicked', false); + } + else { + this.updateIsSubmitDisabled(); + this._goNextStepIfValid(); + this.set('submitButtonClicked', false); } } }, http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/router.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/router.js b/ambari-web/app/router.js index b7ba2cb..d3caf6a 100644 --- a/ambari-web/app/router.js +++ b/ambari-web/app/router.js @@ -44,20 +44,127 @@ App.WizardRoute = Em.Route.extend({ gotoStep10: Em.Router.transitionTo('step10'), isRoutable: function() { - return (typeof this.get('route') === 'string' && App.router.get('loggedIn')); + return typeof this.get('route') === 'string' && App.router.get('loggedIn'); }.property('App.router.loggedIn') }); +/** + * This route executes "back" and "next" handler on the next run-loop + * Reason: It's done like this, because in general transitions have highest priority in the Ember run-loop + * So, CP's and observers for <code>App.router.backBtnClickInProgress</code> and <code>App.router.nextBtnClickInProgress</code> + * will be triggered after "back" or "next" are complete and not before them. + * It's more important for "back", because usually it doesn't do any requests that may cause a little delay for run loops + * <code>Em.run.next</code> is used to avoid this + * + * Example: + * <pre> + * App.Step2Route = App.StepRoute.extend({ + * + * route: '/step2', + * + * connectOutlets: function (router, context) { + * // some code + * }, + * + * nextTransition: function (router) { + * router.transitionTo('step3'); + * }, + * + * backTransition: function (router) { + * router.transitionTo('step1'); + * } + * + * }); + * </pre> + * In this case both <code>transitionTo</code> will be executed in the next run loop after loop where "next" or "back" were called + * <b>IMPORTANT!</b> Flags <code>App.router.backBtnClickInProgress</code> and <code>App.router.nextBtnClickInProgress</code> are set to <code>true</code> + * in the "back" and "next". Be sure to set them <code>false</code> when needed + * + * @type {Em.Route} + */ +App.StepRoute = Em.Route.extend({ + + /** + * @type {Function} + */ + backTransition: Em.K, + + /** + * @type {Function} + */ + nextTransition: Em.K, + + /** + * Default "Back"-action + * Execute <code>backTransition</code> once + * + * @param {Em.Router} router + */ + back: function (router) { + if (App.get('router.btnClickInProgress')) { + return; + } + App.set('router.backBtnClickInProgress', true); + var self = this; + Em.run.next(function () { + Em.tryInvoke(self, 'backTransition', [router]); + }) + }, + + /** + * Default "Next"-action + * Execute <code>nextTransition</code> once + * + * @param {Em.Router} router + */ + next: function (router) { + if (App.get('router.btnClickInProgress')) { + return; + } + App.set('router.nextBtnClickInProgress', true); + var self = this; + Em.run.next(function () { + Em.tryInvoke(self, 'nextTransition', [router]); + }) + } + +}); + App.Router = Em.Router.extend({ enableLogging: true, isFwdNavigation: true, backBtnForHigherStep: false, - transitionInProgress: false, + + /** + * Checks if Back button is clicked + * Set to default value on the <code>App.WizardController.connectOutlet</code> + * + * @type {boolean} + * @default false + */ + backBtnClickInProgress: false, + + /** + * Checks if Next button is clicked + * Set to default value on the <code>App.WizardController.connectOutlet</code> + * + * @type {boolean} + * @default false + */ nextBtnClickInProgress: false, /** + * Checks if Next or Back button is clicked + * Used in the <code>App.StepRoute</code>-instances to avoid "next"/"back" double-clicks + * + * @type {boolean} + * @default false + */ + btnClickInProgress: Em.computed.or('backBtnClickInProgress', 'nextBtnClickInProgress'), + + /** * Path for local login page. This page will be always accessible without * redirect to auth server different from ambari-server. Used in some types of * authorizations like knox sso. @@ -90,9 +197,9 @@ App.Router = Em.Router.extend({ var matches = step.match(/\d+$/); var newStep; if (matches) { - newStep = parseInt(matches[0]); + newStep = parseInt(matches[0], 10); } - var previousStep = parseInt(this.getInstallerCurrentStep()); + var previousStep = parseInt(this.getInstallerCurrentStep(), 10); this.set('isFwdNavigation', newStep >= previousStep); }, @@ -399,10 +506,9 @@ App.Router = Em.Router.extend({ this.hide(); } }); - }else{ - this.setClusterData(data, opt, params); - return false; } + this.setClusterData(data, opt, params); + return false; }, /** @@ -548,13 +654,13 @@ App.Router = Em.Router.extend({ var clusterStatusOnServer = App.clusterStatus.get('value'); if (clusterStatusOnServer) { var wizardControllerRoutes = require('data/controller_route'); - var wizardControllerRoute = wizardControllerRoutes.findProperty('wizardControllerName', clusterStatusOnServer.wizardControllerName); + var wizardControllerRoute = wizardControllerRoutes.findProperty('wizardControllerName', clusterStatusOnServer.wizardControllerName); if (wizardControllerRoute && !App.router.get('wizardWatcherController').get('isNonWizardUser')) { route = wizardControllerRoute.route; } } - if (wizardControllerRoute && wizardControllerRoute.wizardControllerName === 'mainAdminStackAndUpgradeController') { - var clusterController = App.router.get('clusterController'); + if (wizardControllerRoute && wizardControllerRoute.wizardControllerName === 'mainAdminStackAndUpgradeController') { + var clusterController = App.router.get('clusterController'); clusterController.loadClusterName().done(function(){ clusterController.restoreUpgradeState().done(function(){ callback(route); @@ -699,8 +805,9 @@ App.Router = Em.Router.extend({ initAuth: function(){ if (App.db) { var auth = App.db.getAuth(); - if(auth) + if(auth) { App.set('auth', auth); + } } }, http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/routes/add_host_routes.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/add_host_routes.js b/ambari-web/app/routes/add_host_routes.js index ba290cd..c733a66 100644 --- a/ambari-web/app/routes/add_host_routes.js +++ b/ambari-web/app/routes/add_host_routes.js @@ -92,7 +92,7 @@ module.exports = App.WizardRoute.extend({ }, - step1: Em.Route.extend({ + step1: App.StepRoute.extend({ route: '/step1', connectOutlets: function (router) { var controller = router.get('addHostController'); @@ -106,7 +106,7 @@ module.exports = App.WizardRoute.extend({ }); }, - next: function (router) { + nextTransition: function (router) { var controller = router.get('addHostController'); controller.save('installOptions'); //hosts was saved to content.hosts inside wizardStep2Controller @@ -126,7 +126,7 @@ module.exports = App.WizardRoute.extend({ } }), - step2: Em.Route.extend({ + step2: App.StepRoute.extend({ route: '/step2', connectOutlets: function (router) { var controller = router.get('addHostController'); @@ -138,13 +138,13 @@ module.exports = App.WizardRoute.extend({ controller.connectOutlet('wizardStep3', controller.get('content')); }); }, - back: function (router) { + backTransition: function (router) { router.transitionTo('step1'); }, exit: function (router) { router.get('wizardStep3Controller').set('stopBootstrap', true); }, - next: function (router, context) { + nextTransition: function (router, context) { var addHostController = router.get('addHostController'); var wizardStep3Controller = router.get('wizardStep3Controller'); var wizardStep6Controller = router.get('wizardStep6Controller'); @@ -170,7 +170,7 @@ module.exports = App.WizardRoute.extend({ } }), - step3: Em.Route.extend({ + step3: App.StepRoute.extend({ route: '/step3', connectOutlets: function (router, context) { var controller = router.get('addHostController'); @@ -182,7 +182,9 @@ module.exports = App.WizardRoute.extend({ controller.connectOutlet('wizardStep6', controller.get('content')); }); }, - back: Em.Router.transitionTo('step2'), + backTransition: function (router) { + router.transitionTo('step2'); + }, next: function (router) { App.set('router.nextBtnClickInProgress', true); var addHostController = router.get('addHostController'); @@ -205,7 +207,7 @@ module.exports = App.WizardRoute.extend({ } }), - step4: Em.Route.extend({ + step4: App.StepRoute.extend({ route: '/step4', connectOutlets: function (router, context) { var controller = router.get('addHostController'); @@ -222,10 +224,10 @@ module.exports = App.WizardRoute.extend({ }); }); }, - back: function (router) { + backTransition: function (router) { router.transitionTo('step3'); }, - next: function (router) { + nextTransition: function (router) { var addHostController = router.get('addHostController'); addHostController.saveServiceConfigGroups(); router.transitionTo('step5'); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/routes/add_service_routes.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/add_service_routes.js b/ambari-web/app/routes/add_service_routes.js index 0a20ccf..4a5f565 100644 --- a/ambari-web/app/routes/add_service_routes.js +++ b/ambari-web/app/routes/add_service_routes.js @@ -91,7 +91,7 @@ module.exports = App.WizardRoute.extend({ }, - step1: Em.Route.extend({ + step1: App.StepRoute.extend({ route: '/step1', connectOutlets: function (router) { var controller = router.get('addServiceController'); @@ -112,7 +112,7 @@ module.exports = App.WizardRoute.extend({ }); }); }, - next: function (router) { + nextTransition: function (router) { var addServiceController = router.get('addServiceController'); var wizardStep4Controller = router.get('wizardStep4Controller'); addServiceController.saveServices(wizardStep4Controller); @@ -127,7 +127,7 @@ module.exports = App.WizardRoute.extend({ } }), - step2: Em.Route.extend({ + step2: App.StepRoute.extend({ route: '/step2', connectOutlets: function (router) { var controller = router.get('addServiceController'); @@ -142,7 +142,11 @@ module.exports = App.WizardRoute.extend({ }); }, - back: Em.Router.transitionTo('step1'), + + backTransition: function (router) { + router.transitionTo('step1'); + }, + next: function (router) { var addServiceController = router.get('addServiceController'); var wizardStep5Controller = router.get('wizardStep5Controller'); @@ -155,7 +159,7 @@ module.exports = App.WizardRoute.extend({ } }), - step3: Em.Route.extend({ + step3: App.StepRoute.extend({ route: '/step3', connectOutlets: function (router) { var controller = router.get('addServiceController'); @@ -168,14 +172,15 @@ module.exports = App.WizardRoute.extend({ }); }); }, - back: function (router) { + + backTransition: function (router) { var controller = router.get('addServiceController'); if (!controller.get('content.skipMasterStep')) { - router.transitionTo('step2'); - } else { - router.transitionTo('step1'); + return router.transitionTo('step2'); } + return router.transitionTo('step1'); }, + next: function (router) { App.set('router.nextBtnClickInProgress', true); var addServiceController = router.get('addServiceController'); @@ -194,14 +199,13 @@ module.exports = App.WizardRoute.extend({ router.get('wizardStep7Controller').set('recommendationsConfigs', null); router.get('wizardStep7Controller').clearAllRecommendations(); addServiceController.setDBProperty('serviceConfigGroups', undefined); - App.set('router.nextBtnClickInProgress', false); router.transitionTo('step4'); }); }); } }), - step4: Em.Route.extend({ + step4: App.StepRoute.extend({ route: '/step4', connectOutlets: function (router) { var controller = router.get('addServiceController'); @@ -221,15 +225,16 @@ module.exports = App.WizardRoute.extend({ }); }); }, - back: function (router) { + + backTransition: function (router) { var controller = router.get('addServiceController'); if (!controller.get('content.skipSlavesStep')) { - router.transitionTo('step3'); - } else if (!controller.get('content.skipMasterStep')) { - router.transitionTo('step2'); - } else { - router.transitionTo('step1'); + return router.transitionTo('step3'); } + if (!controller.get('content.skipMasterStep')) { + return router.transitionTo('step2'); + } + return router.transitionTo('step1'); }, next: function (router) { var addServiceController = router.get('addServiceController'); @@ -261,21 +266,15 @@ module.exports = App.WizardRoute.extend({ back: function (router) { var controller = router.get('addServiceController'); if (!controller.get('content.skipConfigStep')) { - router.transitionTo('step4'); + return router.transitionTo('step4'); } - else { - if (!controller.get('content.skipSlavesStep')) { - router.transitionTo('step3'); - } - else { - if (!controller.get('content.skipMasterStep')) { - router.transitionTo('step2'); - } - else { - router.transitionTo('step1'); - } - } + if (!controller.get('content.skipSlavesStep')) { + return router.transitionTo('step3'); + } + if (!controller.get('content.skipMasterStep')) { + return router.transitionTo('step2'); } + return router.transitionTo('step1'); }, next: function (router) { if (App.Cluster.find().objectAt(0).get('isKerberosEnabled')) { @@ -289,7 +288,7 @@ module.exports = App.WizardRoute.extend({ } }), - step6: Em.Route.extend({ + step6: App.StepRoute.extend({ route: '/step6', connectOutlets: function (router, context) { var controller = router.get('addServiceController'); @@ -305,28 +304,21 @@ module.exports = App.WizardRoute.extend({ router.get('kerberosWizardStep5Controller').getCSVData(true); } }, - back: function (router) { + backTransition: function (router) { var controller = router.get('addServiceController'); if (App.get('isKerberosEnabled')) { - router.transitionTo('step5'); - return; + return router.transitionTo('step5'); } if (!controller.get('content.skipConfigStep')) { - router.transitionTo('step4'); + return router.transitionTo('step4'); } - else { - if (!controller.get('content.skipSlavesStep')) { - router.transitionTo('step3'); - } - else { - if (!controller.get('content.skipMasterStep')) { - router.transitionTo('step2'); - } - else { - router.transitionTo('step1'); - } - } + if (!controller.get('content.skipSlavesStep')) { + return router.transitionTo('step3'); + } + if (!controller.get('content.skipMasterStep')) { + return router.transitionTo('step2'); } + return router.transitionTo('step1'); }, next: function (router) { var addServiceController = router.get('addServiceController'); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/routes/installer.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js index 9a4534b..6aa8d8c 100644 --- a/ambari-web/app/routes/installer.js +++ b/ambari-web/app/routes/installer.js @@ -156,7 +156,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, { back: Em.Router.transitionTo('step0'), next: function (router) { console.time('step1 next'); - if(router.get('nextBtnClickInProgress') || router.transitionInProgress){ + if(router.get('btnClickInProgress')) { return; } var wizardStep1Controller = router.get('wizardStep1Controller'); @@ -164,7 +164,6 @@ module.exports = Em.Route.extend(App.RouterRedirections, { installerController.validateJDKVersion(function() { installerController.checkRepoURL(wizardStep1Controller).done(function () { App.set('router.nextBtnClickInProgress', true); - router.set('transitionInProgress', true); installerController.setDBProperty('service', undefined); installerController.setStacks(); installerController.clearInstallOptions(); @@ -191,8 +190,8 @@ module.exports = Em.Route.extend(App.RouterRedirections, { back: Em.Router.transitionTo('step1'), next: function (router) { console.time('step2 next'); - if (!router.transitionInProgress) { - router.set('transitionInProgress', true); + if (!router.get('btnClickInProgress')) { + App.set('router.nextBtnClickInProgress', true); var controller = router.get('installerController'); controller.save('installOptions'); //hosts was saved to content.hosts inside wizardStep2Controller @@ -203,7 +202,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, { } }), - step3: Em.Route.extend({ + step3: App.StepRoute.extend({ route: '/step3', connectOutlets: function (router) { console.time('step3 connectOutlets'); @@ -216,13 +215,15 @@ module.exports = Em.Route.extend(App.RouterRedirections, { console.timeEnd('step3 connectOutlets'); }); }, - back: function (router) { + + backTransition: function (router) { router.transitionTo('step2'); }, + next: function (router, context) { console.time('step3 next'); - if (!router.transitionInProgress) { - router.set('transitionInProgress', true); + if (!router.get('btnClickInProgress')) { + App.set('router.nextBtnClickInProgress', true); var installerController = router.get('installerController'); var wizardStep3Controller = router.get('wizardStep3Controller'); installerController.saveConfirmedHosts(wizardStep3Controller); @@ -250,7 +251,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, { } }), - step4: Em.Route.extend({ + step4: App.StepRoute.extend({ route: '/step4', connectOutlets: function (router, context) { console.time('step4 connectOutlets'); @@ -264,12 +265,15 @@ module.exports = Em.Route.extend(App.RouterRedirections, { console.timeEnd('step4 connectOutlets'); }); }, - back: Em.Router.transitionTo('step3'), + + backTransition: function(router) { + router.transitionTo('step3'); + }, next: function (router) { console.time('step4 next'); - if (!router.transitionInProgress) { - router.set('transitionInProgress', true); + if (!router.get('btnClickInProgress')) { + App.set('router.nextBtnClickInProgress', true); var controller = router.get('installerController'); var wizardStep4Controller = router.get('wizardStep4Controller'); controller.saveServices(wizardStep4Controller); @@ -286,7 +290,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, { } }), - step5: Em.Route.extend({ + step5: App.StepRoute.extend({ route: '/step5', connectOutlets: function (router, context) { console.time('step5 connectOutlets'); @@ -304,11 +308,13 @@ module.exports = Em.Route.extend(App.RouterRedirections, { console.timeEnd('step5 connectOutlets'); }); }, - back: Em.Router.transitionTo('step4'), + backTransition: function(router) { + router.transitionTo('step4'); + }, next: function (router) { console.time('step5 next'); - if (!router.transitionInProgress) { - router.set('transitionInProgress', true); + if (!router.get('btnClickInProgress')) { + App.set('router.nextBtnClickInProgress', true); var controller = router.get('installerController'); var wizardStep5Controller = router.get('wizardStep5Controller'); var wizardStep6Controller = router.get('wizardStep6Controller'); @@ -324,7 +330,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, { } }), - step6: Em.Route.extend({ + step6: App.StepRoute.extend({ route: '/step6', connectOutlets: function (router, context) { console.time('step6 connectOutlets'); @@ -338,17 +344,18 @@ module.exports = Em.Route.extend(App.RouterRedirections, { console.timeEnd('step6 connectOutlets'); }); }, - back: Em.Router.transitionTo('step5'), + backTransition: function(router) { + router.transitionTo('step5'); + }, next: function (router) { console.time('step6 next'); - App.set('router.nextBtnClickInProgress', true); var controller = router.get('installerController'); var wizardStep6Controller = router.get('wizardStep6Controller'); if (!wizardStep6Controller.get('submitDisabled')) { wizardStep6Controller.showValidationIssuesAcceptBox(function () { - if (!router.transitionInProgress) { - router.set('transitionInProgress', true); + if (!router.get('btnClickInProgress')) { + App.set('router.nextBtnClickInProgress', true); controller.saveSlaveComponentHosts(wizardStep6Controller); controller.get('content').set('serviceConfigProperties', null); controller.setDBProperties({ @@ -357,7 +364,6 @@ module.exports = Em.Route.extend(App.RouterRedirections, { recommendationsHostGroups: wizardStep6Controller.get('content.recommendationsHostGroups'), recommendationsConfigs: null }); - App.set('router.nextBtnClickInProgress', false); router.transitionTo('step7'); console.timeEnd('step6 next'); } @@ -366,14 +372,16 @@ module.exports = Em.Route.extend(App.RouterRedirections, { } }), - step7: Em.Route.extend({ + step7: App.StepRoute.extend({ route: '/step7', + enter: function (router) { console.time('step7 enter'); var controller = router.get('installerController'); controller.setCurrentStep('7'); console.timeEnd('step7 enter'); }, + connectOutlets: function (router, context) { console.time('step7 connectOutlets'); var controller = router.get('installerController'); @@ -385,7 +393,8 @@ module.exports = Em.Route.extend(App.RouterRedirections, { console.timeEnd('step7 connectOutlets'); }); }, - back: function (router) { + + backTransition: function (router) { console.time('step7 back'); var step = router.get('installerController.content.skipSlavesStep') ? 'step5' : 'step6'; var wizardStep7Controller = router.get('wizardStep7Controller'); @@ -403,22 +412,20 @@ module.exports = Em.Route.extend(App.RouterRedirections, { }, next: function (router) { console.time('step7 next'); - if (!router.transitionInProgress) { - router.set('transitionInProgress', true); + if (!router.get('btnClickInProgress')) { App.set('router.nextBtnClickInProgress', true); var controller = router.get('installerController'); var wizardStep7Controller = router.get('wizardStep7Controller'); controller.saveServiceConfigProperties(wizardStep7Controller); controller.saveServiceConfigGroups(wizardStep7Controller); controller.setDBProperty('recommendationsConfigs', wizardStep7Controller.get('recommendationsConfigs')); - App.set('router.nextBtnClickInProgress', false); router.transitionTo('step8'); console.timeEnd('step7 next'); } } }), - step8: Em.Route.extend({ + step8: App.StepRoute.extend({ route: '/step8', connectOutlets: function (router, context) { console.time('step8 connectOutlets'); @@ -431,15 +438,15 @@ module.exports = Em.Route.extend(App.RouterRedirections, { console.timeEnd('step8 connectOutlets'); }); }, - back: function (router) { - if(router.get('wizardStep8Controller.isBackBtnDisabled') == false){ + backTransition: function (router) { + if(router.get('wizardStep8Controller.isBackBtnDisabled') == false) { router.transitionTo('step7'); } }, next: function (router) { console.time('step8 next'); - if (!router.transitionInProgress) { - router.set('transitionInProgress', true); + if (!router.get('btnClickInProgress')) { + App.set('router.nextBtnClickInProgress', true); var installerController = router.get('installerController'); var wizardStep8Controller = router.get('wizardStep8Controller'); // invoke API call to install selected services @@ -448,7 +455,6 @@ module.exports = Em.Route.extend(App.RouterRedirections, { // We need to do recovery based on whether we are in Add Host or Installer wizard installerController.saveClusterState('CLUSTER_INSTALLING_3'); wizardStep8Controller.set('servicesInstalled', true); - router.set('nextBtnClickInProgress', false); router.transitionTo('step9'); console.timeEnd('step8 next'); }); @@ -506,8 +512,8 @@ module.exports = Em.Route.extend(App.RouterRedirections, { }, next: function (router) { console.time('step9 next'); - if(!router.transitionInProgress) { - router.set('transitionInProgress', true); + if(!router.get('btnClickInProgress')) { + App.set('router.nextBtnClickInProgress', true); var installerController = router.get('installerController'); var wizardStep9Controller = router.get('wizardStep9Controller'); installerController.saveInstalledHosts(wizardStep9Controller); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/common/assign_master_components.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/assign_master_components.hbs b/ambari-web/app/templates/common/assign_master_components.hbs index 00a2719..fc19508 100644 --- a/ambari-web/app/templates/common/assign_master_components.hbs +++ b/ambari-web/app/templates/common/assign_master_components.hbs @@ -141,9 +141,19 @@ {{/if}} <div class="btn-area"> {{#if view.isBackButtonVisible}} - <a class="btn pull-left installer-back-btn" {{action back}}>← {{t common.back}}</a> + <button type="button" class="btn pull-left installer-back-btn" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action back}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </button> {{/if}} - <a class="btn btn-success pull-right" {{bindAttr disabled="submitDisabled"}} {{action submit target="controller"}}>{{view.acceptButtonText}}</a> + <a class="btn btn-success pull-right" {{bindAttr disabled="submitDisabled"}} {{action submit target="controller"}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{view.acceptButtonText}} + </a> {{#if view.isCancelButtonVisible}} <a class="btn pull-right mrm" {{action onCancel target="controller"}}>{{t common.cancel}}</a> {{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/main/host/addHost/step4.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/host/addHost/step4.hbs b/ambari-web/app/templates/main/host/addHost/step4.hbs index 8bad634..132d10b 100644 --- a/ambari-web/app/templates/main/host/addHost/step4.hbs +++ b/ambari-web/app/templates/main/host/addHost/step4.hbs @@ -45,7 +45,17 @@ </table> </div> <div class="btn-area"> - <a class="btn" {{action back}}>← {{t common.back}}</a> - <a class="btn btn-success pull-right" {{action next}}>{{t common.next}} →</a> + <button class="btn" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action back}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </button> + <button class="btn btn-success pull-right" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action next}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.next}} → + </button> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step0.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step0.hbs b/ambari-web/app/templates/wizard/step0.hbs index 4971969..4b1cc49 100644 --- a/ambari-web/app/templates/wizard/step0.hbs +++ b/ambari-web/app/templates/wizard/step0.hbs @@ -35,7 +35,12 @@ </div> <div class="btn-area"> - <a class="btn btn-success pull-right" {{bindAttr disabled="invalidClusterName"}} {{action "submit" target="controller"}}>{{t common.next}} →</a> + <button type="button" class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action "submit" target="controller"}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.next}} → + </button> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/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 a7636c1..72a2099 100644 --- a/ambari-web/app/templates/wizard/step1.hbs +++ b/ambari-web/app/templates/wizard/step1.hbs @@ -213,6 +213,16 @@ <a href="javascript:void(null)" {{action "retryRepoUrls" target="view"}}>{{t installer.step1.retryRepoUrls}}</a> </div> {{/if}} - <a class="btn pull-left installer-back-btn" {{action back}}>← {{t common.back}}</a> - <button class="btn btn-success pull-right" {{bindAttr disabled="view.isSubmitDisabled"}} {{action next}}>{{t common.next}} →</button> + <button type="button" class="btn pull-left installer-back-btn" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action back}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </button> + <button type="button" class="btn btn-success pull-right" {{bindAttr disabled="view.isSubmitDisabled"}} {{action next}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.next}} → + </button> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step10.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step10.hbs b/ambari-web/app/templates/wizard/step10.hbs index 6a28f05..f2caf9c 100644 --- a/ambari-web/app/templates/wizard/step10.hbs +++ b/ambari-web/app/templates/wizard/step10.hbs @@ -49,6 +49,11 @@ </ul> </div> <div class="btn-area"> - <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action complete}}>{{t common.complete}} →</a> + <button type="button" class="btn btn-success pull-right" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action complete}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.complete}} → + </button> </div> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step2.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step2.hbs b/ambari-web/app/templates/wizard/step2.hbs index 5aa4f89..790d23d 100644 --- a/ambari-web/app/templates/wizard/step2.hbs +++ b/ambari-web/app/templates/wizard/step2.hbs @@ -145,10 +145,19 @@ <div class="btn-area"> {{#unless view.parentView.controller.hideBackButton}} - <a class="btn pull-left installer-back-btn" {{action back}}>← {{t common.back}}</a> + <a class="btn pull-left installer-back-btn" {{action back}} {{bindAttr disabled="App.router.btnClickInProgress"}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </a> {{/unless}} <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action evaluateStep target="controller"}}> - {{t installer.step2.registerAndConfirm}} →</a> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t installer.step2.registerAndConfirm}} → + </a> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step3.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step3.hbs b/ambari-web/app/templates/wizard/step3.hbs index d19943d..f4108cd 100644 --- a/ambari-web/app/templates/wizard/step3.hbs +++ b/ambari-web/app/templates/wizard/step3.hbs @@ -148,7 +148,17 @@ {{/unless}} </div> <div class="btn-area"> - <button class="btn pull-left installer-back-btn" {{bindAttr disabled="isBackDisabled"}} {{action back}}>← {{t common.back}}</button> - <button class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} →</button> + <button type="button" class="btn pull-left installer-back-btn" {{bindAttr disabled="isBackDisabled"}} {{action back}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </button> + <button type="button" class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.next}} → + </button> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step4.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step4.hbs b/ambari-web/app/templates/wizard/step4.hbs index 21c2aae..c62d369 100644 --- a/ambari-web/app/templates/wizard/step4.hbs +++ b/ambari-web/app/templates/wizard/step4.hbs @@ -50,8 +50,18 @@ <div class="btn-area"> {{#unless view.parentView.controller.hideBackButton}} - <a class="btn pull-left installer-back-btn" {{action back}}>← {{t common.back}}</a> + <button type="button" class="btn pull-left installer-back-btn" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action back}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </button> {{/unless}} - <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}> {{t common.next}} →</a> + <button type="button" class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.next}} → + </button> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step6.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step6.hbs b/ambari-web/app/templates/wizard/step6.hbs index 31d62f9..126c9a6 100644 --- a/ambari-web/app/templates/wizard/step6.hbs +++ b/ambari-web/app/templates/wizard/step6.hbs @@ -94,10 +94,17 @@ </div> </div> <div class="btn-area"> - <a class="btn installer-back-btn" {{action back}}>← {{t common.back}}</a> - <a class="btn btn-success pull-right" {{bindAttr disabled="submitDisabled"}} {{action next}}>{{t common.next}} →</a> - {{#if App.router.nextBtnClickInProgress}} - {{view App.SpinnerView tagName="span" classNames="pull-right"}} - {{/if}} + <button type="button" class="btn installer-back-btn" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action back}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </button> + <button type="button" class="btn btn-success pull-right" {{bindAttr disabled="submitDisabled"}} {{action next}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.next}} → + </button> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step7.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step7.hbs b/ambari-web/app/templates/wizard/step7.hbs index c29fdc9..f6d640b 100644 --- a/ambari-web/app/templates/wizard/step7.hbs +++ b/ambari-web/app/templates/wizard/step7.hbs @@ -31,16 +31,22 @@ <div class="btn-area"> - <a class="btn installer-back-btn" {{action back}}>← {{t common.back}}</a> + <button type="button" class="btn installer-back-btn" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action back}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </button> <div class="pull-right"> {{#if App.supports.preInstallChecks}} <a class="btn" {{action runPreInstallChecks target="App.router.preInstallChecksController"}} {{bindAttr disabled="isSubmitDisabled"}}><i class="icon-exclamation"></i> {{t installer.step7.preInstallChecks}}</a> {{/if}} - {{#if App.router.nextBtnClickInProgress}} - {{view App.SpinnerView tagName="span"}} - {{/if}} - <a class="btn btn-success" {{bindAttr disabled="isSubmitDisabled"}} - {{action submit target="controller"}}>{{t common.next}} →</a> + <button type="button" class="btn btn-success" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.next}} → + </button> </div> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step8.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step8.hbs b/ambari-web/app/templates/wizard/step8.hbs index 856ddeb..caa2e28 100644 --- a/ambari-web/app/templates/wizard/step8.hbs +++ b/ambari-web/app/templates/wizard/step8.hbs @@ -78,10 +78,20 @@ </div> </div> <div class="btn-area"> - <a class="btn pull-left installer-back-btn" {{bindAttr disabled="controller.isBackBtnDisabled"}} {{action back}}>← {{t common.back}}</a> - <a class="btn btn-success pull-right" - id="spinner" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.deploy}} →</a> - <a class="btn btn-info pull-right" {{action printReview target="view"}}>{{t common.print}}</a> - <a {{bindAttr class=":btn :btn-primary :pull-right :mrm controller.showDownloadCsv::hide"}} {{action downloadCSV target="controller"}}>{{t admin.kerberos.wizard.step5.downloadCSV}}</a> + <button type="button" class="btn pull-left installer-back-btn" {{bindAttr disabled="App.router.btnClickInProgress"}} {{action back}}> + ← {{t common.back}} + {{#if App.router.backBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + </button> + <button type="button" class="btn btn-success pull-right" + id="spinner" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action submit target="controller"}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.deploy}} → + </button> + <button type="button" class="btn btn-info pull-right" {{action printReview target="view"}}>{{t common.print}}</button> + <button type="button" {{bindAttr class=":btn :btn-primary :pull-right :mrm controller.showDownloadCsv::hide"}} {{action downloadCSV target="controller"}}>{{t admin.kerberos.wizard.step5.downloadCSV}}</button> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/templates/wizard/step9.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step9.hbs b/ambari-web/app/templates/wizard/step9.hbs index e65d4e1..9385df7 100644 --- a/ambari-web/app/templates/wizard/step9.hbs +++ b/ambari-web/app/templates/wizard/step9.hbs @@ -136,8 +136,12 @@ </p> {{/if}} <div class="btn-area"> - <button - class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} →</button> + <button class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}> + {{#if App.router.nextBtnClickInProgress}} + {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}} + {{/if}} + {{t common.next}} → + </button> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/views/wizard/step1_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/wizard/step1_view.js b/ambari-web/app/views/wizard/step1_view.js index 19be3bc..503d5ef 100644 --- a/ambari-web/app/views/wizard/step1_view.js +++ b/ambari-web/app/views/wizard/step1_view.js @@ -69,7 +69,7 @@ App.WizardStep1View = Em.View.extend({ * * @type {bool} */ - isSubmitDisabled: Em.computed.or('invalidFormatUrlExist', 'isNoOsChecked', 'controller.content.isCheckInProgress'), + isSubmitDisabled: Em.computed.or('invalidFormatUrlExist', 'isNoOsChecked', 'controller.content.isCheckInProgress', 'App.router.btnClickInProgress'), /** * Onclick handler for recheck repos urls. Used in Advanced Repository Options. http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/views/wizard/step4_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/wizard/step4_view.js b/ambari-web/app/views/wizard/step4_view.js index b24c89d..137b9f5 100644 --- a/ambari-web/app/views/wizard/step4_view.js +++ b/ambari-web/app/views/wizard/step4_view.js @@ -21,9 +21,6 @@ var App = require('app'); App.WizardStep4View = Em.View.extend({ - templateName: require('templates/wizard/step4'), - - didInsertElement: function () { - } + templateName: require('templates/wizard/step4') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/app/views/wizard/step7_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/wizard/step7_view.js b/ambari-web/app/views/wizard/step7_view.js index b7e2934..a715912 100644 --- a/ambari-web/app/views/wizard/step7_view.js +++ b/ambari-web/app/views/wizard/step7_view.js @@ -20,8 +20,7 @@ var App = require('app'); App.WizardStep7View = Em.View.extend({ - templateName: require('templates/wizard/step7'), - didInsertElement: function () { - } + templateName: require('templates/wizard/step7') + }); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/test/controllers/wizard/step0_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step0_test.js b/ambari-web/test/controllers/wizard/step0_test.js index 336f445..53fea69 100644 --- a/ambari-web/test/controllers/wizard/step0_test.js +++ b/ambari-web/test/controllers/wizard/step0_test.js @@ -27,13 +27,13 @@ describe('App.WizardStep0Controller', function () { wizardStep0Controller = App.WizardStep0Controller.create({content: {cluster: {}}}); sinon.stub(App.clusterStatus, 'set', Em.K); sinon.stub(App.router, 'send', Em.K); - App.router.nextBtnClickInProgress = false; + App.set('router.nextBtnClickInProgress', false); }); afterEach(function() { App.clusterStatus.set.restore(); App.router.send.restore(); - App.router.nextBtnClickInProgress = false; + App.set('router.nextBtnClickInProgress', false); }); describe('#invalidClusterName', function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/test/controllers/wizard/step2_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step2_test.js b/ambari-web/test/controllers/wizard/step2_test.js index 6e6ad25..c1614b9 100644 --- a/ambari-web/test/controllers/wizard/step2_test.js +++ b/ambari-web/test/controllers/wizard/step2_test.js @@ -74,7 +74,7 @@ describe('App.WizardStep2Controller', function () { App.TestAliases.testAsComputedAlias(getController(), 'agentUser', 'content.installOptions.agentUser', 'string'); - App.TestAliases.testAsComputedOr(getController(), 'isSubmitDisabled', ['hostsError', 'sshKeyError', 'sshUserError', 'sshPortError', 'agentUserError']); + App.TestAliases.testAsComputedOr(getController(), 'isSubmitDisabled', ['hostsError', 'sshKeyError', 'sshUserError', 'sshPortError', 'agentUserError', 'App.router.btnClickInProgress']); describe('#hostNames', function() { it('should be equal to content.installOptions.hostNames', function() { http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/test/controllers/wizard/step3_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step3_test.js b/ambari-web/test/controllers/wizard/step3_test.js index a214656..92b607d 100644 --- a/ambari-web/test/controllers/wizard/step3_test.js +++ b/ambari-web/test/controllers/wizard/step3_test.js @@ -42,14 +42,14 @@ describe('App.WizardStep3Controller', function () { sinon.stub(App.db, 'getDisplayLength', Em.K); sinon.stub(App.db, 'getFilterConditions').returns([]); sinon.stub(App.router, 'send', Em.K); - App.router.nextBtnClickInProgress = false; + App.set('router.nextBtnClickInProgress', false); }); afterEach(function () { App.db.getDisplayLength.restore(); App.router.send.restore(); App.db.getFilterConditions.restore(); - App.router.nextBtnClickInProgress = false; + App.set('router.nextBtnClickInProgress', false); }); App.TestAliases.testAsComputedGt(getController(), 'isHostHaveWarnings', 'warnings.length', 0); @@ -1068,19 +1068,6 @@ describe('App.WizardStep3Controller', function () { expect(c.get('confirmedHosts')).to.eql(bootHosts); }); - it('if Next button is clicked multiple times before the next step renders, it must not be processed',function(){ - var bootHosts = [ - Em.Object.create({name: 'c1'}) - ]; - c.reopen({isHostHaveWarnings: false, bootHosts: bootHosts, hosts: []}); - c.submit(); - expect(App.router.send.calledWith('next')).to.equal(true); - - App.router.send.reset(); - c.submit(); - expect(App.router.send.calledWith('next')).to.equal(false); - }); - }); describe('#hostLogPopup', function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/test/controllers/wizard/step4_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step4_test.js b/ambari-web/test/controllers/wizard/step4_test.js index 3bb6fb5..13532e7 100644 --- a/ambari-web/test/controllers/wizard/step4_test.js +++ b/ambari-web/test/controllers/wizard/step4_test.js @@ -573,27 +573,6 @@ describe('App.WizardStep4Controller', function () { }) }); - describe('#submit for Next click', function() { - var c; - beforeEach(function(){ - c = App.WizardStep4Controller.create(); - sinon.stub(App.router, 'send', Em.K); - App.router.nextBtnClickInProgress = false; - }); - afterEach(function(){ - App.router.nextBtnClickInProgress = false; - App.router.send.restore(); - }); - it('if Next button is clicked multiple times before the next step renders, it must not be processed',function(){ - c.reopen({isSubmitDisabled:false}); - c.submit(); - expect(App.router.send.calledWith('next')).to.equal(true); - - App.router.send.reset(); - c.submit(); - expect(App.router.send.calledWith('next')).to.equal(false); - }); - }); describe('#dependencies', function() { var tests = [ { http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/test/controllers/wizard/step5_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step5_test.js b/ambari-web/test/controllers/wizard/step5_test.js index a1ecbce..821a709 100644 --- a/ambari-web/test/controllers/wizard/step5_test.js +++ b/ambari-web/test/controllers/wizard/step5_test.js @@ -26,12 +26,12 @@ describe('App.WizardStep5Controller', function () { beforeEach(function () { c = App.WizardStep5Controller.create(); sinon.stub(App.router, 'send', Em.K); - App.router.nextBtnClickInProgress = false; + App.set('router.nextBtnClickInProgress', false); }); afterEach(function () { App.router.send.restore(); - App.router.nextBtnClickInProgress = false; + App.set('router.nextBtnClickInProgress', false); }); var controller = App.WizardStep5Controller.create(); @@ -1282,17 +1282,4 @@ describe('App.WizardStep5Controller', function () { }); - describe('#submit',function(){ - it('if Next button is clicked multiple times before the next step renders, it must not be processed',function(){ - c.reopen({isSubmitDisabled:false, submitDisabled:false, useServerValidation:false}); - c.submit(); - expect(App.router.send.calledWith('next')).to.equal(true); - - App.router.send.reset(); - c.submit(); - expect(App.router.send.calledWith('next')).to.equal(false); - - }); - }); - }); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/test/controllers/wizard/step7_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step7_test.js b/ambari-web/test/controllers/wizard/step7_test.js index 0668381..d43e18d 100644 --- a/ambari-web/test/controllers/wizard/step7_test.js +++ b/ambari-web/test/controllers/wizard/step7_test.js @@ -111,11 +111,11 @@ describe('App.InstallerStep7Controller', function () { beforeEach(function () { sinon.stub(App.config, 'setPreDefinedServiceConfigs', Em.K); installerStep7Controller = getController(); - App.router.nextBtnClickInProgress = false; + App.set('router.nextBtnClickInProgress', false); }); afterEach(function() { - App.router.nextBtnClickInProgress = false; + App.set('router.nextBtnClickInProgress', false); App.config.setPreDefinedServiceConfigs.restore(); installerStep7Controller.destroy(); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/test/router_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/router_test.js b/ambari-web/test/router_test.js index 1b1ee51..e17c9e2 100644 --- a/ambari-web/test/router_test.js +++ b/ambari-web/test/router_test.js @@ -86,11 +86,11 @@ describe('App.Router', function () { }); - describe('#adminViewInfoSuccessCallback', function() { - beforeEach(function() { + describe('#adminViewInfoSuccessCallback', function () { + beforeEach(function () { sinon.stub(window.location, 'replace', Em.K); }); - afterEach(function() { + afterEach(function () { window.location.replace.restore(); }); @@ -135,7 +135,7 @@ describe('App.Router', function () { expected: '/views/ADMIN_VIEW/2.1.0/INSTANCE/#/' }]; - tests.forEach(function(data, index) { + tests.forEach(function (data, index) { it('should redirect to the latest version of admin view ("' + data.expected + '") #' + (index + 1), function () { router.adminViewInfoSuccessCallback(data.mockData); expect(window.location.replace.calledWith(data.expected)).to.be.true; @@ -143,46 +143,46 @@ describe('App.Router', function () { }); }); - describe.skip("#savePreferedPath()", function() { + describe.skip("#savePreferedPath()", function () { beforeEach(function () { router.set('preferedPath', null); }); - it("has no key", function() { + it("has no key", function () { router.savePreferedPath('path'); expect(router.get('preferedPath')).to.equal('path'); }); - it("path does not contain key", function() { + it("path does not contain key", function () { router.savePreferedPath('path', 'key'); expect(router.get('preferedPath')).to.be.null; }); - it("path contains key", function() { + it("path contains key", function () { router.savePreferedPath('key=path', 'key='); expect(router.get('preferedPath')).to.equal('path'); }); }); - describe.skip("#restorePreferedPath()", function() { - it("preferedPath is null", function() { + describe.skip("#restorePreferedPath()", function () { + it("preferedPath is null", function () { router.set('preferedPath', null); expect(router.restorePreferedPath()).to.be.false; expect(router.get('preferedPath')).to.be.null; }); - it("preferedPath is '/relativeURL'", function() { + it("preferedPath is '/relativeURL'", function () { router.set('preferedPath', '/relativeURL'); expect(router.restorePreferedPath()).to.be.true; expect(router.get('preferedPath')).to.be.null; }); - it("preferedPath is '#/relativeURL'", function() { + it("preferedPath is '#/relativeURL'", function () { router.set('preferedPath', '#/relativeURL'); expect(router.restorePreferedPath()).to.be.true; expect(router.get('preferedPath')).to.be.null; }); - it("preferedPath is '#/login'", function() { + it("preferedPath is '#/login'", function () { router.set('preferedPath', '#/login'); expect(router.restorePreferedPath()).to.be.false; expect(router.get('preferedPath')).to.be.null; }); - it("preferedPath is 'http://absoluteURL'", function() { + it("preferedPath is 'http://absoluteURL'", function () { router.set('preferedPath', 'http://absoluteURL'); expect(router.restorePreferedPath()).to.be.false; expect(router.get('preferedPath')).to.be.null; @@ -419,7 +419,7 @@ describe('App.Router', function () { }); }); - describe("#getAuthenticated", function() { + describe("#getAuthenticated", function () { beforeEach(function () { router = App.Router.create(); this.mockGetCurrentLocationUrl = sinon.stub(router, 'getCurrentLocationUrl'); @@ -447,7 +447,7 @@ describe('App.Router', function () { lastSetURL: '/main/dashboard', isResolved: false, responseData: { - responseText: JSON.stringify({ jwtProviderUrl: 'http://some.com?originalUrl=' }), + responseText: JSON.stringify({jwtProviderUrl: 'http://some.com?originalUrl='}), status: 403 }, redirectCalled: true, @@ -457,25 +457,26 @@ describe('App.Router', function () { lastSetURL: '/login/local', isResolved: false, responseData: { - responseText: JSON.stringify({ jwtProviderUrl: 'http://some.com?originalUrl=' }), + responseText: JSON.stringify({jwtProviderUrl: 'http://some.com?originalUrl='}), status: 403 }, redirectCalled: false, m: 'jwtProviderUrl is present, current location is local login url, no redirect' } - ].forEach(function(test) { - describe(test.m, function() { + ].forEach(function (test) { + describe(test.m, function () { var mockCurrentUrl; beforeEach(function () { mockCurrentUrl = 'http://localhost:3333/#/some/hash'; router.set('location.lastSetURL', test.lastSetURL); App.ajax.send.restore(); // default ajax-mock can't be used here - sinon.stub(App.ajax, 'send', function() { + sinon.stub(App.ajax, 'send', function () { if (!test.isResolved) { router.onAuthenticationError(test.responseData); } return { - complete: function() {} + complete: function () { + } }; }); this.mockGetCurrentLocationUrl.returns(mockCurrentUrl); @@ -577,3 +578,95 @@ describe('App.Router', function () { }); }); + +describe('App.StepRoute', function () { + + beforeEach(function () { + this.route = App.StepRoute.create(); + this.nextTransitionSpy = sinon.spy(this.route, 'nextTransition'); + this.backTransitionSpy = sinon.spy(this.route, 'backTransition'); + this.appGetStub = sinon.stub(App, 'get'); + this.appSetStub = sinon.stub(App, 'set'); + this.runNextStub = sinon.stub(Em.run, 'next', Em.clb); + }); + + afterEach(function () { + this.nextTransitionSpy.restore(); + this.backTransitionSpy.restore(); + this.appGetStub.restore(); + this.appSetStub.restore(); + this.runNextStub.restore(); + }); + + describe('#back', function () { + + [ + { + btnClickInProgress: true, + backBtnClickInProgressIsSet: false, + backTransitionIsCalled: false, + m: 'backTransition is not called' + }, + { + btnClickInProgress: false, + backBtnClickInProgressIsSet: true, + backTransitionIsCalled: true, + m: 'backTransition is called' + } + ].forEach(function (test) { + describe(test.m, function () { + + beforeEach(function () { + this.appGetStub.withArgs('router.btnClickInProgress').returns(test.btnClickInProgress); + this.route.back({}); + }); + + it('backTransition call', function () { + expect(this.backTransitionSpy.called).to.be.equal(test.backTransitionIsCalled); + }); + + it('backBtnClickInProgress is set', function () { + expect(this.appSetStub.calledWith('router.backBtnClickInProgress')).to.be.equal(test.backBtnClickInProgressIsSet); + }); + + }); + }); + + }); + + describe('#next', function () { + + [ + { + btnClickInProgress: true, + nextBtnClickInProgressIsSet: false, + nextTransitionIsCalled: false, + m: 'nextTransition is not called' + }, + { + btnClickInProgress: false, + nextBtnClickInProgressIsSet: true, + nextTransitionIsCalled: true, + m: 'nextTransition is called' + } + ].forEach(function (test) { + describe(test.m, function () { + + beforeEach(function () { + this.appGetStub.withArgs('router.btnClickInProgress').returns(test.btnClickInProgress); + this.route.next({}); + }); + + it('nextTransition call', function () { + expect(this.nextTransitionSpy.called).to.be.equal(test.nextTransitionIsCalled); + }); + + it('nextBtnClickInProgress is set', function () { + expect(this.appSetStub.calledWith('router.nextBtnClickInProgress')).to.be.equal(test.nextBtnClickInProgressIsSet); + }); + + }); + }); + }); + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/fb69fb6f/ambari-web/test/views/wizard/step1_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/wizard/step1_view_test.js b/ambari-web/test/views/wizard/step1_view_test.js index f94720a..3621aa9 100644 --- a/ambari-web/test/views/wizard/step1_view_test.js +++ b/ambari-web/test/views/wizard/step1_view_test.js @@ -33,7 +33,7 @@ describe('App.WizardStep1View', function () { App.TestAliases.testAsComputedEveryBy(getView(), 'isNoOsChecked', 'controller.selectedStack.operatingSystems', 'isSelected', false); - App.TestAliases.testAsComputedOr(getView(), 'isSubmitDisabled', ['invalidFormatUrlExist', 'isNoOsChecked', 'controller.content.isCheckInProgress']); + App.TestAliases.testAsComputedOr(getView(), 'isSubmitDisabled', ['invalidFormatUrlExist', 'isNoOsChecked', 'controller.content.isCheckInProgress', 'App.router.btnClickInProgress']); App.TestAliases.testAsComputedSomeBy(getView(), 'invalidUrlExist', 'allRepositories', 'validation', App.Repository.validation.INVALID);