From eb2c447e412d66d145802b999ab888db45121251 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Mon, 7 Mar 2016 02:25:52 +0100 Subject: [PATCH] Improved translations. --- .../_application_controller_generic.coffee | 9 +++++++++ .../app/controllers/_profile/password.coffee | 4 ++-- .../_ui_element/postmaster_set.coffee | 4 ++-- .../app/controllers/getting_started.coffee | 12 +++++------ .../app/controllers/object_manager.coffee | 20 +++++++++---------- .../app/controllers/widget/invite_user.coffee | 11 +++++++--- .../javascripts/app/lib/app_post/i18n.coffee | 9 ++++++++- .../javascripts/app/models/overview.coffee | 16 +++++++-------- .../app/views/channel/chat.jst.eco | 16 +++++++-------- .../channel/email_account_overview.jst.eco | 2 +- .../app/views/getting_started/base.jst.eco | 2 +- .../javascripts/app/views/link/add.jst.eco | 18 ++++++++--------- .../app/views/translation/list.jst.eco | 8 ++++---- .../app/views/translation/todo.jst.eco | 2 +- app/assets/stylesheets/zammad.scss | 4 ++++ app/models/translation.rb | 13 +++++++++++- public/assets/tests/core.js | 3 +++ 17 files changed, 96 insertions(+), 57 deletions(-) diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee index 4c7428251..31bcee9b0 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee @@ -678,6 +678,15 @@ class App.Sidebar extends App.Controller @showSidebar() class App.Wizard extends App.Controller + constructor: -> + super + + # rerender view, e. g. on langauge change + @bind('ui:rerender', => + @render() + 'wizard' + ) + goToSlide: (e) => e.preventDefault() slide = $(e.target).data('slide') diff --git a/app/assets/javascripts/app/controllers/_profile/password.coffee b/app/assets/javascripts/app/controllers/_profile/password.coffee index 34a7e4442..dccafb7fe 100644 --- a/app/assets/javascripts/app/controllers/_profile/password.coffee +++ b/app/assets/javascripts/app/controllers/_profile/password.coffee @@ -14,8 +14,8 @@ class Index extends App.Controller html = $( App.view('profile/password')() ) configure_attributes = [ - { name: 'password_old', display: 'Current Password', tag: 'input', type: 'password', limit: 100, null: false, class: 'input', single: true }, - { name: 'password_new', display: 'New Password', tag: 'input', type: 'password', limit: 100, null: false, class: 'input', }, + { name: 'password_old', display: 'Current password', tag: 'input', type: 'password', limit: 100, null: false, class: 'input', single: true }, + { name: 'password_new', display: 'New password', tag: 'input', type: 'password', limit: 100, null: false, class: 'input', }, ] @form = new App.ControllerForm( diff --git a/app/assets/javascripts/app/controllers/_ui_element/postmaster_set.coffee b/app/assets/javascripts/app/controllers/_ui_element/postmaster_set.coffee index 37cdc9ca1..e6092a2bf 100644 --- a/app/assets/javascripts/app/controllers/_ui_element/postmaster_set.coffee +++ b/app/assets/javascripts/app/controllers/_ui_element/postmaster_set.coffee @@ -34,7 +34,7 @@ class App.UiElement.postmaster_set { value: 'x-zammad-ignore' name: 'Ignore Message' - options: { true: 'Yes', false: 'No'} + options: { true: 'yes', false: 'no'} }, ] expert: @@ -43,7 +43,7 @@ class App.UiElement.postmaster_set { value: 'x-zammad-article-internal' name: 'Internal' - options: { true: 'Yes', false: 'No'} + options: { true: 'yes', false: 'no'} }, { value: 'x-zammad-article-type_id' diff --git a/app/assets/javascripts/app/controllers/getting_started.coffee b/app/assets/javascripts/app/controllers/getting_started.coffee index 97ba544a9..56e4708e8 100644 --- a/app/assets/javascripts/app/controllers/getting_started.coffee +++ b/app/assets/javascripts/app/controllers/getting_started.coffee @@ -1,4 +1,4 @@ -class Index extends App.ControllerContent +class Index extends App.Wizard className: 'getstarted fit' constructor: -> @@ -130,7 +130,7 @@ App.Config.set( 'getting_started/auto_wizard', AutoWizard, 'Routes' ) App.Config.set( 'getting_started/auto_wizard/:token', AutoWizard, 'Routes' ) -class Admin extends App.ControllerContent +class Admin extends App.Wizard className: 'getstarted fit' events: 'submit form': 'submit' @@ -505,7 +505,7 @@ class EmailNotification extends App.Wizard App.Config.set( 'getting_started/email_notification', EmailNotification, 'Routes' ) -class Channel extends App.ControllerContent +class Channel extends App.Wizard className: 'getstarted fit' constructor: -> @@ -558,7 +558,7 @@ class Channel extends App.ControllerContent App.Config.set( 'getting_started/channel', Channel, 'Routes' ) -class ChannelEmailPreConfigured extends App.ControllerContent +class ChannelEmailPreConfigured extends App.Wizard className: 'getstarted fit' constructor: -> @@ -895,7 +895,7 @@ class ChannelEmail extends App.Wizard App.Config.set( 'getting_started/channel/email', ChannelEmail, 'Routes' ) -class Agent extends App.ControllerContent +class Agent extends App.Wizard className: 'getstarted fit' events: 'submit form': 'submit' @@ -995,7 +995,7 @@ class Agent extends App.ControllerContent App.Config.set( 'getting_started/agents', Agent, 'Routes' ) -class Channel extends App.ControllerContent +class Channel extends App.Wizard className: 'getstarted fit' constructor: -> diff --git a/app/assets/javascripts/app/controllers/object_manager.coffee b/app/assets/javascripts/app/controllers/object_manager.coffee index 11bd5fec8..96541febf 100644 --- a/app/assets/javascripts/app/controllers/object_manager.coffee +++ b/app/assets/javascripts/app/controllers/object_manager.coffee @@ -174,7 +174,7 @@ class Edit extends App.ControllerModal textarea: 'Text (normal - multiline)' richtext: 'Text (richtext)' checkbox: 'Checkbox' - boolean: 'Yes/No' + boolean: 'yes/no' configureAttributesTop = [ { name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, 'null': false }, @@ -193,11 +193,11 @@ class Edit extends App.ControllerModal configureAttributesInput = [ { name: 'data_option::type', display: 'Type', tag: 'select', multiple: false, nulloption: true, null: false, options: { text: 'text', email: 'email', url: 'url', email: 'email', password: 'password', phone: 'phone'}, translate: true }, { name: 'data_option::maxlength', display: 'Max. Length', tag: 'input', type: 'text', limit: 100, 'null': false }, - { name: 'data_option::null', display: 'Required', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'No', false: 'Yes' }, translate: true }, - { name: 'data_option::autocapitalize', display: 'autocapitalize', tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'No', false: 'Yes' }, translate: true }, - { name: 'data_option::autocomplete', display: 'autocomplete', tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'No', false: 'Yes' }, translate: true }, + { name: 'data_option::null', display: 'Required', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true }, + { name: 'data_option::autocapitalize', display: 'autocapitalize', tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'no', false: 'yes' }, translate: true }, + { name: 'data_option::autocomplete', display: 'autocomplete', tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'no', false: 'yes' }, translate: true }, { name: 'data_option::default', display: 'Default', tag: 'input', type: 'text', limit: 100, null: true }, - { name: 'data_option::note', display: 'Note', tag: 'input', type: 'text', limit: 100, null: true }, + { name: 'data_option::note', display: 'note', tag: 'input', type: 'text', limit: 100, null: true }, ] controller = new App.ControllerForm( model: { configure_attributes: configureAttributesInput, className: '' }, @@ -209,8 +209,8 @@ class Edit extends App.ControllerModal # textarea configureAttributesTextarea = [ { name: 'data_option::maxlength', display: 'Max. Length', tag: 'input', type: 'text', limit: 100, null: false }, - { name: 'data_option::null', display: 'Required', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'No', false: 'Yes' }, translate: true }, - { name: 'data_option::autocapitalize', display: 'autocapitalize', tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'No', false: 'Yes' }, translate: true }, + { name: 'data_option::null', display: 'Required', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true }, + { name: 'data_option::autocapitalize', display: 'autocapitalize', tag: 'select', multiple: false, nulloption: true, null: false, options: { true: 'no', false: 'yes' }, translate: true }, { name: 'data_option::note', display: 'autocomplete', tag: 'input', type: 'text', limit: 100, null: true }, ] controller = new App.ControllerForm( @@ -222,11 +222,11 @@ class Edit extends App.ControllerModal # select configureAttributesSelect = [ - { name: 'data_option::nulloption', display: 'Empty Selection', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'No', false: 'Yes' }, translate: true }, - { name: 'data_option::null', display: 'Required', tag: 'boolean', multiple: false, nulloption: false, null: false, options: { true: 'No', false: 'Yes' }, translate: true }, + { name: 'data_option::nulloption', display: 'Empty Selection', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true }, + { name: 'data_option::null', display: 'Required', tag: 'boolean', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true }, { name: 'data_option::relation', display: 'Relation', tag: 'input', type: 'text', limit: 100, null: true }, { name: 'data_option::options', display: 'Options', tag: 'hash', multiple: true, null: false }, - { name: 'data_option::translate', display: 'Übersetzen', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'No', false: 'Yes' }, translate: true }, + { name: 'data_option::translate', display: 'Übersetzen', tag: 'select', multiple: false, nulloption: false, null: false, options: { true: 'no', false: 'yes' }, translate: true }, { name: 'data_option::note', display: 'Note', tag: 'input', type: 'text', limit: 100, null: true }, ] controller = new App.ControllerForm( diff --git a/app/assets/javascripts/app/controllers/widget/invite_user.coffee b/app/assets/javascripts/app/controllers/widget/invite_user.coffee index 978d9950e..14a920a6f 100644 --- a/app/assets/javascripts/app/controllers/widget/invite_user.coffee +++ b/app/assets/javascripts/app/controllers/widget/invite_user.coffee @@ -25,15 +25,20 @@ class App.InviteUser extends App.Wizard @el.remove() render: => - @html App.view('widget/invite_user')( + modal = $(App.view('widget/invite_user')( head: @head - ) + )) new App.ControllerForm( - el: @$('.js-form') + el: modal.find('.js-form') model: App.User screen: @screen autofocus: true ) + if !@initRenderingDone + @initRenderingDone = true + @html modal + else + @$('.modal-dialog').replaceWith(modal) submit: (e) => e.preventDefault() diff --git a/app/assets/javascripts/app/lib/app_post/i18n.coffee b/app/assets/javascripts/app/lib/app_post/i18n.coffee index 9dd04d535..dbf8af22a 100644 --- a/app/assets/javascripts/app/lib/app_post/i18n.coffee +++ b/app/assets/javascripts/app/lib/app_post/i18n.coffee @@ -267,7 +267,14 @@ class _i18nSingleton extends Spine.Module true getNotTranslated: (locale) => - @_notTranslated[locale || @locale] + notTranslated = @_notTranslated[locale || @locale] + return notTranslated if locale && locale isnt @locale + + # remove already translated entries + for local_locale, translation_list of notTranslated + if @mapString[local_locale] && @mapString[local_locale] isnt '' + delete notTranslated[local_locale] + notTranslated removeNotTranslated: (locale, key) => delete @_notTranslated[locale][key] diff --git a/app/assets/javascripts/app/models/overview.coffee b/app/assets/javascripts/app/models/overview.coffee index 9f78efae3..bf69afcd0 100644 --- a/app/assets/javascripts/app/models/overview.coffee +++ b/app/assets/javascripts/app/models/overview.coffee @@ -52,15 +52,15 @@ class App.Overview extends App.Model }, { value: 'last_contact' - name: 'Last Contact' + name: 'Last contact' }, { value: 'last_contact_agent' - name: 'Last Contact Agent' + name: 'Last contact (agent)' }, { value: 'last_contact_customer' - name: 'Last Contact Customer' + name: 'Last contact (customer)' }, { value: 'first_response' @@ -68,7 +68,7 @@ class App.Overview extends App.Model }, { value: 'close_time' - name: 'Close Time' + name: 'Close time' }, { value: 'article_count' @@ -94,11 +94,11 @@ class App.Overview extends App.Model group: 'Group' owner: 'Owner' created_at: 'Age' - last_contact: 'Last Contact' - last_contact_agent: 'Last Contact Agent' - last_contact_customer: 'Last Contact Customer' + last_contact: 'Last contact' + last_contact_agent: 'Last contact (agent)' + last_contact_customer: 'Last contact (customer)' first_response: 'First Response' - close_time: 'Close Time' + close_time: 'Close time' article_count: 'Article Count' class: 'span4' }, diff --git a/app/assets/javascripts/app/views/channel/chat.jst.eco b/app/assets/javascripts/app/views/channel/chat.jst.eco index 558fa6668..e2510172c 100644 --- a/app/assets/javascripts/app/views/channel/chat.jst.eco +++ b/app/assets/javascripts/app/views/channel/chat.jst.eco @@ -21,7 +21,7 @@
iPhone 6
-
<%- @T('1:1') %>
+
1:1
MacBook
@@ -34,7 +34,7 @@
- +
@@ -131,13 +131,13 @@

