Improved pretty time.
This commit is contained in:
parent
fefb728954
commit
0a96e8b421
9 changed files with 221 additions and 87 deletions
|
@ -151,32 +151,6 @@ class App.Controller extends Spine.Controller
|
|||
formValidate: (data) ->
|
||||
App.ControllerForm.validate(data)
|
||||
|
||||
ticketTableAttributes: (attributes) =>
|
||||
all_attributes = [
|
||||
{ name: 'number', type: 'link', title: 'title', dataType: 'edit' },
|
||||
{ name: 'title', type: 'link', title: 'title', dataType: 'edit' },
|
||||
{ name: 'customer', class: 'user-popover', data: { id: true } },
|
||||
{ name: 'state', translate: true, title: true },
|
||||
{ name: 'priority', translate: true, title: true },
|
||||
{ name: 'group', title: 'group' },
|
||||
{ name: 'owner', class: 'user-popover', data: { id: true } },
|
||||
{ name: 'created_at', callback: @frontendTime },
|
||||
{ name: 'last_contact', callback: @frontendTime },
|
||||
{ name: 'last_contact_agent', callback: @frontendTime },
|
||||
{ name: 'last_contact_customer', callback: @frontendTime },
|
||||
{ name: 'first_response', callback: @frontendTime },
|
||||
{ name: 'close_time', callback: @frontendTime },
|
||||
{ name: 'escalation_time', callback: @frontendTime, subclass: 'escalation' },
|
||||
{ name: 'article_count', },
|
||||
]
|
||||
shown_all_attributes = []
|
||||
for all_attribute in all_attributes
|
||||
for attribute in attributes
|
||||
if all_attribute['name'] is attribute
|
||||
shown_all_attributes.push all_attribute
|
||||
break
|
||||
return shown_all_attributes
|
||||
|
||||
# redirectToLogin: (data) ->
|
||||
#
|
||||
|
||||
|
@ -188,66 +162,11 @@ class App.Controller extends Spine.Controller
|
|||
size = Math.round( size / 1024 ) + ' KBytes'
|
||||
else
|
||||
size = size + ' Bytes'
|
||||
return size
|
||||
size
|
||||
|
||||
# human readable time
|
||||
humanTime: ( time, escalation ) =>
|
||||
current = new Date()
|
||||
created = new Date(time)
|
||||
string = ''
|
||||
diff = ( current - created ) / 1000
|
||||
escalated = ''
|
||||
if escalation
|
||||
if diff > 0
|
||||
escalated = '-'
|
||||
if diff >= 0
|
||||
style = "class=\"label label-danger\""
|
||||
else if diff > -60 * 60
|
||||
style = "class=\"label label-warning\""
|
||||
else
|
||||
style = "class=\"label label-success\""
|
||||
|
||||
if diff.toString().match('-')
|
||||
diff = diff.toString().replace('-', '')
|
||||
diff = parseFloat(diff)
|
||||
|
||||
if diff >= 86400
|
||||
unit = Math.floor( ( diff / 86400 ) )
|
||||
# if unit > 1
|
||||
# return unit + ' ' + App.i18n.translateContent('days')
|
||||
# else
|
||||
# return unit + ' ' + App.i18n.translateContent('day')
|
||||
string = unit + ' ' + App.i18n.translateInline('d')
|
||||
if diff >= 3600
|
||||
unit = Math.floor( ( diff / 3600 ) % 24 )
|
||||
# if unit > 1
|
||||
# return unit + ' ' + App.i18n.translateContent('hours')
|
||||
# else
|
||||
# return unit + ' ' + App.i18n.translateContent('hour')
|
||||
if string isnt ''
|
||||
string = string + ' ' + unit + ' ' + App.i18n.translateInline('h')
|
||||
if escalation
|
||||
string = "<span #{style}>#{escalated}#{string}</b>"
|
||||
return string
|
||||
else
|
||||
string = unit + ' ' + App.i18n.translateInline('h')
|
||||
if diff <= 86400
|
||||
unit = Math.floor( ( diff / 60 ) % 60 )
|
||||
# if unit > 1
|
||||
# return unit + ' ' + App.i18n.translateContent('minutes')
|
||||
# else
|
||||
# return unit + ' ' + App.i18n.translateContent('minute')
|
||||
if string isnt ''
|
||||
string = string + ' ' + unit + ' ' + App.i18n.translateInline('m')
|
||||
if escalation
|
||||
string = "<span #{style}>#{escalated}#{string}</b>"
|
||||
return string
|
||||
else
|
||||
string = unit + ' ' + App.i18n.translateInline('m')
|
||||
|
||||
if escalation
|
||||
string = "<span #{style}>#{escalated}#{string}</b>"
|
||||
return string
|
||||
humanTime: ( time, escalation, long = true ) =>
|
||||
App.PrettyDate.humanTime( time, escalation, long )
|
||||
|
||||
userInfo: (data) =>
|
||||
el = data.el || $('[data-id="customer_info"]')
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
class App.PrettyDate
|
||||
|
||||
# human readable time
|
||||
@humanTime: ( time, escalation, long = true ) =>
|
||||
return '' if !time
|
||||
current = new Date()
|
||||
created = new Date(time)
|
||||
diff = ( current - created ) / 1000
|
||||
|
||||
escalated = ''
|
||||
if escalation
|
||||
if diff > 0
|
||||
escalated = '-'
|
||||
if diff >= 0
|
||||
style = "class=\"label label-danger\""
|
||||
else if diff > -60 * 60
|
||||
style = "class=\"label label-warning\""
|
||||
else
|
||||
style = "class=\"label label-success\""
|
||||
|
||||
# remember past/future
|
||||
direction = 'future'
|
||||
if diff > -1
|
||||
direction = 'past'
|
||||
|
||||
# strip not longer needed -
|
||||
if diff.toString().match('-')
|
||||
diff = diff.toString().replace('-', '')
|
||||
diff = parseFloat(diff)
|
||||
|
||||
# days
|
||||
string = ''
|
||||
count = 0
|
||||
if diff >= 86400
|
||||
count++
|
||||
unit = Math.floor( ( diff / 86400 ) )
|
||||
day = App.i18n.translateInline('d')
|
||||
if long
|
||||
if unit > 1 || unit is 0
|
||||
day = App.i18n.translateContent('days')
|
||||
else
|
||||
day = App.i18n.translateContent('day')
|
||||
string = unit + ' ' + day
|
||||
diff = diff - ( unit * 86400 )
|
||||
if unit >= 9 || diff < 3600 || count is 2
|
||||
if direction is 'past'
|
||||
string = App.i18n.translateInline('%s ago', string)
|
||||
else
|
||||
string = App.i18n.translateInline('in %s', string)
|
||||
if escalation
|
||||
string = "<span #{style}>#{string}</b>"
|
||||
return string
|
||||
|
||||
# hours
|
||||
if diff >= 3600
|
||||
count++
|
||||
unit = Math.floor( ( diff / 3600 ) % 24 )
|
||||
hour = App.i18n.translateInline('h')
|
||||
if long
|
||||
if unit > 1 || unit is 0
|
||||
hour = App.i18n.translateInline('hours')
|
||||
else
|
||||
hour = App.i18n.translateInline('hour')
|
||||
if string isnt ''
|
||||
string = string + ' '
|
||||
string = string + unit + ' ' + hour
|
||||
diff = diff - ( unit * 3600 )
|
||||
if unit >= 9 || diff < 60 || count is 2
|
||||
if direction is 'past'
|
||||
string = App.i18n.translateInline('%s ago', string)
|
||||
else
|
||||
string = App.i18n.translateInline('in %s', string)
|
||||
if escalation
|
||||
string = "<span #{style}>#{string}</b>"
|
||||
return string
|
||||
|
||||
# minutes
|
||||
unit = Math.floor( ( diff / 60 ) % 60 )
|
||||
minute = App.i18n.translateInline('m')
|
||||
if long
|
||||
if unit > 1 || unit is 0
|
||||
minute = App.i18n.translateContent('minutes')
|
||||
else
|
||||
minute = App.i18n.translateContent('minute')
|
||||
if string isnt ''
|
||||
string = string + ' '
|
||||
string = string + unit + ' ' + minute
|
||||
if direction is 'past'
|
||||
string = App.i18n.translateInline('%s ago', string)
|
||||
else
|
||||
string = App.i18n.translateInline('in %s', string)
|
||||
if escalation
|
||||
string = "<span #{style}>#{string}</b>"
|
||||
return string
|
|
@ -9,6 +9,13 @@ class TestsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# GET /tests/ui
|
||||
def ui
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
# GET /tests/from
|
||||
def form
|
||||
respond_to do |format|
|
||||
|
|
|
@ -20,5 +20,3 @@ body {
|
|||
<button type="submit" class="btn btn-primary submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
15
app/views/tests/ui.html.erb
Normal file
15
app/views/tests/ui.html.erb
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
<link rel="stylesheet" href="/assets/tests/qunit-1.10.0.css">
|
||||
<script src="/assets/tests/qunit-1.10.0.js"></script>
|
||||
<script src="/assets/tests/ui.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
<div id="qunit"></div>
|
|
@ -1,6 +1,7 @@
|
|||
Zammad::Application.routes.draw do
|
||||
|
||||
match '/tests-core', :to => 'tests#core', :via => :get
|
||||
match '/tests-ui', :to => 'tests#ui', :via => :get
|
||||
match '/tests-form', :to => 'tests#form', :via => :get
|
||||
match '/tests-table', :to => 'tests#table', :via => :get
|
||||
match '/tests/wait/:sec', :to => 'tests#wait', :via => :get
|
||||
|
|
|
@ -1700,7 +1700,7 @@ Translation.create_if_not_exists( :locale => 'de', :source => "Close time", :tar
|
|||
Translation.create_if_not_exists( :locale => 'de', :source => "First response", :target => "Erste Reaktion" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Ticket %s created!", :target => "Ticket %s erstellt!" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "day", :target => "Tag" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "days", :target => "Tage" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "days", :target => "Tagen" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "hour", :target => "Stunde" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "hours", :target => "Stunden" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "minute", :target => "Minute" )
|
||||
|
@ -1864,6 +1864,8 @@ Translation.create_if_not_exists( :locale => 'de', :source => "Here you can crea
|
|||
Translation.create_if_not_exists( :locale => 'de', :source => "Fold in", :target => "Einklappen" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "from", :target => "von" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "to", :target => "nach" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "%s ago", :target => "vor %s" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "in %s", :target => "in %s" )
|
||||
#Translation.create_if_not_exists( :locale => 'de', :source => "", :target => "" )
|
||||
|
||||
# install all packages in auto_install
|
||||
|
|
76
public/assets/tests/ui.js
Normal file
76
public/assets/tests/ui.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
|
||||
// pretty date
|
||||
test( "check pretty date", function() {
|
||||
var current = new Date()
|
||||
|
||||
// past
|
||||
var result = App.PrettyDate.humanTime( current );
|
||||
equal( result, '0 minutes ago', 'right now')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - 60000 );
|
||||
equal( result, '1 minute ago', '1 min ago')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 2 * 60000 ) );
|
||||
equal( result, '2 minutes ago', '2 min ago')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 ) ) ;
|
||||
equal( result, '1 hour ago', '1 hour')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 2 ) );
|
||||
equal( result, '2 hours ago', '2 hours')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 2.5 ) );
|
||||
equal( result, '2 hours 30 minutes ago', '2.5 hours')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 12.5 ) );
|
||||
equal( result, '12 hours ago', '12.5 hours')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 24 ) ) ;
|
||||
equal( result, '1 day ago', '1 day')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 24 * 2 ) );
|
||||
equal( result, '2 days ago', '2 days')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 24 * 2 ) - ( 60000 * 5 ) );
|
||||
equal( result, '2 days ago', '2 days')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 24 * 2.5 ) );
|
||||
equal( result, '2 days 12 hours ago', '2.5 days')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 24 * 2.5 ) - ( 60000 * 5 ) );
|
||||
equal( result, '2 days 12 hours ago', '2.5 days')
|
||||
|
||||
result = App.PrettyDate.humanTime( current - ( 60000 * 60 * 24 * 10.5 ) );
|
||||
equal( result, '10 days ago', '10.5 days')
|
||||
|
||||
// future
|
||||
current = new Date()
|
||||
result = App.PrettyDate.humanTime( current );
|
||||
equal( result, '0 minutes ago', 'right now')
|
||||
|
||||
result = App.PrettyDate.humanTime( current.getTime() + 65000 );
|
||||
equal( result, 'in 1 minute', 'in 1 min')
|
||||
|
||||
result = App.PrettyDate.humanTime( current.getTime() + ( 2 * 65000 ) );
|
||||
equal( result, 'in 2 minutes', 'in 2 min')
|
||||
|
||||
result = App.PrettyDate.humanTime( current.getTime() + ( 60500 * 60 ) ) ;
|
||||
equal( result, 'in 1 hour', 'in 1 hour')
|
||||
|
||||
result = App.PrettyDate.humanTime( current.getTime() + ( 60050 * 60 * 2 ) );
|
||||
equal( result, 'in 2 hours', 'in 2 hours')
|
||||
|
||||
result = App.PrettyDate.humanTime( current.getTime() + ( 60050 * 60 * 2.5 ) );
|
||||
equal( result, 'in 2 hours 30 minutes', 'in 2.5 hours')
|
||||
|
||||
result = App.PrettyDate.humanTime( current.getTime() + ( 60050 * 60 * 24 ) ) ;
|
||||
equal( result, 'in 1 day', 'in 1 day')
|
||||
|
||||
result = App.PrettyDate.humanTime( current.getTime() + ( 60050 * 60 * 24 * 2 ) );
|
||||
equal( result, 'in 2 days', 'in 2 days')
|
||||
|
||||
result = App.PrettyDate.humanTime( current.getTime() + ( 60050 * 60 * 24 * 2.5 ) );
|
||||
equal( result, 'in 2 days 12 hours', 'in 2.5 days')
|
||||
|
||||
|
||||
});
|
|
@ -24,6 +24,28 @@ class AAbUnitTest < TestCase
|
|||
]
|
||||
browser_single_test(tests)
|
||||
end
|
||||
def test_ui
|
||||
tests = [
|
||||
{
|
||||
:name => 'start',
|
||||
:instance => browser_instance,
|
||||
:url => browser_url + '/tests-ui',
|
||||
:action => [
|
||||
{
|
||||
:execute => 'wait',
|
||||
:value => 8,
|
||||
},
|
||||
{
|
||||
:execute => 'match',
|
||||
:css => '.result .failed',
|
||||
:value => '0',
|
||||
:match_result => true,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
browser_single_test(tests)
|
||||
end
|
||||
def test_form
|
||||
tests = [
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue