You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2015/10/02 11:31:42 UTC

[3/3] ambari git commit: AMBARI-13293. Ambari Web: Set/change the timezone (onechiporenko)

AMBARI-13293. Ambari Web: Set/change the timezone (onechiporenko)


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

Branch: refs/heads/branch-2.1
Commit: deb5a06a4efecc3dff8c3f52b6832c690bdfddfc
Parents: 57a56c5
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Fri Oct 2 12:29:08 2015 +0300
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Fri Oct 2 12:29:08 2015 +0300

----------------------------------------------------------------------
 ambari-web/app/controllers.js                   |    1 +
 ambari-web/app/controllers/application.js       |   68 -
 .../global/background_operations_controller.js  |    4 +-
 .../controllers/global/cluster_controller.js    |    2 +-
 .../global/user_settings_controller.js          |  214 +
 ambari-web/app/controllers/installer.js         |    3 +-
 ambari-web/app/controllers/login_controller.js  |    1 +
 .../app/controllers/main/admin/kerberos.js      |    2 +-
 ambari-web/app/controllers/main/host.js         |    2 +-
 ambari-web/app/controllers/main/host/details.js |    2 +-
 ambari-web/app/controllers/main/service.js      |    6 +-
 .../controllers/main/service/info/summary.js    |    7 +-
 ambari-web/app/controllers/main/service/item.js |    8 +-
 .../mappers/alert_definition_summary_mapper.js  |    2 +-
 .../app/mappers/alert_instances_mapper.js       |    2 +
 .../mappers/service_config_version_mapper.js    |    1 +
 ambari-web/app/messages.js                      |    1 +
 ambari-web/app/mixins/common/userPref.js        |    4 +-
 ambari-web/app/templates/application.hbs        |    2 +-
 ambari-web/app/templates/common/settings.hbs    |   10 +
 .../app/utils/batch_scheduled_requests.js       |    2 +-
 ambari-web/app/utils/date.js                    |   18 +-
 ambari-web/app/utils/helper.js                  |   13 +
 ambari-web/app/utils/host_progress_popup.js     |    3 +-
 .../app/views/common/chart/linear_time.js       |  491 +-
 .../dashboard/widgets/uptime_text_widget.js     |   38 +-
 ambari-web/app/views/main/host/summary.js       |    5 +-
 .../app/views/main/service/reconfigure.js       |    2 +-
 ambari-web/config.coffee                        |    1 +
 ambari-web/test/controllers/application_test.js |   94 +-
 .../global/user_settings_controller_test.js     |   74 +
 .../test/controllers/main/host/details_test.js  |    2 +-
 .../widgets/hbase_master_uptime_test.js         |   42 +-
 .../moment-timezone-with-data-2010-2020.js      | 1015 ++
 ambari-web/vendor/scripts/moment.js             | 9961 +++++-------------
 35 files changed, 4358 insertions(+), 7745 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers.js b/ambari-web/app/controllers.js
index 12f1753..ae037c0 100644
--- a/ambari-web/app/controllers.js
+++ b/ambari-web/app/controllers.js
@@ -25,6 +25,7 @@ require('controllers/wizard');
 require('controllers/installer');
 require('controllers/experimental');
 require('controllers/global/background_operations_controller');
+require('controllers/global/user_settings_controller');
 require('controllers/main');
 require('controllers/main/dashboard');
 require('controllers/main/dashboard/config_history_controller');

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/application.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/application.js b/ambari-web/app/controllers/application.js
index 23ff4dc..0f30a62 100644
--- a/ambari-web/app/controllers/application.js
+++ b/ambari-web/app/controllers/application.js
@@ -81,78 +81,10 @@ App.ApplicationController = Em.Controller.extend(App.UserPref, {
     });
   },
 
-  dataLoading: function () {
-    var dfd = $.Deferred();
-    var self = this;
-    this.getUserPref(this.persistKey()).complete(function () {
-      var curPref = self.get('currentPrefObject');
-      self.set('currentPrefObject', null);
-      dfd.resolve(curPref);
-    });
-    return dfd.promise();
-  },
-  persistKey: function (loginName) {
-    if (App.get('testMode')) {
-      return 'admin_settings_show_bg';
-    }
-    if (!loginName)
-      loginName = App.router.get('loginName');
-    return 'admin-settings-show-bg-' + loginName;
-  },
-  currentPrefObject: null,
-
-  getUserPrefSuccessCallback: function (response, request, data) {
-    if (response != null) {
-      console.log('Got persist value from server with key ' + data.key + '. Value is: ' + response);
-      this.set('currentPrefObject', response);
-      return response;
-    }
-  },
-  getUserPrefErrorCallback: function (request, ajaxOptions, error) {
-    // this user is first time login
-    if (request.status == 404) {
-      console.log('Persist did NOT find the key');
-      this.set('currentPrefObject', true);
-      this.postUserPref(this.persistKey(), true);
-      return true;
-    }
-  },
-
   goToAdminView: function () {
     App.router.route("adminView");
   },
 
