Some html and markup improvements for inline translation feature.
This commit is contained in:
parent
d8f5046400
commit
2c93b1c57d
10 changed files with 112 additions and 114 deletions
|
@ -29,13 +29,10 @@ class App.CustomerChat extends App.Controller
|
|||
active_agents: 0
|
||||
|
||||
@render()
|
||||
|
||||
@on 'layout-has-changed', @propagateLayoutChange
|
||||
|
||||
# update navbar on new status
|
||||
@bind(
|
||||
'chat_status_agent'
|
||||
(data) =>
|
||||
@bind('chat_status_agent', (data) =>
|
||||
@meta = data
|
||||
@updateMeta()
|
||||
if !@pushStateStarted
|
||||
|
@ -44,21 +41,27 @@ class App.CustomerChat extends App.Controller
|
|||
)
|
||||
|
||||
# add new chat window
|
||||
@bind(
|
||||
'chat_session_start'
|
||||
(data) =>
|
||||
@bind('chat_session_start', (data) =>
|
||||
if data.session
|
||||
@addChat(data.session)
|
||||
)
|
||||
|
||||
# on new login or on
|
||||
@bind(
|
||||
'ws:login chat_agent_state'
|
||||
->
|
||||
@bind('ws:login chat_agent_state', ->
|
||||
App.WebSocket.send(event:'chat_status_agent')
|
||||
)
|
||||
App.WebSocket.send(event:'chat_status_agent')
|
||||
|
||||
# rerender view, e. g. on langauge change
|
||||
@bind('ui:rerender', =>
|
||||
return if !@authenticate(true)
|
||||
for session_id, chat of @chatWindows
|
||||
chat.el.remove()
|
||||
@chatWindows = {}
|
||||
@render()
|
||||
App.WebSocket.send(event:'chat_status_agent')
|
||||
)
|
||||
|
||||
pushState: =>
|
||||
App.WebSocket.send(
|
||||
event:'chat_agent_state'
|
||||
|
@ -212,23 +215,17 @@ class chatWindow extends App.Controller
|
|||
|
||||
@on 'layout-change', @scrollToBottom
|
||||
|
||||
@bind(
|
||||
'chat_session_typing'
|
||||
(data) =>
|
||||
@bind('chat_session_typing', (data) =>
|
||||
return if data.session_id isnt @session.session_id
|
||||
return if data.self_written
|
||||
@showWritingLoader()
|
||||
)
|
||||
@bind(
|
||||
'chat_session_message'
|
||||
(data) =>
|
||||
@bind('chat_session_message', (data) =>
|
||||
return if data.session_id isnt @session.session_id
|
||||
return if data.self_written
|
||||
@receiveMessage(data.message.content)
|
||||
)
|
||||
@bind(
|
||||
'chat_session_left chat_session_closed'
|
||||
(data) =>
|
||||
@bind('chat_session_left chat_session_closed', (data) =>
|
||||
return if data.session_id isnt @session.session_id
|
||||
return if data.self_written
|
||||
@addStatusMessage("<strong>#{data.realname}</strong> has left the conversation")
|
||||
|
@ -401,7 +398,7 @@ class chatWindow extends App.Controller
|
|||
timestamp = Date.now()
|
||||
|
||||
if !@lastTimestamp or timestamp - @lastTimestamp > @showTimeEveryXMinutes * 60000
|
||||
label = App.i18n.translateContent('today')
|
||||
label = App.i18n.translateInline('today')
|
||||
time = new Date().toTimeString().substr(0,5)
|
||||
if @lastAddedType is 'timestamp'
|
||||
# update last time
|
||||
|
|
|
@ -95,10 +95,9 @@ class _i18nSingleton extends Spine.Module
|
|||
$this = $(e.target)
|
||||
$this.data 'before', $this.html()
|
||||
return $this
|
||||
# .delegate '.translation', 'blur keyup paste', (e) =>
|
||||
.delegate '.translation', 'blur', (e) =>
|
||||
$this = $(e.target)
|
||||
source = $this.attr('data-text')
|
||||
source = $this.attr('title')
|
||||
|
||||
# get new translation
|
||||
translation_new = $this.html()
|
||||
|
@ -117,7 +116,7 @@ class _i18nSingleton extends Spine.Module
|
|||
@mapString[source] = translation_new
|
||||
|
||||
# replace rest in page
|
||||
$(".translation[data-text='#{source}']").html( translation_new )
|
||||
$(".translation[title='#{source}']").html(translation_new)
|
||||
|
||||
# update permanent translation mapString
|
||||
translation = App.Translation.findByAttribute('source', source)
|
||||
|
@ -126,9 +125,9 @@ class _i18nSingleton extends Spine.Module
|
|||
else
|
||||
translation = new App.Translation
|
||||
translation.load(
|
||||
locale: @locale,
|
||||
source: source,
|
||||
target: translation_new,
|
||||
locale: @locale
|
||||
source: source
|
||||
target: translation_new
|
||||
)
|
||||
translation.save()
|
||||
|
||||
|
@ -224,15 +223,10 @@ class _i18nSingleton extends Spine.Module
|
|||
App.Utils.htmlEscape(@translate(string, args))
|
||||
|
||||
translateContent: (string, args) =>
|
||||
translated = App.Utils.htmlEscape( @translate( string, args ) )
|
||||
# replace = '<span class="translation" contenteditable="true" data-text="' + App.Utils.htmlEscape(string) + '">' + translated + '<span class="icon-edit"></span>'
|
||||
if App.Config.get('translation_inline')
|
||||
replace = '<span class="translation" contenteditable="true" data-text="' + App.Utils.htmlEscape(string) + '">' + translated + ''
|
||||
# if !@_translated
|
||||
# replace += '<span class="missing">XX</span>'
|
||||
replace += '</span>'
|
||||
else
|
||||
translated
|
||||
return '<span class="translation" contenteditable="true" title="' + App.Utils.htmlEscape(string) + '">' + App.Utils.htmlEscape(@translate(string)) + '</span>'
|
||||
|
||||
translated = App.Utils.htmlEscape(@translate(string, args))
|
||||
|
||||
translatePlain: (string, args) =>
|
||||
@translate(string, args)
|
||||
|
@ -265,13 +259,14 @@ class _i18nSingleton extends Spine.Module
|
|||
@_notTranslated[@locale][string] = true
|
||||
|
||||
# search %s
|
||||
if args
|
||||
for arg in args
|
||||
translated = translated.replace(/%s/, arg)
|
||||
|
||||
@log 'debug', 'translate', string, args, translated
|
||||
|
||||
# return translated string
|
||||
return translated
|
||||
translated
|
||||
|
||||
meta: =>
|
||||
@mapMeta
|
||||
|
@ -328,4 +323,4 @@ class _i18nSingleton extends Spine.Module
|
|||
format = format.replace /SS/, s(S, 2)
|
||||
format = format.replace /MM/, s(M, 2)
|
||||
format = format.replace /HH/, s(H, 2)
|
||||
return format
|
||||
format
|
||||
|
|
|
@ -41,9 +41,9 @@ class App.PrettyDate
|
|||
day = App.i18n.translateInline('d')
|
||||
if long
|
||||
if unit > 1 || unit is 0
|
||||
day = App.i18n.translateContent('days')
|
||||
day = App.i18n.translateInline('days')
|
||||
else
|
||||
day = App.i18n.translateContent('day')
|
||||
day = App.i18n.translateInline('day')
|
||||
string = unit + ' ' + day
|
||||
diff = diff - ( unit * 86400 )
|
||||
if unit >= 9 || diff < 3600 || count is 2
|
||||
|
@ -83,9 +83,9 @@ class App.PrettyDate
|
|||
minute = App.i18n.translateInline('m')
|
||||
if long
|
||||
if unit > 1 || unit is 0
|
||||
minute = App.i18n.translateContent('minutes')
|
||||
minute = App.i18n.translateInline('minutes')
|
||||
else
|
||||
minute = App.i18n.translateContent('minute')
|
||||
minute = App.i18n.translateInline('minute')
|
||||
if string isnt ''
|
||||
string = string + ' '
|
||||
string = string + unit + ' ' + minute
|
||||
|
|
|
@ -93,6 +93,8 @@ class App.Utils
|
|||
|
||||
# htmlEscaped = App.Utils.htmlEscape( rawText )
|
||||
@htmlEscape: ( ascii ) ->
|
||||
return ascii if !ascii
|
||||
return ascii if !ascii.replace
|
||||
ascii.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
|
|
|
@ -16,5 +16,5 @@
|
|||
</div>
|
||||
<div class="chat-controls">
|
||||
<div class="chat-input form-control form-control--small form-control--multiline js-customerChatInput" contenteditable="true"></div>
|
||||
<div class="btn btn--primary btn--slim btn--small js-send"><%= @T('Send') %></div>
|
||||
<div class="btn btn--primary btn--slim btn--small js-send"><%- @T('Send') %></div>
|
||||
</div>
|
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="page-header-meta">
|
||||
<div class="btn btn--action" data-type="settings"><%= @T('Settings') %></div>
|
||||
<div class="btn btn--action" data-type="settings"><%- @T('Settings') %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-workspace"></div>
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
<div class="stats-row email-channel">
|
||||
<%- @Icon(channel.icon, 'stat-channel-icon') %>
|
||||
<div class="stat-bars">
|
||||
<div class="stat-bar primary" style="height: <%- channel.inbound_in_percent %>%" title="<%- @T('Inbound') %>: <%- channel.inbound_in_percent %>% (<%- channel.inbound %>)"></div>
|
||||
<div class="stat-bar secondary" style="height: <%- channel.outbound_in_percent %>%" title="<%- @T('Outbound') %>: <%- channel.outbound_in_percent %>% (<%- channel.outbound %>)"></div>
|
||||
<div class="stat-bar primary" style="height: <%- channel.inbound_in_percent %>%" title="<%- @Ti('Inbound') %>: <%- channel.inbound_in_percent %>% (<%- channel.inbound %>)"></div>
|
||||
<div class="stat-bar secondary" style="height: <%- channel.outbound_in_percent %>%" title="<%- @Ti('Outbound') %>: <%- channel.outbound_in_percent %>% (<%- channel.outbound %>)"></div>
|
||||
</div>
|
||||
<div class="stat-label"></div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<% for item in @item_list: %>
|
||||
<a href="<%- item.data.url %>" title="<%= item.data.title %>" class="nav-tab task <%= item.data.class %><% if item.task.active: %> is-active<% end %><% if item.task.notify: %> is-modified<% end %>" data-key="<%- item.task.key %>">
|
||||
<div class="nav-tab-icon" title="<%- @T(item.data.iconTitle) %>">
|
||||
<div class="nav-tab-icon" title="<%- @Ti(item.data.iconTitle) %>">
|
||||
<% if item.data.type is 'task': %>
|
||||
<% if item.task.notify: %>
|
||||
<%- @Icon('status-modified-inner-circle', "icon-task-state #{item.data.iconClass}") %>
|
||||
|
|
|
@ -1 +1 @@
|
|||
<div contenteditable="true" class="ticket-title-update" data-placeholder="<%= @Ti('Enter Title...') %>"><%= @ticket.title %></div>
|
||||
<div contenteditable="true" class="ticket-title-update" data-placeholder="<%- @Ti('Enter Title...') %>"><%= @ticket.title %></div>
|
|
@ -2564,6 +2564,10 @@ footer {
|
|||
.translation[contenteditable="true"] {
|
||||
display: inline;
|
||||
}
|
||||
.translation[contenteditable="true"]:hover,
|
||||
.translation[contenteditable="true"]:focus {
|
||||
background: none;
|
||||
}
|
||||
.translation .icon-edit {
|
||||
display: none;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue