Просмотр исходного кода

AMBARI-13332. User Timezone setting fixes (onechiporenko)

Oleg Nechiporenko 9 лет назад
Родитель
Сommit
e1caac3aaa

+ 44 - 6
ambari-web/app/controllers/global/user_settings_controller.js

@@ -18,6 +18,8 @@
 
 var App = require('app');
 
+var dateUtils = require('utils/date');
+
 /**
  * Controller for user settings
  * Allows to get them from persist and update them to the persist
@@ -47,11 +49,47 @@ App.UserSettingsController = Em.Controller.extend(App.UserPref, {
       },
       timezone: {
         name: prefix + 'timezone-' + loginName,
-        defaultValue: ''
+        defaultValue: dateUtils.detectUserTimezone()
       }
     };
   }.property('App.router.loginName'),
 
+  init: function () {
+    this.set('timezonesFormatted', this._parseTimezones());
+    this._super();
+  },
+
+  /**
+   *
+   * @private
+   * @method _parseTimezones
+   * @return {{utcOffset: number, label: string, value: string}[]}
+   */
+  _parseTimezones: function () {
+    return dateUtils.getAllTimezoneNames().map(function (timeZoneName) {
+      var zone = moment(new Date()).tz(timeZoneName);
+      var offset = zone.format('Z');
+      return {
+        utcOffset: zone.utcOffset(),
+        label: '(UTC' + offset + ') ' + timeZoneName,
+        value: timeZoneName
+      };
+    }).sort(function (zoneA, zoneB) {
+      if (zoneA.utcOffset === zoneB.utcOffset) {
+        if (zoneA.value === zoneB.value) {
+          return 0;
+        }
+        return zoneA.value < zoneB.value ? -1 : 1;
+      }
+      else {
+        if(zoneA.utcOffset === zoneB.utcOffset) {
+          return 0;
+        }
+        return zoneA.utcOffset < zoneB.utcOffset ? -1 : 1;
+      }
+    });
+  },
+
   /**
    * Load some user's setting from the persist
    * If <code>persistKey</code> is not provided, all settings are loaded
@@ -152,11 +190,11 @@ App.UserSettingsController = Em.Controller.extend(App.UserPref, {
     var self = this;
     var curValue = null;
     var keys = this.get('userSettingsKeys');
+    var timezonesFormatted = this.get('timezonesFormatted');
 
     this.dataLoading().done(function (response) {
       var initValue = JSON.parse(response[keys.show_bg.name]);
-      var initTimezone = JSON.parse(response[keys.timezone.name]);
-
+      var initTimezone = timezonesFormatted.findProperty('value', JSON.parse(response[keys.timezone.name]));
       return App.ModalPopup.show({
 
         header: Em.I18n.t('common.userSettings'),
@@ -172,9 +210,9 @@ App.UserSettingsController = Em.Controller.extend(App.UserPref, {
           }.observes('isNotShowBgChecked'),
 
           /**
-           * @type {string[]}
+           * @type {{label: string, value: string}}
            */
-          timezonesList: [''].concat(moment.tz.names())
+          timezonesList: timezonesFormatted
 
         }),
 
@@ -191,7 +229,7 @@ App.UserSettingsController = Em.Controller.extend(App.UserPref, {
           }
           if (!App.get('testMode')) {
             self.postUserPref('show_bg', curValue);
-            self.postUserPref('timezone', this.get('selectedTimezone'));
+            self.postUserPref('timezone', this.get('selectedTimezone.value'));
           }
           if (this.needsPageRefresh()) {
             location.reload();

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

@@ -39,9 +39,11 @@ Em.I18n.translations = {
   'app.settings':'Settings',
   'app.manageAmbari': 'Manage Ambari',
   'app.aboutAmbari':'About',
-  'app.settings.selectTimezone': 'Select your timezone',
+  'app.settings.selectTimezone': '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',
+  'app.settings.categories.general': 'General',
+  'app.settings.categories.locale': 'Locale',
 
   'app.aboutAmbari.getInvolved': 'Get involved!',
   'app.aboutAmbari.version': 'Version',

+ 10 - 1
ambari-web/app/styles/application.less

@@ -3741,8 +3741,17 @@ table.graphs {
 }
 
 .admin-user-settings {
+  hr {
+    margin: 5px 0;
+  }
+  select {
+    width: auto;
+  }
+  .setting-wrapper {
+    margin-bottom: 20px;
+  }
   .checkbox {
-    margin: 0px;
+    margin: 0;
   }
 }
 /*End Admin*/

+ 13 - 7
ambari-web/app/templates/common/settings.hbs

@@ -17,20 +17,26 @@
 }}
 
 <div class="admin-user-settings">
-  <div>
+  <div class="setting-wrapper">
+    <h4>{{t app.settings.categories.general}}</h4>
+    <hr />
     <label>
       {{view Ember.Checkbox checkedBinding="view.isNotShowBgChecked" class="checkbox"}}
       {{t app.settings.notshowBgOperationsPopup}}
     </label>
   </div>
-  <div>
+  <div class="setting-wrapper">
+    <h4>{{t app.settings.categories.locale}}</h4>
+    <hr />
     <label>
       {{t app.settings.selectTimezone}}
-      {{view Em.Select
-        contentBinding="view.timezonesList"
-        selectionBinding="view.parentView.selectedTimezone"
-        class="group-select select-group-box"
-      }}
+        {{view Em.Select
+          contentBinding="view.timezonesList"
+          optionLabelPath="content.label"
+          optionValuePath="content.value"
+          selectionBinding="view.parentView.selectedTimezone"
+          class="group-select select-group-box"
+        }}
     </label>
   </div>
 </div>

+ 28 - 0
ambari-web/app/utils/date.js

@@ -210,5 +210,33 @@ module.exports = {
       duration = endTime - startTime;
     }
     return duration;
+  },
+
+  /**
+   * Load list of timezones from moment.tz
+   * Zones "Etc/*" are excluded
+   * @returns {object[]}
+   */
+  getAllTimezoneNames: function () {
+    return moment.tz.names().filter(function (timeZoneName) {
+      return !timeZoneName.startsWith('Etc/');
+    });
+  },
+
+  /**
+   * Try detect user's timezone using timezoneOffset and moment.tz
+   * @returns {string}
+   */
+  detectUserTimezone: function () {
+    var timezoneOffset = new Date().getTimezoneOffset();
+    var timezoneNames = this.getAllTimezoneNames();
+    for (var i = 0; i < timezoneNames.length; i++) {
+      var zone = moment.tz.zone(timezoneNames[i]);
+      if (zone.offsets.contains(timezoneOffset)) {
+        return timezoneNames[i];
+      }
+    }
+    return '';
   }
+
 };