Add support for global timezones. Closes #1600

This commit is contained in:
Jonathan Budzenski 2015-10-16 13:46:33 -05:00
parent 6a3ee68141
commit 95714696fb
8 changed files with 76 additions and 13 deletions

View file

@ -108,6 +108,7 @@
"minimatch": "2.0.10",
"mkdirp": "0.5.1",
"moment": "2.10.6",
"moment-timezone": "^0.4.1",
"raw-loader": "0.5.1",
"request": "2.61.0",
"requirefrom": "0.2.0",
@ -147,6 +148,7 @@
"html-entities": "1.1.3",
"husky": "0.8.1",
"istanbul-instrumenter-loader": "0.1.3",
"json-loader": "^0.5.3",
"karma": "0.13.9",
"karma-chrome-launcher": "0.2.0",
"karma-coverage": "0.5.1",

View file

@ -105,6 +105,7 @@ class BaseOptimizer {
},
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', `css${mapQ}`) },
{ test: /\.jade$/, loader: 'jade' },
{ test: /\.json$/, loader: 'json' },
{ test: /\.(html|tmpl)$/, loader: 'raw' },
{ test: /\.png$/, loader: 'url?limit=10000&name=[path][name].[ext]' },
{ test: /\.(woff|woff2|ttf|eot|svg|ico)(\?|$)/, loader: 'file?name=[path][name].[ext]' },

View file

@ -4,6 +4,8 @@ require('plugins/kibana/dashboard/index');
require('plugins/kibana/settings/index');
require('plugins/kibana/doc/index');
var moment = require('moment-timezone');
var chrome = require('ui/chrome');
var routes = require('ui/routes');
var modules = require('ui/modules');
@ -48,8 +50,15 @@ chrome
}
])
.setRootController('kibana', function ($scope, $rootScope, courier, config) {
function setDefaultTimezone() {
moment.tz.setDefault(config.get('dateFormat:tz'));
}
// wait for the application to finish loading
$scope.$on('application.load', function () {
courier.start();
});
$scope.$on('init:config', setDefaultTimezone);
$scope.$on('change:config.dateFormat:tz', setDefaultTimezone);
});

View file

@ -7,7 +7,9 @@ define(function (require) {
var TimeBuckets = Private(require('ui/time_buckets'));
var createFilter = Private(require('ui/agg_types/buckets/create_filter/date_histogram'));
var intervalOptions = Private(require('ui/agg_types/buckets/_interval_options'));
var timeZone = tzDetect.determine().name();
var configDefaults = Private(require('ui/config/defaults'));
var detectedTimezone = tzDetect.determine().name();
var tzOffset = moment().format('Z');
function getInterval(agg) {
@ -94,7 +96,11 @@ define(function (require) {
var interval = agg.buckets.getInterval();
output.bucketInterval = interval;
output.params.interval = interval.expression;
output.params.time_zone = timeZone || tzOffset;
var isDefaultTimezone = config.get('dateFormat:tz') === configDefaults['dateFormat:tz'].value;
output.params.time_zone = isDefaultTimezone ?
(detectedTimezone || tzOffset) :
config.get('dateFormat:tz');
var scaleMetrics = interval.scaled && interval.scale < 1;
if (scaleMetrics) {

View file

@ -1,4 +1,7 @@
define(function () {
define(function (require) {
var moment = require('moment-timezone');
var _ = require('lodash');
return function configDefaultsProvider() {
// wraped in provider so that a new instance is given to each app/test
@ -20,6 +23,12 @@ define(function () {
value: 'MMMM Do YYYY, HH:mm:ss.SSS',
description: 'When displaying a pretty formatted date, use this format',
},
'dateFormat:tz': {
value: 'Default',
description: 'Which timezone should be used. "Default" will use your detected timezone.',
type: 'select',
options: _.union(['Default'], moment.tz.names())
},
'dateFormat:scaled': {
type: 'json',
value:

View file

@ -1,20 +1,47 @@
describe('Date Format', function () {
var fieldFormats;
var expect = require('expect.js');
var ngMock = require('ngMock');
var moment = require('moment-timezone');
var fieldFormats;
var settings;
var convert;
var $scope;
var off;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
beforeEach(ngMock.inject(function (Private, config, $rootScope) {
$scope = $rootScope;
settings = config;
fieldFormats = Private(require('ui/registry/field_formats'));
var DateFormat = fieldFormats.getType('date');
var date = new DateFormat();
convert = date.convert.bind(date);
}));
it('decoding an undefined or null date should return an empty string', function () {
var DateFormat = fieldFormats.getType('date');
var date = new DateFormat({
pattern: 'dd-MM-yyyy'
});
expect(date.convert(null)).to.be('-');
expect(date.convert(undefined)).to.be('-');
expect(convert(null)).to.be('-');
expect(convert(undefined)).to.be('-');
});
it('should clear the memoization cache after changing the date', function () {
function setDefaultTimezone() {
moment.tz.setDefault(settings.get('dateFormat:tz'));
}
var time = 1445027693942;
off = $scope.$on('change:config.dateFormat:tz', setDefaultTimezone);
settings.set('dateFormat:tz', 'America/Chicago');
$scope.$digest();
var chicagoTime = convert(time);
settings.set('dateFormat:tz', 'America/Phoenix');
$scope.$digest();
var phoenixTime = convert(time);
expect(chicagoTime).not.to.equal(phoenixTime);
off();
});
});

View file

@ -17,7 +17,8 @@ define(function (require) {
DateTime.fieldType = 'date';
DateTime.paramDefaults = new BoundToConfigObj({
pattern: '=dateFormat'
pattern: '=dateFormat',
timezone: '=dateFormat:tz'
});
DateTime.editor = {
@ -41,9 +42,14 @@ define(function (require) {
// don't give away our ref to converter so
// we can hot-swap when config changes
var pattern = this.param('pattern');
var timezone = this.param('timezone');
if (this._memoizedPattern !== pattern) {
var timezoneChanged = this._timeZone !== timezone;
var datePatternChanged = this._memoizedPattern !== pattern;
if (timezoneChanged || datePatternChanged) {
this._timeZone = timezone;
this._memoizedPattern = pattern;
this._memoizedConverter = _.memoize(function converter(val) {
if (val === null || val === undefined) {
return '-';
@ -51,6 +57,7 @@ define(function (require) {
return moment(val).format(pattern);
});
}
return this._memoizedConverter(val);
};

View file

@ -0,0 +1,2 @@
var moment = module.exports = require('../node_modules/moment-timezone/moment-timezone');
moment.tz.load(require('../node_modules/moment-timezone/data/packed/latest.json'));