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

ambari git commit: AMBARI-8807. Alerts UI: cleanup. (xiwang via yusaku)

Repository: ambari
Updated Branches:
  refs/heads/trunk 6a39f2b37 -> 72e56dc6d


AMBARI-8807. Alerts UI: cleanup. (xiwang via yusaku)


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

Branch: refs/heads/trunk
Commit: 72e56dc6dd20464c2ddf1ee9b6c81e863a466401
Parents: 6a39f2b
Author: Yusaku Sako <yu...@hortonworks.com>
Authored: Mon Dec 22 17:10:54 2014 -0800
Committer: Yusaku Sako <yu...@hortonworks.com>
Committed: Mon Dec 22 17:10:54 2014 -0800

----------------------------------------------------------------------
 .../main/alerts/alert_instances_controller.js   |  7 +++
 .../alerts/definition_configs_controller.js     | 37 ++++++---------
 .../alerts/definition_details_controller.js     | 21 ++++++++-
 .../manage_alert_notifications_controller.js    | 49 ++++++++++++++++++++
 .../controllers/main/service/info/summary.js    | 13 ++++--
 .../app/mappers/alert_definitions_mapper.js     | 20 +++++---
 ambari-web/app/messages.js                      |  4 +-
 .../app/mixins/common/table_server_mixin.js     |  2 +-
 ambari-web/app/models/alert_definition.js       | 20 ++++++++
 ambari-web/app/styles/alerts.less               | 13 ++++--
 .../alerts/configs/alert_config_threshold.hbs   |  6 +--
 .../main/alerts/create_alert_notification.hbs   | 27 +++++++++--
 .../main/alerts/definition_details.hbs          |  2 +-
 .../alerts/manage_alert_notifications_popup.hbs | 12 ++++-
 .../definitions_configs_controller_test.js      |  4 +-
 .../definitions_details_controller_test.js      | 24 ++++++----
 16 files changed, 197 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/alert_instances_controller.js b/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
index 93d2994..024887a 100644
--- a/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
+++ b/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
@@ -29,6 +29,12 @@ App.MainAlertInstancesController = Em.Controller.extend({
   isLoaded: false,
 
   /**
+   * A flag to reload alert instances table every 10 seconds
+   * @type {boolean}
+   */
+  reload: false,
+
+  /**
    * Causes automatic updates of content if set to true
    * @type {boolean}
    */
@@ -153,6 +159,7 @@ App.MainAlertInstancesController = Em.Controller.extend({
   getAlertInstancesSuccessCallback: function (json) {
     App.alertInstanceMapper.map(json);
     this.set('isLoaded', true);
+    this.set('reload', !this.get('reload'));
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/definition_configs_controller.js b/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
index 199e0cd..4fa0e5b 100644
--- a/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
+++ b/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
@@ -171,13 +171,12 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
         value: isWizard ? '' : this.getThresholdsProperty('ok', 'value')
       }),
       App.AlertConfigProperties.Thresholds.WarningThreshold.create({
-        valueMetric: 'Sec',
+        valueMetric: 'Seconds',
         text: isWizard ? '' : this.getThresholdsProperty('warning', 'text'),
         value: isWizard ? '' : this.getThresholdsProperty('warning', 'value')
-
       }),
       App.AlertConfigProperties.Thresholds.CriticalThreshold.create({
-        valueMetric: 'Sec',
+        valueMetric: 'Seconds',
         text: isWizard ? '' : this.getThresholdsProperty('critical', 'text'),
         value: isWizard ? '' : this.getThresholdsProperty('critical', 'value')
       })
@@ -195,6 +194,8 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
     var result = [];
     var alertDefinition = this.get('content');
     var isWizard = this.get('isWizard');
+    var units = this.get('content.reporting').findProperty('type','units') ?
+      this.get('content.reporting').findProperty('type','units').get('text'): null;
 
     if (this.get('isWizard')) {
       result = result.concat(this.renderCommonWizardConfigs());
@@ -214,10 +215,12 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
         value: isWizard ? '' : this.getThresholdsProperty('ok', 'value')
       }),
       App.AlertConfigProperties.Thresholds.WarningThreshold.create({
+        valueMetric: units,
         text: isWizard ? '' : this.getThresholdsProperty('warning', 'text'),
         value: isWizard ? '' : this.getThresholdsProperty('warning', 'value')
       }),
       App.AlertConfigProperties.Thresholds.CriticalThreshold.create({
+        valueMetric: units,
         text: isWizard ? '' : this.getThresholdsProperty('critical', 'text'),
         value: isWizard ? '' : this.getThresholdsProperty('critical', 'value')
       })
@@ -288,22 +291,6 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
       }),
       App.AlertConfigProperties.Interval.create({
         value: isWizard ? '' : alertDefinition.get('interval')
-      }),
-      App.AlertConfigProperties.Thresholds.OkThreshold.create({
-        label: 'Thresholds',
-        showInputForValue: false,
-        text: isWizard ? '' : this.getThresholdsProperty('ok', 'text'),
-        value: isWizard ? '' : this.getThresholdsProperty('ok', 'value')
-      }),
-      App.AlertConfigProperties.Thresholds.WarningThreshold.create({
-        showInputForValue: false,
-        text: isWizard ? '' : this.getThresholdsProperty('warning', 'text'),
-        value: isWizard ? '' : this.getThresholdsProperty('warning', 'value')
-      }),
-      App.AlertConfigProperties.Thresholds.CriticalThreshold.create({
-        showInputForValue: false,
-        text: isWizard ? '' : this.getThresholdsProperty('critical', 'text'),
-        value: isWizard ? '' : this.getThresholdsProperty('critical', 'value')
       })
     ]);
 
