You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2016/02/25 13:15:47 UTC

[2/2] ambari git commit: AMBARI-15180. Remove duplicate code from widgets views (onechiporenko)

AMBARI-15180. Remove duplicate code from widgets views (onechiporenko)


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

Branch: refs/heads/trunk
Commit: 87f8746f46494d688b5cc0ae6040ec137723b414
Parents: afc2f7b
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Thu Feb 25 14:05:24 2016 +0200
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Thu Feb 25 14:15:25 2016 +0200

----------------------------------------------------------------------
 ambari-web/app/mixins.js                        |   2 +
 .../mixins/main/dashboard/widgets/editable.js   | 124 ++++++++++++
 .../dashboard/widgets/editable_with_limit.js    | 138 +++++++++++++
 ambari-web/app/utils/ajax/ajax.js               |   2 +-
 ambari-web/app/views/main/dashboard/widget.js   |  63 +++---
 ambari-web/app/views/main/dashboard/widgets.js  |   4 +-
 .../dashboard/widgets/cluster_metrics_widget.js |   4 +
 .../main/dashboard/widgets/datanode_live.js     | 200 +++++--------------
 .../main/dashboard/widgets/flume_agent_live.js  | 131 ++----------
 .../main/dashboard/widgets/hawqsegment_live.js  | 191 +++++-------------
 .../dashboard/widgets/hbase_average_load.js     | 109 +---------
 .../views/main/dashboard/widgets/hbase_links.js |   6 +-
 .../main/dashboard/widgets/hbase_master_heap.js |   4 +-
 .../widgets/hbase_regions_in_transition.js      | 112 +----------
 .../main/dashboard/widgets/hdfs_capacity.js     |  34 ++--
 .../views/main/dashboard/widgets/hdfs_links.js  |   8 +-
 .../main/dashboard/widgets/links_widget.js      |   1 -
 .../main/dashboard/widgets/namenode_cpu.js      |  26 +--
 .../main/dashboard/widgets/namenode_heap.js     |   5 +-
 .../main/dashboard/widgets/namenode_rpc.js      | 124 ++----------
 .../dashboard/widgets/node_managers_live.js     | 138 ++-----------
 .../main/dashboard/widgets/pie_chart_widget.js  |  41 ++--
 .../dashboard/widgets/resource_manager_heap.js  |   5 +-
 .../widgets/resource_manager_uptime.js          |   1 -
 .../main/dashboard/widgets/supervisor_live.js   | 133 ++----------
 .../views/main/dashboard/widgets/text_widget.js |   9 +-
 .../dashboard/widgets/uptime_text_widget.js     |   4 +-
 .../views/main/dashboard/widgets/yarn_memory.js |   1 -
 .../test/views/main/dashboard/widget_test.js    |   2 +
 .../dashboard/widgets/datanode_live_test.js     |  87 ++++----
 .../dashboard/widgets/hawqsegment_live_test.js  |  72 ++++---
 .../widgets/hbase_average_load_test.js          |  24 ---
 .../widgets/hbase_regions_in_transition_test.js |  24 ---
 .../main/dashboard/widgets/links_widget_test.js |   3 +
 .../main/dashboard/widgets/namenode_rpc_test.js |  14 --
 .../widgets/resource_manager_uptime_test.js     |  12 --
 .../main/dashboard/widgets/text_widget_test.js  |  33 ---
 .../widgets/uptime_text_widget_test.js          |   7 +-
 38 files changed, 610 insertions(+), 1288 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/mixins.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins.js b/ambari-web/app/mixins.js
index 460953e..0a686b3 100644
--- a/ambari-web/app/mixins.js
+++ b/ambari-web/app/mixins.js
@@ -28,6 +28,8 @@ require('mixins/common/reload_popup');
 require('mixins/common/serverValidator');
 require('mixins/common/table_server_view_mixin');
 require('mixins/common/table_server_mixin');
