AgularJS pages display dates using Horizon's Settings Timezone
Horizon's AngularJS pages (for example Images and Keypairs) display dates using browser's timezone now. This change makes AngularJS pages use Horizon's Settings Timezone instead of browser's timezone and if Timezone is not set under Settings, AngularJS pages will display dates in 'UTC' timezone. Closes-Bug: 1832768 Change-Id: Ibbed19600bfe6b13c43b9f09fa484cb78524b0d6
This commit is contained in:
parent
85a1dddf12
commit
a464a94655
@ -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…
x
Reference in New Issue
Block a user