You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2016/12/02 17:28:05 UTC

[1/2] ambari git commit: AMBARI-19064 Refactor widgets on Dashboard page. (atkach)

Repository: ambari
Updated Branches:
  refs/heads/trunk 7eb2eaa73 -> 9348725b1


http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widget_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widget_test.js b/ambari-web/test/views/main/dashboard/widget_test.js
index 0544ff6..63da712 100644
--- a/ambari-web/test/views/main/dashboard/widget_test.js
+++ b/ambari-web/test/views/main/dashboard/widget_test.js
@@ -21,178 +21,84 @@ require('views/main/dashboard/widget');
 
 describe('App.DashboardWidgetView', function () {
 
-  var dashboardWidgetView = App.DashboardWidgetView.create({
+  var dashboardWidgetView;
+
+  dashboardWidgetView = App.DashboardWidgetView.create({
     parentView: Em.Object.create({
       widgetsMapper: Em.K,
-      getUserPref: function () {return {complete: Em.K}},
+      getUserPref: function () {
+        return {complete: Em.K}
+      },
       postUserPref: Em.K,
       translateToReal: Em.K,
       visibleWidgets: [],
       hiddenWidgets: []
+    }),
+    widget: Em.Object.create({
+      id: 5,
+      sourceName: 'HDFS',
+      title: 'Widget'
     })
   });
 
   describe('#viewID', function () {
     it('viewID is computed with id', function () {
-      dashboardWidgetView.set('id', 5);
       expect(dashboardWidgetView.get('viewID')).to.equal('widget-5');
     });
   });
 
   describe('#model', function () {
-    it('model_type is null', function () {
-      dashboardWidgetView.set('model_type', null);
+
+    beforeEach(function() {
+      sinon.stub(dashboardWidgetView, 'findModelBySource').returns(Em.Object.create({serviceName: 'HDFS'}));
+    });
+
+    afterEach(function() {
+      dashboardWidgetView.findModelBySource.restore();
+    });
+
+    it('sourceName is null', function () {
+      dashboardWidgetView.set('widget.sourceName', null);
       dashboardWidgetView.propertyDidChange('model');
-      expect(dashboardWidgetView.get('model')).to.eql({});
+      expect(dashboardWidgetView.get('model')).to.be.an.object;
     });
-    it('model_type is valid', function () {
-      dashboardWidgetView.set('model_type', 's');
+    it('sourceName is valid', function () {
+      dashboardWidgetView.set('widget.sourceName', 'HDFS');
       dashboardWidgetView.propertyDidChange('model');
-      dashboardWidgetView.set('parentView.s_model', {'s': {}});
-      expect(dashboardWidgetView.get('model')).to.eql({'s': {}});
+      expect(dashboardWidgetView.get('model')).to.eql(Em.Object.create({serviceName: 'HDFS'}));
     });
   });
 
   describe("#didInsertElement()", function () {
-    before(function () {
+
+    beforeEach(function () {
       sinon.stub(App, 'tooltip', Em.K);
     });
-    after(function () {
+    afterEach(function () {
       App.tooltip.restore();
     });
+
     it("call App.tooltip", function () {
       dashboardWidgetView.didInsertElement();
       expect(App.tooltip.calledOnce).to.be.true;
     });
   });
 
-  describe("#deleteWidget()", function () {
-    beforeEach(function () {
-      sinon.stub(dashboardWidgetView.get('parentView'), 'widgetsMapper').returns({});
-      sinon.stub(dashboardWidgetView.get('parentView'), 'getUserPref').returns({
-        complete: Em.K
-      });
-    });
-
-    afterEach(function () {
-      dashboardWidgetView.get('parentView').widgetsMapper.restore();
-      dashboardWidgetView.get('parentView').getUserPref.restore();
-    });
-
-    it("testMode is off", function () {
-      dashboardWidgetView.set('parentView.persistKey', 'key');
-      dashboardWidgetView.deleteWidget();
-      expect(dashboardWidgetView.get('parentView').getUserPref.calledWith('key')).to.be.true;
-    });
-  });
+  describe("#editWidget()", function () {
 
-  describe("#deleteWidgetComplete()", function () {
     beforeEach(function () {
-      sinon.spy(dashboardWidgetView.get('parentView'), 'postUserPref');
-      sinon.spy(dashboardWidgetView.get('parentView'), 'translateToReal');
-      dashboardWidgetView.set('parentView.currentPrefObject', {
-        dashboardVersion: 'new',
-        visible: ['1', '2'],
-        hidden: [],
-        threshold: 'threshold'
-      });
-      dashboardWidgetView.set('parentView.persistKey', 'key');
-      dashboardWidgetView.deleteWidgetComplete();
-    });
-    afterEach(function () {
-      dashboardWidgetView.get('parentView').postUserPref.restore();
-      dashboardWidgetView.get('parentView').translateToReal.restore();
-    });
-    it("postUserPref is called with correct data", function () {
-      var arg = JSON.parse(JSON.stringify(dashboardWidgetView.get('parentView').postUserPref.args[0][1]));
-      expect(arg).to.be.eql({
-        dashboardVersion: 'new',
-        visible: ['1', '2'],
-        hidden: [[5, null]],
-        threshold: 'threshold'
-      });
-    });
-    it("translateToReal is called with valid data", function () {
-      var arg = JSON.parse(JSON.stringify(dashboardWidgetView.get('parentView').translateToReal.args[0][0]));
-      expect(arg).to.be.eql({
-        dashboardVersion: 'new',
-        visible: ['1', '2'],
-        hidden: [[5, null]],
-        threshold: 'threshold'
-      });
-    });
-  });
-
-  describe("#editWidget()", function () {
-    before(function () {
       sinon.stub(dashboardWidgetView, 'showEditDialog', Em.K);
     });
-    after(function () {
+    afterEach(function () {
       dashboardWidgetView.showEditDialog.restore();
     });
+
     it("call showEditDialog", function () {
       dashboardWidgetView.editWidget();
       expect(dashboardWidgetView.showEditDialog.calledOnce).to.be.true;
     });
   });
 
-  describe("#showEditDialog()", function () {
-    var obj = Em.Object.create({
-      observeThresh1Value: Em.K,
-      observeThresh2Value: Em.K,
-      thresh1: '1',
-      thresh2: '2'
-    });
-    beforeEach(function () {
-      sinon.spy(obj, 'observeThresh1Value');
-      sinon.spy(obj, 'observeThresh2Value');
-      sinon.stub(dashboardWidgetView.get('parentView'), 'getUserPref').returns({
-        complete: Em.K
-      });
-      var popup = dashboardWidgetView.showEditDialog(obj);
-      popup.onPrimary();
-    });
-    afterEach(function () {
-      obj.observeThresh1Value.restore();
-      obj.observeThresh2Value.restore();
-      dashboardWidgetView.get('parentView').getUserPref.restore();
-    });
-
-    it("observeThresh1Value is called once", function () {
-      expect(obj.observeThresh1Value.calledOnce).to.be.true;
-    });
-
-    it("observeThresh2Value is called once", function () {
-      expect(obj.observeThresh2Value.calledOnce).to.be.true;
-    });
-
-    it("thresh1 = 1", function () {
-      expect(dashboardWidgetView.get('thresh1')).to.equal(1);
-    });
-
-    it("thresh2 = 2", function () {
-      expect(dashboardWidgetView.get('thresh2')).to.equal(2);
-    });
-
-    it("getUserPref is called once", function () {
-      expect(dashboardWidgetView.get('parentView').getUserPref.calledOnce).to.be.true;
-    });
-  });
-
-  describe('#model', function () {
-    it('model_type is null', function () {
-      dashboardWidgetView.set('model_type', null);
-      dashboardWidgetView.propertyDidChange('model');
-      expect(dashboardWidgetView.get('model')).to.eql({});
-    });
-    it('model_type is valid', function () {
-      dashboardWidgetView.set('model_type', 's');
-      dashboardWidgetView.propertyDidChange('model');
-      dashboardWidgetView.set('parentView.s_model', {'s': {}});
-      expect(dashboardWidgetView.get('model')).to.eql({'s': {}});
-    });
-  });
-
   describe('#hoverContentTopClass', function () {
     var tests = [
       {
@@ -258,7 +164,7 @@ describe('App.DashboardWidgetView', function () {
       var testCases = [
         {
           data: {
-            thresh1: '',
+            thresholdMin: '',
             maxValue: 0
           },
           result: {
@@ -268,7 +174,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: 'NaN',
+            thresholdMin: 'NaN',
             maxValue: 0
           },
           result: {
@@ -278,7 +184,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '-1',
+            thresholdMin: '-1',
             maxValue: 0
           },
           result: {
@@ -288,7 +194,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '2',
+            thresholdMin: '2',
             maxValue: 1
           },
           result: {
@@ -298,8 +204,8 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '1',
-            thresh2: '1',
+            thresholdMin: '1',
+            thresholdMax: '1',
             maxValue: 2
           },
           result: {
@@ -309,8 +215,8 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '1',
-            thresh2: '0',
+            thresholdMin: '1',
+            thresholdMax: '0',
             maxValue: 2
           },
           result: {
@@ -320,8 +226,8 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '1',
-            thresh2: '2',
+            thresholdMin: '1',
+            thresholdMax: '2',
             maxValue: 2
           },
           result: {
@@ -331,12 +237,12 @@ describe('App.DashboardWidgetView', function () {
         }
       ];
       testCases.forEach(function (test) {
-        describe("thresh1 - " + test.data.thresh1 + ', maxValue - ' + test.data.maxValue, function () {
+        describe("thresholdMin - " + test.data.thresholdMin + ', maxValue - ' + test.data.maxValue, function () {
 
           beforeEach(function () {
             widget.set('isThresh2Error', false);
-            widget.set('thresh2', test.data.thresh2 || "");
-            widget.set('thresh1', test.data.thresh1);
+            widget.set('thresholdMax', test.data.thresholdMax || "");
+            widget.set('thresholdMin', test.data.thresholdMin);
             widget.set('maxValue', test.data.maxValue);
             widget.observeThresh1Value();
           });
@@ -367,7 +273,7 @@ describe('App.DashboardWidgetView', function () {
       var testCases = [
         {
           data: {
-            thresh2: '',
+            thresholdMax: '',
             maxValue: 0
           },
           result: {
@@ -377,7 +283,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh2: 'NaN',
+            thresholdMax: 'NaN',
             maxValue: 0
           },
           result: {
@@ -387,7 +293,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh2: '-1',
+            thresholdMax: '-1',
             maxValue: 0
           },
           result: {
@@ -397,7 +303,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh2: '2',
+            thresholdMax: '2',
             maxValue: 1
           },
           result: {
@@ -407,7 +313,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh2: '2',
+            thresholdMax: '2',
             maxValue: 2
           },
           result: {
@@ -417,10 +323,10 @@ describe('App.DashboardWidgetView', function () {
         }
       ];
       testCases.forEach(function (test) {
-        describe("thresh2 - " + test.data.thresh2 + ', maxValue - ' + test.data.maxValue, function () {
+        describe("thresholdMax - " + test.data.thresholdMax + ', maxValue - ' + test.data.maxValue, function () {
 
           beforeEach(function () {
-            widget.set('thresh2', test.data.thresh2 || "");
+            widget.set('thresholdMax', test.data.thresholdMax || "");
             widget.set('maxValue', test.data.maxValue);
             widget.observeThresh2Value();
           });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js b/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js
index e3a08c9..8cb3246 100644
--- a/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js
@@ -82,8 +82,8 @@ describe('App.HBaseAverageLoadView', function() {
 
   App.TestAliases.testAsComputedAlias(getView(), 'data', 'model.averageLoad', 'number');
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresh2');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresholdMax');
 
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresh1');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresholdMin');
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js b/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js
index 8ad1531..4366ab6 100644
--- a/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js
@@ -23,7 +23,7 @@ require('views/main/dashboard/widgets/text_widget');
 require('views/main/dashboard/widget');
 
 function getView() {
-  return App.HBaseRegionsInTransitionView.create({model_type:null});
+  return App.HBaseRegionsInTransitionView.create({});
 }
 
 describe('App.HBaseRegionsInTransitionView', function() {
@@ -81,9 +81,9 @@ describe('App.HBaseRegionsInTransitionView', function() {
 
   App.TestAliases.testAsComputedAlias(getView(), 'data', 'model.regionsInTransition', 'number');
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresh2');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresholdMax');
 
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresh1');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresholdMin');
 
   App.TestAliases.testAsComputedAnd(getView(), 'isOrange', ['!isGreen', '!isRed']);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js b/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js
index 474d099..15b7503 100644
--- a/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js
@@ -35,7 +35,6 @@ describe('App.NameNodeRpcView', function() {
         nameNodeRpc: 1
       },
       e: {
-        isOrange: true,
         isNA: false,
         content: '1.00 ms',
         data: '1.00'
@@ -46,7 +45,6 @@ describe('App.NameNodeRpcView', function() {
         nameNodeRpc: 10
       },
       e: {
-        isOrange: false,
         isNA: false,
         content: '10.00 ms',
         data: '10.00'
@@ -57,7 +55,6 @@ describe('App.NameNodeRpcView', function() {
         nameNodeRpc: 0
       },
       e: {
-        isOrange: false,
         isNA: false,
         content: '0 ms',
         data: 0
@@ -68,7 +65,6 @@ describe('App.NameNodeRpcView', function() {
         nameNodeRpc: null
       },
       e: {
-        isOrange: false,
         isNA: true,
         content: Em.I18n.t('services.service.summary.notAvailable'),
         data: null
@@ -78,24 +74,21 @@ describe('App.NameNodeRpcView', function() {
 
   tests.forEach(function(test) {
     describe('nameNodeRpc - ' + test.model.nameNodeRpc, function() {
-      var jobTrackerRpcView = App.NameNodeRpcView.create({model_type:null, model: test.model});
+      var jobTrackerRpcView = App.NameNodeRpcView.create({model: test.model});
       it('content', function() {
         expect(jobTrackerRpcView.get('content')).to.equal(test.e.content);
       });
       it('data', function() {
         expect(jobTrackerRpcView.get('data')).to.equal(test.e.data);
       });
-      it('isOrange', function() {
-        expect(jobTrackerRpcView.get('isOrange')).to.equal(test.e.isOrange);
-      });
       it('isNA', function() {
         expect(jobTrackerRpcView.get('isNA')).to.equal(test.e.isNA);
       });
     });
   });
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresh2');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresholdMax');
 
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresh1');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresholdMin');
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js b/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js
index e564922..3136c35 100644
--- a/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js
@@ -22,7 +22,7 @@ require('views/main/dashboard/widget');
 require('views/main/dashboard/widgets/text_widget_single_threshold');
 
 function getView() {
-  return App.TextDashboardSingleThresholdWidgetView.create({thresh1:0});
+  return App.TextDashboardSingleThresholdWidgetView.create({thresholdMin:0});
 }
 
 describe('App.TextDashboardSingleThresholdWidgetView', function() {
@@ -43,8 +43,8 @@ describe('App.TextDashboardSingleThresholdWidgetView', function() {
   ];
 
   tests.forEach(function(test) {
-    describe('data - ' + test.data + ' | thresh1 - 0', function() {
-      var textDashboardWidgetSingleThresholdView = App.TextDashboardSingleThresholdWidgetView.create({thresh1:0});
+    describe('data - ' + test.data + ' | thresholdMin - 0', function() {
+      var textDashboardWidgetSingleThresholdView = App.TextDashboardSingleThresholdWidgetView.create({thresholdMin:0});
       textDashboardWidgetSingleThresholdView.set('data', test.data);
       it('isNA', function() {
         expect(textDashboardWidgetSingleThresholdView.get('isNA')).to.equal(test.e.isNA);
@@ -52,6 +52,6 @@ describe('App.TextDashboardSingleThresholdWidgetView', function() {
     });
   });
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresh1');
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresh1');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresholdMin');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresholdMin');
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js b/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js
index 730e209..096d782 100644
--- a/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js
@@ -22,7 +22,7 @@ require('views/main/dashboard/widget');
 require('views/main/dashboard/widgets/text_widget');
 
 function getView() {
-  return App.TextDashboardWidgetView.create({thresh1:40, thresh2:70});
+  return App.TextDashboardWidgetView.create({thresholdMin:40, thresholdMax:70});
 }
 
 describe('App.TextDashboardWidgetView', function() {
@@ -43,8 +43,8 @@ describe('App.TextDashboardWidgetView', function() {
   ];
 
   tests.forEach(function(test) {
-    describe('data - ' + test.data + ' | thresh1 - 40 | thresh2 - 70', function() {
-      var textDashboardWidgetView = App.TextDashboardWidgetView.create({thresh1:40, thresh2:70});
+    describe('data - ' + test.data + ' | thresholdMin - 40 | thresholdMax - 70', function() {
+      var textDashboardWidgetView = App.TextDashboardWidgetView.create({thresholdMin:40, thresholdMax:70});
       textDashboardWidgetView.set('data', test.data);
       it('isNA', function() {
         expect(textDashboardWidgetView.get('isNA')).to.equal(test.e.isNA);
@@ -52,9 +52,9 @@ describe('App.TextDashboardWidgetView', function() {
     });
   });
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isGreen', 'data', 'thresh2');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isGreen', 'data', 'thresholdMax');
 
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isRed', 'data', 'thresh1');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isRed', 'data', 'thresholdMin');
 
   App.TestAliases.testAsComputedAnd(getView(), 'isOrange', ['!isGreen', '!isRed']);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js b/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js
index fbe2694..fa20593 100644
--- a/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js
@@ -25,7 +25,7 @@ var uptimeTextDashboardWidgetView;
 describe('App.UptimeTextDashboardWidgetView', function() {
 
   beforeEach(function () {
-    uptimeTextDashboardWidgetView = App.UptimeTextDashboardWidgetView.create({thresh1:40, thresh2:70});
+    uptimeTextDashboardWidgetView = App.UptimeTextDashboardWidgetView.create({thresholdMin:40, thresholdMax:70});
   });
 
   describe('#timeConverter', function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets_test.js b/ambari-web/test/views/main/dashboard/widgets_test.js
index 0781c79..707087a 100644
--- a/ambari-web/test/views/main/dashboard/widgets_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets_test.js
@@ -25,526 +25,325 @@ require('views/main/dashboard/widgets');
 
 describe('App.MainDashboardWidgetsView', function () {
 
-  var view = App.MainDashboardWidgetsView.create();
-
-  describe('#setInitPrefObject', function () {
-    var hostMetricsWidgetsCount = 4;
-    var hdfsWidgetsCount = 7;
-    var hbaseWidgetsCount = 4;
-    var yarnWidgetsCount = 4;
-    var totalWidgetsCount = 20;
-    var tests = Em.A([
-      {
-        models: {
-          host_metrics_model: null,
-          hdfs_model: null,
-          hbase_model: null,
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - hostMetricsWidgetsCount - hdfsWidgetsCount - hbaseWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 0
-        },
-        m: 'All models are null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: null,
-          hbase_model: null,
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - hdfsWidgetsCount - hbaseWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 0
-        },
-        m: 'hdfs_model, hbase_model, yarn_model are null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: {},
-          hbase_model: null,
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - hbaseWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 0
-        },
-        m: 'hbase_model, yarn_model are null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: {},
-          hbase_model: null,
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - hbaseWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 0
-        },
-        m: 'hbase_model and yarn_model are null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: {},
-          hbase_model: {},
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 1
-        },
-        m: 'yarn_model is null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: {},
-          hbase_model: {},
-          yarn_model: {}
-        },
-        e: {
-          visibleL: totalWidgetsCount - 1,
-          hiddenL: 1
-        },
-        m: 'All models are not null'
-      }
-    ]);
+  var view;
+
+  beforeEach(function() {
+    view = App.MainDashboardWidgetsView.create({
+      getUserPref: Em.K,
+      postUserPref: Em.K,
+      setDBProperty: Em.K,
+      persistKey: 'key'
+    });
+  });
+
+  describe('#didInsertElement()', function() {
 
     beforeEach(function() {
-      sinon.stub(view, 'resolveConfigDependencies');
+      sinon.stub(view, 'loadWidgetsSettings').returns({
+        complete: Em.clb
+      });
+      sinon.stub(view, 'checkServicesChange');
+      sinon.stub(view, 'renderWidgets');
+      sinon.stub(Em.run, 'next');
+      view.didInsertElement();
     });
 
     afterEach(function() {
-      view.resolveConfigDependencies.restore();
+      view.loadWidgetsSettings.restore();
+      view.checkServicesChange.restore();
+      view.renderWidgets.restore();
+      Em.run.next.restore();
     });
 
-    tests.forEach(function (test) {
-      describe(test.m, function () {
-
-        beforeEach(function () {
-          view.set('host_metrics_model', test.models.host_metrics_model);
-          view.set('hdfs_model', test.models.hdfs_model);
-          view.set('hbase_model', test.models.hbase_model);
-          view.set('yarn_model', test.models.yarn_model);
-          view.setInitPrefObject();
-        });
-
-        it('visible.length is ' + test.e.visibleL, function () {
-          expect(view.get('initPrefObject.visible.length')).to.equal(test.e.visibleL);
-        });
-
-        it('hidden.length is ' + test.e.hiddenL, function () {
-          expect(view.get('initPrefObject.hidden.length')).to.equal(test.e.hiddenL);
-        });
-
-      });
+    it('checkServicesChange should be called', function() {
+      expect(view.checkServicesChange).to.be.calledOnce;
     });
-  });
 
-  describe('#persistKey', function () {
-    beforeEach(function () {
-      sinon.stub(App, 'get').withArgs('router.loginName').returns('tdk');
+    it('renderWidgets should be called', function() {
+      expect(view.renderWidgets).to.be.calledOnce;
     });
-    afterEach(function () {
-      App.get.restore();
+
+    it('isDataLoaded should be true', function() {
+      expect(view.get('isDataLoaded')).to.be.true;
     });
-    it('Check it', function () {
-      expect(view.get('persistKey')).to.equal('user-pref-tdk-dashboard');
+
+    it('Em.run.next should be called', function() {
+      expect(Em.run.next.calledWith(view, 'makeSortable')).to.be.true;
     });
   });
 
-  describe("#didInsertElement()", function () {
-    beforeEach(function () {
-      sinon.stub(view, 'setWidgetsDataModel', Em.K);
-      sinon.stub(view, 'setInitPrefObject', Em.K);
-      sinon.stub(view, 'setOnLoadVisibleWidgets', Em.K);
-      sinon.stub(Em.run, 'next', Em.K);
-      view.didInsertElement();
-    });
-    afterEach(function () {
-      view.setWidgetsDataModel.restore();
-      view.setInitPrefObject.restore();
-      view.setOnLoadVisibleWidgets.restore();
-      Em.run.next.restore();
-    });
-    it("setWidgetsDataModel is called once", function () {
-      expect(view.setWidgetsDataModel.calledOnce).to.be.true;
-    });
-    it("setInitPrefObject is called once", function () {
-      expect(view.setInitPrefObject.calledOnce).to.be.true;
-    });
-    it("setOnLoadVisibleWidgets is called once", function () {
-      expect(view.setOnLoadVisibleWidgets.calledOnce).to.be.true;
+  describe('#loadWidgetsSettings()', function() {
+
+    beforeEach(function() {
+      sinon.spy(view, 'getUserPref');
     });
-    it("makeSortable is called in the next loop", function () {
-      expect(Em.run.next.calledWith(view, 'makeSortable')).to.be.true;
+
+    afterEach(function() {
+      view.getUserPref.restore();
     });
-    it("isDataLoaded is true", function () {
-      expect(view.get('isDataLoaded')).to.be.true
+
+    it('getUserPref should be called', function() {
+      view.loadWidgetsSettings();
+      expect(view.getUserPref.calledWith('key')).to.be.true;
     });
   });
 
-  describe("#setWidgetsDataModel()", function () {
-    beforeEach(function () {
-      this.model = sinon.stub(App.Service, 'find');
-      this.get = sinon.stub(App, 'get');
-    });
-    afterEach(function () {
-      this.model.restore();
-      this.get.restore();
+  describe('#saveWidgetsSettings()', function() {
+
+    beforeEach(function() {
+      sinon.stub(view, 'setDBProperty');
+      sinon.stub(view, 'postUserPref');
+      view.saveWidgetsSettings({settings:{}});
     });
-    it("No host_metrics_model", function () {
-      this.get.returns([]);
-      this.model.returns([Em.Object.create({
-        serviceName: 'S1',
-        id: 'S1'
-      })]);
-      view.set('host_metrics_model', null);
-      view.setWidgetsDataModel();
-      expect(view.get('host_metrics_model')).to.be.null;
-      expect(view.get('s1_model')).to.eql(Em.Object.create({
-        serviceName: 'S1',
-        id: 'S1'
-      }));
+
+    afterEach(function() {
+      view.setDBProperty.restore();
+      view.postUserPref.restore();
     });
-    it("host_metrics_model is present", function () {
-      this.get.returns([1]);
-      this.model.returns([Em.Object.create({
-        serviceName: 'HDFS',
-        id: 'HDFS'
-      })]);
-      view.set('host_metrics_model', null);
-      view.setWidgetsDataModel();
-      expect(view.get('host_metrics_model')).to.eql([1]);
-      expect(view.get('hdfs_model.id')).to.equal('HDFS');
+
+    it('setDBProperty should be called', function() {
+      expect(view.setDBProperty.calledWith('key', {settings:{}})).to.be.true;
     });
-  });
 
-  describe("#plusButtonFilterView", function () {
-    var plusButtonFilterView = view.get('plusButtonFilterView').create({
-      parentView: view
+    it('postUserPref should be called', function() {
+      expect(view.postUserPref.calledWith('key', {settings:{}})).to.be.true;
     });
-    plusButtonFilterView.reopen({
-      visibleWidgets: [],
-      hiddenWidgets: []
+
+    it('userPreferences should be set', function() {
+      expect(view.get('userPreferences')).to.be.eql({settings:{}});
     });
+  });
 
-    describe("#applyFilter()", function () {
-      var widget = {checked: true};
-      beforeEach(function () {
-        sinon.stub(view, 'getUserPref').returns({
-          complete: Em.K
-        });
-        sinon.stub(view, 'widgetsMapper').returns(widget);
-      });
+  describe('#getUserPrefSuccessCallback()', function() {
 
-      afterEach(function () {
-        view.getUserPref.restore();
-        view.widgetsMapper.restore();
-      });
+    beforeEach(function() {
+      sinon.stub(view, 'getUserPrefErrorCallback');
+    });
 
-      it("testMode is off", function () {
-        plusButtonFilterView.applyFilter();
-        expect(view.getUserPref.calledOnce).to.be.true;
-      });
+    afterEach(function() {
+      view.getUserPrefErrorCallback.restore();
     });
 
-    describe("#applyFilterComplete()", function () {
-      beforeEach(function () {
-        sinon.stub(view, 'postUserPref');
-        sinon.stub(view, 'translateToReal');
-        sinon.stub(App.router, 'get', function (k) {
-          if ('loginName' === k) return 'tdk';
-          return Em.get(App.router, k);
-        });
-        plusButtonFilterView.set('hiddenWidgets', [
-          Em.Object.create({
-            checked: true,
-            id: 1,
-            displayName: 'i1'
-          }),
-          Em.Object.create({
-            checked: false,
-            id: 2,
-            displayName: 'i2'
-          })
-        ]);
-        view.set('currentPrefObject', Em.Object.create({
-          dashboardVersion: 'new',
-          visible: [],
-          hidden: [],
-          threshold: 'threshold'
-        }));
-        view.set('persistKey', 'key');
-        plusButtonFilterView.applyFilterComplete();
-      });
-      afterEach(function () {
-        view.postUserPref.restore();
-        view.translateToReal.restore();
-        App.router.get.restore();
-      });
-      it("postUserPref is called once", function () {
-        expect(view.postUserPref.calledOnce).to.be.true;
-      });
-      it("translateToReal is called with correct data", function () {
-        expect(view.translateToReal.getCall(0).args[0]).to.eql(Em.Object.create({
-          dashboardVersion: 'new',
-          visible: [1],
-          hidden: [
-            [2, 'i2']
-          ],
-          threshold: 'threshold'
-        }));
-      });
-      it("1 hidden widget", function () {
-        expect(plusButtonFilterView.get('hiddenWidgets.length')).to.equal(1);
-      });
+    it('getUserPrefErrorCallback should be called', function() {
+      view.getUserPrefSuccessCallback(null);
+      expect(view.getUserPrefErrorCallback).to.be.calledOnce;
     });
-  });
 
-  describe("#translateToReal()", function () {
-    beforeEach(function () {
-      sinon.stub(view, 'widgetsMapper').returns(Em.Object.create());
-      view.set('visibleWidgets', []);
-      view.set('hiddenWidgets', []);
-    });
-    afterEach(function () {
-      view.widgetsMapper.restore();
-    });
-    it("version is not new", function () {
-      var data = {
-        dashboardVersion: null,
-        visible: [],
-        hidden: [],
-        threshold: []
-      };
-      view.translateToReal(data);
-      expect(view.get('visibleWidgets')).to.be.empty;
-      expect(view.get('hiddenWidgets')).to.be.empty;
-    });
-    it("version is new", function () {
-      var data = {
-        dashboardVersion: 'new',
-        visible: [1],
-        hidden: [
-          ['id', 'title']
-        ],
-        threshold: [
-          [],
-          [
-            ['tresh1'],
-            ['tresh2']
-          ]
-        ]
-      };
-      view.translateToReal(data);
-      expect(view.get('visibleWidgets')).to.not.be.empty;
-      expect(view.get('hiddenWidgets')).to.not.be.empty;
+    it('userPreferences should be set', function() {
+      view.getUserPrefSuccessCallback({settings:{}});
+      expect(view.get('userPreferences')).to.be.eql({settings:{}});
     });
   });
 
-  describe("#setOnLoadVisibleWidgets()", function () {
-    beforeEach(function () {
-      sinon.stub(view, 'translateToReal', Em.K);
-      sinon.stub(view, 'getUserPref').returns({complete: Em.K});
-    });
+  describe('#getUserPrefErrorCallback()', function() {
 
-    afterEach(function () {
-      view.translateToReal.restore();
-      view.getUserPref.restore();
+    beforeEach(function() {
+      sinon.stub(view, 'generateDefaultUserPreferences').returns({settings:{}});
+      sinon.stub(view, 'saveWidgetsSettings');
     });
 
-    it("testMode is false", function () {
-      view.setOnLoadVisibleWidgets();
-      expect(view.getUserPref.calledOnce).to.be.true;
+    afterEach(function() {
+      view.generateDefaultUserPreferences.restore();
+      view.saveWidgetsSettings.restore();
     });
-  });
 
-  describe("#removeWidget()", function () {
-    var widget;
-    var value;
-    beforeEach(function () {
-      widget = {};
-      value = {
-        visible: [widget],
-        hidden: [
-          [widget]
-        ]
-      };
-      value = view.removeWidget(value, widget);
-    });
-    it("value.visible is empty", function () {
-      expect(value.visible).to.be.empty;
-    });
-    it("value.hidden is empty", function () {
-      expect(value.hidden).to.be.empty;
+    it('saveWidgetsSettings should be called', function() {
+      view.getUserPrefErrorCallback();
+      expect(view.saveWidgetsSettings.calledWith({settings:{}})).to.be.true;
     });
   });
 
-  describe("#containsWidget()", function () {
-    it("widget visible", function () {
-      var widget = {};
-      var value = {
-        visible: [widget],
-        hidden: [
-          [widget]
-        ]
-      };
-      expect(view.containsWidget(value, widget)).to.be.true;
-    });
-    it("widget absent", function () {
-      var widget = {};
-      var value = {
-        visible: [],
-        hidden: []
-      };
-      expect(view.containsWidget(value, widget)).to.be.false;
-    });
-    it("widget hidden", function () {
-      var widget = {};
-      var value = {
-        visible: [],
-        hidden: [
-          [widget]
-        ]
-      };
-      expect(view.containsWidget(value, widget)).to.be.true;
+  describe('#resolveConfigDependencies()', function() {
+
+    beforeEach(function() {
+      this.mock = sinon.stub(App.router, 'get');
     });
-  });
 
-  describe("#persistKey", function () {
-    before(function () {
-      sinon.stub(App, 'get').withArgs('router.loginName').returns('user');
+    afterEach(function() {
+      App.router.get.restore();
     });
-    after(function () {
-      App.get.restore();
+
+    it('isHiddenByDefault should be undefined', function() {
+      var widgets = [{id: 20}];
+      this.mock.returns({properties: {'hide_yarn_memory_widget': 'false'}});
+      view.resolveConfigDependencies(widgets);
+      expect(widgets[0].isHiddenByDefault).to.be.undefined;
     });
-    it("depends on router.loginName", function () {
-      view.propertyDidChange('persistKey');
-      expect(view.get('persistKey')).to.equal('user-pref-user-dashboard');
+
+    it('isHiddenByDefault should be true', function() {
+      var widgets = [{id: 20}];
+      this.mock.returns({properties: {'hide_yarn_memory_widget': 'true'}});
+      view.resolveConfigDependencies(widgets);
+      expect(widgets[0].isHiddenByDefault).to.be.true;
     });
   });
 
-  describe("#getUserPrefSuccessCallback()", function () {
+  describe('#generateDefaultUserPreferences', function() {
 
-    it("response is null", function () {
-      view.set('currentPrefObject', null);
-      view.getUserPrefSuccessCallback(null, {}, {});
-      expect(view.get('currentPrefObject')).to.be.null;
+    beforeEach(function() {
+      sinon.stub(view, 'resolveConfigDependencies');
+      sinon.stub(App.Service, 'find').returns(Em.Object.create());
+      view.set('widgetsDefinition', [
+        Em.Object.create({sourceName: 'S1', id: 1}),
+        Em.Object.create({sourceName: 'HOST_METRICS', id: 2, isHiddenByDefault: true, threshold: []}),
+        Em.Object.create({sourceName: 'HOST_METRICS', id: 3, threshold: [1, 2]})
+      ]);
     });
 
-    it("response is correct", function () {
-      view.set('currentPrefObject', null);
-      view.getUserPrefSuccessCallback({}, {}, {});
-      expect(view.get('currentPrefObject')).to.eql({});
+    afterEach(function() {
+      view.resolveConfigDependencies.restore();
+      App.Service.find.restore();
     });
 
-    it('should update missing thresholds', function () {
+    it('should generate default preferences', function() {
+      expect(JSON.stringify(view.generateDefaultUserPreferences())).to.be.eql(JSON.stringify({
+        "visible": [3],
+        "hidden": [2],
+        "threshold": {
+          "2": [],
+          "3": [1,2]
+        }
+      }));
+      expect(view.resolveConfigDependencies).to.be.calledOnce;
+    });
+  });
+
+  describe('#renderWidgets()', function() {
 
-      view.set('currentPrefObject', null);
-      view.getUserPrefSuccessCallback({
+    it('should set visibleWidgets and hiddenWidgets', function() {
+      view.set('userPreferences', {
+        visible: [1],
+        hidden: [2],
         threshold: {
-          17: []
+          1: [],
+          2: [1,2]
         }
-      }, {}, {});
-      expect(view.get('currentPrefObject.threshold')['17']).to.eql([70, 90]);
+      });
+      view.renderWidgets();
+      expect(view.get('visibleWidgets')).to.be.eql([Em.Object.create({
+        id: 1,
+        threshold: [],
+        viewClass: App['NameNodeHeapPieChartView'],
+        sourceName: 'HDFS',
+        title: Em.I18n.t('dashboard.widgets.NameNodeHeap')
+      })]);
+      expect(view.get('hiddenWidgets')).to.be.eql([
+        Em.Object.create({
+          id: 2,
+          title: Em.I18n.t('dashboard.widgets.HDFSDiskUsage'),
+          checked: false
+        })
+      ]);
+    });
+  });
+
+  describe('#checkServicesChange()', function() {
+
+    beforeEach(function() {
+      sinon.stub(view, 'generateDefaultUserPreferences').returns({
+        visible: [1, 2],
+        hidden: [3, 4]
+      });
+      sinon.stub(view, 'saveWidgetsSettings');
+    });
 
+    afterEach(function() {
+      view.generateDefaultUserPreferences.restore();
+      view.saveWidgetsSettings.restore();
     });
 
+    it('userPreferences should be updated', function() {
+      view.set('userPreferences', {
+        visible: [3],
+        hidden: [1],
+        threshold: {}
+      });
+      view.checkServicesChange();
+      expect(view.saveWidgetsSettings.getCall(0).args[0]).to.be.eql({
+        visible: [3, 2],
+        hidden: [1, 4],
+        threshold: {}
+      });
+    });
   });
 
-  describe("#resetAllWidgets()", function () {
+  describe('#resetAllWidgets()', function() {
 
-    beforeEach(function () {
+    beforeEach(function() {
       sinon.stub(App, 'showConfirmationPopup', Em.clb);
-      sinon.stub(view, 'postUserPref', Em.K);
-      sinon.stub(view, 'setDBProperty', Em.K);
-      sinon.stub(view, 'translateToReal', Em.K);
-      view.setProperties({
-        currentTimeRangeIndex: 1,
-        customStartTime: 1000,
-        customEndTime: 2000
-      });
+      sinon.stub(view, 'generateDefaultUserPreferences').returns({settings: {}});
+      sinon.stub(view, 'saveWidgetsSettings');
+      sinon.stub(view, 'renderWidgets');
       view.resetAllWidgets();
     });
 
-    afterEach(function () {
+    afterEach(function() {
       App.showConfirmationPopup.restore();
-      view.postUserPref.restore();
-      view.setDBProperty.restore();
-      view.translateToReal.restore();
+      view.generateDefaultUserPreferences.restore();
+      view.saveWidgetsSettings.restore();
+      view.renderWidgets.restore();
     });
 
-    it('persist reset', function () {
-      expect(view.postUserPref.calledOnce).to.be.true;
-    });
-    it('local storage reset', function () {
-      expect(view.setDBProperty.calledOnce).to.be.true;
+    it('saveWidgetsSettings should be called', function() {
+      expect(view.saveWidgetsSettings.calledWith({settings: {}})).to.be.true;
     });
-    it('time range reset', function () {
-      expect(view.get('currentTimeRangeIndex')).to.equal(0);
+
+    it('renderWidgets should be called', function() {
+      expect(view.renderWidgets).to.be.calledOnce;
     });
-    it('custom start time reset', function () {
+
+    it('properties should be reset', function() {
+      expect(view.get('currentTimeRangeIndex')).to.be.equal(0);
       expect(view.get('customStartTime')).to.be.null;
-    });
-    it('custom end time reset', function () {
       expect(view.get('customEndTime')).to.be.null;
     });
-    it('default settings application', function () {
-      expect(view.translateToReal.calledOnce).to.be.true;
-    });
-
   });
 
-  describe('#checkServicesChange', function () {
+  describe('#plusButtonFilterView', function() {
+    var plusButtonFilterView;
 
-    var emptyCurrentPref = {
-        visible: [],
-        hidden: [],
-        threshold: {}
-      },
-      widgetsMap = {
-        hdfs_model: ['1', '2', '3', '4', '5', '10', '11'],
-        host_metrics_model: ['6', '7', '8', '9'],
-        hbase_model: ['12', '13', '14', '15', '16'],
-        yarn_model: ['17', '18', '19', '20', '23'],
-        storm_model: ['21'],
-        flume_model: ['22']
-      },
-      emptyModelTitle = '{0} absent',
-      notEmptyModelTitle = '{0} present';
-
-    Em.keys(widgetsMap).forEach(function (item, index, array) {
-      it(notEmptyModelTitle.format(item), function () {
-        array.forEach(function (modelName) {
-          view.set(modelName, modelName === item ? {} : null);
-        });
-        expect(view.checkServicesChange(emptyCurrentPref).visible).to.eql(widgetsMap[item]);
+    beforeEach(function() {
+      plusButtonFilterView = view.get('plusButtonFilterView').create({
+        parentView: Em.Object.create({
+          saveWidgetsSettings: Em.K,
+          renderWidgets: Em.K
+        })
       });
     });
 
-    Em.keys(widgetsMap).forEach(function (item, index, array) {
-      it(emptyModelTitle.format(item), function () {
-        var expected = [];
-        array.forEach(function (modelName) {
-          if (modelName === item) {
-            view.set(modelName, null);
-          } else {
-            view.set(modelName, {});
-            expected = expected.concat(widgetsMap[modelName]);
-          }
+    describe('#applyFilter()', function() {
+
+      beforeEach(function() {
+        sinon.spy(plusButtonFilterView.get('parentView'), 'renderWidgets');
+        sinon.spy(plusButtonFilterView.get('parentView'), 'saveWidgetsSettings');
+        plusButtonFilterView.set('parentView.userPreferences', {
+          visible: [2],
+          hidden: [1, 3],
+          threshold: {}
         });
-        expect(view.checkServicesChange({
-          visible: widgetsMap[item],
-          hidden: [],
+        plusButtonFilterView.set('hiddenWidgets', [
+          Em.Object.create({checked: true, id: 1})
+        ]);
+        plusButtonFilterView.applyFilter();
+      });
+
+      afterEach(function() {
+        plusButtonFilterView.get('parentView').renderWidgets.restore();
+        plusButtonFilterView.get('parentView').saveWidgetsSettings.restore();
+      });
+
+      it('saveWidgetsSettings should be called', function() {
+        expect(plusButtonFilterView.get('parentView').saveWidgetsSettings.getCall(0).args[0]).to.be.eql({
+          visible: [2, 1],
+          hidden: [3],
           threshold: {}
-        }).visible).to.eql(expected);
+        });
       });
-    });
 
+      it('renderWidgets should be called', function() {
+        expect(plusButtonFilterView.get('parentView').renderWidgets).to.be.calledOnce;
+      });
+    });
   });
+
 });


[2/2] ambari git commit: AMBARI-19064 Refactor widgets on Dashboard page. (atkach)

Posted by at...@apache.org.
AMBARI-19064 Refactor widgets on Dashboard page. (atkach)


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

Branch: refs/heads/trunk
Commit: 9348725b1067fab38907c8eebc172978729394ad
Parents: 7eb2eaa
Author: Andrii Tkach <at...@apache.org>
Authored: Fri Dec 2 19:27:20 2016 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Fri Dec 2 19:27:20 2016 +0200

----------------------------------------------------------------------
 .../mixins/main/dashboard/widgets/editable.js   |  47 +-
 .../main/dashboard/edit_widget_popup.hbs        |   4 +-
 .../edit_widget_popup_single_threshold.hbs      |   2 +-
 .../main/dashboard/plus_button_filter.hbs       |   2 +-
 .../app/templates/main/dashboard/widgets.hbs    |   8 +-
 .../main/dashboard/widgets/pie_chart.hbs        |   5 +-
 .../app/views/common/not-scrollable-textarea.js |   2 +-
 ambari-web/app/views/main/dashboard/widget.js   | 159 ++--
 ambari-web/app/views/main/dashboard/widgets.js  | 824 +++++++++----------
 .../main/dashboard/widgets/datanode_live.js     |   7 -
 .../main/dashboard/widgets/flume_agent_live.js  |   7 -
 .../main/dashboard/widgets/hawqsegment_live.js  |   7 -
 .../dashboard/widgets/hbase_average_load.js     |  11 +-
 .../views/main/dashboard/widgets/hbase_links.js |   4 -
 .../main/dashboard/widgets/hbase_master_heap.js |   4 -
 .../dashboard/widgets/hbase_master_uptime.js    |   5 -
 .../widgets/hbase_regions_in_transition.js      |  10 +-
 .../main/dashboard/widgets/hdfs_capacity.js     |   4 -
 .../views/main/dashboard/widgets/hdfs_links.js  |   4 -
 .../views/main/dashboard/widgets/metrics_cpu.js |   3 -
 .../main/dashboard/widgets/metrics_load.js      |   3 -
 .../main/dashboard/widgets/metrics_memory.js    |   3 -
 .../main/dashboard/widgets/metrics_network.js   |   3 -
 .../main/dashboard/widgets/namenode_cpu.js      |   4 -
 .../main/dashboard/widgets/namenode_heap.js     |   4 -
 .../main/dashboard/widgets/namenode_rpc.js      |  10 +-
 .../main/dashboard/widgets/namenode_uptime.js   |   5 -
 .../dashboard/widgets/node_managers_live.js     |   7 -
 .../main/dashboard/widgets/pie_chart_widget.js  |  16 +-
 .../views/main/dashboard/widgets/pxf_live.js    |   6 -
 .../dashboard/widgets/resource_manager_heap.js  |   4 -
 .../widgets/resource_manager_uptime.js          |   5 -
 .../main/dashboard/widgets/supervisor_live.js   |   7 -
 .../views/main/dashboard/widgets/text_widget.js |   4 +-
 .../widgets/text_widget_single_threshold.js     |   6 +-
 .../dashboard/widgets/uptime_text_widget.js     |   2 -
 .../views/main/dashboard/widgets/yarn_links.js  |   4 -
 .../views/main/dashboard/widgets/yarn_memory.js |   4 -
 .../test/views/main/dashboard/widget_test.js    | 200 ++---
 .../widgets/hbase_average_load_test.js          |   4 +-
 .../widgets/hbase_regions_in_transition_test.js |   6 +-
 .../main/dashboard/widgets/namenode_rpc_test.js |  13 +-
 .../text_widget_single_threshold_test.js        |  10 +-
 .../main/dashboard/widgets/text_widget_test.js  |  10 +-
 .../widgets/uptime_text_widget_test.js          |   2 +-
 .../test/views/main/dashboard/widgets_test.js   | 669 ++++++---------
 46 files changed, 813 insertions(+), 1317 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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
index f330ec3..3206229 100644
--- a/ambari-web/app/mixins/main/dashboard/widgets/editable.js
+++ b/ambari-web/app/mixins/main/dashboard/widgets/editable.js
@@ -23,24 +23,24 @@ App.EditableWidgetMixin = Em.Mixin.create({
   hintInfo: '',
 
   editWidget: function () {
-    var parent = this;
+    var self = this;
     var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: parent.get('hintInfo'),
+      thresholdMin: self.get('thresholdMin') + '',
+      thresholdMax: self.get('thresholdMax') + '',
+      hintInfo: self.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) {
+        var thresholdMin = this.get('thresholdMin');
+        var thresholdMax = this.get('thresholdMax');
+        if (thresholdMin.trim() !== "") {
+          if (isNaN(thresholdMin) || thresholdMin < 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)){
+          } else if ( this.get('isThresh2Error') === false && parseFloat(thresholdMax)<= parseFloat(thresholdMin)){
             this.set('isThresh1Error', true);
             this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
           } else {
@@ -52,8 +52,8 @@ App.EditableWidgetMixin = Em.Mixin.create({
           this.set('errorMessage1', 'This is required');
         }
 
-        if (thresh2.trim() !== "") {
-          if (isNaN(thresh2) || thresh2 < 0) {
+        if (thresholdMax.trim() !== "") {
+          if (isNaN(thresholdMax) || thresholdMax < 0) {
             this.set('isThresh2Error', true);
             this.set('errorMessage2', 'Invalid! Enter a number larger than 0');
           } else {
@@ -65,12 +65,12 @@ App.EditableWidgetMixin = Em.Mixin.create({
           this.set('errorMessage2', 'This is required');
         }
 
-      }.observes('thresh1', 'thresh2')
+      }.observes('thresholdMin', 'thresholdMax')
 
     });
 
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show( {
+    var browserVersion = this.getInternetExplorerVersion();
+    App.ModalPopup.show({
       header: Em.I18n.t('dashboard.widgets.popupHeader'),
       classNames: [ 'modal-edit-widget'],
       modalDialogClasses: ['modal-lg'],
@@ -82,17 +82,12 @@ App.EditableWidgetMixin = Em.Mixin.create({
       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);
-          }
 
+          var parent = self.get('parentView');
+          var userPreferences = parent.get('userPreferences');
+          userPreferences.threshold[Number(self.get('id'))] = [configObj.get('thresholdMin'), configObj.get('thresholdMax')];
+          parent.saveWidgetsSettings(userPreferences);
+          parent.renderWidgets();
           this.hide();
         }
       },
@@ -102,7 +97,7 @@ App.EditableWidgetMixin = Em.Mixin.create({
         var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
         var handlers = [33, 66]; //fixed value
 
-        if (browserVerion === -1 || browserVerion > 9) {
+        if (browserVersion === -1 || browserVersion > 9) {
           configObj.set('isIE9', false);
           configObj.set('isGreenOrangeRed', true);
           $("#slider-range").slider({
@@ -112,7 +107,7 @@ App.EditableWidgetMixin = Em.Mixin.create({
             max: 100,
             values: handlers,
             create: function (event, ui) {
-              parent.updateColors(handlers, colors);
+              self.updateColors(handlers, colors);
             }
           });
         } else {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs b/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs
index 3a36ed6..3802e29 100644
--- a/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs
+++ b/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs
@@ -41,13 +41,13 @@
           <input type="text" value="0" disabled="disabled" class="form-control" />
         </div>
         <div id="slider-value2" {{bindAttr class="view.configPropertyObj.isThresh1Error:slider-error :value-on-slider :col-md-4 view.configPropertyObj.isThresh1Error:has-error"}}>
-          {{view Ember.TextField class="form-control" valueBinding="view.configPropertyObj.thresh1"}}
+          {{view Ember.TextField class="form-control" valueBinding="view.configPropertyObj.thresholdMin"}}
           {{#if view.configPropertyObj.errorMessage1}}
             <span class="help-block validation-block">{{view.configPropertyObj.errorMessage1}}</span>
           {{/if}}
         </div>
         <div id="slider-value3" {{bindAttr class="view.configPropertyObj.isThresh2Error:slider-error :value-on-slider :col-md-4 view.configPropertyObj.isThresh2Error:has-error"}}>
-          {{view Ember.TextField class="form-control" valueBinding="view.configPropertyObj.thresh2"}}
+          {{view Ember.TextField class="form-control" valueBinding="view.configPropertyObj.thresholdMax"}}
           {{#if view.configPropertyObj.errorMessage1}}
             <span class="help-block validation-block">{{view.configPropertyObj.errorMessage2}}</span>
           {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs b/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs
index d80e601..982dc9b 100644
--- a/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs
+++ b/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs
@@ -43,7 +43,7 @@
       <input type="text" value="0" disabled="disabled" class="form-control" />
     </div>
       <div id="slider-value2" {{bindAttr class="view.configPropertyObj.isThresh1Error:slider-error :value-on-slider :col-md-4 :col-md-offset-2 :col-sm-offset-2 view.configPropertyObj.isThresh1Error:has-error"}}>
-        {{view Ember.TextField valueBinding="view.configPropertyObj.thresh1" class="form-control"}}
+        {{view Ember.TextField valueBinding="view.configPropertyObj.thresholdMin" class="form-control"}}
         {{#if view.configPropertyObj.errorMessage1}}
           <span class="help-block validation-block">{{view.configPropertyObj.errorMessage1}}</span>
         {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs b/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs
index df7714c..81420ff 100644
--- a/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs
+++ b/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs
@@ -21,7 +21,7 @@
       <ul>
         {{#each widget in view.hiddenWidgets}}
           <li>
-            {{view view.widgetCheckbox class="checkbox" checkedBinding="widget.checked" labelBinding="widget.displayName"}}
+            {{view view.widgetCheckbox class="checkbox" checkedBinding="widget.checked" labelBinding="widget.title"}}
           </li>
         {{/each}}
       </ul>

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/widgets.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/widgets.hbs b/ambari-web/app/templates/main/dashboard/widgets.hbs
index a778033..8e04f1c 100644
--- a/ambari-web/app/templates/main/dashboard/widgets.hbs
+++ b/ambari-web/app/templates/main/dashboard/widgets.hbs
@@ -48,13 +48,13 @@
     <div id="dashboard-widgets"  class="widgets-container">
       <div class="thumbnails" id="sortable">
         {{#if view.visibleWidgets.length}}
-          {{#each widgetClass in view.visibleWidgets}}
-            <div {{bindAttr class="widgetClass.class"}}>
-              {{view widgetClass }}
-            </div>
+          {{#each widget in view.visibleWidgets}}
+             {{view widget.viewClass widgetBinding="widget"}}
           {{/each}}
         {{/if}}
       </div>
     </div>
   </div>
+{{else}}
+  {{view App.SpinnerView}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs b/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs
index fdeafd1..1b14503 100644
--- a/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs
+++ b/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs
@@ -42,7 +42,10 @@
 
         {{#if view.isPieExist}}
           <div {{bindAttr class=":widget-content view.hoverContentTopClass"}}>
-            {{view view.content modelBinding="view.model" thresh1Binding="view.thresh1" thresh2Binding="view.thresh2"}}
+            {{view view.content
+                modelBinding="view.model"
+                thresholdMinBinding="view.thresholdMin"
+                thresholdMaxBinding="view.thresholdMax"}}
           </div>
         {{else}}
           <div class="widget-content-isNA">{{t services.service.summary.notAvailable}}</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/common/not-scrollable-textarea.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/not-scrollable-textarea.js b/ambari-web/app/views/common/not-scrollable-textarea.js
index 1898714..d0e4178 100644
--- a/ambari-web/app/views/common/not-scrollable-textarea.js
+++ b/ambari-web/app/views/common/not-scrollable-textarea.js
@@ -26,7 +26,7 @@ var App = require('app');
  */
 App.NotScrollableTextArea = Em.TextArea.extend({
 
-  didInsertElement() {
+  didInsertElement: function() {
     this.fitHeight();
     this.$().select();
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 cc5be28..495db2e 100644
--- a/ambari-web/app/views/main/dashboard/widget.js
+++ b/ambari-web/app/views/main/dashboard/widget.js
@@ -24,26 +24,30 @@ App.DashboardWidgetView = Em.View.extend({
    * @type {string}
    * @default null
    */
-  title: null,
-  templateName: null, // each has specific template
+  title: Em.computed.alias('widget.title'),
+
+  templateName: null,
+
+  sourceName: Em.computed.alias('widget.sourceName'),
+
+  widget: null,
 
   /**
-   * Setup model for widget by `model_type`. Usually `model_type` is a lowercase service name,
-   * for example `hdfs`, `yarn`, etc. You need to set `model_type` in extended object View, for example
-   * look App.DataNodeUpView.
-   * @type {object} - model that set up in App.MainDashboardView.setWidgetsDataModel()
+   * @type {object} - record from model that serve as data source
    */
   model : function () {
-    if (!this.get('model_type')) return {};
-    return this.get('parentView').get(this.get('model_type') + '_model');
-  }.property(),
+    var model = Em.Object.create();
+    if (Em.isNone(this.get('sourceName'))) {
+      return model;
+    }
+    return this.findModelBySource(this.get('sourceName'));
+  }.property('sourceName'),
 
   /**
-   * id 1-10 used to identify
    * @type {number}
    * @default null
    */
-  id: null,
+  id: Em.computed.alias('widget.id'),
 
   /**
    * html id bind to view-class: widget-(1)
@@ -52,6 +56,8 @@ App.DashboardWidgetView = Em.View.extend({
    */
   viewID: Em.computed.format('widget-{0}', 'id'),
 
+  classNames: ['span2p4'],
+
   attributeBindings: ['viewID'],
 
   /**
@@ -74,15 +80,19 @@ App.DashboardWidgetView = Em.View.extend({
 
   /**
    * @type {number}
-   * @default null
+   * @default 0
    */
-  thresh1: null,
+  thresholdMin: function() {
+    return Em.isNone(this.get('widget.threshold')) ? 0 : this.get('widget.threshold')[0];
+  }.property('widget.threshold'),
 
   /**
    * @type {number}
-   * @default null
+   * @default 0
    */
-  thresh2: null,
+  thresholdMax: function() {
+    return Em.isNone(this.get('widget.threshold')) ? 0 : this.get('widget.threshold')[1];
+  }.property('widget.threshold'),
 
   /**
    * @type {Boolean}
@@ -95,8 +105,8 @@ App.DashboardWidgetView = Em.View.extend({
    * @class
    */
   widgetConfig: Ember.Object.extend({
-    thresh1: '',
-    thresh2: '',
+    thresholdMin: '',
+    thresholdMax: '',
     hintInfo: Em.computed.i18nFormat('dashboard.widgets.hintInfo.common', 'maxValue'),
     isThresh1Error: false,
     isThresh2Error: false,
@@ -104,15 +114,15 @@ App.DashboardWidgetView = Em.View.extend({
     errorMessage2: "",
     maxValue: 0,
     observeThresh1Value: function () {
-      var thresh1 = this.get('thresh1');
-      var thresh2 = this.get('thresh2');
+      var thresholdMin = this.get('thresholdMin');
+      var thresholdMax = this.get('thresholdMax');
       var maxValue = this.get('maxValue');
 
-      if (thresh1.trim() !== "") {
-        if (isNaN(thresh1) || thresh1 > maxValue || thresh1 < 0) {
+      if (thresholdMin.trim() !== "") {
+        if (isNaN(thresholdMin) || thresholdMin > maxValue || thresholdMin < 0) {
           this.set('isThresh1Error', true);
           this.set('errorMessage1', Em.I18n.t('dashboard.widgets.error.invalid').format(maxValue));
-        } else if (this.get('isThresh2Error') === false && parseFloat(thresh2) <= parseFloat(thresh1)) {
+        } else if (this.get('isThresh2Error') === false && parseFloat(thresholdMax) <= parseFloat(thresholdMin)) {
           this.set('isThresh1Error', true);
           this.set('errorMessage1', Em.I18n.t('dashboard.widgets.error.smaller'));
         } else {
@@ -124,13 +134,13 @@ App.DashboardWidgetView = Em.View.extend({
         this.set('errorMessage1', Em.I18n.t('admin.users.editError.requiredField'));
       }
       this.updateSlider();
-    }.observes('thresh1', 'maxValue'),
+    }.observes('thresholdMin', 'maxValue'),
     observeThresh2Value: function () {
-      var thresh2 = this.get('thresh2');
+      var thresholdMax = this.get('thresholdMax');
       var maxValue = this.get('maxValue');
 
-      if (thresh2.trim() !== "") {
-        if (isNaN(thresh2) || thresh2 > maxValue || thresh2 < 0) {
+      if (thresholdMax.trim() !== "") {
+        if (isNaN(thresholdMax) || thresholdMax > maxValue || thresholdMax < 0) {
           this.set('isThresh2Error', true);
           this.set('errorMessage2', Em.I18n.t('dashboard.widgets.error.invalid').format(maxValue));
         } else {
@@ -142,15 +152,15 @@ App.DashboardWidgetView = Em.View.extend({
         this.set('errorMessage2', Em.I18n.t('admin.users.editError.requiredField'));
       }
       this.updateSlider();
-    }.observes('thresh2', 'maxValue'),
+    }.observes('thresholdMax', 'maxValue'),
     updateSlider: function () {
-      var thresh1 = this.get('thresh1');
-      var thresh2 = this.get('thresh2');
+      var thresholdMin = this.get('thresholdMin');
+      var thresholdMax = this.get('thresholdMax');
       // update the slider handles and color
       if (this.get('isThresh1Error') === false && this.get('isThresh2Error') === false) {
         $("#slider-range")
-          .slider('values', 0, parseFloat(thresh1))
-          .slider('values', 1, parseFloat(thresh2));
+          .slider('values', 0, parseFloat(thresholdMin))
+          .slider('values', 1, parseFloat(thresholdMax));
       }
     }
   }),
@@ -162,46 +172,36 @@ App.DashboardWidgetView = Em.View.extend({
     });
   },
 
+  findModelBySource: function (source) {
+    if (source === 'HOST_METRICS' && App.get('services.hostMetrics').length > 0) {
+      return App.get('services.hostMetrics');
+    }
+    var extendedModel = App.Service.extendedModel[source];
+    if (extendedModel) {
+      return App[extendedModel].find(source);
+    } else {
+      return App.Service.find(source);
+    }
+  },
+
   willDestroyElement : function() {
     $("[rel='ZoomInTooltip']").tooltip('destroy');
   },
+
   /**
    * delete widget
-   * @param {object} event
    */
   deleteWidget: function () {
     var parent = this.get('parentView');
-    var self = this;
-
-    if (App.get('testMode')) {
-      //update view on dashboard
-      var objClass = parent.widgetsMapper(this.get('id'));
-      parent.get('visibleWidgets').removeObject(objClass);
-      parent.get('hiddenWidgets').pushObject(Em.Object.create({displayName: this.get('title'), id: this.get('id'), checked: false}));
-    } else {
-      //reconstruct new persist value then post in persist
-      parent.getUserPref(parent.get('persistKey')).complete(function () {
-        self.deleteWidgetComplete.apply(self);
-      });
-    }
-  },
-
-  /**
-   * delete widget complete callback
-   */
-  deleteWidgetComplete: function () {
-    var parent = this.get('parentView');
-    var oldValue = parent.get('currentPrefObject');
+    var userPreferences = parent.get('userPreferences');
     var deletedId = this.get('id');
-    var newValue = Em.Object.create({
-      dashboardVersion: oldValue.dashboardVersion,
-      visible: oldValue.visible.slice(0).without(deletedId),
-      hidden: oldValue.hidden,
-      threshold: oldValue.threshold
-    });
-    newValue.hidden.push([deletedId, this.get('title')]);
-    parent.postUserPref(parent.get('persistKey'), newValue);
-    parent.translateToReal(newValue);
+    var newValue = {
+      visible: userPreferences.visible.slice(0).without(deletedId),
+      hidden: userPreferences.hidden.concat([deletedId]),
+      threshold: userPreferences.threshold
+    };
+    parent.saveWidgetsSettings(newValue);
+    parent.renderWidgets();
   },
 
   /**
@@ -210,8 +210,8 @@ App.DashboardWidgetView = Em.View.extend({
    */
   editWidget: function (event) {
     var configObj = this.get('widgetConfig').create({
-      thresh1: this.get('thresh1') + '',
-      thresh2: this.get('thresh2') + '',
+      thresholdMin: this.get('thresholdMin') + '',
+      thresholdMax: this.get('thresholdMax') + '',
       maxValue: parseFloat(this.get('maxValue'))
     });
     this.showEditDialog(configObj)
@@ -239,18 +239,14 @@ App.DashboardWidgetView = Em.View.extend({
         configObj.observeThresh1Value();
         configObj.observeThresh2Value();
         if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          self.set('thresh1', parseFloat(configObj.get('thresh1')));
-          self.set('thresh2', parseFloat(configObj.get('thresh2')));
-
-          if (!App.get('testMode')) {
-            // save to persist
-            var parent = self.get('parentView');
-            parent.getUserPref(parent.get('persistKey')).complete(function () {
-              var oldValue = parent.get('currentPrefObject');
-              oldValue.threshold[parseInt(self.get('id'), 10)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-              parent.postUserPref(parent.get('persistKey'), oldValue);
-            });
-          }
+          self.set('thresholdMin', parseFloat(configObj.get('thresholdMin')));
+          self.set('thresholdMax', parseFloat(configObj.get('thresholdMax')));
+
+          var parent = self.get('parentView');
+          var userPreferences = parent.get('userPreferences');
+          userPreferences.threshold[Number(self.get('id'))] = [configObj.get('thresholdMin'), configObj.get('thresholdMax')];
+          parent.saveWidgetsSettings(userPreferences);
+          parent.renderWidgets();
 
           this.hide();
         }
@@ -259,7 +255,7 @@ App.DashboardWidgetView = Em.View.extend({
       didInsertElement: function () {
         this._super();
         var browserVersion = self.getInternetExplorerVersion();
-        var handlers = [configObj.get('thresh1'), configObj.get('thresh2')];
+        var handlers = [configObj.get('thresholdMin'), configObj.get('thresholdMax')];
         var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
 
         if (browserVersion === -1 || browserVersion > 9) {
@@ -275,8 +271,8 @@ App.DashboardWidgetView = Em.View.extend({
             },
             slide: function (event, ui) {
               updateColors(ui.values);
-              configObj.set('thresh1', ui.values[0] + '');
-              configObj.set('thresh2', ui.values[1] + '');
+              configObj.set('thresholdMin', ui.values[0] + '');
+              configObj.set('thresholdMax', ui.values[1] + '');
             },
             change: function (event, ui) {
               updateColors(ui.values);
@@ -351,8 +347,3 @@ App.DashboardWidgetView = Em.View.extend({
   }.property('hiddenInfo.length')
 
 });
-
-
-App.DashboardWidgetView.reopenClass({
-  class: 'span2p4'
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 999fc08..4e22aad 100644
--- a/ambari-web/app/views/main/dashboard/widgets.js
+++ b/ambari-web/app/views/main/dashboard/widgets.js
@@ -20,20 +20,187 @@ var App = require('app');
 var filters = require('views/common/filter_view');
 
 App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, App.TimeRangeMixin, {
-
   name: 'mainDashboardWidgetsView',
-
   templateName: require('templates/main/dashboard/widgets'),
 
-  didInsertElement: function () {
-    this._super();
-    this.setWidgetsDataModel();
-    this.setInitPrefObject();
-    this.setOnLoadVisibleWidgets();
-    this.set('isDataLoaded', true);
-    App.loadTimer.finish('Dashboard Metrics Page');
-    Em.run.next(this, 'makeSortable');
-  },
+  widgetsDefinition: [
+    {
+      id: 1,
+      viewName: 'NameNodeHeapPieChartView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.NameNodeHeap'),
+      threshold: [80, 90]
+    },
+    {
+      id: 2,
+      viewName: 'NameNodeCapacityPieChartView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.HDFSDiskUsage'),
+      threshold: [85, 95]
+    },
+    {
+      id: 3,
+      viewName: 'NameNodeCpuPieChartView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.NameNodeCpu'),
+      threshold: [90, 95]
+    },
+    {
+      id: 4,
+      viewName: 'DataNodeUpView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.DataNodeUp'),
+      threshold: [80, 90]
+    },
+    {
+      id: 5,
+      viewName: 'NameNodeRpcView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.NameNodeRpc'),
+      threshold: [1000, 3000]
+    },
+    {
+      id: 6,
+      viewName: 'ChartClusterMetricsMemoryWidgetView',
+      sourceName: 'HOST_METRICS',
+      title: Em.I18n.t('dashboard.clusterMetrics.memory'),
+      threshold: []
+    },
+    {
+      id: 7,
+      viewName: 'ChartClusterMetricsNetworkWidgetView',
+      sourceName: 'HOST_METRICS',
+      title: Em.I18n.t('dashboard.clusterMetrics.network'),
+      threshold: []
+    },
+    {
+      id: 8,
+      viewName: 'ChartClusterMetricsCPUWidgetView',
+      sourceName: 'HOST_METRICS',
+      title: Em.I18n.t('dashboard.clusterMetrics.cpu'),
+      threshold: []
+    },
+    {
+      id: 9,
+      viewName: 'ChartClusterMetricsLoadWidgetView',
+      sourceName: 'HOST_METRICS',
+      title: Em.I18n.t('dashboard.clusterMetrics.load'),
+      threshold: []
+    },
+    {
+      id: 10,
+      viewName: 'NameNodeUptimeView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.NameNodeUptime'),
+      threshold: []
+    },
+    {
+      id: 11,
+      viewName: 'HDFSLinksView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.HDFSLinks'),
+      threshold: []
+    },
+    {
+      id: 12,
+      viewName: 'HBaseLinksView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseLinks'),
+      threshold: []
+    },
+    {
+      id: 13,
+      viewName: 'HBaseMasterHeapPieChartView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseMasterHeap'),
+      threshold: [70, 90]
+    },
+    {
+      id: 14,
+      viewName: 'HBaseAverageLoadView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseAverageLoad'),
+      threshold: [150, 250]
+    },
+    {
+      id: 15,
+      viewName: 'HBaseRegionsInTransitionView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseRegionsInTransition'),
+      threshold: [3, 10],
+      isHiddenByDefault: true
+    },
+    {
+      id: 16,
+      viewName: 'HBaseMasterUptimeView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseMasterUptime'),
+      threshold: []
+    },
+    {
+      id: 17,
+      viewName: 'ResourceManagerHeapPieChartView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.ResourceManagerHeap'),
+      threshold: [70, 90]
+    },
+    {
+      id: 18,
+      viewName: 'ResourceManagerUptimeView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.ResourceManagerUptime'),
+      threshold: []
+    },
+    {
+      id: 19,
+      viewName: 'NodeManagersLiveView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.NodeManagersLive'),
+      threshold: [50, 75]
+    },
+    {
+      id: 20,
+      viewName: 'YARNMemoryPieChartView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.YARNMemory'),
+      threshold: [50, 75]
+    },
+    {
+      id: 21,
+      viewName: 'SuperVisorUpView',
+      sourceName: 'STORM',
+      title: Em.I18n.t('dashboard.widgets.SuperVisorUp'),
+      threshold: [85, 95]
+    },
+    {
+      id: 22,
+      viewName: 'FlumeAgentUpView',
+      sourceName: 'FLUME',
+      title: Em.I18n.t('dashboard.widgets.FlumeAgentUp'),
+      threshold: [85, 95]
+    },
+    {
+      id: 23,
+      viewName: 'YARNLinksView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.YARNLinks'),
+      threshold: []
+    },
+    {
+      id: 24,
+      viewName: 'HawqSegmentUpView',
+      sourceName: 'HAWQ',
+      title: Em.I18n.t('dashboard.widgets.HawqSegmentUp'),
+      threshold: [75, 90]
+    },
+    {
+      id: 25,
+      viewName: 'PxfUpView',
+      sourceName: 'PXF',
+      title: Em.I18n.t('dashboard.widgets.PxfUp'),
+      threshold: []
+    }
+  ],
 
   /**
    * List of services
@@ -42,6 +209,12 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
   content: [],
 
   /**
+   * Key-name to store data in Local Storage and Persist
+   * @type {string}
+   */
+  persistKey: Em.computed.format('user-pref-{0}-dashboard', 'App.router.loginName'),
+
+  /**
    * @type {boolean}
    */
   isDataLoaded: false,
@@ -52,177 +225,6 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
    */
   isMoving: false,
 
-  timeRangeClassName: 'pull-left',
-
-  /**
-   * Make widgets' list sortable on New Dashboard style
-   */
-  makeSortable: function () {
-    var self = this;
-    $("#sortable").sortable({
-      items: "> div",
-      //placeholder: "sortable-placeholder",
-      cursor: "move",
-      tolerance: "pointer",
-      scroll: false,
-      update: function (event, ui) {
-        if (!App.get('testMode')) {
-          // update persist then translate to real
-          var widgetsArray = $('div[viewid]'); // get all in DOM
-          self.getUserPref(self.get('persistKey')).complete(function () {
-            var oldValue = self.get('currentPrefObject') || self.getDBProperty(self.get('persistKey'));
-            var newValue = Em.Object.create({
-              dashboardVersion: oldValue.dashboardVersion,
-              visible: [],
-              hidden: oldValue.hidden,
-              threshold: oldValue.threshold
-            });
-            var size = oldValue.visible.length;
-            for (var j = 0; j <= size - 1; j++) {
-              var viewID = widgetsArray.get(j).getAttribute('viewid');
-              var id = viewID.split("-").get(1);
-              newValue.visible.push(id);
-            }
-            self.postUserPref(self.get('persistKey'), newValue);
-            self.setDBProperty(self.get('persistKey'), newValue);
-            //self.translateToReal(newValue);
-          });
-        }
-      },
-      activate: function (event, ui) {
-        self.set('isMoving', true);
-      },
-      deactivate: function (event, ui) {
-        self.set('isMoving', false);
-      }
-    }).disableSelection();
-  },
-
-  /**
-   * Set Service model values
-   */
-  setWidgetsDataModel: function () {
-    if (App.get('services.hostMetrics').length > 0) {
-      this.set('host_metrics_model', App.get('services.hostMetrics'));
-    }
-    App.Service.find().forEach(function (item) {
-      var extendedModel = App.Service.extendedModel[item.get('serviceName')];
-      var key = item.get('serviceName').toLowerCase() + '_model';
-      if (extendedModel && App[extendedModel].find(item.get('id'))) {
-        this.set(key, App[extendedModel].find(item.get('id')));
-      } else {
-        this.set(key, item);
-      }
-    }, this);
-  },
-
-  resolveConfigDependencies: function(visibleFull, hiddenFull) {
-    var clusterEnv = App.router.get('clusterController.clusterEnv').properties;
-
-    if (clusterEnv['hide_yarn_memory_widget'] === 'true') {
-      hiddenFull.push(['20', 'YARN Memory']);
-    } else {
-      visibleFull.splice(visibleFull.indexOf('19'), 0, '20');
-    }
-  },
-
-  /**
-   * Load widget statuses to <code>initPrefObject</code>
-   */
-  setInitPrefObject: function () {
-    //in case of some service not installed
-    var visibleFull = [
-      '2', '4', '11', //hdfs
-      '6', '7', '8', '9', //host metrics
-      '1', '5', '3', '10', //hdfs
-      '13', '12', '14', '16', //hbase
-      '17', '18', '19', '23', // all yarn
-      '21', // storm
-      '22', // flume
-      '24', // hawq
-      '25' // pxf
-    ]; // all in order
-    var hiddenFull = [
-      ['15', 'Region In Transition']
-    ];
-    this.resolveConfigDependencies(visibleFull, hiddenFull);
-
-    // Display widgets for host metrics if the stack definition has a host metrics service to display it.
-    if (this.get('host_metrics_model') == null) {
-      var hostMetrics = ['6', '7', '8', '9'];
-      hostMetrics.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-
-    if (this.get('hdfs_model') == null) {
-      var hdfs = ['1', '2', '3', '4', '5', '10', '11'];
-      hdfs.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('hbase_model') == null) {
-      var hbase = ['12', '13', '14', '16'];
-      hbase.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-      hiddenFull = hiddenFull.filter(function(item) {
-        return item[0] !== '15';
-      });
-    }
-    if (this.get('yarn_model') == null) {
-      var yarn = ['17', '18', '19', '20', '23'];
-      yarn.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('storm_model') == null) {
-      var storm = ['21'];
-      storm.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('flume_model') == null) {
-      var flume = ['22'];
-      flume.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('hawq_model') == null) {
-      var hawq = ['24'];
-      hawq.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('pxf_model') == null) {
-      var pxf = ['25'];
-      pxf.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    var obj = this.get('initPrefObject');
-    obj.set('visible', visibleFull);
-    obj.set('hidden', hiddenFull);
-  },
-
-  host_metrics_model: null,
-
-  hdfs_model: null,
-
-  mapreduce2_model: null,
-
-  yarn_model: null,
-
-  hbase_model: null,
-
-  storm_model: null,
-
-  flume_model: null,
-
-  hawq_model: null,
-
-  pxf_model: null,
-
   /**
    * List of visible widgets
    * @type {Ember.Enumerable}
@@ -235,302 +237,162 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
    */
   hiddenWidgets: [], // widget child view will push object in this array if deleted
 
-  /**
-   * Submenu view for New Dashboard style
-   * @type {Ember.View}
-   * @class
-   */
-  plusButtonFilterView: Ember.View.extend({
-    tagName: 'ul',
-    classNames: ['dropdown-menu'],
-    templateName: require('templates/main/dashboard/plus_button_filter'),
-    hiddenWidgetsBinding: 'parentView.hiddenWidgets',
-    visibleWidgetsBinding: 'parentView.visibleWidgets',
-    valueBinding: '',
-    widgetCheckbox: App.CheckboxView.extend({
-      didInsertElement: function () {
-        $('.checkbox').click(function (event) {
-          event.stopPropagation();
-        });
-      }
-    }),
-    closeFilter: Em.K,
-    applyFilter: function () {
-      var self = this;
-      var parent = this.get('parentView');
-      var hiddenWidgets = this.get('hiddenWidgets');
-      var checkedWidgets = hiddenWidgets.filterProperty('checked', true);
-
-      if (App.get('testMode')) {
-        var visibleWidgets = this.get('visibleWidgets');
-        checkedWidgets.forEach(function (item) {
-          var newObj = parent.widgetsMapper(item.id);
-          visibleWidgets.pushObject(newObj);
-          hiddenWidgets.removeObject(item);
-        }, this);
-      } else {
-        //save in persist
-        parent.getUserPref(parent.get('persistKey')).complete(function(){
-          self.applyFilterComplete.apply(self);
-        });
-      }
-    },
-    applyFilterComplete: function () {
-      var parent = this.get('parentView'),
-        hiddenWidgets = this.get('hiddenWidgets'),
-        oldValue = parent.get('currentPrefObject'),
-        newValue = Em.Object.create({
-          dashboardVersion: oldValue.dashboardVersion,
-          visible: oldValue.visible,
-          hidden: [],
-          threshold: oldValue.threshold
-        });
-      hiddenWidgets.filterProperty('checked').forEach(function (item) {
-        newValue.visible.push(item.id);
-        hiddenWidgets.removeObject(item);
-      }, this);
-      hiddenWidgets.forEach(function (item) {
-        newValue.hidden.push([item.id, item.displayName]);
-      }, this);
-      parent.postUserPref(parent.get('persistKey'), newValue);
-      parent.translateToReal(newValue);
-    }
-  }),
+  timeRangeClassName: 'pull-left',
 
   /**
-   * Translate from Json value got from persist to real widgets view
+   * Example:
+   * {
+   *   visible: [1, 2, 4],
+   *   hidden: [3, 5],
+   *   threshold: {
+   *     1: [80, 90],
+   *     2: [],
+   *     3: [1, 2]
+   *   }
+   * }
+   * @type {Object|null}
    */
-  translateToReal: function (value) {
-    var version = value.dashboardVersion;
-    var visible = value.visible;
-    var hidden = value.hidden;
-    var threshold = value.threshold;
-
-    if (version === 'new') {
-      var visibleWidgets = [];
-      var hiddenWidgets = [];
-      // re-construct visibleWidgets and hiddenWidgets
-      for (var i = 0; i < visible.length; i++) {
-        var id = visible[i];
-        var widgetClass = this.widgetsMapper(id);
-        //override with new threshold
-        if (threshold[id].length > 0) {
-          widgetClass.reopen({
-            thresh1: threshold[id][0],
-            thresh2: threshold[id][1]
-          });
-        }
-        visibleWidgets.pushObject(widgetClass);
-      }
-      for (var j = 0; j < hidden.length; j++) {
-        var title = hidden[j][1];
-        hiddenWidgets.pushObject(Em.Object.create({displayName: title, id: hidden[j][0], checked: false}));
-      }
-      this.set('visibleWidgets', visibleWidgets);
-      this.set('hiddenWidgets', hiddenWidgets);
-    }
+  userPreferences: null,
+
+  didInsertElement: function () {
+    var self = this;
+
+    this._super();
+    this.loadWidgetsSettings().complete(function() {
+      self.checkServicesChange();
+      self.renderWidgets();
+      self.set('isDataLoaded', true);
+      App.loadTimer.finish('Dashboard Metrics Page');
+      Em.run.next(self, 'makeSortable');
+    });
   },
 
   /**
    * Set visibility-status for widgets
    */
-  setOnLoadVisibleWidgets: function () {
-    var self = this;
-    if (App.get('testMode')) {
-      this.translateToReal(this.get('initPrefObject'));
-    } else {
-      // called when first load/refresh/jump back page
-      this.getUserPref(this.get('persistKey')).complete(function () {
-        if (self.get('state') === 'inDOM') {
-          self.setOnLoadVisibleWidgetsComplete.apply(self);
-        }
-      });
-    }
+  loadWidgetsSettings: function () {
+    return this.getUserPref(this.get('persistKey'));
   },
 
   /**
-   * complete load of visible widgets
+   * make POST call to save settings
+   * @param {object} settings
    */
-  setOnLoadVisibleWidgetsComplete: function () {
-    var currentPrefObject = this.get('currentPrefObject') || this.getDBProperty(this.get('persistKey'));
-    if (currentPrefObject) { // fit for no dashboard version
-      if (!currentPrefObject.dashboardVersion) {
-        currentPrefObject.dashboardVersion = 'new';
-        this.postUserPref(this.get('persistKey'), currentPrefObject);
-        this.setDBProperty(this.get('persistKey'), currentPrefObject);
-      }
-      this.set('currentPrefObject', this.checkServicesChange(currentPrefObject));
-      this.translateToReal(this.get('currentPrefObject'));
-    }
-    else {
-      // post persist then translate init object
-      this.postUserPref(this.get('persistKey'), this.get('initPrefObject'));
-      this.setDBProperty(this.get('persistKey'), this.get('initPrefObject'));
-      this.translateToReal(this.get('initPrefObject'));
-    }
+  saveWidgetsSettings: function (settings) {
+    this.set('userPreferences', settings);
+    this.setDBProperty(this.get('persistKey'), settings);
+    this.postUserPref(this.get('persistKey'), settings);
   },
 
-  /**
-   * Remove widget from visible and hidden lists
-   * @param {Object} value
-   * @param {Object} widget
-   * @returns {*}
-   */
-  removeWidget: function (value, widget) {
-    value.visible = value.visible.without(widget);
-    for (var j = 0; j < value.hidden.length; j++) {
-      if (value.hidden[j][0] == widget) {
-        value.hidden.splice(j, 1);
-      }
+  getUserPrefSuccessCallback: function (response) {
+    if (response) {
+      this.set('userPreferences', response);
+    } else {
+      this.getUserPrefErrorCallback();
     }
-    return value;
   },
 
-  /**
-   * Check if widget is in visible or hidden list
-   * @param {Object} value
-   * @param {Object} widget
-   * @returns {bool}
-   */
-  containsWidget: function (value, widget) {
-    var flag = value.visible.contains(widget);
-    for (var j = 0; j < value.hidden.length; j++) {
-      if (!flag && value.hidden[j][0] == widget) {
-        flag = true;
-        break;
-      }
+  getUserPrefErrorCallback: function () {
+    var userPreferences = this.generateDefaultUserPreferences();
+    this.saveWidgetsSettings(userPreferences);
+  },
+
+  resolveConfigDependencies: function(widgetsDefinition) {
+    var clusterEnv = App.router.get('clusterController.clusterEnv').properties;
+    var yarnMemoryWidget = widgetsDefinition.findProperty('id', 20);
+
+    if (clusterEnv['hide_yarn_memory_widget'] === 'true') {
+      yarnMemoryWidget.isHiddenByDefault = true;
     }
-    return flag;
   },
 
-  /**
-   * check if stack has upgraded from HDP 1.0 to 2.0 OR add/delete services.
-   * Update the value on server if true.
-   * @param {Object} currentPrefObject
-   * @return {Object}
-   */
-  checkServicesChange: function (currentPrefObject) {
-    var toDelete = $.extend(true, {}, currentPrefObject);
-    var toAdd = [];
-    var serviceWidgetsMap = {
-      hdfs_model: ['1', '2', '3', '4', '5', '10', '11'],
-      host_metrics_model: ['6', '7', '8', '9'],
-      hbase_model: ['12', '13', '14', '15', '16'],
-      yarn_model: ['17', '18', '19', '20', '23'],
-      storm_model: ['21'],
-      flume_model: ['22'],
-      hawq_model: ['24'],
-      pxf_model: ['25']
+  generateDefaultUserPreferences: function() {
+    var widgetsDefinition = this.get('widgetsDefinition');
+    var preferences = {
+      visible: [],
+      hidden: [],
+      threshold: {}
     };
 
-    // check each service, find out the newly added service and already deleted service
-    Em.keys(serviceWidgetsMap).forEach(function (modelName) {
-      if (!Em.isNone(this.get(modelName))) {
-        var ids = serviceWidgetsMap[modelName];
-        var flag = this.containsWidget(toDelete, ids[0]);
-        if (flag) {
-          ids.forEach(function (item) {
-            toDelete = this.removeWidget(toDelete, item);
-          }, this);
+    this.resolveConfigDependencies(widgetsDefinition);
+
+    widgetsDefinition.forEach(function(widget) {
+      if (App.Service.find(widget.sourceName).get('isLoaded') || widget.sourceName === 'HOST_METRICS') {
+        if (widget.isHiddenByDefault) {
+          preferences.hidden.push(widget.id);
         } else {
-          toAdd = toAdd.concat(ids);
+          preferences.visible.push(widget.id);
         }
       }
-    }, this);
+      preferences.threshold[widget.id] = widget.threshold;
+    });
 
-    var value = currentPrefObject;
-    if (toDelete.visible.length || toDelete.hidden.length) {
-      toDelete.visible.forEach(function (item) {
-        value = this.removeWidget(value, item);
-      }, this);
-      toDelete.hidden.forEach(function (item) {
-        value = this.removeWidget(value, item[0]);
-      }, this);
-    }
-    if (toAdd.length) {
-      value.visible = value.visible.concat(toAdd);
-      var allThreshold = this.get('initPrefObject').threshold;
-      // add new threshold OR override with default value
-      toAdd.forEach(function (item) {
-        value.threshold[item] = allThreshold[item];
-      }, this);
-    }
-    return value;
+    return preferences;
   },
 
   /**
-   * Get view for widget by widget's id
-   * @param {string} id
-   * @returns {Ember.View}
+   * set widgets to view in order to render
    */
-  widgetsMapper: function (id) {
-    return Em.get({
-      '1': App.NameNodeHeapPieChartView,
-      '2': App.NameNodeCapacityPieChartView,
-      '3': App.NameNodeCpuPieChartView,
-      '4': App.DataNodeUpView,
-      '5': App.NameNodeRpcView,
-      '6': App.ChartClusterMetricsMemoryWidgetView,
-      '7': App.ChartClusterMetricsNetworkWidgetView,
-      '8': App.ChartClusterMetricsCPUWidgetView,
-      '9': App.ChartClusterMetricsLoadWidgetView,
-      '10': App.NameNodeUptimeView,
-      '11': App.HDFSLinksView,
-      '12': App.HBaseLinksView,
-      '13': App.HBaseMasterHeapPieChartView,
-      '14': App.HBaseAverageLoadView,
-      '15': App.HBaseRegionsInTransitionView,
-      '16': App.HBaseMasterUptimeView,
-      '17': App.ResourceManagerHeapPieChartView,
-      '18': App.ResourceManagerUptimeView,
-      '19': App.NodeManagersLiveView,
-      '20': App.YARNMemoryPieChartView,
-      '21': App.SuperVisorUpView,
-      '22': App.FlumeAgentUpView,
-      '23': App.YARNLinksView,
-      '24': App.HawqSegmentUpView,
-      '25': App.PxfUpView
-    }, id);
-  },
+  renderWidgets: function () {
+    var widgetsDefinitionMap = this.get('widgetsDefinition').toMapByProperty('id');
+    var userPreferences = this.get('userPreferences');
+    var visibleWidgets = [];
+    var hiddenWidgets = [];
+
+    userPreferences.visible.forEach(function(id) {
+      var widget = widgetsDefinitionMap[id];
+      visibleWidgets.push(Em.Object.create({
+        id: id,
+        threshold: userPreferences.threshold[id],
+        viewClass: App[widget.viewName],
+        sourceName: widget.sourceName,
+        title: widget.title
+      }));
+    });
 
-  /**
-   * @type {Object|null}
-   */
-  currentPrefObject: null,
+    userPreferences.hidden.forEach(function(id) {
+      var widget = widgetsDefinitionMap[id];
+      hiddenWidgets.push(Em.Object.create({
+        id: id,
+        title: widget.title,
+        checked: false
+      }));
+    });
 
-  /**
-   * @type {Ember.Object}
-   */
-  initPrefObject: Em.Object.create({
-    dashboardVersion: 'new',
-    visible: [],
-    hidden: [],
-    threshold: {1: [80, 90], 2: [85, 95], 3: [90, 95], 4: [80, 90], 5: [1000, 3000], 6: [], 7: [], 8: [], 9: [], 10: [], 11: [], 12: [], 13: [70, 90], 14: [150, 250], 15: [3, 10], 16: [],
-      17: [70, 90], 18: [], 19: [50, 75], 20: [50, 75], 21: [85, 95], 22: [85, 95], 23: [], 24: [75, 90], 25: []} // id:[thresh1, thresh2]
-  }),
+    this.set('visibleWidgets', visibleWidgets);
+    this.set('hiddenWidgets', hiddenWidgets);
+  },
 
   /**
-   * Key-name to store data in Local Storage and Persist
-   * @type {string}
+   * check if stack has upgraded from HDP 1.0 to 2.0 OR add/delete services.
+   * Update the value on server if true.
    */
-  persistKey: Em.computed.format('user-pref-{0}-dashboard', 'App.router.loginName'),
+  checkServicesChange: function () {
+    var userPreferences = this.get('userPreferences');
+    var defaultPreferences = this.generateDefaultUserPreferences();
+    var newValue = {
+      visible: userPreferences.visible.slice(0),
+      hidden: userPreferences.hidden.slice(0),
+      threshold: userPreferences.threshold
+    };
+    var isChanged = false;
 
-  getUserPrefSuccessCallback: function (response, request, data) {
-    if (response) {
-      var initPrefObject = this.get('initPrefObject');
-      initPrefObject.get('threshold');
-      for(var k in response.threshold) {
-        if (response.threshold.hasOwnProperty(k)) {
-          if (response.threshold[k].length === 0 && initPrefObject.get('threshold')[k] && initPrefObject.get('threshold')[k].length) {
-            response.threshold[k] = initPrefObject.get('threshold')[k];
-          }
-        }
+    defaultPreferences.visible.forEach(function(id) {
+      if (!userPreferences.visible.contains(id) && !userPreferences.hidden.contains(id)) {
+        isChanged = true;
+        newValue.visible.push(id);
       }
-      this.set('currentPrefObject', response);
-    }
-  },
+    });
 
-  getUserPrefErrorCallback: function (request) {
+    defaultPreferences.hidden.forEach(function(id) {
+      if (!userPreferences.visible.contains(id) && !userPreferences.hidden.contains(id)) {
+        isChanged = true;
+        newValue.hidden.push(id);
+      }
+    });
+    if (isChanged) {
+      this.saveWidgetsSettings(newValue);
+    }
   },
 
   /**
@@ -539,19 +401,91 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
   resetAllWidgets: function () {
     var self = this;
     App.showConfirmationPopup(function () {
-      if (!App.get('testMode')) {
-        self.postUserPref(self.get('persistKey'), self.get('initPrefObject'));
-        self.setDBProperty(self.get('persistKey'), self.get('initPrefObject'));
-      }
+      self.saveWidgetsSettings(self.generateDefaultUserPreferences());
       self.setProperties({
         currentTimeRangeIndex: 0,
         customStartTime: null,
         customEndTime: null
       });
-      self.translateToReal(self.get('initPrefObject'));
+      self.renderWidgets();
     });
   },
 
+  /**
+   * Make widgets' list sortable on New Dashboard style
+   */
+  makeSortable: function () {
+    var self = this;
+    return $("#sortable").sortable({
+      items: "> div",
+      cursor: "move",
+      tolerance: "pointer",
+      scroll: false,
+      update: function () {
+        var widgetsArray = $('div[viewid]');
+
+        var userPreferences = self.get('userPreferences') || self.getDBProperty(self.get('persistKey'));
+        var newValue = Em.Object.create({
+          visible: [],
+          hidden: userPreferences.hidden,
+          threshold: userPreferences.threshold
+        });
+        var size = userPreferences.visible.length;
+        for (var j = 0; j <= size - 1; j++) {
+          var viewID = widgetsArray.get(j).getAttribute('viewid');
+          var id = Number(viewID.split("-").get(1));
+          newValue.visible.push(id);
+        }
+        self.saveWidgetsSettings(newValue);
+      },
+      activate: function (event, ui) {
+        self.set('isMoving', true);
+      },
+      deactivate: function (event, ui) {
+        self.set('isMoving', false);
+      }
+    }).disableSelection();
+  },
+
+  /**
+   * Submenu view for New Dashboard style
+   * @type {Ember.View}
+   * @class
+   */
+  plusButtonFilterView: Ember.View.extend({
+    tagName: 'ul',
+    classNames: ['dropdown-menu'],
+    templateName: require('templates/main/dashboard/plus_button_filter'),
+    hiddenWidgetsBinding: 'parentView.hiddenWidgets',
+    valueBinding: '',
+    widgetCheckbox: App.CheckboxView.extend({
+      didInsertElement: function () {
+        $('.checkbox').click(function (event) {
+          event.stopPropagation();
+        });
+      }
+    }),
+    closeFilter: Em.K,
+    applyFilter: function () {
+      var parent = this.get('parentView'),
+        hiddenWidgets = this.get('hiddenWidgets'),
+        userPreferences = parent.get('userPreferences'),
+        newValue = {
+          visible: userPreferences.visible.slice(0),
+          hidden: userPreferences.hidden.slice(0),
+          threshold: userPreferences.threshold
+        };
+
+      hiddenWidgets.filterProperty('checked').forEach(function (item) {
+        newValue.visible.push(item.id);
+        newValue.hidden = newValue.hidden.without(item.id);
+        hiddenWidgets.removeObject(item);
+      }, this);
+      parent.saveWidgetsSettings(newValue);
+      parent.renderWidgets();
+    }
+  }),
+
   showAlertsPopup: Em.K
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 184b046..ff1daaa 100644
--- a/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
@@ -30,11 +30,6 @@ function counterOrNA(key) {
 
 App.DataNodeUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.DataNodeUp'),
-  id: '4',
-
-  model_type: 'hdfs',
-
   hiddenInfo: function () {
     return [
       this.get('dataNodesLive') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'),
@@ -45,8 +40,6 @@ App.DataNodeUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWid
 
   hiddenInfoClass: "hidden-info-three-line",
 
-  thresh1: 40,
-  thresh2: 70,
   maxValue: 100,
 
   dataNodesLive: counterOrNA('liveDataNodes'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 e8169c9..280c25d 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
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.FlumeAgentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.FlumeAgentUp'),
-  id: '22',
-
-  model_type: 'flume',
-
   hiddenInfo: function () {
     return [
       this.get('flumeAgentsLive.length') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'),
@@ -34,8 +29,6 @@ App.FlumeAgentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitW
 
   hiddenInfoClass: "hidden-info-two-line",
 
-  thresh1: 40,
-  thresh2: 70,
   maxValue: 100,
 
   flumeAgentComponents: Em.computed.filterBy('model.hostComponents', 'componentName', 'FLUME_HANDLER'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 04e7d66..ac35c07 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
@@ -31,11 +31,6 @@ function counterOrNA(key) {
 
 App.HawqSegmentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.HawqSegmentUp'),
-  id: '24',
-
-  model_type: 'hawq',
-
   hiddenInfo: function () {
     return [
       this.get('hawqSegmentsStarted') + ' ' + Em.I18n.t('dashboard.services.components.started'),
@@ -46,8 +41,6 @@ App.HawqSegmentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimit
 
   hiddenInfoClass: "hidden-info-three-line",
 
-  thresh1: 75,
-  thresh2: 90,
   maxValue: 100,
 
   hawqSegmentsStarted: counterOrNA('hawqSegmentsStarted'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 48c4de0..986953f 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
@@ -20,11 +20,6 @@ var App = require('app');
 
 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)) {
@@ -33,15 +28,13 @@ App.HBaseAverageLoadView = App.TextDashboardWidgetView.extend(App.EditableWidget
     return [Em.I18n.t('dashboard.services.hbase.averageLoadPerServer').format(avgLoad)];
   }.property("model.averageLoad"),
 
-  isGreen: Em.computed.lteProperties('data', 'thresh1'),
-  isRed: Em.computed.gtProperties('data', 'thresh2'),
+  isGreen: Em.computed.lteProperties('data', 'thresholdMin'),
+  isRed: Em.computed.gtProperties('data', 'thresholdMax'),
 
   isNA: function (){
     return this.get('data') === null || isNaN(this.get('data'));
   }.property('data'),
 
-  thresh1: 0.5,
-  thresh2: 2,
   maxValue: 'infinity',
 
   data: Em.computed.alias('model.averageLoad'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 4f2053a..9600094 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
@@ -21,10 +21,6 @@ var App = require('app');
 App.HBaseLinksView = App.LinkDashboardWidgetView.extend({
 
   templateName: require('templates/main/dashboard/widgets/hbase_links'),
-  title: Em.I18n.t('dashboard.widgets.HBaseLinks'),
-  id: '12',
-
-  model_type: 'hbase',
 
   port: function() {
     return App.StackService.find('HBASE').compareCurrentVersion('1.1') > -1 ? '16010' : '60010';

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 63b1cc2..4ddba36 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
@@ -21,10 +21,6 @@ var numberUtils = require('utils/number_utils');
 
 App.HBaseMasterHeapPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.HBaseMasterHeap'),
-  id: '13',
-
-  model_type: 'hbase',
   modelFieldMax: 'heapMemoryMax',
   modelFieldUsed: 'heapMemoryUsed',
   widgetHtmlId: 'widget-hbase-heap',

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js b/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js
index 0801ac2..ea338dd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.HBaseMasterUptimeView = App.UptimeTextDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.HBaseMasterUptime'),
-  id: '16',
-
-  model_type: 'hbase',
-
   component: 'Hbase Master',
   modelField: 'masterStartTime',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 1f225c6..922a10e 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
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.HBaseRegionsInTransitionView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.HBaseRegionsInTransition'),
-  id: '15',
-
-  model_type: 'hbase',
   hiddenInfo: function () {
     return [
       this.get("model.regionsInTransition") + " regions",
@@ -32,15 +28,13 @@ App.HBaseRegionsInTransitionView = App.TextDashboardWidgetView.extend(App.Editab
   }.property("model.regionsInTransition"),
 
   classNameBindings: ['isRed', 'isOrange', 'isGreen', 'isNA'],
-  isGreen: Em.computed.lteProperties('data', 'thresh1'),
-  isRed: Em.computed.gtProperties('data', 'thresh2'),
+  isGreen: Em.computed.lteProperties('data', 'thresholdMin'),
+  isRed: Em.computed.gtProperties('data', 'thresholdMax'),
   isOrange: Em.computed.and('!isGreen', '!isRed'),
   isNA: function () {
     return this.get('data') === null;
   }.property('data'),
 
-  thresh1: 0.5,
-  thresh2: 2,
   maxValue: 'infinity',
 
   data: Em.computed.alias('model.regionsInTransition'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 e64534d..6bc19d9 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
@@ -21,10 +21,6 @@ var numberUtils = require('utils/number_utils');
 
 App.NameNodeCapacityPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.HDFSDiskUsage'),
-  id: '2',
-
-  model_type: 'hdfs',
   modelFieldMax: 'capacityTotal',
   /**
    * HDFS model has 'remaining' value, but not 'used'

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 cfe5eb1..900a900 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
@@ -21,10 +21,6 @@ var App = require('app');
 App.HDFSLinksView = App.LinkDashboardWidgetView.extend({
 
   templateName: require('templates/main/dashboard/widgets/hdfs_links'),
-  title: Em.I18n.t('dashboard.widgets.HDFSLinks'),
-  id: '11',
-
-  model_type: 'hdfs',
 
   port: '50070',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js b/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js
index 72ef1c2..b7efaab 100644
--- a/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js
+++ b/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js
@@ -20,9 +20,6 @@ var App = require('app');
 
 App.ChartClusterMetricsCPUWidgetView = App.ClusterMetricsDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.clusterMetrics.cpu'),
-  id: '8',
-
   content: App.ChartClusterMetricsCPU.extend({
     noTitleUnderGraph: true,
     inWidget: true

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/metrics_load.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/metrics_load.js b/ambari-web/app/views/main/dashboard/widgets/metrics_load.js
index c357934..c13e047 100644
--- a/ambari-web/app/views/main/dashboard/widgets/metrics_load.js
+++ b/ambari-web/app/views/main/dashboard/widgets/metrics_load.js
@@ -20,9 +20,6 @@ var App = require('app');
 
 App.ChartClusterMetricsLoadWidgetView = App.ClusterMetricsDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.clusterMetrics.load'),
-  id: '9',
-
   content: App.ChartClusterMetricsLoad.extend({
     noTitleUnderGraph: true,
     inWidget: true

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js b/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js
index 659d647..824c9dd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js
+++ b/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js
@@ -20,9 +20,6 @@ var App = require('app');
 
 App.ChartClusterMetricsMemoryWidgetView = App.ClusterMetricsDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.clusterMetrics.memory'),
-  id: '6',
-
   content: App.ChartClusterMetricsMemory.extend({
     noTitleUnderGraph: true,
     inWidget: true

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/metrics_network.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/metrics_network.js b/ambari-web/app/views/main/dashboard/widgets/metrics_network.js
index 40fdb0b..8f9e6cd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/metrics_network.js
+++ b/ambari-web/app/views/main/dashboard/widgets/metrics_network.js
@@ -20,9 +20,6 @@ var App = require('app');
 
 App.ChartClusterMetricsNetworkWidgetView = App.ClusterMetricsDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.clusterMetrics.network'),
-  id: '7',
-
   content: App.ChartClusterMetricsNetwork.extend({
     noTitleUnderGraph: true,
     inWidget: true

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 161b5c0..d6a3ebd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.NameNodeCpuPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.NameNodeCpu'),
-  id: '3',
-
-  model_type: 'hdfs',
   widgetHtmlId: 'widget-nn-cpu',
   cpuWio: null,
   nnHostName: "",

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 731143c..2ef6470 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.NameNodeHeapPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.NameNodeHeap'),
-  id: '1',
-
-  model_type: 'hdfs',
   modelFieldMax: 'jvmMemoryHeapMax',
   modelFieldUsed: 'jvmMemoryHeapUsed',
   widgetHtmlId: 'widget-nn-heap',

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 58b86d9..769fd22 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.NameNodeRpcView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.NameNodeRpc'),
-  id: '5',
-
-  model_type: 'hdfs',
   hiddenInfo: function () {
     return [
       this.get('content') + ' average RPC',
@@ -31,13 +27,11 @@ App.NameNodeRpcView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin
     ];
   }.property('content'),
 
-  thresh1: 0.5,
-  thresh2: 2,
   maxValue: 'infinity',
 
-  isGreen: Em.computed.lteProperties('data', 'thresh1'),
+  isGreen: Em.computed.lteProperties('data', 'thresholdMin'),
 
-  isRed: Em.computed.gtProperties('data', 'thresh2'),
+  isRed: Em.computed.gtProperties('data', 'thresholdMax'),
 
   data: function () {
     if (this.get('model.nameNodeRpc')) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js b/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js
index e55f871..30ae592 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.NameNodeUptimeView = App.UptimeTextDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.NameNodeUptime'),
-  id: '10',
-
-  model_type: 'hdfs',
-
   component: 'NameNode',
   modelField: 'nameNodeStartTime',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 d5bf50b..5dc5430 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
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.NodeManagersLiveView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.NodeManagersLive'),
-  id: '19',
-
-  model_type: 'yarn',
-
   hiddenInfo: function () {
     var nmActive = this.get('model.nodeManagersCountActive') == null ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.nodeManagersCountActive');
     var nmLost = this.get('model.nodeManagersCountLost') == null ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.nodeManagersCountLost');
@@ -43,8 +38,6 @@ App.NodeManagersLiveView = App.TextDashboardWidgetView.extend(App.EditableWithLi
 
   hiddenInfoClass: "hidden-info-five-line",
 
-  thresh1: 40,
-  thresh2: 70,
   maxValue: 100,
 
   isDataAvailable: Em.computed.and('!model.metricsNotAvailable', 'App.router.clusterController.isComponentsStateLoaded'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/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 8f2dc90..5dd85d1 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
@@ -85,8 +85,8 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
     model: null,  //data bind here
     id: Em.computed.alias('parentView.widgetHtmlId'), // html id
     stroke: '#D6DDDF', //light grey
-    thresh1: null, //bind from parent
-    thresh2: null,
+    thresholdMin: null, //bind from parent
+    thresholdMax: null,
     innerR: 25,
 
     existCenterText: true,
@@ -107,15 +107,15 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
 
     contentColor: function () {
       var used = parseFloat(this.get('parentView.dataForPieChart')[1]);
-      var thresh1 = parseFloat(this.get('thresh1'));
-      var thresh2 = parseFloat(this.get('thresh2'));
-      if (used <= thresh1) {
+      var thresholdMin = parseFloat(this.get('thresholdMin'));
+      var thresholdMax = parseFloat(this.get('thresholdMax'));
+      if (used <= thresholdMin) {
         this.set('palette', new Rickshaw.Color.Palette({
           scheme: ['#FFFFFF', App.healthStatusGreen].reverse()
         }));
         return App.healthStatusGreen;
       }
-      if (used <= thresh2) {
+      if (used <= thresholdMax) {
         this.set('palette', new Rickshaw.Color.Palette({
           scheme: ['#FFFFFF', App.healthStatusOrange].reverse()
         }));
@@ -125,7 +125,7 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
         scheme: ['#FFFFFF', App.healthStatusRed].reverse()
       }));
       return App.healthStatusRed;
-    }.property('data', 'thresh1', 'thresh2'),
+    }.property('data', 'thresholdMin', 'thresholdMax'),
 
     // refresh text and color when data in model changed
     refreshSvg: function () {
@@ -137,6 +137,6 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
 
       // draw new svg
       this.appendSvg();
-    }.observes('data', 'thresh1', 'thresh2')
+    }.observes('data', 'thresholdMin', 'thresholdMax')
   })
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/pxf_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/pxf_live.js b/ambari-web/app/views/main/dashboard/widgets/pxf_live.js
index 74b2096..a002fe3 100644
--- a/ambari-web/app/views/main/dashboard/widgets/pxf_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/pxf_live.js
@@ -31,11 +31,6 @@ function counterOrNA(key) {
 
 App.PxfUpView = App.TextDashboardSingleThresholdWidgetView.extend(App.SingleNumericThresholdMixin,{
 
-  title: Em.I18n.t('dashboard.widgets.PxfUp'),
-  id: '25',
-
-  model_type: 'pxf',
-
   hiddenInfo: function () {
     return [
       this.get('pxfsStarted') + ' ' + Em.I18n.t('dashboard.services.components.started'),
@@ -46,7 +41,6 @@ App.PxfUpView = App.TextDashboardSingleThresholdWidgetView.extend(App.SingleNume
 
   hiddenInfoClass: "hidden-info-three-line",
 
-  thresh1: 0,
   maxValue: counterOrNA('pxfsTotal'),
 
   pxfsStarted: counterOrNA('pxfsStarted'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js b/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js
index 9509053..e0e6514 100644
--- a/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js
+++ b/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.ResourceManagerHeapPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.ResourceManagerHeap'),
-  id: '17',
-
-  model_type: 'yarn',
   modelFieldMax: 'jvmMemoryHeapMax',
   modelFieldUsed: 'jvmMemoryHeapUsed',
   widgetHtmlId: 'widget-rm-heap',

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js b/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js
index 6d87741..72f2ca3 100644
--- a/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js
+++ b/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.ResourceManagerUptimeView = App.UptimeTextDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.ResourceManagerUptime'),
-  id: '18',
-
-  model_type: 'yarn',
-
   component: 'ResourceManager',
   modelField: 'resourceManagerStartTime',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js b/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
index b8e36ca..9158e59 100644
--- a/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.SuperVisorUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.SuperVisorUp'),
-  id: '21',
-
-  model_type: 'storm',
-
   hiddenInfo: function () {
     return [
       this.get('superVisorsLive') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'),
@@ -34,8 +29,6 @@ App.SuperVisorUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitW
 
   hiddenInfoClass: "hidden-info-two-line",
 
-  thresh1: 40,
-  thresh2: 70,
   maxValue: 100,
 
   superVisorsLive: Em.computed.alias('model.superVisorsStarted'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/text_widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/text_widget.js b/ambari-web/app/views/main/dashboard/widgets/text_widget.js
index 388ea52..daa354c 100644
--- a/ambari-web/app/views/main/dashboard/widgets/text_widget.js
+++ b/ambari-web/app/views/main/dashboard/widgets/text_widget.js
@@ -24,9 +24,9 @@ App.TextDashboardWidgetView = App.DashboardWidgetView.extend({
 
   classNameBindings: ['isRed', 'isOrange', 'isGreen', 'isNA'],
 
-  isRed: Em.computed.lteProperties('data', 'thresh1'),
+  isRed: Em.computed.lteProperties('data', 'thresholdMin'),
   isOrange: Em.computed.and('!isGreen', '!isRed'),
-  isGreen: Em.computed.gtProperties('data', 'thresh2'),
+  isGreen: Em.computed.gtProperties('data', 'thresholdMax'),
 
   isNA: function () {
     return this.get('data') === null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js b/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js
index 69c5821..e079446 100644
--- a/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js
+++ b/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js
@@ -23,8 +23,8 @@ App.TextDashboardSingleThresholdWidgetView = App.DashboardWidgetView.extend({
   templateName: require('templates/main/dashboard/widgets/simple_text'),
 
   classNameBindings: ['isRed', 'isGreen', 'isNA'],
-  isGreen: Em.computed.lteProperties('data', 'thresh1'),
-  isRed: Em.computed.gtProperties('data', 'thresh1'),
+  isGreen: Em.computed.lteProperties('data', 'thresholdMin'),
+  isRed: Em.computed.gtProperties('data', 'thresholdMin'),
 
   isNA: function () {
     return this.get('data') === null;
@@ -32,6 +32,6 @@ App.TextDashboardSingleThresholdWidgetView = App.DashboardWidgetView.extend({
 
   hiddenInfo: [],
 
-  maxValue: null,
+  maxValue: null
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js b/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js
index 792aa70..74d59f1 100644
--- a/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js
+++ b/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js
@@ -27,8 +27,6 @@ App.UptimeTextDashboardWidgetView = App.TextDashboardWidgetView.extend({
 
   hiddenInfoClass: "hidden-info-three-line",
 
-  thresh1: 5,
-  thresh2: 10,
   maxValue: 'infinity',
 
   component: null,

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/yarn_links.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/yarn_links.js b/ambari-web/app/views/main/dashboard/widgets/yarn_links.js
index d7b6488..e7be6d2 100644
--- a/ambari-web/app/views/main/dashboard/widgets/yarn_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/yarn_links.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.YARNLinksView = App.LinkDashboardWidgetView.extend({
   templateName: require('templates/main/dashboard/widgets/yarn_links'),
-  title: Em.I18n.t('dashboard.widgets.YARNLinks'),
-  id: '23',
-
-  model_type: 'yarn',
 
   componentName : 'NODEMANAGER'
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js b/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js
index b4dc9b7..be3beb2 100644
--- a/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js
+++ b/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js
@@ -20,11 +20,7 @@ var App = require('app');
 
 App.YARNMemoryPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.YARNMemory'),
-  id: '20',
-
   widgetHtmlId: 'widget-yarn-memory',
-  model_type: 'yarn',
   modelFieldUsed: 'allocatedMemory',
   modelFieldMax: 'maxMemory',