You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by db...@apache.org on 2017/02/23 14:33:29 UTC

ambari git commit: AMBARI-20123 Click feedback/disable toggle is missing for transition buttons in Kerberos Wizard - prone to various failures (dbuzhor)

Repository: ambari
Updated Branches:
  refs/heads/trunk b68bb74c4 -> 307c8ad26


AMBARI-20123 Click feedback/disable toggle is missing for transition buttons in Kerberos Wizard - prone to various failures (dbuzhor)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/307c8ad2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/307c8ad2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/307c8ad2

Branch: refs/heads/trunk
Commit: 307c8ad26cdefa08e0dfc9454655c16dc603d1ff
Parents: b68bb74
Author: Denys Buzhor <bd...@hortonworks.com>
Authored: Thu Feb 23 10:52:04 2017 +0200
Committer: Denys Buzhor <bd...@hortonworks.com>
Committed: Thu Feb 23 16:32:16 2017 +0200

----------------------------------------------------------------------
 .../main/admin/kerberos/step1_controller.js     |  2 +-
 .../main/admin/kerberos/step2_controller.js     | 10 ++-
 .../main/admin/kerberos/step4_controller.js     |  2 +
 .../main/admin/kerberos/step5_controller.js     |  4 +
 .../wizard/wizardProgressPageController.js      |  2 +
 ambari-web/app/routes/add_kerberos_routes.js    | 50 ++++++-------
 ambari-web/app/styles/common.less               |  6 ++
 .../app/templates/common/button_progress.hbs    | 29 ++++++++
 ambari-web/app/templates/common/progress.hbs    |  6 +-
 .../app/templates/main/admin/kerberos/step1.hbs |  2 +-
 .../app/templates/main/admin/kerberos/step2.hbs |  5 +-
 .../app/templates/main/admin/kerberos/step3.hbs |  4 +-
 .../app/templates/main/admin/kerberos/step4.hbs |  5 +-
 .../app/templates/main/admin/kerberos/step5.hbs | 13 +++-
 ambari-web/app/views.js                         |  2 +
 .../common/buttons/button_progress_view.js      | 77 ++++++++++++++++++++
 .../app/views/common/buttons/wizard_buttons.js  | 36 +++++++++
 .../admin/kerberos/step1_controller_test.js     |  6 +-
 .../admin/kerberos/step2_controller_test.js     |  2 +-
 19 files changed, 213 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
index c0decfc..2e41e3d 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
@@ -144,7 +144,7 @@ App.KerberosWizardStep1Controller = Em.Controller.extend({
     }
   },
 