<%- @T('Usage') %>

-

<%- marked(@T('Insert the widget-code into the source code of every page the chat should be visible on. It should be placed at the end of the page source code before the `` closing tag.')) %>

+

<%- marked(@T('Insert the widget-code into the source code of every page the chat should be visible on. It should be placed at the end of the page source code before the §§ closing tag.')) %>

-

Requirements

+

<%- @T('Requirements') %>

<%- @T("Zammad Chat requires jQuery. If you don't already use it on your website include it like this:") %>

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
-

<%- @T('Auto-show chat') %>

+

<%- @T('Auto-show chat') %> (<%- @T('default') %>)

<%- @T('The chat will show up once the connection to the server got established and if there is someone online to chat with.') %>

<script src="<%= @baseurl %>/assets/chat/chat.min.js"></script>
@@ -150,7 +150,7 @@ $(function() {
 </script>

<%- @T('Manually open chat') %>

-

<%- marked(@T('If you want to open the chat by the press of a button set the option `show` to `false` and add the class `open-zammad-chat` to the button.')) %>

+

<%- @T('If you want to open the chat by the press of a button set the option §show§ to §false§ and add the class §open-zammad-chat§ to the button.') %>

<button class="open-zammad-chat">Chat with us</button>
 
 <script src="<%= @baseurl %>/assets/chat/chat.min.js"></script>
@@ -172,7 +172,7 @@ $(function() {
       
  • <%- @T('The chat is turned off.') %>
  • <%- @T('There are too many people in queue for the chat.') %> - <%- marked(@T('When you turn on debugging by setting the option `debug` to `true` the reason gets printed to the javascript console.')) %> + <%- @T('When you turn on debugging by setting the option §debug§ to §true§ the reason gets printed to the javascript console.') %>

    <%- @T('Options') %>

    @@ -188,7 +188,7 @@ $(function() { <% for option in @apiOptions: %> - <%- @T(option.name) %> + <%= option.name %> <%= option.default %> <%= option.type %> <%- @T(option.description, option.descriptionSubstitute) %> diff --git a/app/assets/javascripts/app/views/channel/email_account_overview.jst.eco b/app/assets/javascripts/app/views/channel/email_account_overview.jst.eco index 819c0ac26..9cecb874b 100644 --- a/app/assets/javascripts/app/views/channel/email_account_overview.jst.eco +++ b/app/assets/javascripts/app/views/channel/email_account_overview.jst.eco @@ -104,7 +104,7 @@ <% for email_address in channel.email_addresses: %>
  • <%= email_address.email %>
    -
    <%- @T('Edit') %>
    +
    <%- @T('Edit') %>
    <% if channel.email_addresses.length > 1: %>
    <%- @Icon('diagonal-cross') %> diff --git a/app/assets/javascripts/app/views/getting_started/base.jst.eco b/app/assets/javascripts/app/views/getting_started/base.jst.eco index 6607253aa..64ba81f09 100644 --- a/app/assets/javascripts/app/views/getting_started/base.jst.eco +++ b/app/assets/javascripts/app/views/getting_started/base.jst.eco @@ -22,7 +22,7 @@ -

    The URL to this installation of Zammad.

    +

    <%- @T('The URL to this installation of Zammad.') %>

    <% end %> diff --git a/app/assets/javascripts/app/views/link/add.jst.eco b/app/assets/javascripts/app/views/link/add.jst.eco index 409e89af9..97c9d3f23 100644 --- a/app/assets/javascripts/app/views/link/add.jst.eco +++ b/app/assets/javascripts/app/views/link/add.jst.eco @@ -1,22 +1,22 @@
    - <%- @T( 'Link' ) %> - <%- @T( @link_object ) %> + <%- @T('Link') %> + <%- @T(@link_object) %> - <%- @T( 'as' ) %> + <%- @T('as') %> - <%- @T( 'of' ) %> + <%- @T('of') %> Ticket# <%= @object.number %>.
    -

    <%- @T( 'Recent Customer Tickets' ) %>

    +

    <%- @T('Recent Customer Tickets') %>


    -

    <%- @T( 'Recent viewed Tickets' ) %>

    +

    <%- @T('Recent viewed Tickets') %>

    \ No newline at end of file diff --git a/app/assets/javascripts/app/views/translation/list.jst.eco b/app/assets/javascripts/app/views/translation/list.jst.eco index 216f0d859..46dfd287a 100644 --- a/app/assets/javascripts/app/views/translation/list.jst.eco +++ b/app/assets/javascripts/app/views/translation/list.jst.eco @@ -16,7 +16,7 @@ <%= time[1] %> <%= time[3]%> - <%- @T('Reset') %> + <%- @T('Reset') %> <% end %> @@ -39,10 +39,10 @@ <% changed = false %> <% changed = true if item[2] isnt item[3] %> class="warning"<% end %>> - <%= item[1] %> + <%= item[1] %> - <%= item[3]%> - <%- @T('Reset') %> + <%= item[3]%> + <%- @T('Reset') %> <% end %> diff --git a/app/assets/javascripts/app/views/translation/todo.jst.eco b/app/assets/javascripts/app/views/translation/todo.jst.eco index 1b33172a2..5d9f64713 100644 --- a/app/assets/javascripts/app/views/translation/todo.jst.eco +++ b/app/assets/javascripts/app/views/translation/todo.jst.eco @@ -12,7 +12,7 @@ <%= item[1] %> - <%- @T('Create') %> / <%- @T('is the same') %> + <%- @T('Create') %> / <%- @T('is the same') %> <% end %> \ No newline at end of file diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss index 8b3d9b020..39d66b320 100644 --- a/app/assets/stylesheets/zammad.scss +++ b/app/assets/stylesheets/zammad.scss @@ -2755,6 +2755,10 @@ footer { display: inline-block; } +.translationOverview .btn + .btn { + margin: -10px; +} + .sub_attribute .control-label { width: 60px; } diff --git a/app/models/translation.rb b/app/models/translation.rb index aca7a7399..0794353e1 100644 --- a/app/models/translation.rb +++ b/app/models/translation.rb @@ -200,7 +200,18 @@ get list of translations end list.push translation_item } - data['list'] = list + + # add presorted on top + presorted_list = [] + %w(yes no or Year Month Day Days Hour Hours Minute Minutes Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec January February March April May June July August September October November December Mon Tue Wed Thu Fri Sat Sun Monday Tuesday Wednesday Thursday Friday Saturday Sunday).each {|presort| + list.each {|item| + next if item[1] != presort + presorted_list.push item + list.delete item + #list.unshift presort + } + } + data['list'] = presorted_list.concat list # set cache if !admin diff --git a/public/assets/tests/core.js b/public/assets/tests/core.js index 0749e3a48..08f90dca0 100644 --- a/public/assets/tests/core.js +++ b/public/assets/tests/core.js @@ -335,6 +335,9 @@ test( "i18n", function() { translated = App.i18n.translateContent('§%s§ %s test', 123, 'xxx'); equal( translated, '123 xxx test', 'en-us - §%s§ %s' ); + translated = App.i18n.translateContent('Here you can search for ticket, customers and organizations. Use the wildcard §*§ to find everything. E. g. §smi*§ or §rosent*l§. You also can use ||double quotes|| for searching phrases §"some phrase"§.'); + equal( translated, 'Here you can search for ticket, customers and organizations. Use the wildcard * to find everything. E. g. smi* or rosent*l. You also can use double quotes for searching phrases "some phrase".', 'en-us - §§ §§ §§ || §§' ); + translated = App.i18n.translateContent('//%s// %s test', 123, 'xxx'); equal( translated, '123 xxx test', 'en-us - //%s// %s' );