Fixes #3018: Times in ticket history are displayed in UTC
This commit is contained in:
parent
3d86eb8543
commit
0fb4c1234e
5 changed files with 177 additions and 3 deletions
|
@ -83,7 +83,7 @@ class App.GenericHistory extends App.ControllerModal
|
||||||
else
|
else
|
||||||
content = "#{ @T( item.type ) } #{ @T(item.object) } "
|
content = "#{ @T( item.type ) } #{ @T(item.object) } "
|
||||||
if item.attribute
|
if item.attribute
|
||||||
content += "#{ @T(item.attribute) }"
|
content += "#{ @translateItemAttribute(item) }"
|
||||||
|
|
||||||
# convert time stamps
|
# convert time stamps
|
||||||
if item.object is 'User' && item.attribute is 'last_login'
|
if item.object is 'User' && item.attribute is 'last_login'
|
||||||
|
@ -95,12 +95,12 @@ class App.GenericHistory extends App.ControllerModal
|
||||||
if item.value_from
|
if item.value_from
|
||||||
if item.value_to
|
if item.value_to
|
||||||
content += " #{ @T( 'from' ) }"
|
content += " #{ @T( 'from' ) }"
|
||||||
content += " '#{ App.Utils.htmlEscape(item.value_from) }'"
|
content += " '#{ @translateItemValue(item, item.value_from) }'"
|
||||||
|
|
||||||
if item.value_to
|
if item.value_to
|
||||||
if item.value_from
|
if item.value_from
|
||||||
content += ' →'
|
content += ' →'
|
||||||
content += " '#{ App.Utils.htmlEscape(item.value_to) }'"
|
content += " '#{ @translateItemValue(item, item.value_to) }'"
|
||||||
else if item.value_from
|
else if item.value_from
|
||||||
content += " → '-'"
|
content += " → '-'"
|
||||||
|
|
||||||
|
@ -110,3 +110,28 @@ class App.GenericHistory extends App.ControllerModal
|
||||||
newItems.push newItem
|
newItems.push newItem
|
||||||
|
|
||||||
newItems
|
newItems
|
||||||
|
|
||||||
|
translateItemValue: ({object, attribute}, value) ->
|
||||||
|
localAttribute = @objectAttribute(object, attribute)
|
||||||
|
if localAttribute && localAttribute.tag is 'datetime'
|
||||||
|
return App.i18n.translateTimestamp(value)
|
||||||
|
|
||||||
|
if /_(time|at)$/.test(attribute)
|
||||||
|
return App.i18n.translateTimestamp(value)
|
||||||
|
|
||||||
|
if localAttribute && localAttribute.translate is true
|
||||||
|
return @T(value)
|
||||||
|
|
||||||
|
App.Utils.htmlEscape(value)
|
||||||
|
|
||||||
|
translateItemAttribute: ({object, attribute}) ->
|
||||||
|
localAttribute = @objectAttribute(object, attribute)
|
||||||
|
if localAttribute && localAttribute.display
|
||||||
|
return @T(localAttribute.display)
|
||||||
|
|
||||||
|
@T(attribute)
|
||||||
|
|
||||||
|
objectAttribute: (object, attribute) ->
|
||||||
|
return if !App[object]
|
||||||
|
return if !App[object].attributesGet()
|
||||||
|
App[object].attributesGet()["#{attribute}_id"] || App[object].attributesGet()[attribute]
|
||||||
|
|
|
@ -365,6 +365,11 @@ class _i18nSingleton extends Spine.Module
|
||||||
return time if !time
|
return time if !time
|
||||||
@convert(time, offset, @mapTime['timestamp'] || @timestampFormat)
|
@convert(time, offset, @mapTime['timestamp'] || @timestampFormat)
|
||||||
|
|
||||||
|
convertUTC: (time) ->
|
||||||
|
timeArray = time.match(/\d+/g)
|
||||||
|
[y, m, d, H, M] = timeArray
|
||||||
|
new Date(Date.UTC(y, m - 1, d, H, M))
|
||||||
|
|
||||||
formatNumber: (num, digits) ->
|
formatNumber: (num, digits) ->
|
||||||
while num.toString().length < digits
|
while num.toString().length < digits
|
||||||
num = '0' + num
|
num = '0' + num
|
||||||
|
@ -374,6 +379,13 @@ class _i18nSingleton extends Spine.Module
|
||||||
|
|
||||||
timeObject = new Date(time)
|
timeObject = new Date(time)
|
||||||
|
|
||||||
|
# On firefox the Date constructor does not recongise date format that
|
||||||
|
# ends with UTC, instead it returns a NaN (Invalid Date Format) this
|
||||||
|
# block serves as polyfill to support time format that ends UTC in firefox
|
||||||
|
if isNaN(timeObject)
|
||||||
|
# works for only time string with this format: 2021-02-08 09:13:20 UTC
|
||||||
|
timeObject = @convertUTC(time) if time.match(/ UTC/)
|
||||||
|
|
||||||
# add timezone diff, needed for unit tests
|
# add timezone diff, needed for unit tests
|
||||||
if offset
|
if offset
|
||||||
timeObject = new Date(timeObject.getTime() + (timeObject.getTimezoneOffset() * 60000))
|
timeObject = new Date(timeObject.getTime() + (timeObject.getTimezoneOffset() * 60000))
|
||||||
|
|
|
@ -114,6 +114,9 @@ test('i18n .detectBrowserLocale', function() {
|
||||||
var timestamp = App.i18n.translateTimestamp('2012-11-06T21:07:24Z', offset);
|
var timestamp = App.i18n.translateTimestamp('2012-11-06T21:07:24Z', offset);
|
||||||
equal(timestamp, '06.11.2012 21:07', 'de-de - timestamp translated correctly')
|
equal(timestamp, '06.11.2012 21:07', 'de-de - timestamp translated correctly')
|
||||||
|
|
||||||
|
var timestamp = App.i18n.translateTimestamp('2021-02-08 09:13:20 UTC', offset);
|
||||||
|
equal(timestamp, '08.02.2021 09:13', 'de-de - timestamp translated correctly with UTC format')
|
||||||
|
|
||||||
timestamp = App.i18n.translateTimestamp('', offset);
|
timestamp = App.i18n.translateTimestamp('', offset);
|
||||||
equal(timestamp, '', 'de-de - timestamp translated correctly')
|
equal(timestamp, '', 'de-de - timestamp translated correctly')
|
||||||
|
|
||||||
|
|
81
spec/system/ticket/history_spec.rb
Normal file
81
spec/system/ticket/history_spec.rb
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Ticket history', type: :system, authenticated_as: true, time_zone: 'Europe/London' do
|
||||||
|
let(:group) { Group.find_by(name: 'Users') }
|
||||||
|
let(:ticket) { create(:ticket, group: group) }
|
||||||
|
let!(:session_user) { User.find_by(login: 'master@example.com') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
freeze_time
|
||||||
|
|
||||||
|
travel_to DateTime.parse('2021-01-22 13:40:00 UTC')
|
||||||
|
current_time = Time.current
|
||||||
|
ticket.update(title: 'New Ticket Title')
|
||||||
|
ticket_article = create(:ticket_article, ticket: ticket, internal: true)
|
||||||
|
ticket.update! state: Ticket::State.lookup(name: 'open')
|
||||||
|
ticket.update! last_owner_update_at: current_time
|
||||||
|
ticket.update! priority: Ticket::Priority.lookup(name: '1 low')
|
||||||
|
ticket.update! last_contact_at: current_time
|
||||||
|
ticket.update! last_contact_customer_at: current_time
|
||||||
|
ticket.update! last_contact_agent_at: current_time
|
||||||
|
ticket_article.update! internal: false
|
||||||
|
|
||||||
|
travel_to DateTime.parse('2021-04-06 23:30:00 UTC')
|
||||||
|
current_time = Time.current
|
||||||
|
ticket.update! state: Ticket::State.lookup(name: 'pending close')
|
||||||
|
ticket.update! priority: Ticket::Priority.lookup(name: '3 high')
|
||||||
|
ticket_article.update! internal: true
|
||||||
|
ticket.update! last_contact_at: current_time
|
||||||
|
ticket.update! last_contact_customer_at: current_time
|
||||||
|
ticket.update! last_contact_agent_at: current_time
|
||||||
|
ticket.update! pending_time: current_time
|
||||||
|
ticket.update! first_response_escalation_at: current_time
|
||||||
|
|
||||||
|
travel_back
|
||||||
|
|
||||||
|
session_user.preferences[:locale] = 'de-de'
|
||||||
|
session_user.save!
|
||||||
|
|
||||||
|
refresh
|
||||||
|
|
||||||
|
visit "#ticket/zoom/#{ticket.id}"
|
||||||
|
find('[data-tab="ticket"] .js-actions').click
|
||||||
|
click('[data-type="ticket-history"]')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "translates timestamp when attribute's tag is datetime" do
|
||||||
|
expect(page).to have_css('li', text: /22.01.2021 13:40/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not include time with UTC format' do
|
||||||
|
expect(page).to have_no_text(/ UTC/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates value when attribute is state' do
|
||||||
|
expect(page).to have_css('li', text: /Ticket Status von 'neu'/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates value when attribute is priority' do
|
||||||
|
expect(page).to have_css('li', text: /Ticket Priorität von '1 niedrig'/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates value when attribute is internal' do
|
||||||
|
expect(page).to have_css('li', text: /Artikel intern von 'true'/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates last_contact_at display attribute' do
|
||||||
|
expect(page).to have_css('li', text: /Ticket Letzter Kontakt von '22.01.2021 13:40' → '07.04.2021 00:30'/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates last_contact_customer_at display attribute' do
|
||||||
|
expect(page).to have_css('li', text: /Ticket Letzter Kontakt \(Kunde\) von '22.01.2021 13:40' → '07.04.2021 00:30'/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates last_contact_agent_at display attribute' do
|
||||||
|
expect(page).to have_css('li', text: /Ticket Letzter Kontakt \(Agent\) von '22.01.2021 13:40' → '07.04.2021 00:30'/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates pending_time display attribute' do
|
||||||
|
expect(page).to have_css('li', text: /Ticket Warten bis '07.04.2021 00:30'/)
|
||||||
|
end
|
||||||
|
end
|
53
spec/system/user/history_spec.rb
Normal file
53
spec/system/user/history_spec.rb
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Ticket history', type: :system, authenticated_as: true, time_zone: 'Europe/London' do
|
||||||
|
let(:group) { Group.find_by(name: 'Users') }
|
||||||
|
let(:customer) { create(:customer) }
|
||||||
|
let!(:session_user) { User.find_by(login: 'master@example.com') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
freeze_time
|
||||||
|
|
||||||
|
travel_to DateTime.parse('2021-01-22 13:40:00 UTC')
|
||||||
|
current_time = Time.current
|
||||||
|
customer.update! firstname: 'Customer'
|
||||||
|
customer.update! email: 'test@example.com'
|
||||||
|
customer.update! country: 'Germany'
|
||||||
|
customer.update! out_of_office_start_at: current_time
|
||||||
|
customer.update! last_login: current_time
|
||||||
|
|
||||||
|
travel_to DateTime.parse('2021-04-06 23:30:00 UTC')
|
||||||
|
current_time = Time.current
|
||||||
|
customer.update! lastname: 'Example'
|
||||||
|
customer.update! mobile: '5757473827'
|
||||||
|
customer.update! out_of_office_end_at: current_time
|
||||||
|
customer.update! last_login: current_time
|
||||||
|
|
||||||
|
travel_back
|
||||||
|
|
||||||
|
session_user.preferences[:locale] = 'de-de'
|
||||||
|
session_user.save!
|
||||||
|
|
||||||
|
refresh
|
||||||
|
|
||||||
|
visit "#user/profile/#{customer.id}"
|
||||||
|
find('#userAction').click
|
||||||
|
click('[data-type="history"]')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "translates timestamp when attribute's tag is datetime" do
|
||||||
|
expect(page).to have_css('li', text: /'22.01.2021 00:00'/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not include time with UTC format' do
|
||||||
|
expect(page).to have_no_text(/ UTC/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates out_of_office_start_at value to time stamp' do
|
||||||
|
expect(page).to have_css('li', text: /Benutzer out_of_office_start_at '22.01.2021 00:00'/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'translates out_of_office_end_at value to time stamp' do
|
||||||
|
expect(page).to have_css('li', text: /Benutzer out_of_office_end_at '06.04.2021 01:00'/)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue