فهرست منبع

AMBARI-9320. Alerts: Prompt to save or discard changes when navigating from Alert Definition page. (akovalenko)

Aleksandr Kovalenko 10 سال پیش
والد
کامیت
3449ef33fd

+ 74 - 15
ambari-web/app/controllers/main/alerts/definition_details_controller.js

@@ -25,7 +25,7 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
         .filterProperty('definitionId', this.get('content.id'));
   }.property('App.router.mainAlertInstancesController.isLoaded', 'App.router.mainAlertInstancesController.reload'),
 
-  // stores object with editing form data (label, description, thresholds)
+  // stores object with editing form data (label)
   editing: Em.Object.create({
     label: Em.Object.create({
       name: 'label',
@@ -34,14 +34,6 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
       originalValue: '',
       isError: false,
       bindingValue: 'content.label'
-    }),
-    description: Em.Object.create({
-      name: 'description',
-      isEditing: false,
-      value: '',
-      originalValue: '',
-      isError: false,
-      bindingValue: 'content.description'
     })
   }),
 
@@ -51,6 +43,12 @@ 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}
@@ -68,12 +66,14 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
   }.observes('editing.label.value'),
 
   /**
-   * Validation function to define if description field populated correctly
-   * @method descriptionValidation
+   * Set init values for variables
    */
-  descriptionValidation: function () {
-    this.set('editing.description.isError', !this.get('editing.description.value').trim());
-  }.observes('editing.description.value'),
+  clearStep: function () {
+    var editing = this.get('editing');
+    Em.keys(editing).forEach(function (key) {
+      editing.get(key).set('isEditing', false);
+    });
+  },
 
   /**
    * Load alert instances for current alertDefinition
@@ -144,7 +144,7 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
   },
 
   /**
-   * Save button handler, could save label/description/thresholds of alert definition
+   * Save button handler, could save label of alert definition
    * @param {object} event
    * @returns {$.ajax}
    * @method saveEdit
@@ -168,6 +168,22 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
     });
   },
 
+  /**
+   * Onclick handler for save button on Save popup
+   * Save changes of label and configs
+   */
+  saveLabelAndConfigs: function () {
+    var configsController = App.router.get('mainAlertDefinitionConfigsController');
+    if (configsController.get('canEdit')) {
+      configsController.saveConfigs();
+    }
+    if (this.get('editing.label.isEditing')) {
+      this.saveEdit({
+        context: this.get('editing.label')
+      });
+    }
+  },
+
   /**
    * "Delete" button handler
    * @param {object} event
@@ -267,5 +283,48 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
       App.router.get('mainHostDetailsController').set('referer', App.router.location.lastSetURL);
       App.router.transitionTo('main.hosts.hostDetails.alerts', event.context);
     }
+  },
+
+  /**
+   * Define if label or configs are in edit mode
+   * @type {Boolean}
+   */
+  isEditing: function () {
+    return this.get('editing.label.isEditing') || App.router.get('mainAlertDefinitionConfigsController.canEdit');
+  }.property('editing.label.isEditing', 'App.router.mainAlertDefinitionConfigsController.canEdit'),
+
+  /**
+   * If some configs or label are changed and user navigates away, show this popup with propose to save changes
+   * @param {String} path
+   * @method showSavePopup
+   */
+  showSavePopup: function (path) {
+    var self = this;
+    return App.ModalPopup.show({
+      header: Em.I18n.t('common.warning'),
+      bodyClass: Em.View.extend({
+        template: Ember.Handlebars.compile('{{t alerts.saveChanges}}')
+      }),
+      primary: Em.I18n.t('common.save'),
+      secondary: Em.I18n.t('common.discard'),
+      third: Em.I18n.t('common.cancel'),
+      disablePrimary: function () {
+        return App.router.get('mainAlertDefinitionDetailsController.editing.label.isError') || App.router.get('mainAlertDefinitionConfigsController.hasErrors');
+      }.property('App.router.mainAlertDefinitionDetailsController.editing.label.isError', 'App.router.mainAlertDefinitionConfigsController.hasErrors'),
+      onPrimary: function () {
+        self.saveLabelAndConfigs();
+        self.set('forceTransition', true);
+        App.router.route(path);
+        this.hide();
+      },
+      onSecondary: function () {
+        self.set('forceTransition', true);
+        App.router.route(path);
+        this.hide();
+      },
+      onThird: function () {
+        this.hide();
+      }
+    });
   }
 });

+ 1 - 0
ambari-web/app/messages.js

@@ -915,6 +915,7 @@ Em.I18n.translations = {
   'alerts.table.state.disabled.confirm.btn': 'Confirm Enable',
   'alerts.filters.filteredAlertsInfo': '{0} of {1} definitions showing',
   'alerts.definition.name': 'Alert Definition Name',
+  'alerts.saveChanges': 'You have unsaved changes',
 
   'alerts.definition.details.enable': 'Enable',
   'alerts.definition.details.disable': 'Disable',

+ 10 - 0
ambari-web/app/routes/main.js

@@ -261,6 +261,16 @@ module.exports = Em.Route.extend({
 
       exit: function (router) {
         router.set('mainAlertInstancesController.isUpdating', false);
+      },
+
+      unroutePath: function (router, context) {
+        var controller = router.get('mainAlertDefinitionDetailsController');
+        if (!controller.get('forceTransition') && controller.get('isEditing')) {
+          controller.showSavePopup(context);
+        } else {
+          controller.set('forceTransition', false);
+          this._super(router, context);
+        }
       }
     }),
 

+ 2 - 1
ambari-web/app/views/main/alerts/definition_details_view.js

@@ -43,6 +43,7 @@ App.MainAlertDefinitionDetailsView = App.TableView.extend({
   }.property('controller.alerts.@each'),
 
   willInsertElement: function () {
+    this.get('controller').clearStep();
     var self = this,
       updater = App.router.get('updateController');
     if (self.get('controller.content.isLoaded')) {
@@ -56,7 +57,7 @@ App.MainAlertDefinitionDetailsView = App.TableView.extend({
             self.set('isLoaded', true);
             // App.AlertDefinition doesn't represents real models
             // Real model (see AlertDefinition types) should be used
-            self.set('controller.content', App.AlertDefinition.getAllDefinitions().findProperty('id', parseInt(self.get('controller.content.id'))));
+            self.set('controller.content', App.AlertDefinition.find().findProperty('id', parseInt(self.get('controller.content.id'))));
             self.get('controller').loadAlertInstances();
           });
         });

+ 0 - 10
ambari-web/test/controllers/main/alerts/definitions_details_controller_test.js

@@ -25,7 +25,6 @@ describe('App.MainAlertDefinitionDetailsController', function () {
   beforeEach(function () {
     controller = App.MainAlertDefinitionDetailsController.create({
       content: Em.Object.create({
-        description: 'description',
         label: 'label'
       })
     });
@@ -40,15 +39,6 @@ describe('App.MainAlertDefinitionDetailsController', function () {
 
   });
 
-  describe('#descriptionValidation()', function () {
-
-    it('should set editing.description.isError to true', function () {
-      controller.set('editing.description.value', ' ');
-      expect(controller.get('editing.description.isError')).to.be.true;
-    });
-
-  });
-
   describe('#edit()', function () {
 
     it('should change value of value, originalValue and isEditing properties', function () {