AMBARI-17297 While deleting a service, confirmation popup took a long time (~30 
seconds) to appear      (akovalenko)


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

Branch: refs/heads/branch-2.4
Commit: 5914838102040461e80a58015d3b4b1ed177834e
Parents: 5889ffc
Author: Aleksandr Kovalenko <akovale...@hortonworks.com>
Authored: Fri Jun 17 16:57:20 2016 +0300
Committer: Aleksandr Kovalenko <akovale...@hortonworks.com>
Committed: Fri Jun 17 20:15:48 2016 +0300

----------------------------------------------------------------------
 ambari-web/app/controllers/main/service/item.js | 47 ++++++++--
 ambari-web/app/messages.js                      |  1 +
 .../app/mixins/common/configs/configs_saver.js  |  6 +-
 ambari-web/app/styles/application.less          | 14 +++
 .../test/controllers/main/service/item_test.js  | 95 ++++++++++++++++++--
 5 files changed, 149 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/59148381/ambari-web/app/controllers/main/service/item.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/item.js 
b/ambari-web/app/controllers/main/service/item.js
index 4f8d9009..79188aa 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -19,6 +19,7 @@
 var App = require('app');
 var batchUtils = require('utils/batch_scheduled_requests');
 var blueprintUtils = require('utils/blueprint');
+var stringUtils = require('utils/string_utils');
 
 App.MainServiceItemController = 
