Merge "AgularJS pages display dates using Horizon's Settings Timezone"
This commit is contained in:
commit
bd5642dc73
@ -17,7 +17,7 @@
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.framework.util.filters')
|
||||
.module('horizon.framework.util.filters', ['ngCookies'])
|
||||
.filter('yesno', yesNoFilter)
|
||||
.filter('simpleDate', simpleDateFilter)
|
||||
.filter('mediumDate', mediumDateFilter)
|
||||
@ -53,10 +53,18 @@
|
||||
* @description
|
||||
* Evaluates given for display as a short date, returning '-' if empty.
|
||||
*/
|
||||
simpleDateFilter.$inject = ['$filter'];
|
||||
function simpleDateFilter($filter) {
|
||||
simpleDateFilter.$inject = [
|
||||
'$cookies',
|
||||
'$filter',
|
||||
'horizon.framework.util.timezones.service'
|
||||
];
|
||||
function simpleDateFilter($cookies, $filter, timeZoneService) {
|
||||
return function (input) {
|
||||
return $filter('noValue')($filter('date')(input, 'short'));
|
||||
var currentTimeZone = $cookies.get('django_timezone') || 'UTC';
|
||||
currentTimeZone = currentTimeZone.replace(/^"(.*)"$/, '$1');
|
||||
return timeZoneService.getTimeZoneOffset(currentTimeZone).then(function (timeZoneOffset) {
|
||||
return $filter('noValue')($filter('date')(input, 'short', timeZoneOffset));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -66,10 +74,23 @@
|
||||
* @description
|
||||
* Evaluates given for display as a medium date, returning '-' if empty.
|
||||
*/
|
||||
mediumDateFilter.$inject = ['$filter'];
|
||||
function mediumDateFilter($filter) {
|
||||
mediumDateFilter.$inject = [
|
||||
'$cookies',
|
||||
'$filter',
|
||||
'horizon.framework.util.timezones.service'
|
||||
];
|
||||
function mediumDateFilter($cookies, $filter, timeZoneService) {
|
||||
return function (input) {
|
||||
return $filter('noValue')($filter('date')(input, 'medium'));
|
||||
/*
|
||||
* For the input time, we need to add "Z" to fit iso8601 time format
|
||||
* so the filter can confirm that the input time is in UTC timezone.
|
||||
*/
|
||||
input = input + 'Z';
|
||||
var currentTimeZone = $cookies.get('django_timezone') || 'UTC';
|
||||
currentTimeZone = currentTimeZone.replace(/^"(.*)"$/, '$1');
|
||||
return timeZoneService.getTimeZoneOffset(currentTimeZone).then(function (timeZoneOffset) {
|
||||
return $filter('noValue')($filter('date')(input, 'medium', timeZoneOffset));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -59,11 +59,19 @@
|
||||
}));
|
||||
|
||||
it('returns blank if nothing', function () {
|
||||
expect(simpleDateFilter()).toBe('-');
|
||||
simpleDateFilter().then(getResult);
|
||||
|
||||
function getResult(result) {
|
||||
expect(result).toBe('-');
|
||||
}
|
||||
});
|
||||
|
||||
it('returns the expected time', function() {
|
||||
expect(simpleDateFilter('2016-06-24T04:19:07')).toBe('6/24/16 4:19 AM');
|
||||
simpleDateFilter().then(getResult);
|
||||
|
||||
function getResult(result) {
|
||||
expect(result).toBe('9/3/19 9:19 AM');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -74,11 +82,19 @@
|
||||
}));
|
||||
|
||||
it('returns blank if nothing', function () {
|
||||
expect(mediumDateFilter()).toBe('-');
|
||||
mediumDateFilter().then(getResult);
|
||||
|
||||
function getResult(result) {
|
||||
expect(result).toBe('-');
|
||||
}
|
||||
});
|
||||
|
||||
it('returns the expected time', function() {
|
||||
expect(mediumDateFilter('2001-02-03T16:05:06')).toBe('Feb 3, 2001 4:05:06 PM');
|
||||
mediumDateFilter().then(getResult);
|
||||
|
||||
function getResult(result) {
|
||||
expect(result).toBe('Sep 3, 2019 9:19:07 AM');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
74
horizon/static/framework/util/timezones/timezone.service.js
Normal file
74
horizon/static/framework/util/timezones/timezone.service.js
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2019 99Cloud Inc.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.framework.util.timezones', [])
|
||||
.factory('horizon.framework.util.timezones.service', timeZoneService);
|
||||
|
||||
timeZoneService.$inject = [
|
||||
'$q',
|
||||
'horizon.framework.util.http.service'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name timeZoneService
|
||||
* @param {Object} $q
|
||||
* @param {Object} ApiService
|
||||
* @description
|
||||
* Horizon's AngularJS pages(for example Images and Keypairs) display dates
|
||||
* using browser's timezone now. This service get timezone offset from
|
||||
* Horizon's Settings and if Timezone is not set under Settings, AngularJS
|
||||
* pages will display dates in 'UTC' timezone.
|
||||
* @returns {Object} The service
|
||||
*/
|
||||
|
||||
function timeZoneService($q, ApiService) {
|
||||
var service = {
|
||||
getTimeZones: getTimeZones,
|
||||
getTimeZoneOffset: getTimeZoneOffset
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
/////////
|
||||
|
||||
function getTimeZones() {
|
||||
return ApiService.get('/api/timezones/', {cache: true});
|
||||
}
|
||||
|
||||
function getTimeZoneOffset(timezone) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
function onTimezonesLoaded(response) {
|
||||
var offsetDict = response.data.timezone_dict;
|
||||
timezone = timezone || 'UTC';
|
||||
deferred.resolve(offsetDict[timezone]);
|
||||
}
|
||||
|
||||
function onTimezonesFailure(message) {
|
||||
deferred.reject(message);
|
||||
}
|
||||
|
||||
service.getTimeZones()
|
||||
.then(onTimezonesLoaded, onTimezonesFailure);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
}
|
||||
}());
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2019 99Cloud Inc.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
describe('horizon.framework.util.timezones.service', function () {
|
||||
var service;
|
||||
beforeEach(module('horizon.framework'));
|
||||
beforeEach(inject(function($injector) {
|
||||
service = $injector.get('horizon.framework.util.timezones.service');
|
||||
}));
|
||||
|
||||
it('defines the service', function() {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('get timezone offset', function () {
|
||||
|
||||
it('returns +0000(UTC offset) if nothing', function () {
|
||||
function getResult(result) {
|
||||
expect(result).toBe('+0000');
|
||||
}
|
||||
|
||||
service.getTimeZoneOffset().then(getResult);
|
||||
});
|
||||
|
||||
it('returns the timezone offset', function() {
|
||||
|
||||
function getResult(result) {
|
||||
expect(result).toBe('+0800');
|
||||
}
|
||||
|
||||
service.getTimeZoneOffset('Asia/Shanghai').then(getResult);
|
||||
|
||||
});
|
||||
});
|
||||
}); // end of horizon.framework.util.timezones
|
||||
})();
|
||||
|
@ -27,6 +27,7 @@
|
||||
'horizon.framework.util.promise-toggle',
|
||||
'horizon.framework.util.q',
|
||||
'horizon.framework.util.tech-debt',
|
||||
'horizon.framework.util.timezones',
|
||||
'horizon.framework.util.uuid',
|
||||
'horizon.framework.util.workflow',
|
||||
'horizon.framework.util.validators',
|
||||
|
@ -13,8 +13,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import JsonResponse
|
||||
from django.views import generic
|
||||
import pytz
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.api.rest import urls
|
||||
@ -55,3 +59,15 @@ class Settings(generic.View):
|
||||
in settings_allowed if k not in self.SPECIALS}
|
||||
plain_settings.update(self.SPECIALS)
|
||||
return plain_settings
|
||||
|
||||
|
||||
@urls.register
|
||||
class Timezones(generic.View):
|
||||
"""API for timezone service."""
|
||||
url_regex = r'timezones/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
zones = {tz: datetime.now(pytz.timezone(tz)).strftime('%z')
|
||||
for tz in pytz.common_timezones}
|
||||
return JsonResponse({'timezone_dict': zones})
|
||||
|
Loading…
Reference in New Issue
Block a user