-  showSettingsPopup: function() {
-    // Settings only for admins
-    if (!App.isAccessible('upgrade_ADMIN')) return;
-
-    var self = this;
-    var curValue = null;
-    this.dataLoading().done(function (initValue) {
-      App.ModalPopup.show({
-        header: Em.I18n.t('common.userSettings'),
-        bodyClass: Em.View.extend({
-          templateName: require('templates/common/settings'),
-          isNotShowBgChecked: !initValue,
-          updateValue: function () {
-            curValue = !this.get('isNotShowBgChecked');
-          }.observes('isNotShowBgChecked')
-        }),
-        primary: Em.I18n.t('common.save'),
-        onPrimary: function() {
-          if (curValue == null) {
-            curValue = initValue;
-          }
-          var key = self.persistKey();
-          if (!App.get('testMode')) {
-            self.postUserPref(key, curValue);
-          }
-          this.hide();
-        }
-      })
-    });
-  },
-
   showAboutPopup: function() {
 
     var self = this;

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/global/background_operations_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/background_operations_controller.js b/ambari-web/app/controllers/global/background_operations_controller.js
index 22e1e90..2cc3057 100644
--- a/ambari-web/app/controllers/global/background_operations_controller.js
+++ b/ambari-web/app/controllers/global/background_operations_controller.js
@@ -158,7 +158,7 @@ App.BackgroundOperationsController = Em.Controller.extend({
     if (request.get('isRunning')) {
       request.set('progress', App.HostPopup.getProgress(data.tasks));
       request.set('status', App.HostPopup.getStatus(data.tasks)[0]);
-      request.set('isRunning', (request.get('progress') !== 100));
+      request.set('isRunning', request.get('progress') !== 100);
     }
     request.set('previousTaskStatusMap', currentTaskStatusMap);
     request.set('hostsMap', hostsMap);
@@ -353,7 +353,7 @@ App.BackgroundOperationsController = Em.Controller.extend({
   showPopup: function(){
     // load the checkbox on footer first, then show popup.
     var self = this;
-    App.router.get('applicationController').dataLoading().done(function (initValue) {
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
       App.updater.immediateRun('requestMostRecent');
       if(self.get('popupView') && App.HostPopup.get('isBackgroundOperations')){
         self.set ('popupView.isNotShowBgChecked', !initValue);

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/global/cluster_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js
index dbd7a1b..b098c19 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -179,7 +179,7 @@ App.ClusterController = Em.Controller.extend({
       App.router.get('mainController').startPolling();
       return;
     }
-
+    App.router.get('userSettingsController').getAllUserSettings();
     var clusterUrl = this.getUrl('/data/clusters/cluster.json', '?fields=Clusters');
     var hostsController = App.router.get('mainHostController');
     hostsController.set('isCountersUpdating', true);

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/global/user_settings_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/user_settings_controller.js b/ambari-web/app/controllers/global/user_settings_controller.js
new file mode 100644
index 0000000..e05dfe4
--- /dev/null
+++ b/ambari-web/app/controllers/global/user_settings_controller.js
@@ -0,0 +1,214 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+/**
+ * Controller for user settings
+ * Allows to get them from persist and update them to the persist
+ *
+ * @class UserSettingsController
+ */
+App.UserSettingsController = Em.Controller.extend(App.UserPref, {
+
+  name: 'userSettingsController',
+
+  /**
+   * @type {object}
+   */
+  userSettings: {},
+
+  /**
+   * Each property type is {name: string, defaultValue: *}
+   * @type {object}
+   */
+  userSettingsKeys: function () {
+    var loginName = App.router.get('loginName');
+    var prefix = 'admin-settings-';
+    return {
+      show_bg: {
+        name: prefix +'show-bg-' + loginName,
+        defaultValue: true
+      },
+      timezone: {
+        name: prefix + 'timezone-' + loginName,
+        defaultValue: ''
+      }
+    };
+  }.property('App.router.loginName'),
+
+  /**
+   * Load some user's setting from the persist
+   * If <code>persistKey</code> is not provided, all settings are loaded
+   * @param {string} [persistKey]
+   * @method dataLoading
+   * @returns {$.Deferred.promise}
+   */
+  dataLoading: function (persistKey) {
+    var key = persistKey ? this.get('userSettingsKeys.' + persistKey + '.name') : '';
+    var dfd = $.Deferred();
+    var self = this;
+    this.getUserPref(key).complete(function () {
+      var curPref = self.get('currentPrefObject');
+      self.set('currentPrefObject', null);
+      dfd.resolve(curPref);
+    });
+    return dfd.promise();
+  },
+
+  getUserPrefSuccessCallback: function (response) {
+    if (!Em.isNone(response)) {
+      this.updateUserPrefWithDefaultValues(response);
+    }
+    this.set('currentPrefObject', response);
+    return response;
+  },
+
+  getUserPrefErrorCallback: function (request) {
+    // this user is first time login
+    if (404 == request.status) {
+      this.updateUserPrefWithDefaultValues();
+    }
+  },
+
+  /**
+   * Load all current user's settings to the <code>userSettings</code>
+   * @method getAllUserSettings
+   */
+  getAllUserSettings: function () {
+    var userSettingsKeys = this.get('userSettingsKeys');
+    var userSettings = {};
+    this.dataLoading().done(function (json) {
+      Object.keys(userSettingsKeys).forEach(function (k) {
+        userSettings[k] = JSON.parse(json[userSettingsKeys[k].name]);
+      });
+    });
+    this.set('userSettings', userSettings);
+  },
+
+  /**
+   * If user doesn't have any settings stored in the persist,
+   * default values should be populated there
+   * @param {object} [response]
+   * @method updateUserPrefWithDefaultValues
+   */
+  updateUserPrefWithDefaultValues: function (response) {
+    response = response || {};
+    var keys = this.get('userSettingsKeys');
+    var self = this;
+    Object.keys(keys).forEach(function (key) {
+      if (Em.isNone(response[keys[key].name])) {
+        self.postUserPref(keys[key].name, keys[key].defaultValue);
+      }
+    });
+  },
+
+  /**
+   * "Short"-key method for post user settings to the persist
+   * Example:
+   *  real key is something like 'userSettingsKeys.timezone.name'
+   *  but user should call this method with 'timezone'
+   * @method postUserPref
+   * @param {string} key
+   * @param {*} value
+   * @returns {*}
+   */
+  postUserPref: function (key, value) {
+    return this._super(this.get('userSettingsKeys.' + key + '.name'), value);
+  },
+
+  /**
+   * Sync <code>userSettingsKeys</code> after each POST-update
+   * @returns {*}
+   */
+  postUserPrefSuccessCallback: function () {
+    return this.getAllUserSettings();
+  },
+
+  /**
+   * Open popup with user settings
+   * @method showSettingsPopup
+   */
+  showSettingsPopup: function() {
+    // Settings only for admins
+    if (!App.isAccessible('upgrade_ADMIN')) {
+      return;
+    }
+    var self = this;
+    var curValue = null;
+    var keys = this.get('userSettingsKeys');
+
+    this.dataLoading().done(function (response) {
+      var initValue = JSON.parse(response[keys.show_bg.name]);
+      var initTimezone = JSON.parse(response[keys.timezone.name]);
+
+      return App.ModalPopup.show({
+
+        header: Em.I18n.t('common.userSettings'),
+
+        bodyClass: Em.View.extend({
+
+          templateName: require('templates/common/settings'),
+
+          isNotShowBgChecked: !initValue,
+
+          updateValue: function () {
+            curValue = !this.get('isNotShowBgChecked');
+          }.observes('isNotShowBgChecked'),
+
+          /**
+           * @type {string[]}
+           */
+          timezonesList: [''].concat(moment.tz.names())
+
+        }),
+
+        /**
+         * @type {string}
+         */
+        selectedTimezone: initTimezone,
+
+        primary: Em.I18n.t('common.save'),
+
+        onPrimary: function() {
+          if (Em.isNone(curValue)) {
+            curValue = initValue;
+          }
+          if (!App.get('testMode')) {
+            self.postUserPref('show_bg', curValue);
+            self.postUserPref('timezone', this.get('selectedTimezone'));
+          }
+          if (this.needsPageRefresh()) {
+            location.reload();
+          }
+          this._super();
+        },
+
+        /**
+         * Determines if page should be refreshed after user click "Save"
+         * @returns {boolean}
+         */
+        needsPageRefresh: function () {
+          return initTimezone !== this.get('selectedTimezone');
+        }
+
+      })
+    });
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index 194d862..811f858 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -704,8 +704,7 @@ App.InstallerController = App.WizardController.extend({
   finish: function () {
     this.setCurrentStep('0');
     this.clearStorageData();
-    var persists = App.router.get('applicationController').persistKey();
-    App.router.get('applicationController').postUserPref(persists, true);
+    App.router.get('userSettingsController').postUserPref('show_bg', true);
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/login_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/login_controller.js b/ambari-web/app/controllers/login_controller.js
index 4f5ccf5..f3e873b 100644
--- a/ambari-web/app/controllers/login_controller.js
+++ b/ambari-web/app/controllers/login_controller.js
@@ -49,6 +49,7 @@ App.LoginController = Em.Object.extend({
       }
       this.set('errorMessage', errorMessage);
     }
+    App.router.get('userSettingsController').dataLoading();
     this.set('isSubmitDisabled', false);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/main/admin/kerberos.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos.js b/ambari-web/app/controllers/main/admin/kerberos.js
index 8052704..52ba513 100644
--- a/ambari-web/app/controllers/main/admin/kerberos.js
+++ b/ambari-web/app/controllers/main/admin/kerberos.js
@@ -171,7 +171,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
    */
   regenerateKeytabsSuccess: function (data, opt, params, request) {
     var self = this;
-    App.router.get('applicationController').dataLoading().done(function (initValue) {
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
       if (initValue) {
         App.router.get('backgroundOperationsController').showPopup();
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/main/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host.js b/ambari-web/app/controllers/main/host.js
index 7ffd89e..9a4d600 100644
--- a/ambari-web/app/controllers/main/host.js
+++ b/ambari-web/app/controllers/main/host.js
@@ -990,7 +990,7 @@ App.MainHostController = Em.ArrayController.extend(App.TableServerMixin, {
         secondary: false
       });
     } else {
-      App.router.get('applicationController').dataLoading().done(function (initValue) {
+      App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
         if (initValue) {
           App.router.get('backgroundOperationsController').showPopup();
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/main/host/details.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index 1560f46..3768dde 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -288,7 +288,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
    * @param callback
    */
   showBackgroundOperationsPopup: function (callback) {
-    App.router.get('applicationController').dataLoading().done(function (initValue) {
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
       if (initValue) {
         App.router.get('backgroundOperationsController').showPopup();
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/main/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service.js b/ambari-web/app/controllers/main/service.js
index c589286..266f2ba 100644
--- a/ambari-web/app/controllers/main/service.js
+++ b/ambari-web/app/controllers/main/service.js
@@ -201,7 +201,7 @@ App.MainServiceController = Em.ArrayController.extend({
   silentStopSuccess: function () {
     var self = this;
 
-    App.router.get('applicationController').dataLoading().done(function (initValue) {
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
       if (initValue) {
         App.router.get('backgroundOperationsController').showPopup();
       }
@@ -241,7 +241,7 @@ App.MainServiceController = Em.ArrayController.extend({
    */
   silentCallSuccessCallback: function () {
     // load data (if we need to show this background operations popup) from persist
-    App.router.get('applicationController').dataLoading().done(function (initValue) {
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
       if (initValue) {
         App.router.get('backgroundOperationsController').showPopup();
       }
@@ -259,7 +259,7 @@ App.MainServiceController = Em.ArrayController.extend({
     params.query.set('status', 'SUCCESS');
 
     // load data (if we need to show this background operations popup) from persist
-    App.router.get('applicationController').dataLoading().done(function (initValue) {
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
       if (initValue) {
         App.router.get('backgroundOperationsController').showPopup();
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/main/service/info/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/summary.js b/ambari-web/app/controllers/main/service/info/summary.js
index cb5fe4c..04c1992 100644
--- a/ambari-web/app/controllers/main/service/info/summary.js
+++ b/ambari-web/app/controllers/main/service/info/summary.js
@@ -254,7 +254,7 @@ App.MainServiceInfoSummaryController = Em.Controller.extend(App.WidgetSectionMix
   commandSuccessCallback: function () {
     console.log('Send request for refresh configs successfully');
     // load data (if we need to show this background operations popup) from persist
-    App.router.get('applicationController').dataLoading().done(function (showPopup) {
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (showPopup) {
       if (showPopup) {
         App.router.get('backgroundOperationsController').showPopup();
       }
@@ -279,9 +279,12 @@ App.MainServiceInfoSummaryController = Em.Controller.extend(App.WidgetSectionMix
         controllerBinding: 'App.router.mainAlertDefinitionsController',
         didInsertElement: function () {
           Em.run.next(this, function () {
-            App.tooltip($(".timeago"));
+            App.tooltip(this.$(".timeago"));
           });
         },
+        willDestroyElement:function () {
+          this.$(".timeago").tooltip('destroy');
+        },
         alerts: function () {
           var serviceDefinitions = this.get('controller.content').filterProperty('service', service);
           // definitions should be sorted in order: critical, warning, ok, unknown, other

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/controllers/main/service/item.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js
index 89f44ac..2cd539b 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -133,7 +133,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
         }, App.get('testModeDelayForActions'));
       }
       // load data (if we need to show this background operations popup) from persist
-      App.router.get('applicationController').dataLoading().done(function (initValue) {
+      App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
         if (initValue) {
           App.router.get('backgroundOperationsController').showPopup();
         }
@@ -401,7 +401,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
     return App.showConfirmationPopup(function() {
       self.set("content.runRebalancer", true);
       // load data (if we need to show this background operations popup) from persist
-      App.router.get('applicationController').dataLoading().done(function (initValue) {
+      App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
         if (initValue) {
           App.router.get('backgroundOperationsController').showPopup();
         }
@@ -576,7 +576,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
     return App.showConfirmationPopup(function() {
       self.set("content.runCompaction", true);
       // load data (if we need to show this background operations popup) from persist
-      App.router.get('applicationController').dataLoading().done(function (initValue) {
+      App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
         if (initValue) {
           App.router.get('backgroundOperationsController').showPopup();
         }
@@ -666,7 +666,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
   runSmokeTestSuccessCallBack: function (data, ajaxOptions, params) {
     if (data.Requests.id) {
       // load data (if we need to show this background operations popup) from persist
-      App.router.get('applicationController').dataLoading().done(function (initValue) {
+      App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
         params.query.set('status', 'SUCCESS');
         if (initValue) {
           App.router.get('backgroundOperationsController').showPopup();

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/mappers/alert_definition_summary_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/alert_definition_summary_mapper.js b/ambari-web/app/mappers/alert_definition_summary_mapper.js
index 04cec55..b795638 100644
--- a/ambari-web/app/mappers/alert_definition_summary_mapper.js
+++ b/ambari-web/app/mappers/alert_definition_summary_mapper.js
@@ -51,7 +51,7 @@ App.alertDefinitionSummaryMapper = App.QuickDataMapper.create({
         });
         summaryMap[alertDefinitionSummary.definition_id] = {
           summary: summary,
-          lastTriggered: parseInt(timestamp)
+          lastTriggered: App.dateTimeWithTimeZone(parseInt(timestamp))
         };
       }
     });

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/mappers/alert_instances_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/alert_instances_mapper.js b/ambari-web/app/mappers/alert_instances_mapper.js
index cd1f8bd..45a4760 100644
--- a/ambari-web/app/mappers/alert_instances_mapper.js
+++ b/ambari-web/app/mappers/alert_instances_mapper.js
@@ -58,6 +58,8 @@ App.alertInstanceMapper = App.QuickDataMapper.create({
 
       json.items.forEach(function (item) {
         var alert = this.parseIt(item, this.get('config'));
+        alert.original_timestamp = App.dateTimeWithTimeZone(alert.original_timestamp);
+        alert.latest_timestamp = App.dateTimeWithTimeZone(alert.latest_timestamp);
         alertInstances.push(alert);
         alertsToDelete = alertsToDelete.without(alert.id);
       }, this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/mappers/service_config_version_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/service_config_version_mapper.js b/ambari-web/app/mappers/service_config_version_mapper.js
index 23dcdcb..e58a7c3 100644
--- a/ambari-web/app/mappers/service_config_version_mapper.js
+++ b/ambari-web/app/mappers/service_config_version_mapper.js
@@ -53,6 +53,7 @@ App.serviceConfigVersionsMapper = App.QuickDataMapper.create({
         var parsedItem = this.parseIt(item, this.get('config'));
         parsedItem.id = this.makeId(parsedItem.service_name, parsedItem.version);
         parsedItem.is_requested = true;
+        parsedItem.create_time = App.dateTimeWithTimeZone(parsedItem.create_time);
         itemIds[parsedItem.id] = true;
         parsedItem.index = index;
         if (serviceToHostMap[item.service_name]) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 2959bc1..3fe0880 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -38,6 +38,7 @@ Em.I18n.translations = {
   'app.settings':'Settings',
   'app.manageAmbari': 'Manage Ambari',
   'app.aboutAmbari':'About',
+  'app.settings.selectTimezone': 'Select your timezone',
   'app.settings.notshowBgOperationsPopup': 'Do not show the Background Operations dialog when starting an operation',
   'app.settings.notShowBgOperations': 'Do not show this dialog again when starting a background operation',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/mixins/common/userPref.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/userPref.js b/ambari-web/app/mixins/common/userPref.js
index a82e014..c4728bc 100644
--- a/ambari-web/app/mixins/common/userPref.js
+++ b/ambari-web/app/mixins/common/userPref.js
@@ -26,8 +26,8 @@ var App = require('app');
  * <ul>
  *   <li>getUserPrefSuccessCallback</li>
  *   <li>getUserPrefErrorCallback</li>
- *   <li>postuserPrefSuccessCallback</li>
- *   <li>postuserPrefErrorCallback</li>
+ *   <li>postUserPrefSuccessCallback</li>
+ *   <li>postUserPrefErrorCallback</li>
  * </ul>
  * @type {Em.Mixin}
  */

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/application.hbs b/ambari-web/app/templates/application.hbs
index 586a0b7..0a8309a 100644
--- a/ambari-web/app/templates/application.hbs
+++ b/ambari-web/app/templates/application.hbs
@@ -80,7 +80,7 @@
                 {{/if}}
                 {{#if isClusterDataLoaded}}
                   {{#isAccessible upgrade_ADMIN}}
-                    <li><a href="" {{action showSettingsPopup target="controller"}}>{{t app.settings}}</a></li>
+                    <li><a href="" {{action showSettingsPopup target="App.router.userSettingsController"}}>{{t app.settings}}</a></li>
                   {{/isAccessible}}
                 {{/if}}
                 {{#if showExitLink}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/templates/common/settings.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/settings.hbs b/ambari-web/app/templates/common/settings.hbs
index dfbcab0..cd1dd44 100644
--- a/ambari-web/app/templates/common/settings.hbs
+++ b/ambari-web/app/templates/common/settings.hbs
@@ -23,4 +23,14 @@
       {{t app.settings.notshowBgOperationsPopup}}
     </label>
   </div>
+  <div>
+    <label>
+      {{t app.settings.selectTimezone}}
+      {{view Em.Select
+        contentBinding="view.timezonesList"
+        selectionBinding="view.parentView.selectedTimezone"
+        class="group-select select-group-box"
+      }}
+    </label>
+  </div>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/utils/batch_scheduled_requests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/batch_scheduled_requests.js b/ambari-web/app/utils/batch_scheduled_requests.js
index 95d8f9b..3e57a3b 100644
--- a/ambari-web/app/utils/batch_scheduled_requests.js
+++ b/ambari-web/app/utils/batch_scheduled_requests.js
@@ -22,7 +22,7 @@ var App = require('app');
  * @type {Function}
  */
 var defaultSuccessCallback = function(data, ajaxOptions, params) {
-  App.router.get('applicationController').dataLoading().done(function(initValue) {
+  App.router.get('userSettingsController').dataLoading('show_bg').done(function(initValue) {
     params.query && params.query.set('status', 'SUCCESS');
     if (initValue) {
       App.router.get('backgroundOperationsController').showPopup();

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/utils/date.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/date.js b/ambari-web/app/utils/date.js
index 73555b4..f6d98f5 100644
--- a/ambari-web/app/utils/date.js
+++ b/ambari-web/app/utils/date.js
@@ -41,8 +41,7 @@ module.exports = {
    * @method dateFormatZeroFirst
    */
   dateFormatZeroFirst: function (time) {
-    if (time < 10) return '0' + time;
-    return ""  + time;
+    return (time < 10 ? '0' : '') + time;
   },
 
   /**
@@ -127,7 +126,6 @@ module.exports = {
     var durationSummary = '';
     var startDate = new Date(startTimestamp);
     var endDate = new Date(endTimestamp);
-    var self = this;
     if (startDate.getFullYear() == 1969 || startTimestamp < 1) {
       // not started
       return Em.I18n.t('common.na');
@@ -176,19 +174,21 @@ module.exports = {
 
     if (lengthOfNumber < 4) {
       return time + ' ms';
-    } else if (lengthOfNumber < 7) {
+    }
+    if (lengthOfNumber < 7) {
       time = (time / 1000).toFixed(2);
       return time + ' secs';
-    } else if (time < oneHourMs) {
+    }
+    if (time < oneHourMs) {
       time = (time / oneMinMs).toFixed(2);
       return time + ' mins';
-    } else if (time < oneDayMs) {
+    }
+    if (time < oneDayMs) {
       time = (time / oneHourMs).toFixed(2);
       return time + ' hours';
-    } else {
-      time = (time / oneDayMs).toFixed(2);
-      return time + ' days';
     }
+    time = (time / oneDayMs).toFixed(2);
+    return time + ' days';
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/utils/helper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js
index 7ced41d..5ccc0a2 100644
--- a/ambari-web/app/utils/helper.js
+++ b/ambari-web/app/utils/helper.js
@@ -621,6 +621,19 @@ App.dateTime = function() {
 };
 
 /**
+ *
+ * @param {number} [x] timestamp
+ * @returns {number}
+ */
+App.dateTimeWithTimeZone = function (x) {
+  var timezone = App.router.get('userSettingsController.userSettings.timezone');
+  if (timezone) {
+    return moment(moment.tz(x ? new Date(x) : new Date(), timezone).toArray()).toDate().getTime();
+  }
+  return x || new Date().getTime();
+};
+
+/**
  * Helper function for bound property helper registration
  * @memberof App
  * @method registerBoundHelper

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/utils/host_progress_popup.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/host_progress_popup.js b/ambari-web/app/utils/host_progress_popup.js
index 6c75340..7e83389 100644
--- a/ambari-web/app/utils/host_progress_popup.js
+++ b/ambari-web/app/utils/host_progress_popup.js
@@ -692,9 +692,8 @@ App.HostPopup = Em.Object.create({
        */
       updateNotShowBgChecked: function () {
         var curVal = !this.get('isNotShowBgChecked');
-        var key = App.router.get('applicationController').persistKey();
         if (!App.get('testMode')) {
-          App.router.get('applicationController').postUserPref(key, curVal);
+          App.router.get('userSettingsController').postUserPref('show_bg', curVal);
         }
       }.observes('isNotShowBgChecked'),
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/views/common/chart/linear_time.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/chart/linear_time.js b/ambari-web/app/views/common/chart/linear_time.js
index 4deb84d..97e3d7d 100644
--- a/ambari-web/app/views/common/chart/linear_time.js
+++ b/ambari-web/app/views/common/chart/linear_time.js
@@ -5,9 +5,9 @@
  * licenses this file to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -17,17 +17,18 @@
 
 var App = require('app');
 var string_utils = require('utils/string_utils');
+var dateUtils = require('utils/date');
 
 /**
  * @class
- * 
+ *
  * This is a view which GETs data from a URL and shows it as a time based line
  * graph. Time is shown on the X axis with data series shown on Y axis. It
  * optionally also has the ability to auto refresh itself over a given time
  * interval.
- * 
+ *
  * This is an abstract class which is meant to be extended.
- * 
+ *
  * Extending classes should override the following:
  * <ul>
  * <li>url - from where the data can be retrieved
@@ -36,12 +37,12 @@ var string_utils = require('utils/string_utils');
  * <li>#transformToSeries(jsonData) - function to map server data into graph
  * series
  * </ul>
- * 
+ *
  * Extending classes could optionally override the following:
  * <ul>
  * <li>#colorForSeries(series) - function to get custom colors per series
  * </ul>
- * 
+ *
  * @extends Ember.Object
  * @extends Ember.View
  */
@@ -151,13 +152,13 @@ App.ChartLinearTimeView = Ember.View.extend({
    */
   displayUnit: null,
 
-  _containerSelector: function() {
-    return ['#', this.get('id'), '-container'].join('');
+  _containerSelector: function () {
+    return '#' + this.get('id') + '-container';
   }.property('id'),
 
-  _popupSelector: function() {
-    return [this.get('_containerSelector'), this.get('popupSuffix')].join('');
-  }.property('_containerSelector'),
+  _popupSelector: function () {
+    return this.get('_containerSelector') + this.get('popupSuffix');
+  }.property('_containerSelector', 'popupSuffix'),
 
   didInsertElement: function () {
     this.loadData();
@@ -174,7 +175,7 @@ App.ChartLinearTimeView = Ember.View.extend({
     $(this.get('_popupSelector') + ' li.line').off();
   },
 
-  registerGraph: function() {
+  registerGraph: function () {
     var graph = {
       name: this.get('title'),
       id: this.get('elementId'),
@@ -183,11 +184,11 @@ App.ChartLinearTimeView = Ember.View.extend({
     App.router.get('updateController.graphs').push(graph);
   },
 
-  loadData: function() {
+  loadData: function () {
     if (this.get('loadGroup') && !this.get('isPopup')) {
-      App.ChartLinearTimeView.LoadAggregator.add(this, this.get('loadGroup'));
+      return App.ChartLinearTimeView.LoadAggregator.add(this, this.get('loadGroup'));
     } else {
-      App.ajax.send({
+      return App.ajax.send({
         name: this.get('ajaxIndex'),
         sender: this,
         data: this.getDataForAjaxRequest(),
@@ -197,7 +198,7 @@ App.ChartLinearTimeView = Ember.View.extend({
     }
   },
 
-  getDataForAjaxRequest: function() {
+  getDataForAjaxRequest: function () {
     var toSeconds = Math.round(App.dateTime() / 1000);
     var hostName = (this.get('content')) ? this.get('content.hostName') : "";
 
@@ -219,7 +220,7 @@ App.ChartLinearTimeView = Ember.View.extend({
     };
   },
 
-  loadDataErrorCallback: function(xhr, textStatus, errorThrown) {
+  loadDataErrorCallback: function (xhr, textStatus, errorThrown) {
     this.set('isReady', true);
     if (xhr.readyState == 4 && xhr.status) {
       textStatus = xhr.status + " " + textStatus;
@@ -237,22 +238,17 @@ App.ChartLinearTimeView = Ember.View.extend({
    * @param tooltip Tooltip content
    * @type: Function
    */
-  _showMessage: function(type, title, message, tooltip) {
+  _showMessage: function (type, title, message, tooltip) {
+    var popupSuffix = this.get('isPopup') ? this.get('popupSuffix') : '';
     var chartOverlay = '#' + this.get('id');
-    var chartOverlayId = chartOverlay + '-chart';
-    var chartOverlayY = chartOverlay + '-yaxis';
-    var chartOverlayX = chartOverlay + '-xaxis';
-    var chartOverlayLegend = chartOverlay + '-legend';
-    var chartOverlayTimeline = chartOverlay + '-timeline';
+    var chartOverlayId = chartOverlay + '-chart' + popupSuffix;
+    var chartOverlayY = chartOverlay + '-yaxis' + popupSuffix;
+    var chartOverlayX = chartOverlay + '-xaxis' + popupSuffix;
+    var chartOverlayLegend = chartOverlay + '-legend' + popupSuffix;
+    var chartOverlayTimeline = chartOverlay + '-timeline' + popupSuffix;
     var tooltipTitle = tooltip ? tooltip : Em.I18n.t('graphs.tooltip.title');
     var chartContent = '';
-    if (this.get('isPopup')) {
-      chartOverlayId += this.get('popupSuffix');
-      chartOverlayY += this.get('popupSuffix');
-      chartOverlayX += this.get('popupSuffix');
-      chartOverlayLegend += this.get('popupSuffix');
-      chartOverlayTimeline += this.get('popupSuffix');
-    }
+
     var typeClass;
     switch (type) {
       case 'error':
@@ -268,7 +264,7 @@ App.ChartLinearTimeView = Ember.View.extend({
         typeClass = '';
         break;
     }
-    $(chartOverlayId+', '+chartOverlayY+', '+chartOverlayX+', '+chartOverlayLegend+', '+chartOverlayTimeline).html('');
+    $(chartOverlayId + ', ' + chartOverlayY + ', ' + chartOverlayX + ', ' + chartOverlayLegend + ', ' + chartOverlayTimeline).html('');
     chartContent += '<div class=\"alert ' + typeClass + '\">';
     if (title) {
       chartContent += '<strong>' + title + '</strong> ';
@@ -295,8 +291,7 @@ App.ChartLinearTimeView = Ember.View.extend({
    *
    */
   transformData: function (seriesData, displayName) {
-    var seriesArray = [];
-    if (seriesData != null) {
+    if (!Em.isNone(seriesData)) {
       // Is it a string?
       if ("string" == typeof seriesData) {
         seriesData = JSON.parse(seriesData);
@@ -306,16 +301,17 @@ App.ChartLinearTimeView = Ember.View.extend({
         // Same number applies to all time.
         var number = seriesData;
         seriesData = [];
-        seriesData.push([number, App.dateTime()-(60*60)]);
+        seriesData.push([number, App.dateTime() - (60 * 60)]);
         seriesData.push([number, App.dateTime()]);
       }
       // We have valid data
       var series = {};
       series.name = displayName;
       series.data = [];
-      for ( var index = 0; index < seriesData.length; index++) {
+      for (var index = 0; index < seriesData.length; index++) {
+        var x = App.dateTimeWithTimeZone(seriesData[index][1] * 1000) / 1000;
         series.data.push({
-          x: seriesData[index][1],
+          x: x,
           y: seriesData[index][0]
         });
       }
@@ -332,7 +328,7 @@ App.ChartLinearTimeView = Ember.View.extend({
    *
    * @type Function
    */
-  yAxisFormatter: function(y) {
+  yAxisFormatter: function (y) {
     return App.ChartLinearTimeView.DefaultFormatter(y);
   },
 
@@ -353,17 +349,17 @@ App.ChartLinearTimeView = Ember.View.extend({
   },
 
   /**
-  * Check whether seriesData is correct data for chart drawing
-  * @param {Array} seriesData
-  * @return {Boolean}
-  */
-  checkSeries : function(seriesData) {
-    if(!seriesData || !seriesData.length) {
+   * Check whether seriesData is correct data for chart drawing
+   * @param {Array} seriesData
+   * @return {Boolean}
+   */
+  checkSeries: function (seriesData) {
+    if (!seriesData || !seriesData.length) {
       return false;
     }
     var result = true;
-    seriesData.forEach(function(item) {
-      if(!item.data || !item.data.length || !item.data[0] || typeof item.data[0].x === 'undefined') {
+    seriesData.forEach(function (item) {
+      if (Em.isNone(Em.get(item, 'data.0.x'))) {
         result = false;
       }
     });
@@ -378,7 +374,7 @@ App.ChartLinearTimeView = Ember.View.extend({
    * @type Function
    */
   _refreshGraph: function (jsonData) {
-    if(this.get('isDestroyed')){
+    if (this.get('isDestroyed')) {
       return;
     }
     var seriesData = this.transformToSeries(jsonData);
@@ -387,7 +383,7 @@ App.ChartLinearTimeView = Ember.View.extend({
     var popup_path = $(this.get('_popupSelector'));
     var graph_container = $(this.get('_containerSelector'));
     var container;
-    if(popup_path.length) {
+    if (popup_path.length) {
       popup_path.children().each(function () {
         $(this).children().remove();
       });
@@ -404,7 +400,7 @@ App.ChartLinearTimeView = Ember.View.extend({
         container = $(this.get('_containerSelector'));
         this.draw(seriesData);
         this.set('hasData', true);
-          //move yAxis value lower to make them fully visible
+        //move yAxis value lower to make them fully visible
         container.find('.y_axis text').attr('y', 8);
         container.attr('data-original-title', Em.I18n.t('graphs.tooltip.title'));
       }
@@ -412,7 +408,7 @@ App.ChartLinearTimeView = Ember.View.extend({
     else {
       this.set('isReady', true);
       //if Axis X time interval is default(60 minutes)
-      if(this.get('timeUnitSeconds') === 3600){
+      if (this.get('timeUnitSeconds') === 3600) {
         this._showMessage('info', null, this.t('graphs.noData.message'), this.t('graphs.noData.tooltip.title'));
         this.set('hasData', false);
       }
@@ -435,9 +431,9 @@ App.ChartLinearTimeView = Ember.View.extend({
    * @type Function
    * @return Rickshaw.Fixtures.Time
    */
-  localeTimeUnit: function(timeUnitSeconds) {
+  localeTimeUnit: function (timeUnitSeconds) {
     var timeUnit = new Rickshaw.Fixtures.Time();
-    switch (timeUnitSeconds){
+    switch (timeUnitSeconds) {
       case 604800:
         timeUnit = timeUnit.unit('day');
         break;
@@ -453,8 +449,8 @@ App.ChartLinearTimeView = Ember.View.extend({
           seconds: timeUnitSeconds / 4,
           formatter: function (d) {
             // format locale specific time
-            var minutes = d.getMinutes() > 9 ? "" + d.getMinutes() : "0" + d.getMinutes();
-            var hours = d.getHours() > 9 ? "" + d.getHours() : "0" + d.getHours();
+            var minutes = dateUtils.dateFormatZeroFirst(d.getMinutes());
+            var hours = dateUtils.dateFormatZeroFirst(d.getHours());
             return hours + ":" + minutes;
           }
         };
@@ -463,34 +459,12 @@ App.ChartLinearTimeView = Ember.View.extend({
   },
 
   /**
-   * temporary fix for incoming data for graph
-   * to shift data time to correct time point
-   * @param {Array} data
-   */
-  dataShiftFix: function(data) {
-    var nowTime = Math.round(App.dateTime() / 1000);
-    data.forEach(function(series){
-      var l = series.data.length;
-      var shiftDiff = nowTime - series.data[l - 1].x;
-      if(shiftDiff > 3600){
-        for(var i = 0;i < l;i++){
-          series.data[i].x = series.data[i].x + shiftDiff;
-        }
-        series.data.unshift({
-          x: nowTime - this.get('timeUnitSeconds'),
-          y: 0
-        });
-      }
-    }, this);
-  },
-
-  /**
    * calculate statistic data for popup legend and set proper colors for series
    * @param {Array} data
    */
-  dataPreProcess: function(data) {
+  dataPreProcess: function (data) {
     var self = this;
-    var palette = new Rickshaw.Color.Palette({ scheme: 'munin'});
+    var palette = new Rickshaw.Color.Palette({scheme: 'munin'});
     // Format series for display
     var series_min_length = 100000000;
     data.forEach(function (series) {
@@ -520,12 +494,12 @@ App.ChartLinearTimeView = Ember.View.extend({
 
 
         series.name = string_utils.pad(series.name.length > 36 ? series.name.substr(0, 36) + '...' : series.name, 40, '&nbsp;', 2) + '|&nbsp;' +
-        string_utils.pad('min', 5, '&nbsp;', 3) +
-        string_utils.pad(self.get('yAxisFormatter')(min), 12, '&nbsp;', 3) +
-        string_utils.pad('avg', 5, '&nbsp;', 3) +
-        string_utils.pad(self.get('yAxisFormatter')(avg / series.data.compact().length), 12, '&nbsp;', 3) +
-        string_utils.pad('max', 12, '&nbsp;', 3) +
-        string_utils.pad(self.get('yAxisFormatter')(max), 5, '&nbsp;', 3);
+          string_utils.pad('min', 5, '&nbsp;', 3) +
+          string_utils.pad(self.get('yAxisFormatter')(min), 12, '&nbsp;', 3) +
+          string_utils.pad('avg', 5, '&nbsp;', 3) +
+          string_utils.pad(self.get('yAxisFormatter')(avg / series.data.compact().length), 12, '&nbsp;', 3) +
+          string_utils.pad('max', 12, '&nbsp;', 3) +
+          string_utils.pad(self.get('yAxisFormatter')(max), 5, '&nbsp;', 3);
       }
       if (series.data.length < series_min_length) {
         series_min_length = series.data.length;
@@ -533,69 +507,40 @@ App.ChartLinearTimeView = Ember.View.extend({
     });
 
     // All series should have equal length
-    data.forEach(function(series) {
+    data.forEach(function (series) {
       if (series.data.length > series_min_length) {
         series.data.length = series_min_length;
       }
     });
   },
 
-  draw: function(seriesData) {
+  draw: function (seriesData) {
     var self = this;
     var isPopup = this.get('isPopup');
     var p = isPopup ? this.get('popupSuffix') : '';
 
-    this.dataShiftFix(seriesData);
     this.dataPreProcess(seriesData);
 
-    var chartId = "#" + this.get('id') + "-chart" + p;
-    var chartOverlayId = "#" + this.get('id') + "-container" + p;
-    var xaxisElementId = "#" + this.get('id') + "-xaxis" + p;
-    var yaxisElementId = "#" + this.get('id') + "-yaxis" + p;
-    var legendElementId = "#" + this.get('id') + "-legend" + p;
+    var chartElement = document.querySelector("#" + this.get('id') + "-chart" + p);
+    var overlayElement = document.querySelector(+this.get('id') + "-container" + p);
+    var xaxisElement = document.querySelector("#" + this.get('id') + "-xaxis" + p);
+    var yaxisElement = document.querySelector("#" + this.get('id') + "-yaxis" + p);
+    var legendElement = document.querySelector("#" + this.get('id') + "-legend" + p);
 
-    var chartElement = document.querySelector(chartId);
-    var overlayElement = document.querySelector(chartOverlayId);
-    var xaxisElement = document.querySelector(xaxisElementId);
-    var yaxisElement = document.querySelector(yaxisElementId);
-    var legendElement = document.querySelector(legendElementId);
-
-    var height = this.get('height');
-    var width = 400;
-    var diff = 32;
-
-    if(this.get('inWidget')) {
-      height = 105; // for widgets view
-      diff = 22;
-    }
-    if (isPopup) {
-      height = 180;
-      width = 670;
-    }
-    else {
-      // If not in popup, the width could vary.
-      // We determine width based on div's size.
-      var thisElement = this.get('element');
-      if (thisElement!=null) {
-        var calculatedWidth = $(thisElement).width();
-        if (calculatedWidth > diff) {
-          width = calculatedWidth - diff;
-        }
-      }
-    }
+    var graphSize = this._calculateGraphSize();
 
     var _graph = new Rickshaw.GraphReopened({
-      height: height,
-      width: width,
+      height: graphSize.height,
+      width: graphSize.width,
       element: chartElement,
       series: seriesData,
       interpolation: 'step-after',
       stroke: true,
       renderer: this.get('renderer'),
-      strokeWidth: (this.get('renderer') != 'area' ? 2 : 1)
+      strokeWidth: 'area' === this.get('renderer') ? 1 : 2
     });
 
-    if (this.get('renderer') === 'area') {
+    if ('area' === this.get('renderer')) {
       _graph.renderer.unstack = false;
     }
 
@@ -606,9 +551,9 @@ App.ChartLinearTimeView = Ember.View.extend({
 
     new Rickshaw.Graph.Axis.Y({
       tickFormat: this.yAxisFormatter,
-      pixelsPerTick: (isPopup ? 75 : 40),
+      pixelsPerTick: isPopup ? 75 : 40,
       element: yaxisElement,
-      orientation: (isPopup ? 'left' : 'right'),
+      orientation: isPopup ? 'left' : 'right',
       graph: _graph
     });
 
@@ -642,12 +587,12 @@ App.ChartLinearTimeView = Ember.View.extend({
       });
     }
 
-    this.$().on('remove', function() {
+    this.$().on('remove', function () {
       $(overlayElement).off();
     });
 
     //show the graph when it's loaded
-    _graph.onUpdate(function() {
+    _graph.onUpdate(function () {
       self.set('isReady', true);
     });
     _graph.render();
@@ -655,13 +600,13 @@ App.ChartLinearTimeView = Ember.View.extend({
     if (isPopup) {
       new Rickshaw.Graph.HoverDetail({
         graph: _graph,
-        yFormatter:function (y) {
+        yFormatter: function (y) {
           return self.yAxisFormatter(y);
         },
-        xFormatter:function (x) {
+        xFormatter: function (x) {
           return (new Date(x * 1000)).toLocaleTimeString();
         },
-        formatter:function (series, x, y, formattedX, formattedY, d) {
+        formatter: function (series, x, y, formattedX, formattedY) {
           return formattedY + '<br />' + formattedX;
         }
       });
@@ -670,14 +615,15 @@ App.ChartLinearTimeView = Ember.View.extend({
     _graph = this.updateSeriesInGraph(_graph);
     if (isPopup) {
       //show the graph when it's loaded
-      _graph.onUpdate(function() {
+      _graph.onUpdate(function () {
         self.set('isPopupReady', true);
       });
       _graph.update();
 
-      $(this.get('_popupSelector') + ' li.line').click(function() {
+      var popupSelector = this.get('_popupSelector');
+      $(popupSelector + ' li.line').click(function () {
         var series = [];
-        $(this.get('_popupSelector') + ' a.action').each(function(index, v) {
+        $(popupSelector + ' a.action').each(function (index, v) {
           series[index] = v.parentNode.classList;
         });
         self.set('_seriesProperties', series);
@@ -687,9 +633,10 @@ App.ChartLinearTimeView = Ember.View.extend({
     }
     else {
       _graph.update();
-      $(this.get('_containerSelector') + ' li.line').click(function() {
+      var containerSelector = this.get('_containerSelector');
+      $(containerSelector + ' li.line').click(function () {
         var series = [];
-        $(this.get('_containerSelector') + ' a.action').each(function(index, v) {
+        $(containerSelector + ' a.action').each(function (index, v) {
           series[index] = v.parentNode.classList;
         });
         self.set('_seriesPropertiesWidget', series);
@@ -700,18 +647,54 @@ App.ChartLinearTimeView = Ember.View.extend({
   },
 
   /**
+   * Calculate graph size
+   * @returns {{width: number, height: number}}
+   * @private
+   */
+  _calculateGraphSize: function () {
+    var isPopup = this.get('isPopup');
+    var height = this.get('height');
+    var width = 400;
+    var diff = 32;
+
+    if (this.get('inWidget')) {
+      height = 105; // for widgets view
+      diff = 22;
+    }
+    if (isPopup) {
+      height = 180;
+      width = 670;
+    }
+    else {
+      // If not in popup, the width could vary.
+      // We determine width based on div's size.
+      var thisElement = this.get('element');
+      if (!Em.isNone(thisElement)) {
+        var calculatedWidth = $(thisElement).width();
+        if (calculatedWidth > diff) {
+          width = calculatedWidth - diff;
+        }
+      }
+    }
+    return {
+      width: width,
+      height: height
+    }
+  },
+
+  /**
    *
    * @param {Rickshaw.Graph} graph
    * @returns {Rickshaw.Graph}
    */
-  updateSeriesInGraph: function(graph) {
+  updateSeriesInGraph: function (graph) {
     var id = this.get('id');
     var isPopup = this.get('isPopup');
     var popupSuffix = this.get('popupSuffix');
     var _series = isPopup ? this.get('_seriesProperties') : this.get('_seriesPropertiesWidget');
-    graph.series.forEach(function(series, index) {
-      if (_series !== null && _series[index] !== null && _series[index] !== undefined ) {
-        if(_series[_series.length - index - 1].length > 1) {
+    graph.series.forEach(function (series, index) {
+      if (_series && !Em.isNone(_series[index])) {
+        if (_series[_series.length - index - 1].length > 1) {
           var s = '#' + id + '-container' + (isPopup ? popupSuffix : '') + ' a.action:eq(' + (_series.length - index - 1) + ')';
           $(s).parent('li').addClass('disabled');
           series.disable();
@@ -721,8 +704,8 @@ App.ChartLinearTimeView = Ember.View.extend({
     return graph;
   },
 
-  showGraphInPopup: function() {
-    if(!this.get('hasData') || this.get('isPreview')) {
+  showGraphInPopup: function () {
+    if (!this.get('hasData') || this.get('isPreview')) {
       return;
     }
 
@@ -745,11 +728,11 @@ App.ChartLinearTimeView = Ember.View.extend({
         titleId: null,
         titleClass: null,
 
-        isReady: function() {
+        isReady: function () {
           return this.get('parentView.graph.isPopupReady');
         }.property('parentView.graph.isPopupReady'),
 
-        didInsertElement: function() {
+        didInsertElement: function () {
           $('#modal').addClass('modal-graph-line');
           var popupSuffix = this.get('parentView.graph.popupSuffix');
           var id = this.get('parentView.graph.id');
@@ -773,38 +756,46 @@ App.ChartLinearTimeView = Ember.View.extend({
         /**
          * check is time paging feature is enable for graph
          */
-        isTimePagingEnable: function() {
+        isTimePagingEnable: function () {
           return !self.get('isTimePagingDisable');
         }.property(),
-        rightArrowVisible: function() {
+
+        rightArrowVisible: function () {
           return (this.get('isReady') && (this.get('parentView.currentTimeIndex') != 0));
         }.property('isReady', 'parentView.currentTimeIndex'),
-        leftArrowVisible: function() {
+
+        leftArrowVisible: function () {
           return (this.get('isReady') && (this.get('parentView.currentTimeIndex') != 7));
         }.property('isReady', 'parentView.currentTimeIndex')
+
       }),
       header: this.get('title'),
       /**
        * App.ChartLinearTimeView
        */
       graph: self,
+
       secondary: null,
-      onPrimary: function() {
-        self.set('currentTimeIndex', 0);
-        this.hide();
-        self.set('isPopup', false);
+
+      onPrimary: function () {
+        self.setProperties({
+          currentTimeIndex: 0,
+          isPopup: false
+        });
+        this._super();
       },
-      onClose: function() {
+
+      onClose: function () {
         this.onPrimary();
       },
       /**
        * move graph back by time
        * @param event
        */
-      switchTimeBack: function(event) {
+      switchTimeBack: function (event) {
         var index = this.get('currentTimeIndex');
         // 7 - number of last time state
-        if(index < 7) {
+        if (index < 7) {
           this.reloadGraphByTime(++index);
         }
       },
@@ -812,9 +803,9 @@ App.ChartLinearTimeView = Ember.View.extend({
        * move graph forward by time
        * @param event
        */
-      switchTimeForward: function(event) {
+      switchTimeForward: function (event) {
         var index = this.get('currentTimeIndex');
-        if(index > 0) {
+        if (index) {
           this.reloadGraphByTime(--index);
         }
       },
@@ -822,16 +813,18 @@ App.ChartLinearTimeView = Ember.View.extend({
        * reload graph depending on the time
        * @param index
        */
-      reloadGraphByTime: function(index) {
+      reloadGraphByTime: function (index) {
         this.set('currentTimeIndex', index);
         self.set('currentTimeIndex', index);
       },
       currentTimeIndex: self.get('currentTimeIndex'),
-      currentTimeState: function() {
+
+      currentTimeState: function () {
         return self.get('timeStates').objectAt(this.get('currentTimeIndex'));
       }.property('currentTimeIndex')
+
     });
-    Ember.run.next(function() {
+    Em.run.next(function () {
       self.loadData();
       self.set('isPopupReady', false);
     });
@@ -839,6 +832,7 @@ App.ChartLinearTimeView = Ember.View.extend({
   reloadGraphByTime: function () {
     this.loadData();
   }.observes('timeUnitSeconds'),
+
   timeStates: [
     {name: Em.I18n.t('graphs.timeRange.hour'), seconds: 3600},
     {name: Em.I18n.t('graphs.timeRange.twoHours'), seconds: 7200},
@@ -851,7 +845,7 @@ App.ChartLinearTimeView = Ember.View.extend({
   ],
   // should be set by time range control dropdown list when create current graph
   currentTimeIndex: 0,
-  timeUnitSeconds: function() {
+  timeUnitSeconds: function () {
     return this.get('timeStates').objectAt(this.get('currentTimeIndex')).seconds;
   }.property('currentTimeIndex')
 });
@@ -859,146 +853,141 @@ App.ChartLinearTimeView = Ember.View.extend({
 /**
  * A formatter which will turn a number into computer storage sizes of the
  * format '23 GB' etc.
- * 
+ *
  * @type {Function}
+ * @return {string}
  */
 App.ChartLinearTimeView.BytesFormatter = function (y) {
-  if (y == 0) return '0 B';
+  if (0 == y) {
+    return '0 B';
+  }
   var value = Rickshaw.Fixtures.Number.formatBase1024KMGTP(y);
-  if (!y || y.length < 1) {
-    value = '0 B';
+  if (!y) {
+    return '0 B';
   }
-  else {
-    if ("number" == typeof value) {
-      value = String(value);
-    }
-    if ("string" == typeof value) {
-      value = value.replace(/\.\d(\d+)/, function($0, $1){ // Remove only 1-digit after decimal part
-        return $0.replace($1, '');
-      }); 
-      // Either it ends with digit or ends with character
-      value = value.replace(/(\d$)/, '$1 '); // Ends with digit like '120'
-      value = value.replace(/([a-zA-Z]$)/, ' $1'); // Ends with character like
-      // '120M'
-      value = value + 'B'; // Append B to make B, MB, GB etc.
-    }
+  if ("number" == typeof value) {
+    value = String(value);
+  }
+  if ("string" == typeof value) {
+    value = value.replace(/\.\d(\d+)/, function ($0, $1) { // Remove only 1-digit after decimal part
+      return $0.replace($1, '');
+    });
+    // Either it ends with digit or ends with character
+    value = value.replace(/(\d$)/, '$1 '); // Ends with digit like '120'
+    value = value.replace(/([a-zA-Z]$)/, ' $1'); // Ends with character like
+    // '120M'
+    value = value + 'B'; // Append B to make B, MB, GB etc.
   }
   return value;
 };
 
 /**
  * A formatter which will turn a number into percentage display like '42%'
- * 
+ *
  * @type {Function}
+ * @param {number} percentage
+ * @return {string}
  */
 App.ChartLinearTimeView.PercentageFormatter = function (percentage) {
-  var value = percentage;
-  if (!value || value.length < 1) {
-    value = '0 %';
-  } else {
-    value = value.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + '%';
-  }
-  return value;
+  return percentage ?
+    percentage.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + '%' :
+    '0 %';
 };
 
 /**
  * A formatter which will turn a number into percentage display like '42%'
  *
  * @type {Function}
+ * @param {number} value
+ * @param {string} displayUnit
+ * @return {string}
  */
 App.ChartLinearTimeView.DisplayUnitFormatter = function (value, displayUnit) {
-  if (!value || value.length === 0) {
-    value = '0 ' + displayUnit;
-  } else {
-    value = value.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + " " + displayUnit;
-  }
-  return value;
+  return value ?
+    value.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + " " + displayUnit :
+    '0 ' + displayUnit;
 };
 
 /**
  * A formatter which will turn elapsed time into display time like '50 ms',
  * '5s', '10 m', '3 hr' etc. Time is expected to be provided in milliseconds.
- * 
+ *
  * @type {Function}
+ * @return {string}
  */
 App.ChartLinearTimeView.TimeElapsedFormatter = function (millis) {
-  var value = millis;
-  if (!value || value.length < 1) {
-    value = '0 ms';
-  } else if ("number" == typeof millis) {
+  if (!millis) {
+    return '0 ms';
+  }
+  if ('number' == Em.typeOf(millis)) {
     var seconds = millis > 1000 ? Math.round(millis / 1000) : 0;
     var minutes = seconds > 60 ? Math.round(seconds / 60) : 0;
     var hours = minutes > 60 ? Math.round(minutes / 60) : 0;
     var days = hours > 24 ? Math.round(hours / 24) : 0;
     if (days > 0) {
-      value = days + ' d';
-    } else if (hours > 0) {
-      value = hours + ' hr';
-    } else if (minutes > 0) {
-      value = minutes + ' m';
-    } else if (seconds > 0) {
-      value = seconds + ' s';
-    } else if (millis > 0) {
-      value = millis.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + ' ms';
-    } else {
-      value = millis.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + ' ms';
+      return days + ' d';
+    }
+    if (hours > 0) {
+      return hours + ' hr';
+    }
+    if (minutes > 0) {
+      return minutes + ' m';
     }
+    if (seconds > 0) {
+      return seconds + ' s';
+    }
+    return millis.toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + ' ms';
   }
-  return value;
+  return millis;
 };
 
 /**
- * The default formatter which uses Rickshaw.Fixtures.Number.formatKMBT 
+ * The default formatter which uses Rickshaw.Fixtures.Number.formatKMBT
  * which shows 10K, 300M etc.
  *
  * @type {Function}
+ * @return {string|number}
  */
-App.ChartLinearTimeView.DefaultFormatter = function(y) {
-  if(isNaN(y)){
+App.ChartLinearTimeView.DefaultFormatter = function (y) {
+  if (!y) {
     return 0;
   }
   var value = Rickshaw.Fixtures.Number.formatKMBT(y);
-  if (value == '') return '0';
+  if ('' == value) return '0';
   value = String(value);
   var c = value[value.length - 1];
-  if (!isNaN(parseInt(c))) {
-    // c is digit
-    value = parseFloat(value).toFixed(3).replace(/0+$/, '').replace(/\.$/, '');
-  }
-  else {
-    // c in not digit
-    value = parseFloat(value.substr(0, value.length - 1)).toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + c;
-  }
-  return value;
+  return isNaN(parseInt(c)) ?
+  parseFloat(value.substr(0, value.length - 1)).toFixed(3).replace(/0+$/, '').replace(/\.$/, '') + c :
+    parseFloat(value).toFixed(3).replace(/0+$/, '').replace(/\.$/, '');
 };
 
 
 /**
- * Creates and returns a formatter that can convert a 'value' 
- * to 'value units/s'. 
- * 
+ * Creates and returns a formatter that can convert a 'value'
+ * to 'value units/s'.
+ *
  * @param unitsPrefix Prefix which will be used in 'unitsPrefix/s'
- * @param valueFormatter  Value itself will need further processing 
+ * @param valueFormatter  Value itself will need further processing
  *        via provided formatter. Ex: '10M requests/s'. Generally
- *        should be App.ChartLinearTimeView.DefaultFormatter. 
+ *        should be App.ChartLinearTimeView.DefaultFormatter.
  * @return {Function}
  */
 App.ChartLinearTimeView.CreateRateFormatter = function (unitsPrefix, valueFormatter) {
-  var suffix = " "+unitsPrefix+"/s";
+  var suffix = " " + unitsPrefix + "/s";
   return function (value) {
     value = valueFormatter(value) + suffix;
     return value;
   };
 };
 
-Rickshaw.GraphReopened = function(a){
+Rickshaw.GraphReopened = function (a) {
   Rickshaw.Graph.call(this, a);
 };
 
 //reopened in order to exclude "null" value from validation
 Rickshaw.GraphReopened.prototype = Object.create(Rickshaw.Graph.prototype, {
-  validateSeries : {
-    value: function(series) {
+  validateSeries: {
+    value: function (series) {
 
       if (!(series instanceof Array) && !(series instanceof Rickshaw.Series)) {
         var seriesSignature = Object.prototype.toString.apply(series);
@@ -1007,7 +996,7 @@ Rickshaw.GraphReopened.prototype = Object.create(Rickshaw.Graph.prototype, {
 
       var pointsCount;
 
-      series.forEach( function(s) {
+      series.forEach(function (s) {
 
         if (!(s instanceof Object)) {
           throw "series element is not an object: " + s;
@@ -1023,7 +1012,7 @@ Rickshaw.GraphReopened.prototype = Object.create(Rickshaw.Graph.prototype, {
 
         if (pointsCount && s.data.length != pointsCount) {
           throw "series cannot have differing numbers of points: " +
-          pointsCount	+ " vs " + s.data.length + "; see Rickshaw.Series.zeroFill()";
+          pointsCount + " vs " + s.data.length + "; see Rickshaw.Series.zeroFill()";
         }
       })
     },
@@ -1034,27 +1023,41 @@ Rickshaw.GraphReopened.prototype = Object.create(Rickshaw.Graph.prototype, {
 });
 
 //show no line if point is "null"
-Rickshaw.Graph.Renderer.Line.prototype.seriesPathFactory = function() {
+Rickshaw.Graph.Renderer.Line.prototype.seriesPathFactory = function () {
 
   var graph = this.graph;
 
   return d3.svg.line()
-    .x( function(d) { return graph.x(d.x) } )
-    .y( function(d) { return graph.y(d.y) } )
-    .defined(function(d) { return d.y!=null; })
+    .x(function (d) {
+      return graph.x(d.x)
+    })
+    .y(function (d) {
+      return graph.y(d.y)
+    })
+    .defined(function (d) {
+      return d.y != null;
+    })
     .interpolate(this.graph.interpolation).tension(this.tension);
 };
 
 //show no area if point is null
-Rickshaw.Graph.Renderer.Stack.prototype.seriesPathFactory = function() {
+Rickshaw.Graph.Renderer.Stack.prototype.seriesPathFactory = function () {
 
   var graph = this.graph;
 
   return d3.svg.area()
-    .x( function(d) { return graph.x(d.x) } )
-    .y0( function(d) { return graph.y(d.y0) } )
-    .y1( function(d) { return graph.y(d.y + d.y0) } )
-    .defined(function(d) { return d.y!=null; })
+    .x(function (d) {
+      return graph.x(d.x)
+    })
+    .y0(function (d) {
+      return graph.y(d.y0)
+    })
+    .y1(function (d) {
+      return graph.y(d.y + d.y0)
+    })
+    .defined(function (d) {
+      return d.y != null;
+    })
     .interpolate(this.graph.interpolation).tension(this.tension);
 };
 
@@ -1171,7 +1174,7 @@ App.ChartLinearTimeView.LoadAggregator = Em.Object.create({
           }, this);
         }).fail(function (jqXHR, textStatus, errorThrown) {
           _request.subRequests.forEach(function (subRequest) {
-            subRequest.context.loadDataErrorCallback.call(subRequest.context, jqXHR, textStatus, errorThrown );
+            subRequest.context.loadDataErrorCallback.call(subRequest.context, jqXHR, textStatus, errorThrown);
           }, this);
         });
       })(bulks[id]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/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 be3c962..a3290de 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
@@ -39,19 +39,16 @@ App.UptimeTextDashboardWidgetView = App.TextDashboardWidgetView.extend({
   modelField: null,
 
   data: null,
+
   content: null,
 
   isGreen: function () {
-    return this.get('data') != null;
+    return !Em.isNone(this.get('data'));
   }.property('data'),
 
-  isOrange: function () {
-    return false;
-  }.property('data'),
+  isOrange: false,
 
-  isRed: function () {
-    return false;
-  }.property('data'),
+  isRed: false,
 
   timeConverter: function (timestamp) {
     var m = moment((new Date(timestamp)));
@@ -73,13 +70,14 @@ App.UptimeTextDashboardWidgetView = App.TextDashboardWidgetView.extend({
   },
 
   calc: function () {
+    // don't do this.setProperties!
     this.set('data', this.calcData());
     this.set('content', this.calcContent());
   },
 
   uptimeProcessing: function (uptime) {
     var uptimeString = this.timeConverter(uptime);
-    var diff = App.dateTime() - uptime;
+    var diff = App.dateTimeWithTimeZone() - uptime;
     if (diff < 0) {
       diff = 0;
     }
@@ -102,11 +100,10 @@ App.UptimeTextDashboardWidgetView = App.TextDashboardWidgetView.extend({
         default:
           timeUnit = formatted.split(" ")[1];
       }
-      this.set('timeUnit', timeUnit);
-      this.set('hiddenInfo', []);
-      this.get('hiddenInfo').pushObject(formatted);
-      this.get('hiddenInfo').pushObject(uptimeString[0]);
-      this.get('hiddenInfo').pushObject(uptimeString[1]);
+      this.setProperties({
+        timeUnit: timeUnit,
+        hiddenInfo: [formatted, uptimeString[0], uptimeString[1]]
+      });
     }
     return formatted;
   },
@@ -114,9 +111,9 @@ App.UptimeTextDashboardWidgetView = App.TextDashboardWidgetView.extend({
   calcData: function () {
     var field = this.get('modelField');
     var uptime = this.get('model').get(field);
-    if (uptime && uptime > 0) {
-      var formatted = this.uptimeProcessing(uptime);
-      if (formatted != null) {
+    if (uptime) {
+      var formatted = this.uptimeProcessing(App.dateTimeWithTimeZone(uptime));
+      if (!Em.isNone(formatted)) {
         return parseFloat(formatted.split(" ")[0]);
       }
     }
@@ -126,11 +123,8 @@ App.UptimeTextDashboardWidgetView = App.TextDashboardWidgetView.extend({
 
   calcContent: function () {
     var data = this.get('data');
-    if (data) {
-      return data.toFixed(1) + ' ' + this.get('timeUnit');
-    }
-    else {
-      return Em.I18n.t('services.service.summary.notAvailable');
-    }
+    return data ?
+      data.toFixed(1) + ' ' + this.get('timeUnit') :
+      Em.I18n.t('services.service.summary.notAvailable');
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/views/main/host/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/summary.js b/ambari-web/app/views/main/host/summary.js
index d70951d..48ff9e8 100644
--- a/ambari-web/app/views/main/host/summary.js
+++ b/ambari-web/app/views/main/host/summary.js
@@ -302,10 +302,7 @@ App.MainHostSummaryView = Em.View.extend({
    */
   timeSinceHeartBeat: function () {
     var d = this.get('content.lastHeartBeatTime');
-    if (d) {
-      return $.timeago(d);
-    }
-    return "";
+    return d ? $.timeago(d) : '';
   }.property('content.lastHeartBeatTime'),
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/app/views/main/service/reconfigure.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/reconfigure.js b/ambari-web/app/views/main/service/reconfigure.js
index aaa1ee4..dd7a8d3 100644
--- a/ambari-web/app/views/main/service/reconfigure.js
+++ b/ambari-web/app/views/main/service/reconfigure.js
@@ -48,7 +48,7 @@ App.StageLabelView = Em.View.extend({
 
   showHostPopup: function (command) {
     var controller = this.get("controller");
-    App.router.get('applicationController').dataLoading().done(function (initValue) {
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
       var popupView = App.HostPopup.initPopup(command.get('label'), controller, false, command.get('requestId'));
       popupView.set('isNotShowBgChecked', !initValue);
     })

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/config.coffee
----------------------------------------------------------------------
diff --git a/ambari-web/config.coffee b/ambari-web/config.coffee
index 3410ac8..2922593 100644
--- a/ambari-web/config.coffee
+++ b/ambari-web/config.coffee
@@ -56,6 +56,7 @@ exports.config =
           'vendor/scripts/jquery.ajax-retry.js',
           'vendor/scripts/jquery.sticky-kit.js',
           'vendor/scripts/moment.js',
+          'vendor/scripts/moment-timezone-with-data-2010-2020.js',
           'vendor/scripts/workflow_visualization.js',
           'vendor/scripts/rickshaw.js',
           'vendor/scripts/spin.js',

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/test/controllers/application_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/application_test.js b/ambari-web/test/controllers/application_test.js
index d894038..203fff0 100644
--- a/ambari-web/test/controllers/application_test.js
+++ b/ambari-web/test/controllers/application_test.js
@@ -22,7 +22,7 @@ require('models/cluster');
 
 describe('App.ApplicationController', function () {
 
-  var installerController = App.ApplicationController.create();
+  var applicationController = App.ApplicationController.create();
 
   describe('#showAboutPopup', function() {
     var dataToShowRes = {};
@@ -35,7 +35,7 @@ describe('App.ApplicationController', function () {
       App.ModalPopup.show.restore();
     });
     it ('Should send correct data to popup', function() {
-      installerController.showAboutPopup();
+      applicationController.showAboutPopup();
       dataToShowRes = JSON.parse(JSON.stringify(dataToShowRes));
       expect(dataToShowRes).to.eql({
         "header": "About",
@@ -52,61 +52,17 @@ describe('App.ApplicationController', function () {
       App.router.get.restore();
     });
     it ('Should return cluster name', function() {
-      expect(installerController.get('clusterName')).to.equal('cl1');
+      expect(applicationController.get('clusterName')).to.equal('cl1');
     });
   });
 
-  describe('#showSettingsPopup', function() {
-    var dataToShowRes = {};
 
-    beforeEach(function () {
-      sinon.stub(App.ModalPopup, 'show', function(dataToShow){
-        dataToShowRes = dataToShow;
-      });
-      sinon.stub(App, 'isAccessible').returns(true);
-      var emulatorClass = function() {};
-      emulatorClass.prototype.done = function(func) {
-        if (func) {
-          func();
-        }
-      };
-      var emulator = new emulatorClass();
-      sinon.stub(installerController, 'dataLoading').returns(emulator);
-    });
-    afterEach(function () {
-      App.isAccessible.restore();
-      App.ModalPopup.show.restore();
-      installerController.dataLoading.restore();
-    });
-    it ('Should show settings popup', function() {
-      installerController.showSettingsPopup();
-      dataToShowRes = JSON.parse(JSON.stringify(dataToShowRes));
-      expect(dataToShowRes).to.eql({
-        "header": "User Settings",
-        "primary": "Save"
-      });
-    });
-  });
 
   describe('#startKeepAlivePoller', function() {
     it ('Should change run poller state', function() {
-      installerController.set('isPollerRunning', false);
-      installerController.startKeepAlivePoller();
-      expect(installerController.get('isPollerRunning')).to.be.true;
-    });
-  });
-
-  describe('#getUserPrefErrorCallback', function() {
-    it ('Should set currentPrefObject', function() {
-      installerController.getUserPrefErrorCallback({status: 404}, {}, {});
-      expect(installerController.get('currentPrefObject')).to.be.true;
-    });
-  });
-
-  describe('#getUserPrefSuccessCallback', function() {
-    it ('Should set currentPrefObject', function() {
-      installerController.getUserPrefSuccessCallback({status: 200}, {}, {});
-      expect(installerController.get('currentPrefObject')).to.be.eql({status: 200});
+      applicationController.set('isPollerRunning', false);
+      applicationController.startKeepAlivePoller();
+      expect(applicationController.get('isPollerRunning')).to.be.true;
     });
   });
 
@@ -122,36 +78,11 @@ describe('App.ApplicationController', function () {
       App.router.route.restore();
     });
     it ('Should call route once', function() {
-      installerController.goToAdminView();
+      applicationController.goToAdminView();
       expect(result).to.be.equal('adminView');
     });
   });
 
-  describe('#dataLoading', function() {
-    beforeEach(function () {
-      sinon.stub(installerController, 'getUserPref', function(){
-        return {
-          complete: function(func) {
-            if (func) {
-              func();
-            }
-          }
-        };
-      });
-    });
-    afterEach(function () {
-      installerController.getUserPref.restore();
-    });
-    it ('Should change run poller state', function() {
-      installerController.set('currentPrefObject', {name: 'n1'});
-      installerController.dataLoading().then(function(data){
-        expect(data).to.be.eql({
-          "name": "n1"
-        });
-      });
-    });
-  });
-
   describe('#getStack', function() {
     var res;
     beforeEach(function () {
@@ -166,13 +97,12 @@ describe('App.ApplicationController', function () {
       var callback = {
         'callback': true
       };
-      installerController.getStack(callback);
+      applicationController.getStack(callback);
       res = JSON.parse(JSON.stringify(res));
       expect(res).to.be.eql({
         "name": "router.login.clusters",
         "sender": {
-          "isPollerRunning": true,
-          "currentPrefObject": null
+          "isPollerRunning": true
         },
         "callback": {
           "callback": true
@@ -183,8 +113,8 @@ describe('App.ApplicationController', function () {
 
   describe('#clusterDisplayName', function() {
     it ('Should return cluster display name', function() {
-      installerController.set('clusterName', '');
-      expect(installerController.get('clusterDisplayName')).to.equal('mycluster');
+      applicationController.set('clusterName', '');
+      expect(applicationController.get('clusterDisplayName')).to.equal('mycluster');
     });
   });
 
@@ -196,7 +126,7 @@ describe('App.ApplicationController', function () {
       App.router.get.restore();
     });
     it ('Should return true, when data loaded', function() {
-      expect(installerController.get('isClusterDataLoaded')).to.be.equal('cl1');
+      expect(applicationController.get('isClusterDataLoaded')).to.be.equal('cl1');
     });
   });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/test/controllers/global/user_settings_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/global/user_settings_controller_test.js b/ambari-web/test/controllers/global/user_settings_controller_test.js
new file mode 100644
index 0000000..99a7df2
--- /dev/null
+++ b/ambari-web/test/controllers/global/user_settings_controller_test.js
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+var userSettingsController;
+
+describe('App.UserSettingsController', function () {
+
+  beforeEach(function () {
+    userSettingsController = App.UserSettingsController.create();
+  });
+  
+  describe('#showSettingsPopup', function() {
+    var dataToShowRes = {};
+
+    beforeEach(function () {
+      sinon.stub(App.ModalPopup, 'show', function(dataToShow){
+        dataToShowRes = dataToShow;
+      });
+      sinon.stub(App, 'isAccessible').returns(true);
+      var emulatorClass = function() {};
+      emulatorClass.prototype.done = function(func) {
+        if (func) {
+          func();
+        }
+      };
+      var emulator = new emulatorClass();
+      sinon.stub(userSettingsController, 'dataLoading').returns(emulator);
+    });
+    afterEach(function () {
+      App.isAccessible.restore();
+      App.ModalPopup.show.restore();
+      userSettingsController.dataLoading.restore();
+    });
+    it ('Should show settings popup', function() {
+      userSettingsController.showSettingsPopup();
+      dataToShowRes = JSON.parse(JSON.stringify(dataToShowRes));
+      expect(dataToShowRes).to.eql({
+        "header": "User Settings",
+        "primary": "Save"
+      });
+    });
+  });
+
+  describe('#getUserPrefErrorCallback', function() {
+    it ('Should set currentPrefObject', function() {
+      applicationController.getUserPrefErrorCallback({status: 404}, {}, {});
+      expect(applicationController.get('currentPrefObject')).to.be.true;
+    });
+  });
+
+  describe('#getUserPrefSuccessCallback', function() {
+    it ('Should set currentPrefObject', function() {
+      applicationController.getUserPrefSuccessCallback({status: 200}, {}, {});
+      expect(applicationController.get('currentPrefObject')).to.be.eql({status: 200});
+    });
+  });
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/test/controllers/main/host/details_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js
index d6b7c9c..be86410 100644
--- a/ambari-web/test/controllers/main/host/details_test.js
+++ b/ambari-web/test/controllers/main/host/details_test.js
@@ -242,7 +242,7 @@ describe('App.MainHostDetailsController', function () {
     };
     beforeEach(function () {
       var stub = sinon.stub(App.router, 'get');
-      stub.withArgs('applicationController').returns({
+      stub.withArgs('userSettingsController').returns({
         dataLoading: function () {
           return mock;
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/deb5a06a/ambari-web/test/views/main/dashboard/widgets/hbase_master_uptime_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/hbase_master_uptime_test.js b/ambari-web/test/views/main/dashboard/widgets/hbase_master_uptime_test.js
index 1f365cf..3a43b54 100644
--- a/ambari-web/test/views/main/dashboard/widgets/hbase_master_uptime_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/hbase_master_uptime_test.js
@@ -23,16 +23,14 @@ require('views/main/dashboard/widgets/hbase_master_uptime');
 require('views/main/dashboard/widgets/text_widget');
 require('views/main/dashboard/widget');
 
-describe('App.HBaseMasterUptimeView', function() {
+describe('App.HBaseMasterUptimeView', function () {
 
   var tests = [
     {
       model: Em.Object.create({
-        masterStartTime: ((new Date()).getTime() - 192.1*24*3600*1000)
+        masterStartTime: ((new Date()).getTime() - 192.1 * 24 * 3600 * 1000)
       }),
       e: {
-        isRed: false,
-        isOrange: false,
         isGreen: true,
         isNA: false,
         content: '192.1 d',
@@ -40,12 +38,10 @@ describe('App.HBaseMasterUptimeView', function() {
       }
     },
     {
-      model:  Em.Object.create({
+      model: Em.Object.create({
         masterStartTime: 0
       }),
       e: {
-        isRed: false,
-        isOrange: false,
         isGreen: false,
         isNA: true,
         content: Em.I18n.t('services.service.summary.notAvailable'),
@@ -53,12 +49,10 @@ describe('App.HBaseMasterUptimeView', function() {
       }
     },
     {
-      model:  Em.Object.create({
+      model: Em.Object.create({
         masterStartTime: null
       }),
       e: {
-        isRed: false,
-        isOrange: false,
         isGreen: false,
         isNA: true,
         content: Em.I18n.t('services.service.summary.notAvailable'),
@@ -67,26 +61,28 @@ describe('App.HBaseMasterUptimeView', function() {
     }
   ];
 
-  tests.forEach(function(test) {
-    var hBaseMasterUptimeView = App.HBaseMasterUptimeView.create({model_type:null, model: test.model});
+  beforeEach(function () {
+    sinon.stub(App.router, 'get').withArgs('userSettingsController.userSettings.timezone').returns('');
+  });
+
+  afterEach(function () {
+    App.router.get.restore();
+  });
+
+  tests.forEach(function (test) {
+    var hBaseMasterUptimeView = App.HBaseMasterUptimeView.create({model_type: null, model: test.model});
     hBaseMasterUptimeView.calc();
-    describe('masterStartTime - ' + test.model.masterStartTime, function() {
-      it('content', function() {
+    describe('#masterStartTime - ' + test.model.masterStartTime, function () {
+      it('content', function () {
         expect(hBaseMasterUptimeView.get('content')).to.equal(test.e.content);
       });
-      it('data', function() {
+      it('data', function () {
         expect(hBaseMasterUptimeView.get('data')).to.equal(test.e.data);
       });
-      it('isRed', function() {
-        expect(hBaseMasterUptimeView.get('isRed')).to.equal(test.e.isRed);
-      });
-      it('isOrange', function() {
-        expect(hBaseMasterUptimeView.get('isOrange')).to.equal(test.e.isOrange);
-      });
-      it('isGreen', function() {
+      it('isGreen', function () {
         expect(hBaseMasterUptimeView.get('isGreen')).to.equal(test.e.isGreen);
       });
-      it('isNA', function() {
+      it('isNA', function () {
         expect(hBaseMasterUptimeView.get('isNA')).to.equal(test.e.isNA);
       });
     });