@@ -502,10 +489,14 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
    * @type {Boolean}
    */
   hasThresholdsError: function () {
-    var smallValue = Em.get(this.get('configs').findProperty('name', 'warning_threshold'), 'value');
-    var smallValid = Em.get(this.get('configs').findProperty('name', 'warning_threshold'), 'isValid');
-    var largeValue = Em.get(this.get('configs').findProperty('name', 'critical_threshold'), 'value');
-    var largeValid = Em.get(this.get('configs').findProperty('name', 'critical_threshold'), 'isValid');
+    if (this.get('configs').findProperty('name', 'warning_threshold')) {
+      var smallValue = Em.get(this.get('configs').findProperty('name', 'warning_threshold'), 'value');
+      var smallValid = Em.get(this.get('configs').findProperty('name', 'warning_threshold'), 'isValid');
+    }
+    if (this.get('configs').findProperty('name', 'critical_threshold')) {
+      var largeValue = Em.get(this.get('configs').findProperty('name', 'critical_threshold'), 'value');
+      var largeValid = Em.get(this.get('configs').findProperty('name', 'critical_threshold'), 'isValid');
+    }
     return smallValid && largeValid ? !(smallValue <= largeValue) : false;
   }.property('configs.@each.value'),
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/controllers/main/alerts/definition_details_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/definition_details_controller.js b/ambari-web/app/controllers/main/alerts/definition_details_controller.js
index 1197ac1..606c1f7 100644
--- a/ambari-web/app/controllers/main/alerts/definition_details_controller.js
+++ b/ambari-web/app/controllers/main/alerts/definition_details_controller.js
@@ -23,7 +23,7 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
   alerts: function () {
     return App.AlertInstance.find().toArray()
         .filterProperty('definitionId', this.get('content.id'));
-  }.property('App.router.mainAlertInstancesController.isLoaded'),
+  }.property('App.router.mainAlertInstancesController.isLoaded', 'App.router.mainAlertInstancesController.reload'),
 
   // stores object with editing form data (label, description, thresholds)
   editing: Em.Object.create({
@@ -211,11 +211,28 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
 
   /**
    * "Disable / Enable" button handler
-   * @returns {$.ajax}
    * @method toggleState
    */
   toggleState: function () {
     var alertDefinition = this.get('content');
+    var self = this;
+    var bodyMessage = Em.Object.create({
+      confirmMsg: alertDefinition.get('enabled') ? Em.I18n.t('alerts.table.state.enabled.confirm.msg') : Em.I18n.t('alerts.table.state.disabled.confirm.msg'),
+      confirmButton: alertDefinition.get('enabled') ? Em.I18n.t('alerts.table.state.enabled.confirm.btn') : Em.I18n.t('alerts.table.state.disabled.confirm.btn')
+    });
+
+    return App.showConfirmationFeedBackPopup(function (query) {
+      self.toggleDefinitionState(alertDefinition);
+    }, bodyMessage);
+  },
+
+  /**
+   * Enable/disable alertDefinition
+   * @param {object} alertDefinition
+   * @returns {$.ajax}
+   * @method toggleDefinitionState
+   */
+  toggleDefinitionState: function (alertDefinition) {
     var newState = !alertDefinition.get('enabled');
     alertDefinition.set('enabled', newState);
     return App.ajax.send({

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
index c05e8dc..6dc28e4 100644
--- a/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
+++ b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
@@ -336,6 +336,10 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
         didInsertElement: function () {
           App.tooltip($('.checkbox-tooltip'));
           this.nameValidation();
+          this.emailToValidation();
+          this.emailFromValidation();
+          this.smtpPortValidation();
+          this.portValidation();
         },
 
         isEmailMethodSelected: function () {
@@ -346,6 +350,51 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
           this.set('parentView.hasErrors', !this.get('controller.inputFields.name.value').trim());
         }.observes('controller.inputFields.name.value'),
 
+        emailToValidation: function () {
+          var emailTo = this.get('controller.inputFields.email.value');
+          if (emailTo && !validator.isValidEmail(emailTo)) {
+            this.set('parentView.hasErrors', true);
+            this.set('controller.inputFields.email.errorMsg', 'Must be a valid email address');
+          } else {
+            this.set('parentView.hasErrors', false);
+            this.set('controller.inputFields.email.errorMsg', null);
+          }
+        }.observes('controller.inputFields.email.value'),
+
+        emailFromValidation: function () {
+          var emailFrom = this.get('controller.inputFields.emailFrom.value');
+          if (emailFrom && !validator.isValidEmail(emailFrom)) {
+            this.set('parentView.hasErrors', true);
+            this.set('controller.inputFields.emailFrom.errorMsg', 'Must be a valid email address');
+          } else {
+            this.set('parentView.hasErrors', false);
+            this.set('controller.inputFields.emailFrom.errorMsg', null);
+          }
+        }.observes('controller.inputFields.emailFrom.value'),
+
+        smtpPortValidation: function () {
+          var value = this.get('controller.inputFields.SMTPPort.value');
+          if (value && (!validator.isValidInt(value) || value < 0)) {
+            this.set('parentView.hasErrors', true);
+            this.set('controller.inputFields.SMTPPort.errorMsg', 'Invalid! Please enter positive integer.');
+          } else {
+            this.set('parentView.hasErrors', false);
+            this.set('controller.inputFields.SMTPPort.errorMsg', null);
+          }
+        }.observes('controller.inputFields.SMTPPort.value'),
+
+        portValidation: function () {
+          var value = this.get('controller.inputFields.port.value');
+          if (value && (!validator.isValidInt(value) || value < 0)) {
+            this.set('parentView.hasErrors', true);
+            this.set('controller.inputFields.port.errorMsg', 'Invalid! Please enter positive integer.');
+          } else {
+            this.set('parentView.hasErrors', false);
+            this.set('controller.inputFields.port.errorMsg', null);
+          }
+        }.observes('controller.inputFields.port.value'),
+
+
         groupsSelectView: Em.Select.extend({
           attributeBindings: ['disabled'],
           init: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/controllers/main/service/info/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/summary.js b/ambari-web/app/controllers/main/service/info/summary.js
index 58f9b23..8800e62 100644
--- a/ambari-web/app/controllers/main/service/info/summary.js
+++ b/ambari-web/app/controllers/main/service/info/summary.js
@@ -118,9 +118,8 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
         },
         alerts: function () {
           var serviceDefinitions = this.get('controller.content').filterProperty('service', service);
-          // definitions should be sorted in order: critical, warning, all other
-          var criticalDefinitions = [];
-          var warningDefinitions = [];
+          // definitions should be sorted in order: critical, warning, ok, unknown, other
+          var criticalDefinitions = [], warningDefinitions = [], okDefinitions = [], unknownDefinitions = [];
           serviceDefinitions.forEach(function (definition) {
             if (definition.get('isCritical')) {
               criticalDefinitions.push(definition);
@@ -128,9 +127,15 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
             } else if (definition.get('isWarning')) {
               warningDefinitions.push(definition);
               serviceDefinitions = serviceDefinitions.without(definition);
+            } else if (definition.get('isOK')) {
+              okDefinitions.push(definition);
+              serviceDefinitions = serviceDefinitions.without(definition);
+            } else if (definition.get('isUnknown')) {
+              unknownDefinitions.push(definition);
+              serviceDefinitions = serviceDefinitions.without(definition);
             }
           });
-          serviceDefinitions = criticalDefinitions.concat(warningDefinitions, serviceDefinitions);
+          serviceDefinitions = criticalDefinitions.concat(warningDefinitions, okDefinitions, unknownDefinitions, serviceDefinitions);
           return serviceDefinitions;
         }.property('controller.content'),
         gotoAlertDetails: function (event) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/mappers/alert_definitions_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/alert_definitions_mapper.js b/ambari-web/app/mappers/alert_definitions_mapper.js
index 414496c..5155180 100644
--- a/ambari-web/app/mappers/alert_definitions_mapper.js
+++ b/ambari-web/app/mappers/alert_definitions_mapper.js
@@ -94,12 +94,20 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
         var reporting = item.AlertDefinition.source.reporting;
         for (var report in reporting) {
           if (reporting.hasOwnProperty(report)) {
-            convertedReportDefinitions.push({
-              id: item.AlertDefinition.id + report,
-              type: report,
-              text: reporting[report].text,
-              value: reporting[report].value
-            });
+            if (report == "units") {
+              convertedReportDefinitions.push({
+                id: item.AlertDefinition.id + report,
+                type: report,
+                text: reporting[report]
+              });
+            } else {
+              convertedReportDefinitions.push({
+                id: item.AlertDefinition.id + report,
+                type: report,
+                text: reporting[report].text,
+                value: reporting[report].value
+              });
+            }
           }
         }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index b40c964..b810042 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -898,7 +898,7 @@ Em.I18n.translations = {
   'alerts.table.state.enabled.confirm.btn': 'Confirm Disable',
   'alerts.table.state.disabled.confirm.btn': 'Confirm Enable',
   'alerts.filters.filteredAlertsInfo': '{0} of {1} definitions showing',
-  'alerts.definition.name': 'Alert Definition name',
+  'alerts.definition.name': 'Alert Definition Name',
 
   'alerts.definition.details.enable': 'Enable',
   'alerts.definition.details.disable': 'Disable',
@@ -1934,6 +1934,8 @@ Em.I18n.translations = {
   'alerts.actions.manage_alert_notifications_popup.community':'Community',
   'alerts.actions.manage_alert_notifications_popup.port':'Port',
   'alerts.actions.manage_alert_notifications_popup.global':'Global',
+  'alerts.actions.manage_alert_notifications_popup.noDescription':'<i>No description</i>',
+  'alerts.actions.manage_alert_notifications_popup.noGroup':'<i>None selected</i>',
   'alerts.actions.manage_alert_notifications_popup.severityFilter':'Severity',
   'alerts.actions.manage_alert_notifications_popup.clearAll':'Clear All',
   'alerts.actions.manage_alert_notifications_popup.selectAll':'Select All',

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/mixins/common/table_server_mixin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/table_server_mixin.js b/ambari-web/app/mixins/common/table_server_mixin.js
index c0610b0..9c35d98 100644
--- a/ambari-web/app/mixins/common/table_server_mixin.js
+++ b/ambari-web/app/mixins/common/table_server_mixin.js
@@ -101,7 +101,7 @@ App.TableServerMixin = Em.Mixin.create({
     savedFilterConditions.forEach(function (filter) {
       var property = filterProperties.findProperty('name', colPropAssoc[filter.iColumn]);
 
-      if (property && filter.value.length > 0 && !filter.skipFilter) {
+      if (property && filter.value && filter.value.length > 0 && !filter.skipFilter) {
         property.isFilter = true;
 
         if (filter.type === 'range') {

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/models/alert_definition.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/alert_definition.js b/ambari-web/app/models/alert_definition.js
index 173897e..d7e56fb 100644
--- a/ambari-web/app/models/alert_definition.js
+++ b/ambari-web/app/models/alert_definition.js
@@ -181,6 +181,26 @@ App.AlertDefinition = DS.Model.extend({
   }.property('summary'),
 
   /**
+   * if this definition is in state: OK
+   * @type {boolean}
+   */
+  isOK: function () {
+    var summary = this.get('summary');
+    var state = 'OK';
+    return !!summary[state];
+  }.property('summary'),
+
+  /**
+   * if this definition is in state: OK
+   * @type {boolean}
+   */
+  isUnknown: function () {
+    var summary = this.get('summary');
+    var state = 'UNKNOWN';
+    return !!summary[state];
+  }.property('summary'),
+
+  /**
    * For alerts we will have processes which are not typical
    * cluster services - like Ambari-Server. This method unifies
    * cluster services and other services into a common display-name.

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/styles/alerts.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/alerts.less b/ambari-web/app/styles/alerts.less
index 87ea103..3d9452d 100644
--- a/ambari-web/app/styles/alerts.less
+++ b/ambari-web/app/styles/alerts.less
@@ -414,6 +414,9 @@
     .control-label {
       font-weight: bold;
     }
+    .error-msg {
+      color: #b94a48;
+    }
   }
   label {
     width: 115px;
@@ -452,16 +455,16 @@
 
 .service-block .summary-box-header {
   .alerts-count-label,.no-alerts-label {
-    padding: 2px 4px;
-    margin-right: 5px;
-    margin-top: 5px;
+    padding: 4px 5px;
+    margin: 4px;
+    font-size: 14px;
     cursor: pointer;
   }
   .alerts-count-label {
-    background: #953B39;
+    background: @health-status-red;
   }
   .no-alerts-label {
-    background: #006400;
+    background: @health-status-green;
   }
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/templates/main/alerts/configs/alert_config_threshold.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/configs/alert_config_threshold.hbs b/ambari-web/app/templates/main/alerts/configs/alert_config_threshold.hbs
index 223b0ef..9e5cad8 100644
--- a/ambari-web/app/templates/main/alerts/configs/alert_config_threshold.hbs
+++ b/ambari-web/app/templates/main/alerts/configs/alert_config_threshold.hbs
@@ -19,14 +19,14 @@
 <div>
   <div class="span2 badge-container"><span {{bindAttr class="view.property.badgeCssClass :alert-threshold-badge :alert-state-single-host :label"}}>{{view.property.badge}}</span>&nbsp;</div>
   {{#if view.property.showInputForValue}}
-    <div {{bindAttr class=":span2 view.property.valueMetric:input-append"}}>
-        {{view Em.TextField valueBinding="view.property.displayValue" disabledBinding="view.property.isDisabled" class="span10"}}
+    <div {{bindAttr class=":span3 view.property.valueMetric:input-append"}}>
+        {{view Em.TextField valueBinding="view.property.displayValue" disabledBinding="view.property.isDisabled" class ="span7"}}
         {{#if view.property.valueMetric}}
           <span class="add-on">{{view.property.valueMetric}}</span>
         {{/if}}
     </div>
   {{/if}}
-  <div {{bindAttr class=":alert-text-input view.property.showInputForValue:span8:span10"}}>
+  <div {{bindAttr class=":alert-text-input view.property.showInputForValue:span7:span10"}}>
     {{#if view.property.showInputForText}}
       {{view Em.TextField valueBinding="view.property.text" disabledBinding="view.property.isDisabled"}}
     {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/templates/main/alerts/create_alert_notification.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/create_alert_notification.hbs b/ambari-web/app/templates/main/alerts/create_alert_notification.hbs
index 9823a7c..42f2c74 100644
--- a/ambari-web/app/templates/main/alerts/create_alert_notification.hbs
+++ b/ambari-web/app/templates/main/alerts/create_alert_notification.hbs
@@ -92,12 +92,16 @@
 
     {{! alert-notification email }}
     {{#if view.isEmailMethodSelected}}
-      <div class="control-group">
+      <div {{bindAttr class=":control-group controller.inputFields.email.errorMsg:error"}}>
         <label class="control-label" for="inputEmail">{{controller.inputFields.email.label}}</label>
 
         <div class="controls">
           {{view Em.TextField valueBinding="controller.inputFields.email.value" id="inputEmail" class="input-xlarge"}}
         </div>
+
+        <div class="controls error-msg">
+          {{controller.inputFields.email.errorMsg}}
+        </div>
       </div>
 
       <div class="control-group">
@@ -108,12 +112,17 @@
         </div>
       </div>
 
-      <div class="control-group">
+      <div {{bindAttr class=":control-group controller.inputFields.SMTPPort.errorMsg:error"}}>
         <label class="control-label">{{controller.inputFields.SMTPPort.label}}</label>
 
         <div class="controls">
-          {{view Em.TextField valueBinding="controller.inputFields.SMTPPort.value" class="input-xlarge"}}
+          {{view Em.TextField valueBinding="controller.inputFields.SMTPPort.value"}}
         </div>
+
+        <div class="controls error-msg">
+          {{controller.inputFields.SMTPPort.errorMsg}}
+        </div>
+
       </div>
 
       <div class="control-group">
@@ -148,12 +157,16 @@
         </div>
       </div>
 
-      <div class="control-group">
+      <div {{bindAttr class=":control-group controller.inputFields.emailFrom.errorMsg:error"}}>
         <label class="control-label">{{controller.inputFields.emailFrom.label}}</label>
 
         <div class="controls">
           {{view Em.TextField valueBinding="controller.inputFields.emailFrom.value" class="input-xlarge"}}
         </div>
+
+        <div class="controls error-msg">
+          {{controller.inputFields.emailFrom.errorMsg}}
+        </div>
       </div>
     {{else}}
       <div class="control-group">
@@ -180,12 +193,16 @@
         </div>
       </div>
 
-      <div class="control-group">
+      <div {{bindAttr class=":control-group controller.inputFields.port.errorMsg:error"}}>
         <label class="control-label">{{controller.inputFields.port.label}}</label>
 
         <div class="controls">
           {{view Em.TextField valueBinding="controller.inputFields.port.value" class="input-xlarge"}}
         </div>
+
+        <div class="controls error-msg">
+          {{controller.inputFields.port.errorMsg}}
+        </div>
       </div>
     {{/if}}
     {{! alert-notification email end }}

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/templates/main/alerts/definition_details.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/definition_details.hbs b/ambari-web/app/templates/main/alerts/definition_details.hbs
index fd04486..da76a5a 100644
--- a/ambari-web/app/templates/main/alerts/definition_details.hbs
+++ b/ambari-web/app/templates/main/alerts/definition_details.hbs
@@ -194,7 +194,7 @@
           {{/each}}
         {{else}}
           <tr>
-            <td colspan="5">
+            <td class="first" colspan="5">
               {{t alerts.definition.details.noAlerts}}
             </td>
           </tr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/app/templates/main/alerts/manage_alert_notifications_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/manage_alert_notifications_popup.hbs b/ambari-web/app/templates/main/alerts/manage_alert_notifications_popup.hbs
index 5f749de..ed18c63 100644
--- a/ambari-web/app/templates/main/alerts/manage_alert_notifications_popup.hbs
+++ b/ambari-web/app/templates/main/alerts/manage_alert_notifications_popup.hbs
@@ -73,7 +73,11 @@
                       {{#if selectedAlertNotification.global}}
                         {{t common.all}}
                       {{else}}
-                        {{view.selectedAlertNotificationGroups}}
+                        {{#if view.selectedAlertNotificationGroups}}
+                          {{view.selectedAlertNotificationGroups}}
+                        {{else}}
+                          {{t alerts.actions.manage_alert_notifications_popup.noGroup}}
+                        {{/if}}
                       {{/if}}
                     </div>
                   </div>
@@ -95,7 +99,11 @@
                   {{/if}}
                   <div class="row-fluid">
                     <div class="span3 input-label">{{t common.description}}</div>
-                    <div class="span9 notification-description">{{selectedAlertNotification.description}}</div>
+                    {{#if selectedAlertNotification.description}}
+                      <div class="span9 notification-description">{{selectedAlertNotification.description}}</div>
+                    {{else}}
+                      <div class="span9 notification-description">{{t alerts.actions.manage_alert_notifications_popup.noDescription}}</div>
+                    {{/if}}
                   </div>
                 {{/if}}
               {{else}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js b/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
index b7a6b85..0ea85e6 100644
--- a/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
+++ b/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
@@ -266,12 +266,12 @@ describe('App.MainAlertDefinitionConfigsController', function () {
       controller.set('isWizard', true);
       var result = controller.renderScriptConfigs();
 
-      expect(result.length).to.equal(11);
+      expect(result.length).to.equal(8);
 
       controller.set('isWizard', false);
       result = controller.renderScriptConfigs();
 
-      expect(result.length).to.equal(5);
+      expect(result.length).to.equal(2);
     });
 
   });

http://git-wip-us.apache.org/repos/asf/ambari/blob/72e56dc6/ambari-web/test/controllers/main/alerts/definitions_details_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/alerts/definitions_details_controller_test.js b/ambari-web/test/controllers/main/alerts/definitions_details_controller_test.js
index d02c39d..18784ad 100644
--- a/ambari-web/test/controllers/main/alerts/definitions_details_controller_test.js
+++ b/ambari-web/test/controllers/main/alerts/definitions_details_controller_test.js
@@ -79,19 +79,25 @@ describe('App.MainAlertDefinitionDetailsController', function () {
 
   });
 
-  describe('#toggleState()', function () {
-
-    it('should call App.ajax.send function', function () {
-
-      sinon.spy(App.ajax, 'send');
-
-      controller.toggleState();
-
-      expect(App.ajax.send.calledOnce).to.be.true;
+  describe('#toggleDefinitionState()', function () {
+    beforeEach(function() {
+      sinon.stub(App.ajax, 'send', Em.K);
+      controller.reopen({
+        content: [
+          App.AlertDefinition.createRecord({id: 1, enabled: true})
+        ]
+      });
+    });
 
+    afterEach(function() {
       App.ajax.send.restore();
     });
 
+    it('should call App.ajax.send function', function () {
+      var alertDefinition = controller.get('content')[0];
+      controller.toggleDefinitionState(alertDefinition);
+      expect(App.ajax.send.calledOnce).to.be.true;
+    });
   });
 
   describe("#goToHostAlerts()", function () {