Em.Controller.extend(App.SupportClientConfigsDownload, App.InstallComponent, 
App.ConfigsSaverMixin, App.EnhancedConfigsMixin, {
   name: 'mainServiceItemController',
@@ -83,6 +84,8 @@ App.MainServiceItemController = 
Em.Controller.extend(App.SupportClientConfigsDow
    */
   routeToConfigs: false,
 
+  deleteServiceProgressPopup: null,
+
   isClientsOnlyService: function() {
     return 
App.get('services.clientOnly').contains(this.get('content.serviceName'));
   }.property('content.serviceName'),
@@ -1341,7 +1344,26 @@ App.MainServiceItemController = 
Em.Controller.extend(App.SupportClientConfigsDow
        * @function onPrimary
        */
       onPrimary: function() {
-        self.deleteServiceCall([serviceName].concat(dependentServiceNames));
+        var serviceNames = [serviceName].concat(dependentServiceNames),
+          serviceDisplayNames = serviceNames.map(function (serviceName) {
+            return App.Service.find(serviceName).get('displayName');
+          }),
+          progressPopup = App.ModalPopup.show({
+            classNames: ['delete-service-progress'],
+            header: Em.I18n.t('services.service.delete.popup.header'),
+            showFooter: false,
+            message: 
Em.I18n.t('services.service.delete.progressPopup.message').format(stringUtils.getFormattedStringFromArray(serviceDisplayNames)),
+            bodyClass: Em.View.extend({
+              classNames: ['delete-service-progress-body'],
+              template: Em.Handlebars.compile('{{view App.SpinnerView}}<div 
class="progress-message">{{message}}</div>')
+            }),
+            onClose: function () {
+              self.set('deleteServiceProgressPopup', null);
+              this._super();
+            }
+          });
+        self.set('deleteServiceProgressPopup', progressPopup);
+        self.deleteServiceCall(serviceNames);
         this._super();
       },
 
@@ -1458,7 +1480,8 @@ App.MainServiceItemController = 
Em.Controller.extend(App.SupportClientConfigsDow
    * @override
    */
   saveConfigs: function() {
-    var data = [];
+    var data = [],
+      progressPopup = this.get('deleteServiceProgressPopup');
     this.get('stepConfigs').forEach(function(stepConfig) {
       var serviceConfig = 
this.getServiceConfigToSave(stepConfig.get('serviceName'), 
stepConfig.get('configs'));
 
@@ -1468,16 +1491,24 @@ App.MainServiceItemController = 
Em.Controller.extend(App.SupportClientConfigsDow
     }, this);
 
     if (Em.isArray(data) && data.length) {
-      this.putChangedConfigurations(data, 'confirmServiceDeletion');
+      this.putChangedConfigurations(data, 'confirmServiceDeletion', function 
() {
+        if (progressPopup) {
+          progressPopup.onClose();
+        }
+      });
     } else {
       this.confirmServiceDeletion();
     }
   },
 
   confirmServiceDeletion: function() {
-    var msg = this.get('interDependentServices.length')
-      ? 
Em.I18n.t('services.service.delete.service.success.confirmation.plural').format(this.get('serviceNamesToDelete').join(','))
-      : 
Em.I18n.t('services.service.delete.service.success.confirmation').format(this.get('content.serviceName'));
+    var progressPopup = this.get('deleteServiceProgressPopup'),
+      msg = this.get('interDependentServices.length')
+        ? 
Em.I18n.t('services.service.delete.service.success.confirmation.plural').format(this.get('serviceNamesToDelete').join(','))
+        : 
Em.I18n.t('services.service.delete.service.success.confirmation').format(this.get('content.serviceName'));
+    if (progressPopup) {
+      progressPopup.onClose();
+    }
     return App.showAlertPopup(Em.I18n.t('popup.confirmation.commonHeader'), 
msg, function() {
       window.location.reload();
     })
@@ -1515,6 +1546,10 @@ App.MainServiceItemController = 
Em.Controller.extend(App.SupportClientConfigsDow
   },
 
   deleteServiceCallErrorCallback: function (jqXHR, ajaxOptions, error, opt) {
+    var progressPopup = this.get('deleteServiceProgressPopup');
+    if (progressPopup) {
+      progressPopup.onClose();
+    }
     App.ajax.defaultErrorHandler(jqXHR, opt.url, opt.type, jqXHR.status);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/59148381/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 6465812..79fe36a 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1845,6 +1845,7 @@ Em.I18n.translations = {
   'services.service.confirmDelete.popup.body.type': 'Type "{0}" to confirm',
   'services.service.confirmDelete.popup.body.dependent': 'You must confirm 
delete of <b>{0}</b> and <b>{1}</b> by typing "{2}"' +
   ' in the confirmation box. <b>This operation is not reversible and all 
configuration history will be lost.</b>',
+  'services.service.delete.progressPopup.message': 'Deleting {0}...',
   'services.service.delete.service.success.confirmation': 'Service {0} was 
successfully deleted',
   'services.service.delete.service.success.confirmation.plural': 'Services {0} 
were successfully deleted',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/59148381/ambari-web/app/mixins/common/configs/configs_saver.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_saver.js 
b/ambari-web/app/mixins/common/configs/configs_saver.js
index f486180..a841951 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -603,10 +603,11 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    * contains the site name and tag to be used.
    * @param {Object[]} services
    * @param {String} [successCallback]
+   * @param {Function} [alwaysCallback]
    * @return {$.ajax}
    * @method putChangedConfigurations
    */
-  putChangedConfigurations: function (services, successCallback) {
+  putChangedConfigurations: function (services, successCallback, 
alwaysCallback) {
     var ajaxData = {
       name: 'common.across.services.configurations',
       sender: this,
@@ -618,6 +619,9 @@ App.ConfigsSaverMixin = Em.Mixin.create({
     if (successCallback) {
       ajaxData.success = successCallback;
     }
+    if (alwaysCallback) {
+      ajaxData.callback = alwaysCallback;
+    }
     return App.ajax.send(ajaxData);
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/59148381/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less 
b/ambari-web/app/styles/application.less
index d525fd4..4ae4c61 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -6420,3 +6420,17 @@ input[type="radio"].align-checkbox, 
input[type="checkbox"].align-checkbox {
   }
 }
 
+.delete-service-progress {
+  .modal-body {
+    text-align: center;
+    .delete-service-progress-body {
+      display: inline-block;
+      .spinner, .progress-message {
+        float: left;
+      }
+      .progress-message {
+        line-height: @spinner-default-height;
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/59148381/ambari-web/test/controllers/main/service/item_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/item_test.js 
b/ambari-web/test/controllers/main/service/item_test.js
index 4176b3d..5c2b34a 100644
--- a/ambari-web/test/controllers/main/service/item_test.js
+++ b/ambari-web/test/controllers/main/service/item_test.js
@@ -1494,18 +1494,99 @@ describe('App.MainServiceItemController', function () {
   describe("#confirmDeleteService()", function() {
     var mainServiceItemController;
 
-    beforeEach(function() {
-      mainServiceItemController = App.MainServiceItemController.create({});
-      sinon.stub(App.ModalPopup, 'show');
+    beforeEach(function () {
+      mainServiceItemController = App.MainServiceItemController.create();
     });
-    afterEach(function() {
+
+    afterEach(function () {
       App.ModalPopup.show.restore();
     });
 
-    it("App.ModalPopup.show should be called", function() {
-      mainServiceItemController.confirmDeleteService('S1', [], '');
-      expect(App.ModalPopup.show.calledOnce).to.be.true;
+    describe('confirmation popup', function () {
+
+      beforeEach(function () {
+        sinon.stub(App.ModalPopup, 'show', Em.K);
+        mainServiceItemController.confirmDeleteService('S1', [], '');
+      });
+
+      it("App.ModalPopup.show should be called", function() {
+        expect(App.ModalPopup.show.calledOnce).to.be.true;
+      });
+
+    });
+
+    describe('progress popup', function () {
+
+      var cases = [
+        {
+          serviceName: 'S0',
+          dependentServiceNames: [],
+          serviceNames: ['S0'],
+          message: 's0',
+          title: 'no dependent services'
+        },
+        {
+          serviceName: 'S1',
+          dependentServiceNames: ['S2', 'S3', 'S4'],
+          serviceNames: ['S1', 'S2', 'S3', 'S4'],
+          message: 's1, s2, s3 and s4',
+          title: 'dependent services present'
+        }
+      ];
+
+      cases.forEach(function (item) {
+
+        describe(item.title, function () {
+
+          beforeEach(function () {
+            sinon.stub(App.ModalPopup, 'show', function (options) {
+              options._super = Em.K;
+              if (options.onPrimary) {
+                options.onPrimary();
+              }
+              return options;
+            });
+            sinon.stub(App.Service, 'find', function (serviceName) {
+              return Em.Object.create({
+                displayName: serviceName.toLowerCase()
+              });
+            });
+            sinon.stub(mainServiceItemController, 'deleteServiceCall', Em.K);
+            mainServiceItemController.confirmDeleteService(item.serviceName, 
item.dependentServiceNames, '');
+          });
+
+          afterEach(function () {
+            App.Service.find.restore();
+            mainServiceItemController.deleteServiceCall.restore();
+          });
+
+          it('modal popups display', function () {
+            expect(App.ModalPopup.show.calledTwice).to.be.true;
+          });
+
+          it('progress popup message', function () {
+            
expect(mainServiceItemController.get('deleteServiceProgressPopup.message')).to.equal(Em.I18n.t('services.service.delete.progressPopup.message').format(item.message));
+          });
+
+          it('delete service call', function () {
+            
expect(mainServiceItemController.deleteServiceCall.calledOnce).to.be.true;
+          });
+
+          it('delete service call arguments', function () {
+            
expect(mainServiceItemController.deleteServiceCall.calledWith(item.serviceNames)).to.be.true;
+          });
+
+          it('progress popup close', function () {
+            
mainServiceItemController.get('deleteServiceProgressPopup').onClose();
+            
expect(mainServiceItemController.get('deleteServiceProgressPopup')).to.be.null;
+          });
+
+        });
+
+      });
+
     });
+
   });
 
   describe('#interDependentServices', function() {

Reply via email to