+require('mixins/main/dashboard/widgets/editable');
+require('mixins/main/dashboard/widgets/editable_with_limit');
 require('mixins/main/host/details/host_components/decommissionable');
 require('mixins/main/host/details/host_components/install_component');
 require('mixins/main/host/details/actions/install_new_version');

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/mixins/main/dashboard/widgets/editable.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/main/dashboard/widgets/editable.js b/ambari-web/app/mixins/main/dashboard/widgets/editable.js
new file mode 100644
index 0000000..9081ee8
--- /dev/null
+++ b/ambari-web/app/mixins/main/dashboard/widgets/editable.js
@@ -0,0 +1,124 @@
+/**
+ * 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.EditableWidgetMixin = Em.Mixin.create({
+
+  hintInfo: '',
+
+  editWidget: function () {
+    var parent = this;
+    var configObj = Ember.Object.create({
+      thresh1: parent.get('thresh1') + '',
+      thresh2: parent.get('thresh2') + '',
+      hintInfo: parent.get('hintInfo'),
+      isThresh1Error: false,
+      isThresh2Error: false,
+      errorMessage1: "",
+      errorMessage2: "",
+      maxValue: 'infinity',
+      observeNewThresholdValue: function () {
+        var thresh1 = this.get('thresh1');
+        var thresh2 = this.get('thresh2');
+        if (thresh1.trim() !== "") {
+          if (isNaN(thresh1) || thresh1 < 0) {
+            this.set('isThresh1Error', true);
+            this.set('errorMessage1', 'Invalid! Enter a number larger than 0');
+          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)){
+            this.set('isThresh1Error', true);
+            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
+          } else {
+            this.set('isThresh1Error', false);
+            this.set('errorMessage1', '');
+          }
+        } else {
+          this.set('isThresh1Error', true);
+          this.set('errorMessage1', 'This is required');
+        }
+
+        if (thresh2.trim() !== "") {
+          if (isNaN(thresh2) || thresh2 < 0) {
+            this.set('isThresh2Error', true);
+            this.set('errorMessage2', 'Invalid! Enter a number larger than 0');
+          } else {
+            this.set('isThresh2Error', false);
+            this.set('errorMessage2', '');
+          }
+        } else {
+          this.set('isThresh2Error', true);
+          this.set('errorMessage2', 'This is required');
+        }
+
+      }.observes('thresh1', 'thresh2')
+
+    });
+
+    var browserVerion = this.getInternetExplorerVersion();
+    App.ModalPopup.show( {
+      header: Em.I18n.t('dashboard.widgets.popupHeader'),
+      classNames: [ 'sixty-percent-width-modal-edit-widget'],
+      bodyClass: Ember.View.extend({
+        templateName: require('templates/main/dashboard/edit_widget_popup'),
+        configPropertyObj: configObj
+      }),
+      primary: Em.I18n.t('common.apply'),
+      onPrimary: function () {
+        configObj.observeNewThresholdValue();
+        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
+          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
+          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
+          if (!App.get('testMode')) {
+            //save to persist
+            var bigParent = parent.get('parentView');
+            bigParent.getUserPref(bigParent.get('persistKey'));
+            var oldValue = bigParent.get('currentPrefObject');
+            oldValue.threshold[parseInt(parent.id, 10)] = [configObj.get('thresh1'), configObj.get('thresh2')];
+            bigParent.postUserPref(bigParent.get('persistKey'),oldValue);
+          }
+
+          this.hide();
+        }
+      },
+
+      didInsertElement: function () {
+        var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
+        var handlers = [33, 66]; //fixed value
+
+        if (browserVerion === -1 || browserVerion > 9) {
+          configObj.set('isIE9', false);
+          configObj.set('isGreenOrangeRed', true);
+          $("#slider-range").slider({
+            range:true,
+            disabled:true, //handlers cannot move
+            min: 0,
+            max: 100,
+            values: handlers,
+            create: function (event, ui) {
+              parent.updateColors(handlers, colors);
+            }
+          });
+        } else {
+          configObj.set('isIE9', true);
+          configObj.set('isGreenOrangeRed', true);
+        }
+      }
+    });
+  }
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/mixins/main/dashboard/widgets/editable_with_limit.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/main/dashboard/widgets/editable_with_limit.js b/ambari-web/app/mixins/main/dashboard/widgets/editable_with_limit.js
new file mode 100644
index 0000000..203bf11
--- /dev/null
+++ b/ambari-web/app/mixins/main/dashboard/widgets/editable_with_limit.js
@@ -0,0 +1,138 @@
+/**
+ * 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');
+
+/**
+ * @type {Em.Mixin}
+ */
+App.EditableWithLimitWidgetMixin = Em.Mixin.create({
+
+  hintInfo: '',
+
+  editWidget: function () {
+    var parent = this;
+    var maxTmp = parseFloat(parent.get('maxValue'));
+    var configObj = Ember.Object.create({
+      thresh1: parent.get('thresh1') + '',
+      thresh2: parent.get('thresh2') + '',
+      hintInfo: parent.get('hintInfo'),
+      isThresh1Error: false,
+      isThresh2Error: false,
+      errorMessage1: "",
+      errorMessage2: "",
+      maxValue: maxTmp,
+      observeNewThresholdValue: function () {
+        var thresh1 = this.get('thresh1');
+        var thresh2 = this.get('thresh2');
+        if (thresh1.trim() !== "") {
+          if (isNaN(thresh1) || thresh1 > maxTmp || thresh1 < 0){
+            this.set('isThresh1Error', true);
+            this.set('errorMessage1', 'Invalid! Enter a number between 0 - ' + maxTmp);
+          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)) {
+            this.set('isThresh1Error', true);
+            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
+          } else {
+            this.set('isThresh1Error', false);
+            this.set('errorMessage1', '');
+          }
+        } else {
+          this.set('isThresh1Error', true);
+          this.set('errorMessage1', 'This is required');
+        }
+
+        if (thresh2.trim() !== "") {
+          if (isNaN(thresh2) || thresh2 > maxTmp || thresh2 < 0) {
+            this.set('isThresh2Error', true);
+            this.set('errorMessage2', 'Invalid! Enter a number between 0 - ' + maxTmp);
+          } else {
+            this.set('isThresh2Error', false);
+            this.set('errorMessage2', '');
+          }
+        } else {
+          this.set('isThresh2Error', true);
+          this.set('errorMessage2', 'This is required');
+        }
+
+        // update the slider handles and color
+        if (this.get('isThresh1Error') === false && this.get('isThresh2Error') === false) {
+          $("#slider-range").slider('values', 0 , parseFloat(thresh1));
+          $("#slider-range").slider('values', 1 , parseFloat(thresh2));
+        }
+      }.observes('thresh1', 'thresh2')
+
+    });
+
+    var browserVerion = this.getInternetExplorerVersion();
+    App.ModalPopup.show({
+      header: Em.I18n.t('dashboard.widgets.popupHeader'),
+      classNames: ['sixty-percent-width-modal-edit-widget'],
+      bodyClass: Ember.View.extend({
+        templateName: require('templates/main/dashboard/edit_widget_popup'),
+        configPropertyObj: configObj
+      }),
+      primary: Em.I18n.t('common.apply'),
+      onPrimary: function () {
+        configObj.observeNewThresholdValue();
+        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
+          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
+          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
+          if (!App.get('testMode')) {
+            var bigParent = parent.get('parentView');
+            bigParent.getUserPref(bigParent.get('persistKey'));
+            var oldValue = bigParent.get('currentPrefObject');
+            oldValue.threshold[parseInt(parent.id, 10)] = [configObj.get('thresh1'), configObj.get('thresh2')];
+            bigParent.postUserPref(bigParent.get('persistKey'),oldValue);
+          }
+          this.hide();
+        }
+      },
+
+      didInsertElement: function () {
+        var handlers = [configObj.get('thresh1'), configObj.get('thresh2')];
+        var colors = [App.healthStatusRed, App.healthStatusOrange, App.healthStatusGreen]; //color red, orange, green
+
+        if (browserVerion === -1 || browserVerion > 9) {
+          configObj.set('isIE9', false);
+          configObj.set('isGreenOrangeRed', false);
+          $("#slider-range").slider({
+            range: true,
+            min: 0,
+            max: maxTmp,
+            values: handlers,
+            create: function () {
+              parent.updateColors(handlers, colors);
+            },
+            slide: function (event, ui) {
+              parent.updateColors(ui.values, colors);
+              configObj.set('thresh1', ui.values[0] + '');
+              configObj.set('thresh2', ui.values[1] + '');
+            },
+            change: function (event, ui) {
+              parent.updateColors(ui.values, colors);
+            }
+          });
+        } else {
+          configObj.set('isIE9', true);
+          configObj.set('isGreenOrangeRed', false);
+        }
+      }
+    });
+  }
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 3ccd01c..f839e58 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -3063,7 +3063,7 @@ var ajax = Em.Object.extend({
   abortRequests: function (requestsArray) {
     requestsArray.forEach(function (xhr) {
       xhr.isForcedAbort = true;
-      xhr.abort();
+      Em.tryInvoke(xhr, 'abort');
     });
     requestsArray.clear();
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widget.js b/ambari-web/app/views/main/dashboard/widget.js
index 9c62675..ba7c59d 100644
--- a/ambari-web/app/views/main/dashboard/widget.js
+++ b/ambari-web/app/views/main/dashboard/widget.js
@@ -55,26 +55,6 @@ App.DashboardWidgetView = Em.View.extend({
   attributeBindings: ['viewID'],
 
   /**
-   * @type {boolean}
-   */
-  isPieChart: false,
-
-  /**
-   * @type {boolean}
-   */
-  isText: false,
-
-  /**
-   * @type {boolean}
-   */
-  isProgressBar: false,
-
-  /**
-   * @type {boolean}
-   */
-  isLinks: false,
-
-  /**
    * widget content pieChart/ text/ progress bar/links/ metrics. etc
    * @type {Array}
    * @default null
@@ -128,7 +108,7 @@ App.DashboardWidgetView = Em.View.extend({
       var thresh2 = this.get('thresh2');
       var maxValue = this.get('maxValue');
 
-      if (thresh1.trim() != "") {
+      if (thresh1.trim() !== "") {
         if (isNaN(thresh1) || thresh1 > maxValue || thresh1 < 0) {
           this.set('isThresh1Error', true);
           this.set('errorMessage1', Em.I18n.t('dashboard.widgets.error.invalid').format(maxValue));
@@ -149,7 +129,7 @@ App.DashboardWidgetView = Em.View.extend({
       var thresh2 = this.get('thresh2');
       var maxValue = this.get('maxValue');
 
-      if (thresh2.trim() != "") {
+      if (thresh2.trim() !== "") {
         if (isNaN(thresh2) || thresh2 > maxValue || thresh2 < 0) {
           this.set('isThresh2Error', true);
           this.set('errorMessage2', Em.I18n.t('dashboard.widgets.error.invalid').format(maxValue));
@@ -168,8 +148,9 @@ App.DashboardWidgetView = Em.View.extend({
       var thresh2 = this.get('thresh2');
       // update the slider handles and color
       if (this.get('isThresh1Error') === false && this.get('isThresh2Error') === false) {
-        $("#slider-range").slider('values', 0, parseFloat(thresh1));
-        $("#slider-range").slider('values', 1, parseFloat(thresh2));
+        $("#slider-range")
+          .slider('values', 0, parseFloat(thresh1))
+          .slider('values', 1, parseFloat(thresh2));
       }
     }
   }),
@@ -182,13 +163,13 @@ App.DashboardWidgetView = Em.View.extend({
   },
 
   willDestroyElement : function() {
-    $('.tooltip').remove();
+    $("[rel='ZoomInTooltip']").tooltip('destroy');
   },
   /**
    * delete widget
    * @param {object} event
    */
-  deleteWidget: function (event) {
+  deleteWidget: function () {
     var parent = this.get('parentView');
     var self = this;
 
@@ -247,7 +228,7 @@ App.DashboardWidgetView = Em.View.extend({
 
     return App.ModalPopup.show({
       header: Em.I18n.t('dashboard.widgets.popupHeader'),
-      classNames: [ 'sixty-percent-width-modal-edit-widget' ],
+      classNames: ['sixty-percent-width-modal-edit-widget'],
       bodyClass: Ember.View.extend({
         templateName: require('templates/main/dashboard/edit_widget_popup'),
         configPropertyObj: configObj
@@ -265,7 +246,7 @@ App.DashboardWidgetView = Em.View.extend({
             var parent = self.get('parentView');
             parent.getUserPref(parent.get('persistKey')).complete(function () {
               var oldValue = parent.get('currentPrefObject');
-              oldValue.threshold[parseInt(self.get('id'))] = [configObj.get('thresh1'), configObj.get('thresh2')];
+              oldValue.threshold[parseInt(self.get('id'), 10)] = [configObj.get('thresh1'), configObj.get('thresh2')];
               parent.postUserPref(parent.get('persistKey'), oldValue);
             });
           }
@@ -279,7 +260,7 @@ App.DashboardWidgetView = Em.View.extend({
         var handlers = [configObj.get('thresh1'), configObj.get('thresh2')];
         var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
 
-        if (browserVersion == -1 || browserVersion > 9) {
+        if (browserVersion === -1 || browserVersion > 9) {
           configObj.set('isIE9', false);
           configObj.set('isGreenOrangeRed', true);
           $("#slider-range").slider({
@@ -287,7 +268,7 @@ App.DashboardWidgetView = Em.View.extend({
             min: 0,
             max: maxValue,
             values: handlers,
-            create: function (event, ui) {
+            create: function () {
               updateColors(handlers);
             },
             slide: function (event, ui) {
@@ -331,18 +312,18 @@ App.DashboardWidgetView = Em.View.extend({
    */
   getInternetExplorerVersion: function () {
     var rv = -1; //return -1 for other browsers
-    if (navigator.appName == 'Microsoft Internet Explorer') {
+    if (navigator.appName === 'Microsoft Internet Explorer') {
       var ua = navigator.userAgent;
       var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
-      if (re.exec(ua) != null)
+      if (re.exec(ua) != null) {
         rv = parseFloat(RegExp.$1); // IE version 1-10
+      }
     }
     var isFirefox = typeof InstallTrigger !== 'undefined';   // Firefox 1.0+
     if (isFirefox) {
       return -2;
-    } else {
-      return rv;
     }
+    return rv;
   },
 
   /**
@@ -353,15 +334,19 @@ App.DashboardWidgetView = Em.View.extend({
    */
   hoverContentTopClass: function () {
     var lineNum = this.get('hiddenInfo.length');
-    if (lineNum == 2) {
+    if (lineNum === 2) {
       return "content-hidden-two-line";
-    } else if (lineNum == 3) {
+    }
+    if (lineNum === 3) {
       return "content-hidden-three-line";
-    } else if (lineNum == 4) {
+    }
+    if (lineNum === 4) {
       return "content-hidden-four-line";
-    } else if (lineNum == 5) {
+    }
+    if (lineNum === 5) {
       return "content-hidden-five-line";
-    } else if (lineNum == 6) {
+    }
+    if (lineNum === 6) {
       return "content-hidden-six-line";
     }
     return '';

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets.js b/ambari-web/app/views/main/dashboard/widgets.js
index 8a86af6..c6723be 100644
--- a/ambari-web/app/views/main/dashboard/widgets.js
+++ b/ambari-web/app/views/main/dashboard/widgets.js
@@ -124,7 +124,7 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
     var visibleFull = [
       '2', '4', '11', //hdfs
       '6', '7', '8', '9', //host metrics
-      '1', '5', '3',  '10', //hdfs
+      '1', '5', '3', '10', //hdfs
       '13', '12', '14', '16', //hbase
       '17', '18', '19', '20', '23', // all yarn
       '21', // storm
@@ -282,7 +282,7 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
     var hidden = value.hidden;
     var threshold = value.threshold;
 
-    if (version == 'new') {
+    if (version === 'new') {
       var visibleWidgets = [];
       var hiddenWidgets = [];
       // re-construct visibleWidgets and hiddenWidgets

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/cluster_metrics_widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/cluster_metrics_widget.js b/ambari-web/app/views/main/dashboard/widgets/cluster_metrics_widget.js
index a688e60..b158509 100644
--- a/ambari-web/app/views/main/dashboard/widgets/cluster_metrics_widget.js
+++ b/ambari-web/app/views/main/dashboard/widgets/cluster_metrics_widget.js
@@ -34,6 +34,10 @@ App.ClusterMetricsDashboardWidgetView = App.DashboardWidgetView.extend(App.Expor
     App.tooltip(this.$('.corner-icon > .icon-save'), {
       title: Em.I18n.t('common.export')
     });
+  },
+
+  willDestroyElement: function () {
+    this.$('.corner-icon > .icon-save').tooltip('destroy');
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/datanode_live.js b/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
index 49220f5..184b046 100644
--- a/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
@@ -18,174 +18,76 @@
 
 var App = require('app');
 
-App.DataNodeUpView = App.TextDashboardWidgetView.extend({
+function counterOrNA(key) {
+  var _key = 'model.{0}.length'.format(key);
+  return Em.computed(_key, function () {
+    if (Em.isNone(this.get('model.'+ key)) || this.get('model.metricsNotAvailable')) {
+      return Em.I18n.t('services.service.summary.notAvailable');
+    }
+    return this.get(_key);
+  });
+}
+
+App.DataNodeUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
   title: Em.I18n.t('dashboard.widgets.DataNodeUp'),
   id: '4',
 
-  isPieChart: false,
-  isText: true,
-  isProgressBar: false,
   model_type: 'hdfs',
 
   hiddenInfo: function () {
-    var result = [];
-    result.pushObject(this.get('dataNodesLive') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'));
-    result.pushObject(this.get('dataNodesDead') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.dead'));
-    result.pushObject(this.get('dataNodesDecom')+ ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.decom'));
-    return result;
+    return [
+      this.get('dataNodesLive') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'),
+      this.get('dataNodesDead') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.dead'),
+      this.get('dataNodesDecom')+ ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.decom')
+    ];
   }.property('dataNodesLive', 'dataNodesDead', 'dataNodesDecom'),
+
   hiddenInfoClass: "hidden-info-three-line",
 
   thresh1: 40,
   thresh2: 70,
   maxValue: 100,
 
-  dataNodesLive: function () {
-    if (!Em.isNone(this.get('model.liveDataNodes')) && !this.get('model.metricsNotAvailable')) {
-      return this.get('model.liveDataNodes.length');
-    } else {
-      return   Em.I18n.t('services.service.summary.notAvailable');
-    }
-  }.property('model.liveDataNodes.length'),
-  dataNodesDead: function () {
-    if (!Em.isNone(this.get('model.deadDataNodes')) && !this.get('model.metricsNotAvailable')) {
-      return this.get('model.deadDataNodes.length');
-    } else {
-      return   Em.I18n.t('services.service.summary.notAvailable');
-    }
-  }.property('model.deadDataNodes.length'),
-  dataNodesDecom: function () {
-    if (!Em.isNone(this.get('model.decommissionDataNodes')) && !this.get('model.metricsNotAvailable')) {
-      return this.get('model.decommissionDataNodes.length');
-    } else {
-      return   Em.I18n.t('services.service.summary.notAvailable');
-    }
-  }.property('model.decommissionDataNodes.length'),
+  dataNodesLive: counterOrNA('liveDataNodes'),
+
+  dataNodesDead: counterOrNA('deadDataNodes'),
 
+  dataNodesDecom: counterOrNA('decommissionDataNodes'),
+
+  /**
+   * @type {?number}
+   */
   data: function () {
-    if (Em.isNone(this.get('model.liveDataNodes')) || Em.isNone(this.get('model.dataNodesTotal')) || this.get('model.metricsNotAvailable')) {
+    if (this.get('someMetricsNA')) {
       return null;
-    } else {
-      return ((this.get('dataNodesLive') / this.get('model.dataNodesTotal')).toFixed(2)) * 100;
     }
-  }.property('model.dataNodesTotal', 'dataNodesLive'),
+    return (this.get('dataNodesLive') / this.get('model.dataNodesTotal')).toFixed(2) * 100;
+  }.property('model.dataNodesTotal', 'dataNodesLive', 'someMetricsNA'),
 
+  /**
+   * @type {string}
+   */
   content: function () {
-    if (Em.isNone(this.get('model.liveDataNodes')) || Em.isNone(this.get('model.dataNodesTotal')) || this.get('model.metricsNotAvailable')) {
-      return  Em.I18n.t('services.service.summary.notAvailable');
-    } else {
-      return this.get('dataNodesLive') + "/" + this.get('model.dataNodesTotal');
+    if (this.get('someMetricsNA')) {
+      return Em.I18n.t('services.service.summary.notAvailable');
     }
-  }.property('model.dataNodesTotal', 'dataNodesLive'),
-
-  editWidget: function (event) {
-    var parent = this;
-    var max_tmp =  parseFloat(parent.get('maxValue'));
-    var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint1').format(max_tmp),
-      isThresh1Error: false,
-      isThresh2Error: false,
-      errorMessage1: "",
-      errorMessage2: "",
-      maxValue: max_tmp,
-      observeNewThresholdValue: function () {
-        var thresh1 = this.get('thresh1');
-        var thresh2 = this.get('thresh2');
-        if (thresh1.trim() != "") {
-          if (isNaN(thresh1) || thresh1 > max_tmp || thresh1 < 0){
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Invalid! Enter a number between 0 - ' + max_tmp);
-          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)) {
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
-          } else {
-            this.set('isThresh1Error', false);
-            this.set('errorMessage1', '');
-          }
-        } else {
-          this.set('isThresh1Error', true);
-          this.set('errorMessage1', 'This is required');
-        }
-
-        if (thresh2.trim() != "") {
-          if (isNaN(thresh2) || thresh2 > max_tmp || thresh2 < 0) {
-            this.set('isThresh2Error', true);
-            this.set('errorMessage2', 'Invalid! Enter a number between 0 - ' + max_tmp);
-          } else {
-            this.set('isThresh2Error', false);
-            this.set('errorMessage2', '');
-          }
-        } else {
-          this.set('isThresh2Error', true);
-          this.set('errorMessage2', 'This is required');
-        }
-
-        // update the slider handles and color
-        if (this.get('isThresh1Error') === false && this.get('isThresh2Error') === false) {
-          $("#slider-range").slider('values', 0 , parseFloat(thresh1));
-          $("#slider-range").slider('values', 1 , parseFloat(thresh2));
-        }
-      }.observes('thresh1', 'thresh2')
-
-    });
-
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show({
-      header: Em.I18n.t('dashboard.widgets.popupHeader'),
-      classNames: [ 'sixty-percent-width-modal-edit-widget'],
-      bodyClass: Ember.View.extend({
-        templateName: require('templates/main/dashboard/edit_widget_popup'),
-        configPropertyObj: configObj
-      }),
-      primary: Em.I18n.t('common.apply'),
-      onPrimary: function () {
-        configObj.observeNewThresholdValue();
-        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
-          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
-          if (!App.get('testMode')) {
-            var big_parent = parent.get('parentView');
-            big_parent.getUserPref(big_parent.get('persistKey'));
-            var oldValue = big_parent.get('currentPrefObject');
-            oldValue.threshold[parseInt(parent.id)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-            big_parent.postUserPref(big_parent.get('persistKey'),oldValue);
-          }
-          this.hide();
-        }
-      },
-
-      didInsertElement: function () {
-        var handlers = [configObj.get('thresh1'), configObj.get('thresh2')];
-        var colors = [App.healthStatusRed, App.healthStatusOrange, App.healthStatusGreen]; //color red, orange, green
-
-        if (browserVerion == -1 || browserVerion > 9) {
-          configObj.set('isIE9', false);
-          configObj.set('isGreenOrangeRed', false);
-          $("#slider-range").slider({
-            range: true,
-            min: 0,
-            max: max_tmp,
-            values: handlers,
-            create: function (event, ui) {
-              parent.updateColors(handlers, colors);
-            },
-            slide: function (event, ui) {
-              parent.updateColors(ui.values, colors);
-              configObj.set('thresh1', ui.values[0] + '');
-              configObj.set('thresh2', ui.values[1] + '');
-            },
-            change: function (event, ui) {
-              parent.updateColors(ui.values, colors);
-            }
-          });
-        } else {
-          configObj.set('isIE9', true);
-          configObj.set('isGreenOrangeRed', false);
-        }
-      }
-    });
-  }
+    return this.get('dataNodesLive') + "/" + this.get('model.dataNodesTotal');
+  }.property('model.dataNodesTotal', 'dataNodesLive', 'someMetricsNA'),
+
+  /**
+   * @type {boolean}
+   */
+  someMetricsNA: function () {
+    return Em.isNone(this.get('model.liveDataNodes')) || Em.isNone(this.get('model.dataNodesTotal')) || this.get('model.metricsNotAvailable');
+  }.property('model.liveDataNodes.[]', 'model.dataNodesTotal.[]', 'model.metricsNotAvailable'),
+
+  /**
+   * @type {string}
+   */
+  hintInfo: function () {
+    var maxTmp = parseFloat(this.get('maxValue'));
+    return Em.I18n.t('dashboard.widgets.hintInfo.hint1').format(maxTmp);
+  }.property('maxValue')
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js b/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js
index 2d73e20..e8169c9 100644
--- a/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js
@@ -18,22 +18,20 @@
 
 var App = require('app');
 
-App.FlumeAgentUpView = App.TextDashboardWidgetView.extend({
+App.FlumeAgentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
   title: Em.I18n.t('dashboard.widgets.FlumeAgentUp'),
   id: '22',
 
-  isPieChart: false,
-  isText: true,
-  isProgressBar: false,
   model_type: 'flume',
 
   hiddenInfo: function () {
-    var result = [];
-    result.pushObject(this.get('flumeAgentsLive').length + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'));
-    result.pushObject(this.get('flumeAgentsDead').length + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.dead'));
-    return result;
+    return [
+      this.get('flumeAgentsLive.length') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'),
+      this.get('flumeAgentsDead.length') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.dead')
+    ];
   }.property('flumeAgentsLive', 'flumeAgentsDead'),
+
   hiddenInfoClass: "hidden-info-two-line",
 
   thresh1: 40,
@@ -55,9 +53,8 @@ App.FlumeAgentUpView = App.TextDashboardWidgetView.extend({
   data: function () {
     if ( !this.get('flumeAgentComponents.length')) {
       return -1;
-    } else {
-      return ((this.get('flumeAgentsLive').length / this.get('model.hostComponents').filterProperty('componentName', 'FLUME_HANDLER').length).toFixed(2)) * 100;
     }
+    return (this.get('flumeAgentsLive').length / this.get('model.hostComponents').filterProperty('componentName', 'FLUME_HANDLER').length).toFixed(2) * 100;
   }.property('model.hostComponents.length', 'flumeAgentsLive'),
 
   content: Em.computed.concat('/', 'flumeAgentsLive.length', 'flumeAgentComponents.length'),
@@ -71,113 +68,9 @@ App.FlumeAgentUpView = App.TextDashboardWidgetView.extend({
     this.set('flumeAgentsDead', this.get('flumeAgentComponents').filterProperty("workStatus", "INSTALLED"));
   },
 
-  editWidget: function (event) {
-    var parent = this;
-    var max_tmp =  parseFloat(parent.get('maxValue'));
-    var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint1').format(max_tmp),
-      isThresh1Error: false,
-      isThresh2Error: false,
-      errorMessage1: "",
-      errorMessage2: "",
-      maxValue: max_tmp,
-      observeNewThresholdValue: function () {
-        var thresh1 = this.get('thresh1');
-        var thresh2 = this.get('thresh2');
-        if (thresh1.trim() != "") {
-          if (isNaN(thresh1) || thresh1 > max_tmp || thresh1 < 0){
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Invalid! Enter a number between 0 - ' + max_tmp);
-          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)) {
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
-          } else {
-            this.set('isThresh1Error', false);
-            this.set('errorMessage1', '');
-          }
-        } else {
-          this.set('isThresh1Error', true);
-          this.set('errorMessage1', 'This is required');
-        }
-
-        if (thresh2.trim() != "") {
-          if (isNaN(thresh2) || thresh2 > max_tmp || thresh2 < 0) {
-            this.set('isThresh2Error', true);
-            this.set('errorMessage2', 'Invalid! Enter a number between 0 - ' + max_tmp);
-          } else {
-            this.set('isThresh2Error', false);
-            this.set('errorMessage2', '');
-          }
-        } else {
-          this.set('isThresh2Error', true);
-          this.set('errorMessage2', 'This is required');
-        }
-
-        // update the slider handles and color
-        if (this.get('isThresh1Error') === false && this.get('isThresh2Error') === false) {
-          $("#slider-range").slider('values', 0 , parseFloat(thresh1));
-          $("#slider-range").slider('values', 1 , parseFloat(thresh2));
-        }
-      }.observes('thresh1', 'thresh2')
-
-    });
-
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show({
-      header: Em.I18n.t('dashboard.widgets.popupHeader'),
-      classNames: [ 'sixty-percent-width-modal-edit-widget'],
-      bodyClass: Ember.View.extend({
-        templateName: require('templates/main/dashboard/edit_widget_popup'),
-        configPropertyObj: configObj
-      }),
-      primary: Em.I18n.t('common.apply'),
-      onPrimary: function () {
-        configObj.observeNewThresholdValue();
-        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
-          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
-          if (!App.get('testMode')) {
-            var big_parent = parent.get('parentView');
-            big_parent.getUserPref(big_parent.get('persistKey'));
-            var oldValue = big_parent.get('currentPrefObject');
-            oldValue.threshold[parseInt(parent.id)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-            big_parent.postUserPref(big_parent.get('persistKey'),oldValue);
-          }
-          this.hide();
-        }
-      },
-
-      didInsertElement: function () {
-        var handlers = [configObj.get('thresh1'), configObj.get('thresh2')];
-        var colors = [App.healthStatusRed, App.healthStatusOrange, App.healthStatusGreen]; //color red, orange, green
-
-        if (browserVerion == -1 || browserVerion > 9) {
-          configObj.set('isIE9', false);
-          configObj.set('isGreenOrangeRed', false);
-          $("#slider-range").slider({
-            range: true,
-            min: 0,
-            max: max_tmp,
-            values: handlers,
-            create: function (event, ui) {
-              parent.updateColors(handlers, colors);
-            },
-            slide: function (event, ui) {
-              parent.updateColors(ui.values, colors);
-              configObj.set('thresh1', ui.values[0] + '');
-              configObj.set('thresh2', ui.values[1] + '');
-            },
-            change: function (event, ui) {
-              parent.updateColors(ui.values, colors);
-            }
-          });
-        } else {
-          configObj.set('isIE9', true);
-          configObj.set('isGreenOrangeRed', false);
-        }
-      }
-    });
-  }
+  hintInfo: function () {
+    var maxTmp = parseFloat(this.get('maxValue'));
+    return Em.I18n.t('dashboard.widgets.hintInfo.hint1').format(maxTmp);
+  }.property('maxValue')
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js b/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
index e8d0656..c35d2b2 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
@@ -18,173 +18,74 @@
 
 var App = require('app');
 
-App.HawqSegmentUpView = App.TextDashboardWidgetView.extend({
+function counterOrNA(key) {
+  var _key = 'model.{0}'.format(key);
+  return Em.computed(_key, function () {
+    var value = this.get(_key);
+    if (Em.isNone(value)) {
+      return Em.I18n.t('services.service.summary.notAvailable');
+    }
+    return value;
+  });
+}
+
+App.HawqSegmentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
   title: Em.I18n.t('dashboard.widgets.HawqSegmentUp'),
   id: '24',
 
-  isPieChart: false,
-  isText: true,
-  isProgressBar: false,
   model_type: 'hawq',
 
   hiddenInfo: function () {
-    var result = [];
-    result.pushObject(this.get('hawqSegmentsStarted') + ' ' + Em.I18n.t('dashboard.services.hawq.segments.started'));
-    result.pushObject(this.get('hawqSegmentsInstalled') + ' ' + Em.I18n.t('dashboard.services.hawq.segments.stopped'));
-    result.pushObject(this.get('hawqSegmentsTotal')+ ' ' + Em.I18n.t('dashboard.services.hawq.segments.total'));
-    return result;
+    return [
+      this.get('hawqSegmentsStarted') + ' ' + Em.I18n.t('dashboard.services.hawq.segments.started'),
+      this.get('hawqSegmentsInstalled') + ' ' + Em.I18n.t('dashboard.services.hawq.segments.stopped'),
+      this.get('hawqSegmentsTotal')+ ' ' + Em.I18n.t('dashboard.services.hawq.segments.total')
+    ];
   }.property('hawqSegmentsStarted', 'hawqSegmentsInstalled', 'hawqSegmentsTotal'),
+
   hiddenInfoClass: "hidden-info-three-line",
 
   thresh1: 40,
   thresh2: 70,
   maxValue: 100,
 
-  hawqSegmentsStarted: function () {
-    if (Em.isNone(this.get('model.hawqSegmentsStarted'))) {
-      return Em.I18n.t('services.service.summary.notAvailable');
-    }
-    return this.get('model.hawqSegmentsStarted');
-  }.property('model.hawqSegmentsStarted'),
+  hawqSegmentsStarted: counterOrNA('hawqSegmentsStarted'),
 
-  hawqSegmentsInstalled: function () {
-    if (Em.isNone(this.get('model.hawqSegmentsInstalled'))) {
-      return Em.I18n.t('services.service.summary.notAvailable');
-    }
-    return this.get('model.hawqSegmentsInstalled');
-  }.property('model.hawqSegmentsInstalled'),
+  hawqSegmentsInstalled: counterOrNA('hawqSegmentsInstalled'),
 
-  hawqSegmentsTotal: function () {
-    if (Em.isNone(this.get('model.hawqSegmentsTotal'))) {
-      return Em.I18n.t('services.service.summary.notAvailable');
-    }
-    return this.get('model.hawqSegmentsTotal');
-  }.property('model.hawqSegmentsTotal'),
+  hawqSegmentsTotal: counterOrNA('hawqSegmentsTotal'),
 
+  /**
+   * @type {?number}
+   */
   data: function () {
-    if (Em.isNone(this.get('model.hawqSegmentsStarted')) || Em.isNone(this.get('model.hawqSegmentsTotal'))) {
+    if (this.get('someMetricsNA')) {
       return null;
-    } else {
-      return ((this.get('hawqSegmentsStarted') / this.get('model.hawqSegmentsTotal')).toFixed(2)) * 100;
     }
-  }.property('model.hawqSegmentsTotal', 'hawqSegmentsStarted'),
+    return (this.get('hawqSegmentsStarted') / this.get('model.hawqSegmentsTotal')).toFixed(2) * 100;
+  }.property('model.hawqSegmentsTotal', 'hawqSegmentsStarted', 'someMetricsNA'),
 
+  /**
+   * @type {string}
+   */
   content: function () {
-    if (Em.isNone(this.get('model.hawqSegmentsStarted')) || Em.isNone(this.get('model.hawqSegmentsTotal'))) {
+    if (this.get('someMetricsNA')) {
       return Em.I18n.t('services.service.summary.notAvailable');
-    } else {
-      return this.get('hawqSegmentsStarted') + "/" + this.get('model.hawqSegmentsTotal');
     }
-  }.property('model.hawqSegmentsTotal', 'hawqSegmentsStarted'),
-
-  editWidget: function (event) {
-    var parent = this;
-    var max_tmp =  parseFloat(parent.get('maxValue'));
-    var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint1').format(max_tmp),
-      isThresh1Error: false,
-      isThresh2Error: false,
-      errorMessage1: "",
-      errorMessage2: "",
-      maxValue: max_tmp,
-      observeNewThresholdValue: function () {
-        var thresh1 = this.get('thresh1');
-        var thresh2 = this.get('thresh2');
-        if (thresh1.trim() != "") {
-          if (isNaN(thresh1) || thresh1 > max_tmp || thresh1 < 0){
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Invalid! Enter a number between 0 - ' + max_tmp);
-          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)) {
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
-          } else {
-            this.set('isThresh1Error', false);
-            this.set('errorMessage1', '');
-          }
-        } else {
-          this.set('isThresh1Error', true);
-          this.set('errorMessage1', 'This is required');
-        }
-
-        if (thresh2.trim() != "") {
-          if (isNaN(thresh2) || thresh2 > max_tmp || thresh2 < 0) {
-            this.set('isThresh2Error', true);
-            this.set('errorMessage2', 'Invalid! Enter a number between 0 - ' + max_tmp);
-          } else {
-            this.set('isThresh2Error', false);
-            this.set('errorMessage2', '');
-          }
-        } else {
-          this.set('isThresh2Error', true);
-          this.set('errorMessage2', 'This is required');
-        }
-
-        // update the slider handles and color
-        if (this.get('isThresh1Error') === false && this.get('isThresh2Error') === false) {
-          $("#slider-range").slider('values', 0 , parseFloat(thresh1));
-          $("#slider-range").slider('values', 1 , parseFloat(thresh2));
-        }
-      }.observes('thresh1', 'thresh2')
-
-    });
-
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show({
-      header: Em.I18n.t('dashboard.widgets.popupHeader'),
-      classNames: [ 'sixty-percent-width-modal-edit-widget'],
-      bodyClass: Ember.View.extend({
-        templateName: require('templates/main/dashboard/edit_widget_popup'),
-        configPropertyObj: configObj
-      }),
-      primary: Em.I18n.t('common.apply'),
-      onPrimary: function () {
-        configObj.observeNewThresholdValue();
-        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
-          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
-          if (!App.get('testMode')) {
-            var big_parent = parent.get('parentView');
-            big_parent.getUserPref(big_parent.get('persistKey'));
-            var oldValue = big_parent.get('currentPrefObject');
-            oldValue.threshold[parseInt(parent.id)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-            big_parent.postUserPref(big_parent.get('persistKey'),oldValue);
-          }
-          this.hide();
-        }
-      },
-
-      didInsertElement: function () {
-        var handlers = [configObj.get('thresh1'), configObj.get('thresh2')];
-        var colors = [App.healthStatusRed, App.healthStatusOrange, App.healthStatusGreen]; //color red, orange, green
-
-        if (browserVerion == -1 || browserVerion > 9) {
-          configObj.set('isIE9', false);
-          configObj.set('isGreenOrangeRed', false);
-          $("#slider-range").slider({
-            range: true,
-            min: 0,
-            max: max_tmp,
-            values: handlers,
-            create: function (event, ui) {
-              parent.updateColors(handlers, colors);
-            },
-            slide: function (event, ui) {
-              parent.updateColors(ui.values, colors);
-              configObj.set('thresh1', ui.values[0] + '');
-              configObj.set('thresh2', ui.values[1] + '');
-            },
-            change: function (event, ui) {
-              parent.updateColors(ui.values, colors);
-            }
-          });
-        } else {
-          configObj.set('isIE9', true);
-          configObj.set('isGreenOrangeRed', false);
-        }
-      }
-    });
-  }
+    return this.get('hawqSegmentsStarted') + "/" + this.get('model.hawqSegmentsTotal');
+  }.property('model.hawqSegmentsTotal', 'hawqSegmentsStarted', 'someMetricsNA'),
+
+  hintInfo: function () {
+    var maxTmp = parseFloat(this.get('maxValue'));
+    return Em.I18n.t('dashboard.widgets.hintInfo.hint1').format(maxTmp);
+  }.property('maxValue'),
+
+  /**
+   * @type {boolean}
+   */
+  someMetricsNA: function() {
+    return Em.isNone(this.get('model.hawqSegmentsStarted')) || Em.isNone(this.get('model.hawqSegmentsTotal'));
+  }.property('model.hawqSegmentsStarted', 'model.hawqSegmentsTotal')
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js b/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js
index 5f8d8aa..48c4de0 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js
@@ -18,20 +18,19 @@
 
 var App = require('app');
 
-App.HBaseAverageLoadView = App.TextDashboardWidgetView.extend({
+App.HBaseAverageLoadView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin, {
 
   title: Em.I18n.t('dashboard.widgets.HBaseAverageLoad'),
   id: '14',
 
   model_type: 'hbase',
+
   hiddenInfo: function () {
     var avgLoad = this.get('model.averageLoad');
     if (isNaN(avgLoad)) {
       avgLoad = Em.I18n.t('services.service.summary.notAvailable');
     }
-    var result = [];
-    result.pushObject(Em.I18n.t('dashboard.services.hbase.averageLoadPerServer').format(avgLoad));
-    return result;
+    return [Em.I18n.t('dashboard.services.hbase.averageLoadPerServer').format(avgLoad)];
   }.property("model.averageLoad"),
 
   isGreen: Em.computed.lteProperties('data', 'thresh1'),
@@ -50,108 +49,10 @@ App.HBaseAverageLoadView = App.TextDashboardWidgetView.extend({
   content: function (){
     if(this.get('data') || this.get('data') == 0){
       return this.get('data') + "";
-    }else{
-      return Em.I18n.t('services.service.summary.notAvailable');
     }
+    return Em.I18n.t('services.service.summary.notAvailable');
   }.property('model.averageLoad'),
 
-  editWidget: function (event) {
-    var parent = this;
-    var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint2'),
-      isThresh1Error: false,
-      isThresh2Error: false,
-      errorMessage1: "",
-      errorMessage2: "",
-      maxValue: 'infinity',
-      observeNewThresholdValue: function () {
-        var thresh1 = this.get('thresh1');
-        var thresh2 = this.get('thresh2');
-        if (thresh1.trim() != "") {
-          if (isNaN(thresh1) || thresh1 < 0) {
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Invalid! Enter a number larger than 0');
-          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)){
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
-          } else {
-            this.set('isThresh1Error', false);
-            this.set('errorMessage1', '');
-          }
-        } else {
-          this.set('isThresh1Error', true);
-          this.set('errorMessage1', 'This is required');
-        }
-
-        if (thresh2.trim() != "") {
-          if (isNaN(thresh2) || thresh2 < 0) {
-            this.set('isThresh2Error', true);
-            this.set('errorMessage2', 'Invalid! Enter a number larger than 0');
-          } else {
-            this.set('isThresh2Error', false);
-            this.set('errorMessage2', '');
-          }
-        } else {
-          this.set('isThresh2Error', true);
-          this.set('errorMessage2', 'This is required');
-        }
-
-      }.observes('thresh1', 'thresh2')
-
-    });
-
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show( {
-      header: Em.I18n.t('dashboard.widgets.popupHeader'),
-      classNames: [ 'sixty-percent-width-modal-edit-widget'],
-      bodyClass: Ember.View.extend({
-        templateName: require('templates/main/dashboard/edit_widget_popup'),
-        configPropertyObj: configObj
-      }),
-      primary: Em.I18n.t('common.apply'),
-      onPrimary: function () {
-        configObj.observeNewThresholdValue();
-        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
-          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
-          if (!App.get('testMode')) {
-            //save to persist
-            var big_parent = parent.get('parentView');
-            big_parent.getUserPref(big_parent.get('persistKey'));
-            var oldValue = big_parent.get('currentPrefObject');
-            oldValue.threshold[parseInt(parent.id)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-            big_parent.postUserPref(big_parent.get('persistKey'),oldValue);
-          }
-
-          this.hide();
-        }
-      },
-
-      didInsertElement: function () {
-        var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
-        var handlers = [33, 66]; //fixed value
-
-        if (browserVerion == -1 || browserVerion > 9) {
-          configObj.set('isIE9', false);
-          configObj.set('isGreenOrangeRed', true);
-          $("#slider-range").slider({
-            range:true,
-            disabled:true, //handlers cannot move
-            min: 0,
-            max: 100,
-            values: handlers,
-            create: function (event, ui) {
-              parent.updateColors(handlers, colors);
-            }
-          });
-        } else {
-          configObj.set('isIE9', true);
-          configObj.set('isGreenOrangeRed', true);
-        }
-      }
-    });
-  }
+  hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint2')
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_links.js b/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
index 01536e6..235f73c 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
@@ -46,10 +46,8 @@ App.HBaseLinksView = App.LinkDashboardWidgetView.extend({
   activeMasterTitle: Em.I18n.t('service.hbase.activeMaster'),
 
   hbaseMasterWebUrl: function () {
-    if (this.get('activeMaster.host') && this.get('activeMaster.host').get('publicHostName')) {
-      return "http://" + this.get('activeMaster.host').get('publicHostName') + ':' + this.get('port');
-    }
-    return '';
+    var hostName = this.get('activeMaster.host.publicHostName');
+    return hostName ? 'http://' + hostName + ':' + this.get('port') : '';
   }.property('activeMaster'),
 
   calcWebUrl: function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js b/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js
index 62bac10..63b1cc2 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js
@@ -35,10 +35,10 @@ App.HBaseMasterHeapPieChartView = App.PieChartDashboardWidgetView.extend({
   },
 
   getUsed: function() {
-    return (this.get('model').get(this.get('modelFieldUsed')) / (1024 * 1024)) || 0;
+    return this.get('model').get(this.get('modelFieldUsed')) / (1024 * 1024) || 0;
   },
 
   getMax: function() {
-    return (this.get('model').get(this.get('modelFieldMax')) / (1024 * 1024)) || 0;
+    return this.get('model').get(this.get('modelFieldMax')) / (1024 * 1024) || 0;
   }
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js b/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js
index 18902b5..1f225c6 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js
@@ -18,17 +18,17 @@
 
 var App = require('app');
 
-App.HBaseRegionsInTransitionView = App.TextDashboardWidgetView.extend({
+App.HBaseRegionsInTransitionView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin, {
 
   title: Em.I18n.t('dashboard.widgets.HBaseRegionsInTransition'),
   id: '15',
 
   model_type: 'hbase',
   hiddenInfo: function () {
-    var result = [];
-    result.pushObject(this.get("model.regionsInTransition") + " regions");
-    result.pushObject("in transition");
-    return result;
+    return [
+      this.get("model.regionsInTransition") + " regions",
+      "in transition"
+    ];
   }.property("model.regionsInTransition"),
 
   classNameBindings: ['isRed', 'isOrange', 'isGreen', 'isNA'],
@@ -45,106 +45,8 @@ App.HBaseRegionsInTransitionView = App.TextDashboardWidgetView.extend({
 
   data: Em.computed.alias('model.regionsInTransition'),
 
-  content: function (){
-    return this.get('data') + "";
-  }.property('model.regionsInTransition'),
+  content: Em.computed.format('{0}', 'data'),
 
-  editWidget: function (event) {
-    var parent = this;
-    var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint2'),
-      isThresh1Error: false,
-      isThresh2Error: false,
-      errorMessage1: "",
-      errorMessage2: "",
-      maxValue: 'infinity',
-      observeNewThresholdValue: function () {
-        var thresh1 = this.get('thresh1');
-        var thresh2 = this.get('thresh2');
-        if (thresh1.trim() != "") {
-          if (isNaN(thresh1) || thresh1 < 0) {
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Invalid! Enter a number larger than 0');
-          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)){
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
-          } else {
-            this.set('isThresh1Error', false);
-            this.set('errorMessage1', '');
-          }
-        } else {
-          this.set('isThresh1Error', true);
-          this.set('errorMessage1', 'This is required');
-        }
-
-        if (thresh2.trim() != "") {
-          if (isNaN(thresh2) || thresh2 < 0) {
-            this.set('isThresh2Error', true);
-            this.set('errorMessage2', 'Invalid! Enter a number larger than 0');
-          } else {
-            this.set('isThresh2Error', false);
-            this.set('errorMessage2', '');
-          }
-        } else {
-          this.set('isThresh2Error', true);
-          this.set('errorMessage2', 'This is required');
-        }
-      }.observes('thresh1', 'thresh2')
-
-    });
-
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show({
-      header: Em.I18n.t('dashboard.widgets.popupHeader'),
-      classNames: [ 'sixty-percent-width-modal-edit-widget'],
-      bodyClass: Ember.View.extend({
-        templateName: require('templates/main/dashboard/edit_widget_popup'),
-        configPropertyObj: configObj
-      }),
-      primary: Em.I18n.t('common.apply'),
-      onPrimary: function () {
-        configObj.observeNewThresholdValue();
-        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
-          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
-          if (!App.get('testMode')) {
-            //save to persist
-            var big_parent = parent.get('parentView');
-            big_parent.getUserPref(big_parent.get('persistKey'));
-            var oldValue = big_parent.get('currentPrefObject');
-            oldValue.threshold[parseInt(parent.id)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-            big_parent.postUserPref(big_parent.get('persistKey'),oldValue);
-          }
-
-          this.hide();
-        }
-      },
-
-      didInsertElement: function () {
-        var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
-        var handlers = [33, 66]; //fixed value
-
-        if (browserVerion == -1 || browserVerion > 9) {
-          configObj.set('isIE9', false);
-          configObj.set('isGreenOrangeRed', true);
-          $("#slider-range").slider({
-            range:true,
-            disabled:true, //handlers cannot move
-            min: 0,
-            max: 100,
-            values: handlers,
-            create: function (event, ui) {
-              parent.updateColors(handlers, colors);
-            }
-          });
-        } else {
-          configObj.set('isIE9', true);
-          configObj.set('isGreenOrangeRed', true);
-        }
-      }
-    });
-  }
+  hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint2')
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js b/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
index 193732b..e64534d 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
@@ -43,34 +43,34 @@ App.NameNodeCapacityPieChartView = App.PieChartDashboardWidgetView.extend({
     var remaining = this.get('model.capacityRemaining');
     var dfsUsed = this.get('model.capacityUsed');
     var nonDfsUsed = this.get('model.capacityNonDfsUsed');
-    var dfsPercent = total > 0 ? ((dfsUsed * 100) / total).toFixed(2) : 0;
-    var nonDfsPercent = total > 0 ? ((nonDfsUsed * 100) / total).toFixed(2) : 0;
-    var remainingPercent = total > 0 ? ((remaining * 100) / total).toFixed(2) : 0;
-    if (dfsPercent == "NaN" || dfsPercent < 0) {
+    var dfsPercent = total > 0 ? (dfsUsed * 100 / total).toFixed(2) : 0;
+    var nonDfsPercent = total > 0 ? (nonDfsUsed * 100 / total).toFixed(2) : 0;
+    var remainingPercent = total > 0 ? (remaining * 100 / total).toFixed(2) : 0;
+    if (dfsPercent === "NaN" || dfsPercent < 0) {
       dfsPercent = Em.I18n.t('services.service.summary.notAvailable') + " ";
     }
-    if (nonDfsPercent == "NaN" || nonDfsPercent < 0) {
+    if (nonDfsPercent === "NaN" || nonDfsPercent < 0) {
       nonDfsPercent = Em.I18n.t('services.service.summary.notAvailable') + " ";
     }
-    if (remainingPercent == "NaN" || remainingPercent < 0) {
+    if (remainingPercent === "NaN" || remainingPercent < 0) {
       remainingPercent = Em.I18n.t('services.service.summary.notAvailable') + " ";
     }
-    var result = [];
-    result.pushObject(Em.I18n.t('dashboard.widgets.HDFSDiskUsage.DFSused'));
-    result.pushObject(Em.I18n.t('dashboard.widgets.HDFSDiskUsage.info').format(numberUtils.bytesToSize(dfsUsed, 1, 'parseFloat'), dfsPercent));
-    result.pushObject(Em.I18n.t('dashboard.widgets.HDFSDiskUsage.nonDFSused'));
-    result.pushObject(Em.I18n.t('dashboard.widgets.HDFSDiskUsage.info').format(numberUtils.bytesToSize(nonDfsUsed, 1, 'parseFloat'), nonDfsPercent));
-    result.pushObject(Em.I18n.t('dashboard.widgets.HDFSDiskUsage.remaining'));
-    result.pushObject(Em.I18n.t('dashboard.widgets.HDFSDiskUsage.info').format(numberUtils.bytesToSize(remaining, 1, 'parseFloat'), remainingPercent));
-    return result;
+    return [
+      Em.I18n.t('dashboard.widgets.HDFSDiskUsage.DFSused'),
+      Em.I18n.t('dashboard.widgets.HDFSDiskUsage.info').format(numberUtils.bytesToSize(dfsUsed, 1, 'parseFloat'), dfsPercent),
+      Em.I18n.t('dashboard.widgets.HDFSDiskUsage.nonDFSused'),
+      Em.I18n.t('dashboard.widgets.HDFSDiskUsage.info').format(numberUtils.bytesToSize(nonDfsUsed, 1, 'parseFloat'), nonDfsPercent),
+      Em.I18n.t('dashboard.widgets.HDFSDiskUsage.remaining'),
+      Em.I18n.t('dashboard.widgets.HDFSDiskUsage.info').format(numberUtils.bytesToSize(remaining, 1, 'parseFloat'), remainingPercent)
+    ];
   },
 
   calcDataForPieChart: function() {
     var total = this.get('model').get(this.get('modelFieldMax')) * 1024 * 1024;
     var used = total - this.get('model').get(this.get('modelFieldUsed')) * 1024 * 1024;
-    var percent = total > 0 ? ((used)*100 / total).toFixed() : 0;
-    var percent_precise = total > 0 ? ((used)*100 / total).toFixed(1) : 0;
-    return [percent, percent_precise];
+    var percent = total > 0 ? (used * 100 / total).toFixed() : 0;
+    var percentPrecise = total > 0 ? (used * 100 / total).toFixed(1) : 0;
+    return [percent, percentPrecise];
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js b/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
index e339e6b..128b997 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
@@ -39,13 +39,9 @@ App.HDFSLinksView = App.LinkDashboardWidgetView.extend({
 
   isHAEnabled: Em.computed.not('model.snameNode'),
 
-  isActiveNNValid: function () {
-    return this.get('model.activeNameNode') != null;
-  }.property('model.activeNameNode'),
+  isActiveNNValid: Em.computed.bool('model.activeNameNode'),
 
-  isStandbyNNValid: function () {
-    return this.get('model.standbyNameNode') != null;
-  }.property('model.standbyNameNode'),
+  isStandbyNNValid: Em.computed.bool('model.standbyNameNode'),
 
   isTwoStandbyNN: Em.computed.and('isActiveNNValid', 'isStandbyNNValid'),
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/links_widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/links_widget.js b/ambari-web/app/views/main/dashboard/widgets/links_widget.js
index 5647617..acd9eb9 100644
--- a/ambari-web/app/views/main/dashboard/widgets/links_widget.js
+++ b/ambari-web/app/views/main/dashboard/widgets/links_widget.js
@@ -17,7 +17,6 @@
  */
 
 var App = require('app');
-var date = require('utils/date/date');
 
 App.LinkDashboardWidgetView = App.DashboardWidgetView.extend({
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js b/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
index ead0d47..161b5c0 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
@@ -39,9 +39,9 @@ App.NameNodeCpuPieChartView = App.PieChartDashboardWidgetView.extend({
       intervalId;
     App.router.get('mainController').isLoading.call(App.router.get('clusterController'), 'isServiceContentFullyLoaded').done(function () {
       if (App.get('isHaEnabled')) {
-        self.set('nnHostName', self.get('model').get('activeNameNode.hostName'));
+        self.set('nnHostName', self.get('model.activeNameNode.hostName'));
       } else {
-        self.set('nnHostName', self.get('model').get('nameNode.hostName'));
+        self.set('nnHostName', self.get('model.nameNode.hostName'));
       }
       if (self.get('nnHostName')) {
         self.getValue();
@@ -77,28 +77,28 @@ App.NameNodeCpuPieChartView = App.PieChartDashboardWidgetView.extend({
   calcHiddenInfo: function () {
     var value = this.get('cpuWio');
     var obj1;
-    if (value == null) {
-      obj1 = Em.I18n.t('services.service.summary.notAvailable');
-    }
-    else {
+    if (value) {
       value = value >= 100 ? 100 : value;
       obj1 = (value + 0).toFixed(2) + '%';
     }
-    var result = [];
-    result.pushObject(obj1);
-    result.pushObject('CPU wait I/O');
-    return result;
+    else {
+      obj1 = Em.I18n.t('services.service.summary.notAvailable');
+    }
+    return [
+      obj1,
+      'CPU wait I/O'
+    ];
   },
 
   calcIsPieExists: function () {
-    return (!Em.isNone(this.get('cpuWio')));
+    return !Em.isNone(this.get('cpuWio'));
   },
 
   calcDataForPieChart: function () {
     var value = this.get('cpuWio');
     value = value >= 100 ? 100 : value;
     var percent = (value + 0).toFixed(1);
-    var percent_precise = (value + 0).toFixed(2);
-    return [percent, percent_precise];
+    var percentPrecise = (value + 0).toFixed(2);
+    return [percent, percentPrecise];
   }
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js b/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
index 692796f..731143c 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
@@ -17,7 +17,6 @@
  */
 
 var App = require('app');
-var numberUtils = require('utils/number_utils');
 
 App.NameNodeHeapPieChartView = App.PieChartDashboardWidgetView.extend({
 
@@ -30,11 +29,11 @@ App.NameNodeHeapPieChartView = App.PieChartDashboardWidgetView.extend({
   widgetHtmlId: 'widget-nn-heap',
 
   getUsed: function() {
-    return (this.get('model').get(this.get('modelFieldUsed')) / (1024 * 1024)) || 0;
+    return this.get('model').get(this.get('modelFieldUsed')) / (1024 * 1024) || 0;
   },
 
   getMax: function() {
-    return (this.get('model').get(this.get('modelFieldMax')) / (1024 * 1024)) || 0;
+    return this.get('model').get(this.get('modelFieldMax')) / (1024 * 1024) || 0;
   },
 
   didInsertElement: function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js b/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
index 4826050..58b86d9 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
@@ -18,18 +18,18 @@
 
 var App = require('app');
 
-App.NameNodeRpcView = App.TextDashboardWidgetView.extend({
+App.NameNodeRpcView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin, {
 
   title: Em.I18n.t('dashboard.widgets.NameNodeRpc'),
   id: '5',
 
   model_type: 'hdfs',
   hiddenInfo: function () {
-    var result = [];
-    result.pushObject(this.get('content') + ' average RPC');
-    result.pushObject('queue wait time');
-    return result;
-  }.property('model.nameNodeRpc'),
+    return [
+      this.get('content') + ' average RPC',
+      'queue wait time'
+    ];
+  }.property('content'),
 
   thresh1: 0.5,
   thresh2: 2,
@@ -42,120 +42,20 @@ App.NameNodeRpcView = App.TextDashboardWidgetView.extend({
   data: function () {
     if (this.get('model.nameNodeRpc')) {
       return (this.get('model.nameNodeRpc')).toFixed(2);
-    } else {
-      if (this.get('model.nameNodeRpc') == 0) {
-        return 0;
-      } else {
-        return null;
-      }
     }
+    if (this.get('model.nameNodeRpc') == 0) {
+      return 0;
+    }
+    return null;
   }.property('model.nameNodeRpc'),
 
   content: function () {
     if (this.get('data') || this.get('data') == 0) {
       return this.get('data') + " ms";
     }
-    else {
-      return Em.I18n.t('services.service.summary.notAvailable');
-    }
+    return Em.I18n.t('services.service.summary.notAvailable');
   }.property('model.nameNodeRpc'),
 
-  editWidget: function (event) {
-    var parent = this;
-    var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint3'),
-      isThresh1Error: false,
-      isThresh2Error: false,
-      errorMessage1: "",
-      errorMessage2: "",
-      maxValue: 'infinity',
-      observeNewThresholdValue: function () {
-        var thresh1 = this.get('thresh1');
-        var thresh2 = this.get('thresh2');
-        if (thresh1.trim() != "") {
-          if (isNaN(thresh1) || thresh1 < 0) {
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Invalid! Enter a number larger than 0');
-          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)){
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
-          } else {
-            this.set('isThresh1Error', false);
-            this.set('errorMessage1', '');
-          }
-        } else {
-          this.set('isThresh1Error', true);
-          this.set('errorMessage1', 'This is required');
-        }
-
-        if (thresh2.trim() != "") {
-          if (isNaN(thresh2) || thresh2 < 0) {
-            this.set('isThresh2Error', true);
-            this.set('errorMessage2', 'Invalid! Enter a number larger than 0');
-          } else {
-            this.set('isThresh2Error', false);
-            this.set('errorMessage2', '');
-          }
-        } else {
-          this.set('isThresh2Error', true);
-          this.set('errorMessage2', 'This is required');
-        }
-      }.observes('thresh1', 'thresh2')
-
-    });
-
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show({
-      header: Em.I18n.t('dashboard.widgets.popupHeader'),
-      classNames: ['sixty-percent-width-modal-edit-widget'],
-      bodyClass: Ember.View.extend({
-        templateName: require('templates/main/dashboard/edit_widget_popup'),
-        configPropertyObj: configObj
-      }),
-      primary: Em.I18n.t('common.apply'),
-      onPrimary: function () {
-        configObj.observeNewThresholdValue();
-        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
-          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
-          if (!App.get('testMode')) {
-            //save to persist
-            var big_parent = parent.get('parentView');
-            big_parent.getUserPref(big_parent.get('persistKey'));
-            var oldValue = big_parent.get('currentPrefObject');
-            oldValue.threshold[parseInt(parent.id)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-            big_parent.postUserPref(big_parent.get('persistKey'),oldValue);
-          }
-
-          this.hide();
-        }
-      },
-
-      didInsertElement: function () {
-        var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
-        var handlers = [33, 66]; //fixed value
-
-        if (browserVerion == -1 || browserVerion > 9) {
-          configObj.set('isIE9', false);
-          configObj.set('isGreenOrangeRed', true);
-          $("#slider-range").slider({
-            range:true,
-            disabled:true, //handlers cannot move
-            min: 0,
-            max: 100,
-            values: handlers,
-            create: function (event, ui) {
-              parent.updateColors(handlers, colors);
-            }
-          });
-        } else {
-          configObj.set('isIE9', true);
-          configObj.set('isGreenOrangeRed', true);
-        }
-      }
-    });
-  }
+  hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint3')
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js b/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
index e555c1d..d5bf50b 100644
--- a/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
@@ -18,7 +18,7 @@
 
 var App = require('app');
 
-App.NodeManagersLiveView = App.TextDashboardWidgetView.extend({
+App.NodeManagersLiveView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
   title: Em.I18n.t('dashboard.widgets.NodeManagersLive'),
   id: '19',
@@ -31,15 +31,16 @@ App.NodeManagersLiveView = App.TextDashboardWidgetView.extend({
     var nmUnhealthy = this.get('model.nodeManagersCountUnhealthy') == null ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.nodeManagersCountUnhealthy');
     var nmRebooted = this.get('model.nodeManagersCountRebooted') == null ? Em.I18n.t('services.service.summary.notAvailable'): this.get('model.nodeManagersCountRebooted');
     var nmDecom = this.get('model.nodeManagersCountDecommissioned') == null ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.nodeManagersCountDecommissioned');
-    var result = [];
-      result.pushObject(nmActive + " active");
-      result.pushObject(nmLost + " lost");
-      result.pushObject(nmUnhealthy + " unhealthy");
-      result.pushObject(nmRebooted + " rebooted");
-      result.pushObject(nmDecom + " decommissioned");
-    return result;
+    return [
+      nmActive + " active",
+      nmLost + " lost",
+      nmUnhealthy + " unhealthy",
+      nmRebooted + " rebooted",
+      nmDecom + " decommissioned"
+    ];
   }.property('model.nodeManagersCountActive', 'model.nodeManagersCountLost',
     'model.nodeManagersCountUnhealthy', 'model.nodeManagersCountRebooted', 'model.nodeManagersCountDecommissioned'),
+
   hiddenInfoClass: "hidden-info-five-line",
 
   thresh1: 40,
@@ -53,126 +54,19 @@ App.NodeManagersLiveView = App.TextDashboardWidgetView.extend({
   data: function () {
     var nodeManagers = this.get('model.nodeManagersTotal');
     var nodeManagersLive = this.get('nodeManagersLive');
-    if (nodeManagersLive == null || !nodeManagers) {
+    if (!nodeManagersLive || !nodeManagers) {
       return null;
-    } else {
-      return (nodeManagersLive / nodeManagers).toFixed(2) * 100;
     }
+    return (nodeManagersLive / nodeManagers).toFixed(2) * 100;
   }.property('model.nodeManagersTotal', 'nodeManagersLive'),
 
   content: function () {
-    return this.get('nodeManagersLive') == null || !this.get('model.nodeManagersTotal') ? Em.I18n.t('services.service.summary.notAvailable') : this.get('nodeManagersLive') + '/' + this.get('model.nodeManagersTotal');
+    return !this.get('nodeManagersLive') || !this.get('model.nodeManagersTotal') ? Em.I18n.t('services.service.summary.notAvailable') : this.get('nodeManagersLive') + '/' + this.get('model.nodeManagersTotal');
   }.property('model.nodeManagersTotal', 'nodeManagersLive'),
 
-  editWidget: function (event) {
-    var parent = this;
-    var max_tmp =  parseFloat(parent.get('maxValue'));
-    var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: Em.I18n.t('dashboard.widgets.hintInfo.hint1').format(max_tmp),
-      isThresh1Error: false,
-      isThresh2Error: false,
-      errorMessage1: "",
-      errorMessage2: "",
-      maxValue: max_tmp,
-      observeNewThresholdValue: function () {
-        var thresh1 = this.get('thresh1');
-        var thresh2 = this.get('thresh2');
-        if (thresh1.trim() != "") {
-          if (isNaN(thresh1) || thresh1 > max_tmp || thresh1 < 0) {
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Invalid! Enter a number between 0 - ' + max_tmp);
-          } else if (this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)){
-            this.set('isThresh1Error', true);
-            this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
-          } else {
-            this.set('isThresh1Error', false);
-            this.set('errorMessage1', '');
-          }
-        } else {
-          this.set('isThresh1Error', true);
-          this.set('errorMessage1', 'This is required');
-        }
-
-        if (thresh2.trim() != "") {
-          if (isNaN(thresh2) || thresh2 > max_tmp || thresh2 < 0) {
-            this.set('isThresh2Error', true);
-            this.set('errorMessage2', 'Invalid! Enter a number between 0 - ' + max_tmp);
-          } else {
-            this.set('isThresh2Error', false);
-            this.set('errorMessage2', '');
-          }
-        } else {
-          this.set('isThresh2Error', true);
-          this.set('errorMessage2', 'This is required');
-        }
-
-        // update the slider handles and color
-        if (this.get('isThresh1Error') === false && this.get('isThresh2Error') === false) {
-          $("#slider-range").slider('values', 0 , parseFloat(thresh1));
-          $("#slider-range").slider('values', 1 , parseFloat(thresh2));
-        }
-      }.observes('thresh1', 'thresh2')
-    });
-
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show({
-      header: 'Customize Widget',
-      classNames: [ 'sixty-percent-width-modal-edit-widget'],
-      bodyClass: Ember.View.extend({
-        templateName: require('templates/main/dashboard/edit_widget_popup'),
-        configPropertyObj: configObj
-      }),
-      primary: Em.I18n.t('common.apply'),
-      onPrimary: function() {
-        configObj.observeNewThresholdValue();
-        if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
-          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
-          if (!App.get('testMode')) {
-            //save to persit
-            var big_parent = parent.get('parentView');
-            big_parent.getUserPref(big_parent.get('persistKey'));
-            var oldValue = big_parent.get('currentPrefObject');
-            oldValue.threshold[parseInt(parent.id)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-            big_parent.postUserPref(big_parent.get('persistKey'),oldValue);
-          }
-          this.hide();
-        }
-      },
-
-      didInsertElement: function () {
-        var self = this;
-        var handlers = [configObj.get('thresh1'), configObj.get('thresh2')];
-        var colors = [App.healthStatusRed, App.healthStatusOrange, App.healthStatusGreen]; //color red, orange, green
-
-        if (browserVerion == -1 || browserVerion > 9) {
-          configObj.set('isIE9', false);
-          configObj.set('isGreenOrangeRed', false);
-          $("#slider-range").slider({
-            range: true,
-            min: 0,
-            max: max_tmp,
-            values: handlers,
-            create: function (event, ui) {
-              parent.updateColors(handlers,colors);
-            },
-            slide: function (event, ui) {
-              parent.updateColors(ui.values,colors);
-              configObj.set('thresh1', ui.values[0] + '');
-              configObj.set('thresh2', ui.values[1] + '');
-            },
-            change: function (event, ui) {
-              parent.updateColors(ui.values,colors);
-            }
-          });
-        } else {
-          configObj.set('isIE9', true);
-          configObj.set('isGreenOrangeRed', false);
-        }
-      }
-    });
-  }
+  hintInfo: function () {
+    var maxTmp = parseFloat(this.get('maxValue'));
+    return Em.I18n.t('dashboard.widgets.hintInfo.hint1').format(maxTmp);
+  }.property('maxValue')
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/87f8746f/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js b/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js
index 801dc6c..8f2dc90 100644
--- a/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js
+++ b/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js
@@ -55,15 +55,15 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
   },
 
   calcIsPieExists: function() {
-    return (this.get('model').get(this.get('modelFieldMax')) > 0);
+    return this.get('model').get(this.get('modelFieldMax')) > 0;
   },
 
   calcDataForPieChart: function() {
     var used = this.getUsed();
     var total = this.getMax();
-    var percent = total > 0 ? ((used)*100 / total).toFixed() : 0;
-    var percent_precise = total > 0 ? ((used)*100 / total).toFixed(1) : 0;
-    return [percent, percent_precise];
+    var percent = total > 0 ? (used * 100 / total).toFixed() : 0;
+    var percentPrecise = total > 0 ? (used * 100 / total).toFixed(1) : 0;
+    return [percent, percentPrecise];
   },
 
   calc: function() {
@@ -97,8 +97,8 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
     }),
 
     data: function() {
-      var ori_data = this.get('parentView.dataForPieChart');
-      return [ ori_data[0], 100 - ori_data[0]];
+      var oriData = this.get('parentView.dataForPieChart');
+      return [oriData[0], 100 - oriData[0]];
     }.property(),
 
     setData: function() {
@@ -109,33 +109,30 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
       var used = parseFloat(this.get('parentView.dataForPieChart')[1]);
       var thresh1 = parseFloat(this.get('thresh1'));
       var thresh2 = parseFloat(this.get('thresh2'));
-      var color_green = App.healthStatusGreen;
-      var color_red = App.healthStatusRed;
-      var color_orange = App.healthStatusOrange;
       if (used <= thresh1) {
         this.set('palette', new Rickshaw.Color.Palette({
-          scheme: [ '#FFFFFF', color_green  ].reverse()
+          scheme: ['#FFFFFF', App.healthStatusGreen].reverse()
         }));
-        return color_green;
-      } else if (used <= thresh2) {
-        this.set('palette', new Rickshaw.Color.Palette({
-          scheme: [ '#FFFFFF', color_orange  ].reverse()
-        }));
-        return color_orange;
-      } else {
+        return App.healthStatusGreen;
+      }
+      if (used <= thresh2) {
         this.set('palette', new Rickshaw.Color.Palette({
-          scheme: [ '#FFFFFF', color_red  ].reverse()
+          scheme: ['#FFFFFF', App.healthStatusOrange].reverse()
         }));
-        return color_red;
+        return App.healthStatusOrange;
       }
+      this.set('palette', new Rickshaw.Color.Palette({
+        scheme: ['#FFFFFF', App.healthStatusRed].reverse()
+      }));
+      return App.healthStatusRed;
     }.property('data', 'thresh1', 'thresh2'),
 
     // refresh text and color when data in model changed
     refreshSvg: function () {
       // remove old svg
-      var old_svg =  $("#" + this.get('id'));
-      if(old_svg){
-        old_svg.remove();
+      var oldSvg = $("#" + this.get('id'));
+      if(oldSvg){
+        oldSvg.remove();
       }
 
       // draw new svg