-  next: function () {
+  submit: function () {
     if (!this.get('isSubmitDisabled')) {
       App.router.send('next');
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
index 992fd34..258a384 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
@@ -60,16 +60,17 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
    * Should Back-button be disabled
    * @type {boolean}
    */
-  isBackBtnDisabled: Em.computed.alias('testConnectionInProgress'),
+  isBackBtnDisabled: Em.computed.or('testConnectionInProgress', 'App.router.nextBtnClickInProgress'),
 
   /**
    * Should Next-button be disabled
    * @type {boolean}
    */
   isSubmitDisabled: function () {
-    if (!this.get('stepConfigs.length') || this.get('testConnectionInProgress') || this.get('submitButtonClicked')) return true;
+    if (!this.get('stepConfigs.length') || this.get('testConnectionInProgress')
+      || this.get('submitButtonClicked') || App.get('router.nextBtnClickInProgress')) return true;
     return (!this.get('stepConfigs').filterProperty('showConfig', true).everyProperty('errorCount', 0) || this.get("miscModalVisible"));
-  }.property('stepConfigs.@each.errorCount', 'miscModalVisible', 'submitButtonClicked', 'testConnectionInProgress'),
+  }.property('stepConfigs.@each.errorCount', 'miscModalVisible', 'submitButtonClicked', 'testConnectionInProgress', 'App.router.nextBtnClickInProgress'),
 
   hostNames: Em.computed.alias('App.allHostNames'),
 
@@ -170,8 +171,8 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
 
   submit: function () {
     var self = this;
-
     if (this.get('isSubmitDisabled')) return false;
+    App.set('router.nextBtnClickInProgress', true);
     this.get('wizardController').deleteKerberosService().always(function () {
       self.configureKerberos();
     });
@@ -183,6 +184,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
     var callback = function () {
       self.createConfigurations().done(function () {
         self.createKerberosAdminSession().done(function () {
+          App.set('router.nextBtnClickInProgress', false);
           App.router.send('next');
         });
       });

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
index 8e5abd5..f23814c 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
@@ -29,6 +29,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
 
   clearStep: function() {
     this.set('isRecommendedLoaded', false);
+    this.set('submitButtonClicked', false);
     this.set('selectedService', null);
     this.set('stepConfigs', []);
   },
@@ -312,6 +313,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
   },
 
   submit: function() {
+    this.set('submitButtonClicked', true);
     this.saveConfigurations();
     App.router.send('next');
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
index 9cb75e0..ac36c6c 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
@@ -48,6 +48,8 @@ App.KerberosWizardStep5Controller = App.KerberosProgressPageController.extend({
     }
   ],
 
+  isCSVRequestInProgress: false,
+
   submit: function() {
     App.router.send('next');
   },
@@ -56,6 +58,7 @@ App.KerberosWizardStep5Controller = App.KerberosProgressPageController.extend({
    * get CSV data from the server
    */
   getCSVData: function (skipDownload) {
+    this.set('isCSVRequestInProgress', true);
     return App.ajax.send({
       name: 'admin.kerberos.cluster.csv',
       sender: this,
@@ -75,6 +78,7 @@ App.KerberosWizardStep5Controller = App.KerberosProgressPageController.extend({
    */
   getCSVDataSuccessCallback: function (data, opt, params) {
     this.set('csvData', this.prepareCSVData(data.split('\n')));
+    this.set('isCSVRequestInProgress', false);
     if (!Em.get(params, 'skipDownload')) {
       fileUtils.downloadTextFile(stringUtils.arrayToCSV(this.get('csvData')), 'csv', 'kerberos.csv');
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/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 d426eda..96eb0ae 100644
--- a/ambari-web/app/mixins/wizard/wizardProgressPageController.js
+++ b/ambari-web/app/mixins/wizard/wizardProgressPageController.js
@@ -731,6 +731,7 @@ App.wizardProgressPageControllerMixin = Em.Mixin.create(App.InstallComponent, {
 
   done: function () {
     if (!this.get('isSubmitDisabled')) {
+      this.set('isSubmitDisabled', true);
       this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
       App.router.send('next');
     }
@@ -738,6 +739,7 @@ App.wizardProgressPageControllerMixin = Em.Mixin.create(App.InstallComponent, {
 
   back: function () {
     if (!this.get('isBackButtonDisabled')) {
+      this.set('isBackButtonDisabled', true);
       this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
       App.router.send('back');
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/routes/add_kerberos_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/add_kerberos_routes.js b/ambari-web/app/routes/add_kerberos_routes.js
index fe21dae..462ce44 100644
--- a/ambari-web/app/routes/add_kerberos_routes.js
+++ b/ambari-web/app/routes/add_kerberos_routes.js
@@ -111,7 +111,7 @@ module.exports = App.WizardRoute.extend({
     });
   },
 
-  step1: Em.Route.extend({
+  step1: App.StepRoute.extend({
     route: '/step1',
 
     connectOutlets: function (router) {
@@ -128,7 +128,7 @@ module.exports = App.WizardRoute.extend({
       return false;
     },
 
-    next: function (router) {
+    nextTransition: function (router) {
       var kerberosWizardController = router.get('kerberosWizardController');
       var kerberosStep1controller = router.get('kerberosWizardStep1Controller');
 
@@ -139,7 +139,7 @@ module.exports = App.WizardRoute.extend({
     }
   }),
 
-  step2: Em.Route.extend({
+  step2: App.StepRoute.extend({
     route: '/step2',
 
     connectOutlets: function (router) {
@@ -156,16 +156,14 @@ module.exports = App.WizardRoute.extend({
     unroutePath: function () {
       return false;
     },
-    back: function(router) {
+    backTransition: function(router) {
       var controller = router.get('kerberosWizardStep2Controller');
       var kerberosWizardController = router.get('kerberosWizardController');
-      if (!controller.get('isBackBtnDisabled')) {
-        kerberosWizardController.overrideVisibility(controller.get('configs'), true, []);
-        router.transitionTo('step1');
-      }
+      kerberosWizardController.overrideVisibility(controller.get('configs'), true, []);
+      router.transitionTo('step1');
     },
 
-    next: function (router) {
+    nextTransition: function (router) {
       var kerberosWizardController = router.get('kerberosWizardController');
       var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');
 
@@ -187,7 +185,7 @@ module.exports = App.WizardRoute.extend({
     }
   }),
 
-  step3: Em.Route.extend({
+  step3: App.StepRoute.extend({
     route: '/step3',
 
     connectOutlets: function (router) {
@@ -203,7 +201,7 @@ module.exports = App.WizardRoute.extend({
       return false;
     },
     back: Em.Router.transitionTo('step2'),
-    next: function (router) {
+    nextTransition: function (router) {
       var kerberosWizardController = router.get('kerberosWizardController');
       kerberosWizardController.setDBProperty('kerberosDescriptorConfigs', null);
       kerberosWizardController.clearCachedStepConfigValues(router.get('kerberosWizardStep4Controller'));
@@ -211,7 +209,7 @@ module.exports = App.WizardRoute.extend({
     }
   }),
 
-  step4: Em.Route.extend({
+  step4: App.StepRoute.extend({
     route: '/step4',
 
     connectOutlets: function (router) {
@@ -230,14 +228,14 @@ module.exports = App.WizardRoute.extend({
     unroutePath: function () {
       return false;
     },
-    back: function (router) {
+    backTransition: function (router) {
       if (router.get('kerberosWizardController.skipClientInstall')) {
         router.transitionTo('step2');
       } else {
         router.transitionTo('step3');
       }
     },
-    next: function (router) {
+    nextTransition: function (router) {
       var kerberosWizardController = router.get('kerberosWizardController');
       var step5Controller = router.get('kerberosWizardStep5Controller');
       var kerberosDescriptor = kerberosWizardController.get('kerberosDescriptorConfigs');
@@ -252,7 +250,7 @@ module.exports = App.WizardRoute.extend({
     }
   }),
 
-  step5: Em.Route.extend({
+  step5: App.StepRoute.extend({
     route: '/step5',
 
     connectOutlets: function (router) {
@@ -280,9 +278,9 @@ module.exports = App.WizardRoute.extend({
       kerberosWizardStep5Controller.getCSVData();
     },
 
-    back: Em.Router.transitionTo('step4'),
+    backTransition: Em.Router.transitionTo('step4'),
 
-    next: function (router) {
+    nextTransition: function (router) {
       var kerberosWizardController = router.get('kerberosWizardController');
       kerberosWizardController.setDBProperties({
         tasksStatuses: null,
@@ -292,7 +290,7 @@ module.exports = App.WizardRoute.extend({
     }
   }),
 
-  step6: Em.Route.extend({
+  step6: App.StepRoute.extend({
     route: '/step6',
 
     connectOutlets: function (router) {
@@ -308,8 +306,8 @@ module.exports = App.WizardRoute.extend({
     unroutePath: function () {
       return false;
     },
-    back: Em.Router.transitionTo('step4'),
-    next: function (router) {
+    backTransition: Em.Router.transitionTo('step4'),
+    nextTransition: function (router) {
       var kerberosWizardController = router.get('kerberosWizardController');
       kerberosWizardController.setDBProperties({
         tasksStatuses: null,
@@ -319,7 +317,7 @@ module.exports = App.WizardRoute.extend({
     }
   }),
 
-  step7: Em.Route.extend({
+  step7: App.StepRoute.extend({
     route: '/step7',
 
     connectOutlets: function (router) {
@@ -337,13 +335,13 @@ module.exports = App.WizardRoute.extend({
     unroutePath: function () {
       return false;
     },
-    back: Em.Router.transitionTo('step4'),
-    next: function (router) {
+    backTransition: Em.Router.transitionTo('step4'),
+    nextTransition: function (router) {
       router.transitionTo('step8');
     }
   }),
 
-  step8: Em.Route.extend({
+  step8: App.StepRoute.extend({
     route: '/step8',
 
     connectOutlets: function (router) {
@@ -359,8 +357,8 @@ module.exports = App.WizardRoute.extend({
     unroutePath: function () {
       return false;
     },
-    back: Em.Router.transitionTo('step7'),
-    next: function (router) {
+    backTransition: Em.Router.transitionTo('step7'),
+    nextTransition: function (router) {
       var controller = router.get('kerberosWizardController');
       controller.resetOnClose(controller, 'adminKerberos.index');
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/styles/common.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/common.less b/ambari-web/app/styles/common.less
index 94a5cd3..ad1da66 100644
--- a/ambari-web/app/styles/common.less
+++ b/ambari-web/app/styles/common.less
@@ -198,3 +198,9 @@
 @modal-header-height: 50px;
 // modal footer height
 @modal-footer-height: 60px;
+
+.btn-primary[disabled] {
+  .icon-spinner {
+    color: white;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/templates/common/button_progress.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/button_progress.hbs b/ambari-web/app/templates/common/button_progress.hbs
new file mode 100644
index 0000000..03f2cbb
--- /dev/null
+++ b/ambari-web/app/templates/common/button_progress.hbs
@@ -0,0 +1,29 @@
+{{!
+* 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.
+}}
+
+<a {{bindAttr id="view.buttonId" class=":btn view.buttonClassNames" disabled="view.isDisabled"}} {{action handleClick target="view"}}>
+  {{#if view.doSpinRight}}
+    {{yield}}
+  {{/if}}
+  {{#if view.isInProgress}}
+    {{view App.SpinnerView tagName="span" classNames="service-button-spinner"}}
+  {{/if}}
+  {{#unless view.doSpinRight}}
+    {{yield}}
+  {{/unless}}
+</a>

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/templates/common/progress.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/progress.hbs b/ambari-web/app/templates/common/progress.hbs
index fce5641..ab59328 100644
--- a/ambari-web/app/templates/common/progress.hbs
+++ b/ambari-web/app/templates/common/progress.hbs
@@ -79,9 +79,11 @@
   <div class="wizard-footer col-md-12">
     <div class="btn-area">
       {{#if view.showBackButton}}
-        <button class="btn btn-default pull-left" {{bindAttr disabled="controller.isBackButtonDisabled"}} {{action back target="controller"}}>&larr; {{t common.back}}</button>
+        {{view App.WizardBackButton action="back" target="controller"}}
       {{/if}}
-      <button class="btn btn-success pull-right" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action done target="controller"}}>{{{view.submitButtonText}}}</button>
+      {{#view App.WizardNextButton action="done" target="controller"}}
+        {{{view.parentView.submitButtonText}}}
+      {{/view}}
     </div>
   </div>
 {{/unless}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/templates/main/admin/kerberos/step1.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step1.hbs b/ambari-web/app/templates/main/admin/kerberos/step1.hbs
index 19e5596..57d0637 100644
--- a/ambari-web/app/templates/main/admin/kerberos/step1.hbs
+++ b/ambari-web/app/templates/main/admin/kerberos/step1.hbs
@@ -57,6 +57,6 @@
 </div>
 <div class="wizard-footer col-md-12">
   <div class="btn-area">
-    <button id="submit-kerberos-step1" class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action "next" target="controller"}}>{{t common.next}} &rarr;</button>
+    {{view App.WizardNextButton buttonId="submit-kerberos-step1" action="submit" target="controller"}}
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/templates/main/admin/kerberos/step2.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step2.hbs b/ambari-web/app/templates/main/admin/kerberos/step2.hbs
index c17347c..942bd5e 100644
--- a/ambari-web/app/templates/main/admin/kerberos/step2.hbs
+++ b/ambari-web/app/templates/main/admin/kerberos/step2.hbs
@@ -34,9 +34,8 @@
   </div>
   <div class="wizard-footer col-md-12">
     <div class="btn-area">
-      <button id="back-kerberos-step2" class="btn btn-default" {{bindAttr disabled="isBackBtnDisabled"}} {{action back}}>&larr; {{t common.back}}</button>
-      <button id="submit-kerberos-step2" class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
-        {{action submit target="controller"}}>{{t common.next}} &rarr;</button>
+      {{view App.WizardBackButton buttonId="back-kerberos-step2" action="back" disabledBinding="controller.isBackBtnDisabled"}}
+      {{view App.WizardNextButton buttonId="submit-kerberos-step2" action="submit" target="controller"}}
     </div>
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/templates/main/admin/kerberos/step3.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step3.hbs b/ambari-web/app/templates/main/admin/kerberos/step3.hbs
index 6e2ea57..01c927d 100644
--- a/ambari-web/app/templates/main/admin/kerberos/step3.hbs
+++ b/ambari-web/app/templates/main/admin/kerberos/step3.hbs
@@ -92,9 +92,9 @@
   <div class="wizard-footer col-md-12">
     <div class="btn-area">
       {{#if view.showBackButton}}
-        <button class="btn btn-default pull-left" {{bindAttr disabled="controller.isBackButtonDisabled"}} {{action back target="controller"}}>&larr; {{t common.back}}</button>
+        {{view App.WizardBackButton action="back" target="controller"}}
       {{/if}}
-      <button class="btn btn-success pull-right" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action done target="controller"}}>{{{view.submitButtonText}}}</button>
+      {{view App.WizardNextButton buttonId="submit-kerberos-step3" action="done" target="controller"}}
     </div>
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/templates/main/admin/kerberos/step4.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step4.hbs b/ambari-web/app/templates/main/admin/kerberos/step4.hbs
index 1e6f956..24f3576 100644
--- a/ambari-web/app/templates/main/admin/kerberos/step4.hbs
+++ b/ambari-web/app/templates/main/admin/kerberos/step4.hbs
@@ -27,9 +27,8 @@
   </div>
   <div class="wizard-footer col-md-12">
     <div class="btn-area">
-      <button id="back-kerberos-step4" class="btn btn-default" {{action back}}>&larr; {{t common.back}}</button>
-      <button id="submit-kerberos-step4" class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
-        {{action submit target="controller"}}>{{t common.next}} &rarr;</button>
+      {{view App.WizardBackButton buttonId="back-kerberos-step4" action="back"}}
+      {{view App.WizardNextButton buttonId="submit-kerberos-step4" action="submit" target="controller"}}
     </div>
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/templates/main/admin/kerberos/step5.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step5.hbs b/ambari-web/app/templates/main/admin/kerberos/step5.hbs
index c0cdc00..0f55d45 100644
--- a/ambari-web/app/templates/main/admin/kerberos/step5.hbs
+++ b/ambari-web/app/templates/main/admin/kerberos/step5.hbs
@@ -45,7 +45,13 @@
         </div>
 
         <div class="additional btn-area clearfix">
-          <button class="btn btn-primary pull-right mls" {{action downloadCSV}}>{{t admin.kerberos.wizard.step5.downloadCSV}}</button>
+          {{#view App.ButtonProgressView
+             classNames="pull-right mls"
+             buttonClassNames="btn-primary"
+             action="downloadCSV"
+             isInProgressBinding="controller.isCSVRequestInProgress"}}
+            {{t admin.kerberos.wizard.step5.downloadCSV}}
+          {{/view}}
           <button class="btn btn-default pull-right" {{action exitWizard}}>{{t admin.kerberos.wizard.step5.exitWizard}}</button>
         </div>
       </div>
@@ -53,9 +59,8 @@
   </div>
   <div class="wizard-footer col-md-12">
     <div class="btn-area">
-      <button id="back-kerberos-step5" class="btn btn-default" {{action back}}>&larr; {{t common.back}}</button>
-      <button id="submit-kerberos-step5" class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
-        {{action submit target="controller"}}>{{t common.next}} &rarr;</button>
+      {{view App.WizardBackButton buttonId="back-kerberos-step5" action="back"}}
+      {{view App.WizardNextButton buttonId="submit-kerberos-step5" action="submit" target="controller"}}
     </div>
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 9addd91..7ec59f7 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -27,6 +27,8 @@ require('views/common/log_file_search_view');
 require('views/common/log_tail_view');
 require('views/common/global/spinner');
 require('views/common/ajax_default_error_popup_body');
+require('views/common/buttons/button_progress_view');
+require('views/common/buttons/wizard_buttons');
 require('views/common/chart');
 require('views/common/chart/pie');
 require('views/common/chart/linear');

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/views/common/buttons/button_progress_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/buttons/button_progress_view.js b/ambari-web/app/views/common/buttons/button_progress_view.js
new file mode 100644
index 0000000..cae2664
--- /dev/null
+++ b/ambari-web/app/views/common/buttons/button_progress_view.js
@@ -0,0 +1,77 @@
+/**
+ * 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');
+
+App.ButtonProgressView = Em.View.extend(Em.TargetActionSupport, {
+  layoutName: require('templates/common/button_progress'),
+  isDisabled: Em.computed.or('disabled', 'isInProgress'),
+  /**
+   * Target to perform `onClick` function default to App.router
+   * @type {Em.Object|Em.View|Em.Controller}
+   */
+  target: null,
+  /**
+   * Property determines progress state
+   * @type {Boolean}
+   */
+  isInProgress: null,
+  /**
+   * on click handler
+   * @type {Function}
+   */
+  action: null,
+  /**
+   * When true spinner appears to right side, when false - to left
+   * @type {Boolean}
+   */
+  doSpinRight: true,
+
+  targetObject: function() {
+    var target = this.get('target'),
+        splitted;
+    if (!target) {
+      return this.get('controller.target');
+    } else if (typeof target === 'string') {
+      splitted = target.split('.');
+      if (splitted[0] === 'view') {
+        splitted = ['parentView'].concat(splitted.slice(1));
+      }
+      return Em.get(this, splitted.join('.'))
+    } else {
+      return target;
+    }
+  }.property('target'),
+
+  handleClick: function() {
+    if (this.get('isDisabled')) {
+      return;
+    }
+    var target = this.get('targetObject');
+    var targetMethod = this.get('action');
+    if (target.isState && typeof target.send === 'function') {
+      target.send(targetMethod);
+    } else if (targetMethod && typeof targetMethod === 'function') {
+      targetMethod.apply(target);
+    } else if (typeof targetMethod === 'string' && typeof Em.get(target, targetMethod) === 'function') {
+      Em.get(target, targetMethod).call(target);
+    } else {
+      Ember.Logger.error('Cannot invoke action %s on target %s', targetMethod, target);
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/app/views/common/buttons/wizard_buttons.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/buttons/wizard_buttons.js b/ambari-web/app/views/common/buttons/wizard_buttons.js
new file mode 100644
index 0000000..3bf89f2
--- /dev/null
+++ b/ambari-web/app/views/common/buttons/wizard_buttons.js
@@ -0,0 +1,36 @@
+/**
+ * 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');
+
+App.WizardNextButton = App.ButtonProgressView.extend({
+  classNames: ['pull-right'],
+  isInProgressBinding: 'App.router.nextBtnClickInProgress',
+  buttonClassNames: ['btn-success'],
+  template: Em.Handlebars.compile('{{t common.next}} &rarr;'),
+  disabledBinding: 'controller.isSubmitDisabled'
+});
+
+App.WizardBackButton = App.ButtonProgressView.extend({
+  classNames: ['pull-left'],
+  isInProgressBinding: 'App.router.backBtnClickInProgress',
+  buttonClassNames: ['btn-default'],
+  template: Em.Handlebars.compile('&larr; {{t common.back}}'),
+  doSpinRight: false,
+  disabledBinding: 'controller.isBackButtonDisabled'
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
index 3181fda..ca80341 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
@@ -70,7 +70,7 @@ describe('App.KerberosWizardStep1Controller', function() {
     });
   });
 
-  describe("#next()", function () {
+  describe("#submit()", function () {
 
     beforeEach(function() {
       sinon.stub(App.router, 'send');
@@ -84,7 +84,7 @@ describe('App.KerberosWizardStep1Controller', function() {
       controller.reopen({
         'isSubmitDisabled': false
       });
-      controller.next();
+      controller.submit();
       expect(App.router.send.calledOnce).to.be.true;
     });
 
@@ -92,7 +92,7 @@ describe('App.KerberosWizardStep1Controller', function() {
       controller.reopen({
         'isSubmitDisabled': true
       });
-      controller.next();
+      controller.submit();
       expect(App.router.send.called).to.be.false;
     });
   });

http://git-wip-us.apache.org/repos/asf/ambari/blob/307c8ad2/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
index 2e603da..78e43f0 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
@@ -37,7 +37,7 @@ describe('App.KerberosWizardStep2Controller', function() {
     controller = getController();
   });
 
-  App.TestAliases.testAsComputedAlias(getController(), 'isBackBtnDisabled', 'testConnectionInProgress', 'boolean');
+  App.TestAliases.testAsComputedOr(getController(), 'isBackBtnDisabled', ['testConnectionInProgress', 'App.router.nextBtnClickInProgress'], 'boolean');
 
   App.TestAliases.testAsComputedAlias(getController(), 'hostNames', 'App.allHostNames', 'array');