Browse Source

AMBARI-14295 No unsaved configs changes warning when opening Add Service Wizard (akovalenko)

Aleksandr Kovalenko 9 years ago
parent
commit
4bd4f27dd2

+ 3 - 11
ambari-web/app/controllers/main/alerts/definition_details_controller.js

@@ -43,12 +43,6 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
    */
   lastDayAlertsCount: null,
 
-  /**
-   * Define if let user leave the page
-   * @type {Boolean}
-   */
-  forceTransition: false,
-
   /**
    * List of all group names related to alert definition
    * @type {Array}
@@ -270,7 +264,7 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
    * @param {String} path
    * @method showSavePopup
    */
-  showSavePopup: function (path) {
+  showSavePopup: function (callback) {
     var self = this;
     return App.ModalPopup.show({
       header: Em.I18n.t('common.warning'),
@@ -283,13 +277,11 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
       disablePrimary: Em.computed.or('App.router.mainAlertDefinitionDetailsController.editing.label.isError', 'App.router.mainAlertDefinitionConfigsController.hasErrors'),
       onPrimary: function () {
         self.saveLabelAndConfigs();
-        self.set('forceTransition', true);
-        App.router.route(path);
+        callback();
         this.hide();
       },
       onSecondary: function () {
-        self.set('forceTransition', true);
-        App.router.route(path);
+        callback();
         this.hide();
       },
       onThird: function () {

+ 0 - 3
ambari-web/app/controllers/main/service/info/configs.js

@@ -26,8 +26,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
 
   isHostsConfigsPage: false,
 
-  forceTransition: false,
-
   isRecommendedLoaded: true,
 
   dataIsLoaded: false,
@@ -273,7 +271,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
       saveInProgress: false,
       isInit: true,
       hash: null,
-      forceTransition: false,
       dataIsLoaded: false,
       versionLoaded: false,
       filter: '',

+ 3 - 5
ambari-web/app/mixins/common/configs/configs_saver.js

@@ -632,7 +632,6 @@ App.ConfigsSaverMixin = Em.Mixin.create({
   showSaveConfigsPopup: function (header, flag, message, messageClass, value, status, urlParams) {
     var self = this;
     if (flag) {
-      this.set('forceTransition', flag);
       self.loadStep();
     }
     return App.ModalPopup.show({
@@ -812,7 +811,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    * @return {App.ModalPopup}
    * @method showSavePopup
    */
-  showSavePopup: function (path, callback) {
+  showSavePopup: function (transitionCallback, callback) {
     var self = this;
     var passwordWasChanged = this.get('passwordConfigsAreChanged');
     return App.ModalPopup.show({
@@ -850,9 +849,8 @@ App.ConfigsSaverMixin = Em.Mixin.create({
       },
       onDiscard: function () {
         self.set('preSelectedConfigVersion', null);
-        if (path) {
-          self.set('forceTransition', true);
-          App.router.route(path);
+        if (transitionCallback) {
+          transitionCallback();
         } else if (callback) {
           self.doCancel();
           // Prevent multiple popups

+ 8 - 9
ambari-web/app/routes/main.js

@@ -311,13 +311,12 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
         router.set('mainAlertInstancesController.isUpdating', false);
       },
 
-      unroutePath: function (router, context) {
+      exitRoute: function (router, context, callback) {
         var controller = router.get('mainAlertDefinitionDetailsController');
-        if (!controller.get('forceTransition') && controller.get('isEditing')) {
-          controller.showSavePopup(context);
+        if (controller.get('isEditing')) {
+          controller.showSavePopup(callback);
         } else {
-          controller.set('forceTransition', false);
-          this._super(router, context);
+          callback();
         }
       }
     }),
@@ -656,12 +655,12 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
             }
           });
         },
-        unroutePath: function (router, context) {
+        exitRoute: function (router, context, callback) {
           var controller = router.get('mainServiceInfoConfigsController');
-          if (!controller.get('forceTransition') && controller.hasUnsavedChanges()) {
-            controller.showSavePopup(context);
+          if (controller.hasUnsavedChanges()) {
+            controller.showSavePopup(callback);
           } else {
-            this._super(router, context);
+            callback();
           }
         }
       }),

+ 54 - 0
ambari-web/app/utils/ember_reopen.js

@@ -216,4 +216,58 @@ Em.View.reopen({
 
 Ember.TextArea.reopen({
   attributeBindings: ['readonly']
+});
+
+
+Ember.Route.reopen({
+  /**
+   *  When you move to a new route by pressing the back or forward button, change url manually, click on link with url defined in href,
+   *  call Router.transitionTo or Router.route this method is called.
+   *  This method unites unroutePath, navigateAway and exit events to handle Route leaving in one place.
+   *  Also unlike the exit event it is possible to stop transition inside this handler.
+   *  To proceed transition just call callback..
+   *
+   * @param {Router}  router
+   * @param {Object|String} context context from transition or path from route
+   * @param {callback} callback should be called to proceed transition
+   */
+  exitRoute: function (router, context, callback) {
+    callback();
+  }
+});
+
+Ember.Router.reopen({
+
+  // reopen original transitionTo and route methods to add calling of exitRoute
+
+  transitionTo: function (router, context) {
+    var self = this;
+    var args = arguments;
+    var transitionTo = self._super;
+    var callback = function () {
+      transitionTo.apply(self, args);
+    };
+    if (!this.get('currentState.exitRoute')) {
+      callback();
+    } else {
+      this.get('currentState').exitRoute(this, context, callback);
+    }
+  },
+
+  route: function (path) {
+    var self = this;
+    var args = arguments;
+    var transitionTo = self._super;
+    var callback = function () {
+      transitionTo.apply(self, args);
+    };
+    var realPath;
+    if (!this.get('currentState.exitRoute')) {
+      callback();
+    } else {
+      realPath = this.get('currentState').absoluteRoute(this);
+      this.get('location').setURL(realPath);
+      this.get('currentState').exitRoute(this, path, callback);
+    }
+  }
 });

+ 19 - 16
ambari-web/test/controllers/main/service/info/config_test.js

@@ -42,10 +42,10 @@ describe("App.MainServiceInfoConfigsController", function () {
   describe("#showSavePopup", function () {
     var tests = [
       {
-        path: false,
-        callback: null,
+        transitionCallback: false,
+        callback: false,
         action: "onSave",
-        m: "save configs without path/callback",
+        m: "save configs without transitionCallback/callback",
         results: [
           {
             method: "restartServicePopup",
@@ -54,10 +54,10 @@ describe("App.MainServiceInfoConfigsController", function () {
         ]
       },
       {
-        path: true,
+        transitionCallback: true,
         callback: true,
         action: "onSave",
-        m: "save configs with path/callback",
+        m: "save configs with transitionCallback/callback",
         results: [
           {
             method: "restartServicePopup",
@@ -66,10 +66,10 @@ describe("App.MainServiceInfoConfigsController", function () {
         ]
       },
       {
-        path: false,
+        transitionCallback: false,
         callback: false,
         action: "onDiscard",
-        m: "discard changes without path/callback",
+        m: "discard changes without transitionCallback/callback",
         results: [
           {
             method: "restartServicePopup",
@@ -78,7 +78,7 @@ describe("App.MainServiceInfoConfigsController", function () {
         ]
       },
       {
-        path: false,
+        transitionCallback: false,
         callback: true,
         action: "onDiscard",
         m: "discard changes with callback",
@@ -98,18 +98,18 @@ describe("App.MainServiceInfoConfigsController", function () {
         ]
       },
       {
-        path: true,
-        callback: null,
+        transitionCallback: true,
+        callback: false,
         action: "onDiscard",
-        m: "discard changes with path",
+        m: "discard changes with transitionCallback",
         results: [
           {
             method: "restartServicePopup",
             called: false
           },
           {
-            field: "forceTransition",
-            value: true
+            method: "transitionCallback",
+            called: true
           }
         ]
       }
@@ -126,13 +126,11 @@ describe("App.MainServiceInfoConfigsController", function () {
       sinon.stub(mainServiceInfoConfigsController, "getHash", function () {
         return "hash"
       });
-      sinon.stub(App.router, "route", Em.K);
     });
     afterEach(function () {
       mainServiceInfoConfigsController.get.restore();
       mainServiceInfoConfigsController.restartServicePopup.restore();
       mainServiceInfoConfigsController.getHash.restore();
-      App.router.route.restore();
     });
 
     tests.forEach(function (t) {
@@ -141,10 +139,15 @@ describe("App.MainServiceInfoConfigsController", function () {
           if (t.callback) {
             t.callback = sinon.stub();
           }
-          mainServiceInfoConfigsController.showSavePopup(t.path, t.callback)[t.action]();
+          if (t.transitionCallback) {
+            t.transitionCallback = sinon.stub();
+          }
+          mainServiceInfoConfigsController.showSavePopup(t.transitionCallback, t.callback)[t.action]();
           if (r.method) {
             if (r.method === 'callback') {
               expect(t.callback.calledOnce).to.equal(r.called);
+            } else if (r.method === 'transitionCallback') {
+              expect(t.transitionCallback.calledOnce).to.equal(r.called);
             } else {
               expect(mainServiceInfoConfigsController[r.method].calledOnce).to.equal(r.called);
             }