Merge branch 'develop' of git.znuny.com:zammad/zammad into develop
This commit is contained in:
commit
b04e0c1b64
21 changed files with 198 additions and 30 deletions
|
@ -32,7 +32,7 @@ class App.SettingsAreaItem extends App.Controller
|
||||||
)
|
)
|
||||||
|
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('.form-item'),
|
el: @el.find('.form-item')
|
||||||
model: { configure_attributes: @configure_attributes, className: '' }
|
model: { configure_attributes: @configure_attributes, className: '' }
|
||||||
autofocus: false
|
autofocus: false
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
class App.SettingsAreaItemDefaultLocale extends App.SettingsAreaItem
|
||||||
|
|
||||||
|
render: =>
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
locales = App.Locale.all()
|
||||||
|
for locale in locales
|
||||||
|
options[locale.locale] = locale.name
|
||||||
|
configure_attributes = [
|
||||||
|
{ name: 'locale_default', display: '', tag: 'searchable_select', null: false, class: 'input', options: options, default: @setting.state_current.value },
|
||||||
|
]
|
||||||
|
|
||||||
|
@html App.view(@template)(
|
||||||
|
setting: @setting
|
||||||
|
)
|
||||||
|
|
||||||
|
new App.ControllerForm(
|
||||||
|
el: @el.find('.form-item')
|
||||||
|
model: { configure_attributes: configure_attributes, className: '' }
|
||||||
|
autofocus: false
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
class DefaultLocale extends App.Controller
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
check = =>
|
||||||
|
|
||||||
|
preferences = App.Session.get('preferences')
|
||||||
|
return if !preferences
|
||||||
|
return if !_.isEmpty(preferences.locale)
|
||||||
|
locale = App.i18n.get()
|
||||||
|
@ajax(
|
||||||
|
id: "i18n-set-user-#{locale}"
|
||||||
|
type: 'PUT'
|
||||||
|
url: "#{App.Config.get('api_path')}/users/preferences"
|
||||||
|
data: JSON.stringify(locale: locale)
|
||||||
|
processData: true
|
||||||
|
)
|
||||||
|
|
||||||
|
App.Event.bind('auth:login', (session) =>
|
||||||
|
@delay(check, 3500, 'default_locale')
|
||||||
|
)
|
||||||
|
|
||||||
|
App.Config.set('default_locale', DefaultLocale, 'Widgets')
|
|
@ -47,4 +47,4 @@ class Widget extends App.ControllerWidgetOnDemand
|
||||||
800
|
800
|
||||||
)
|
)
|
||||||
|
|
||||||
App.Config.set( 'switch_back_to_user', Widget, 'Widgets' )
|
App.Config.set('switch_back_to_user', Widget, 'Widgets')
|
||||||
|
|
|
@ -79,8 +79,7 @@ class App.Auth
|
||||||
@_updateModelAttributes(data.models)
|
@_updateModelAttributes(data.models)
|
||||||
|
|
||||||
# set locale
|
# set locale
|
||||||
locale = window.navigator.userLanguage || window.navigator.language || 'en-us'
|
App.i18n.set(App.i18n.detectBrowserLocale())
|
||||||
App.i18n.set(locale)
|
|
||||||
|
|
||||||
# rebuild navbar with new navbar items
|
# rebuild navbar with new navbar items
|
||||||
App.Event.trigger('auth')
|
App.Event.trigger('auth')
|
||||||
|
@ -120,7 +119,7 @@ class App.Auth
|
||||||
if preferences && preferences.locale
|
if preferences && preferences.locale
|
||||||
locale = preferences.locale
|
locale = preferences.locale
|
||||||
if !locale
|
if !locale
|
||||||
locale = window.navigator.userLanguage || window.navigator.language || 'en-us'
|
locale = App.i18n.detectBrowserLocale()
|
||||||
App.i18n.set(locale)
|
App.i18n.set(locale)
|
||||||
|
|
||||||
App.Event.trigger('auth:login', data.session)
|
App.Event.trigger('auth:login', data.session)
|
||||||
|
|
|
@ -80,6 +80,24 @@ class App.i18n
|
||||||
_instance ?= new _i18nSingleton()
|
_instance ?= new _i18nSingleton()
|
||||||
_instance.mapTime
|
_instance.mapTime
|
||||||
|
|
||||||
|
@detectBrowserLocale: ->
|
||||||
|
return 'en-us' if !window.navigator.userLanguage && !window.navigator.language
|
||||||
|
|
||||||
|
if window.navigator.languages
|
||||||
|
allLocales = App.Locale.all()
|
||||||
|
for browserLocale in window.navigator.languages
|
||||||
|
for localAllLocale in allLocales
|
||||||
|
if browserLocale is localAllLocale.locale
|
||||||
|
return localAllLocale.locale
|
||||||
|
|
||||||
|
for browserLocale in window.navigator.languages
|
||||||
|
browserLocale = browserLocale.substr(0, 2)
|
||||||
|
for localAllLocale in allLocales
|
||||||
|
if browserLocale is localAllLocale.alias
|
||||||
|
return localAllLocale.locale
|
||||||
|
|
||||||
|
window.navigator.userLanguage || window.navigator.language || 'en-us'
|
||||||
|
|
||||||
class _i18nSingleton extends Spine.Module
|
class _i18nSingleton extends Spine.Module
|
||||||
@include App.LogInclude
|
@include App.LogInclude
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,7 @@ class FirstStepsController < ApplicationController
|
||||||
original_user_id = UserInfo.current_user_id
|
original_user_id = UserInfo.current_user_id
|
||||||
result = NotificationFactory::Mailer.template(
|
result = NotificationFactory::Mailer.template(
|
||||||
template: 'test_ticket',
|
template: 'test_ticket',
|
||||||
locale: agent.preferences[:locale] || 'en-us',
|
locale: agent.preferences[:locale] || Setting.get('locale_default') || 'en-us',
|
||||||
objects: {
|
objects: {
|
||||||
agent: agent,
|
agent: agent,
|
||||||
customer: customer,
|
customer: customer,
|
||||||
|
|
|
@ -24,7 +24,7 @@ returns
|
||||||
|
|
||||||
# read used locales based on env, e. g. export Z_LOCALES='en-us:de-de'
|
# read used locales based on env, e. g. export Z_LOCALES='en-us:de-de'
|
||||||
if ENV['Z_LOCALES']
|
if ENV['Z_LOCALES']
|
||||||
locales = Locale.where(active: true, locale: ENV['Z_LOCALES'].split(':') )
|
locales = Locale.where(active: true, locale: ENV['Z_LOCALES'].split(':'))
|
||||||
end
|
end
|
||||||
locales
|
locales
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,7 +18,7 @@ load text modules from online
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.load(locale, overwrite_existing_item = false)
|
def self.load(locale, overwrite_existing_item = false)
|
||||||
raise 'Got no locale' if locale.empty?
|
raise 'Got no locale' if locale.blank?
|
||||||
locale = locale.split(',').first.downcase # in case of accept_language header is given
|
locale = locale.split(',').first.downcase # in case of accept_language header is given
|
||||||
url = "https://i18n.zammad.com/api/v1/text_modules/#{locale}"
|
url = "https://i18n.zammad.com/api/v1/text_modules/#{locale}"
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ push text_modules to online
|
||||||
text_modules_to_push.push text_module
|
text_modules_to_push.push text_module
|
||||||
end
|
end
|
||||||
|
|
||||||
return true if text_modules_to_push.empty?
|
return true if text_modules_to_push.blank?
|
||||||
|
|
||||||
url = 'https://i18n.zammad.com/api/v1/text_modules/thanks_for_your_support'
|
url = 'https://i18n.zammad.com/api/v1/text_modules/thanks_for_your_support'
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Transaction::ClearbitEnrichment
|
||||||
|
|
||||||
config = Setting.get('clearbit_config')
|
config = Setting.get('clearbit_config')
|
||||||
return if !config
|
return if !config
|
||||||
return if config['api_key'].empty?
|
return if config['api_key'].blank?
|
||||||
|
|
||||||
user = User.lookup(id: @item[:object_id])
|
user = User.lookup(id: @item[:object_id])
|
||||||
return if !user
|
return if !user
|
||||||
|
|
|
@ -231,7 +231,7 @@ class Transaction::Notification
|
||||||
def human_changes(user, record)
|
def human_changes(user, record)
|
||||||
|
|
||||||
return {} if !@item[:changes]
|
return {} if !@item[:changes]
|
||||||
locale = user.preferences[:locale] || 'en-us'
|
locale = user.preferences[:locale] || Setting.get('locale_default') || 'en-us'
|
||||||
|
|
||||||
# only show allowed attributes
|
# only show allowed attributes
|
||||||
attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
|
attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
|
||||||
|
|
|
@ -197,7 +197,7 @@ class Transaction::Slack
|
||||||
|
|
||||||
return {} if !@item[:changes]
|
return {} if !@item[:changes]
|
||||||
user = User.find(1)
|
user = User.find(1)
|
||||||
locale = user.preferences[:locale] || 'en-us'
|
locale = user.preferences[:locale] || Setting.get('locale_default') || 'en-us'
|
||||||
|
|
||||||
# only show allowed attributes
|
# only show allowed attributes
|
||||||
attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
|
attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
|
||||||
|
|
|
@ -65,7 +65,7 @@ push translations to online
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true if translations_to_push.empty?
|
return true if translations_to_push.blank?
|
||||||
|
|
||||||
url = 'https://i18n.zammad.com/api/v1/translations/thanks_for_your_support'
|
url = 'https://i18n.zammad.com/api/v1/translations/thanks_for_your_support'
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ reset translations to origin
|
||||||
# only push changed translations
|
# only push changed translations
|
||||||
translations = Translation.where(locale: locale)
|
translations = Translation.where(locale: locale)
|
||||||
translations.each do |translation|
|
translations.each do |translation|
|
||||||
if !translation.target_initial || translation.target_initial.empty?
|
if translation.target_initial.blank?
|
||||||
translation.destroy
|
translation.destroy
|
||||||
elsif translation.target != translation.target_initial
|
elsif translation.target != translation.target_initial
|
||||||
translation.target = translation.target_initial
|
translation.target = translation.target_initial
|
||||||
|
|
28
db/migrate/20171115000001_setting_default_locale.rb
Normal file
28
db/migrate/20171115000001_setting_default_locale.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
class SettingDefaultLocale < ActiveRecord::Migration[5.1]
|
||||||
|
def up
|
||||||
|
|
||||||
|
# return if it's a new setup
|
||||||
|
return if !Setting.find_by(name: 'system_init_done')
|
||||||
|
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Locale',
|
||||||
|
name: 'locale_default',
|
||||||
|
area: 'System::Base',
|
||||||
|
description: 'Defines the system default language.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
name: 'locale_default',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: 'en-us',
|
||||||
|
preferences: {
|
||||||
|
controller: 'SettingsAreaItemDefaultLocale',
|
||||||
|
permission: ['admin.system'],
|
||||||
|
},
|
||||||
|
frontend: true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -183,6 +183,25 @@ Setting.create_or_update(
|
||||||
state: 'relative',
|
state: 'relative',
|
||||||
frontend: true
|
frontend: true
|
||||||
)
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Locale',
|
||||||
|
name: 'locale_default',
|
||||||
|
area: 'System::Base',
|
||||||
|
description: 'Defines the system default language.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
name: 'locale_default',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: 'en-us',
|
||||||
|
preferences: {
|
||||||
|
controller: 'SettingsAreaItemDefaultLocale',
|
||||||
|
permission: ['admin.system'],
|
||||||
|
},
|
||||||
|
frontend: true
|
||||||
|
)
|
||||||
options = {}
|
options = {}
|
||||||
(10..99).each do |item|
|
(10..99).each do |item|
|
||||||
options[item] = item
|
options[item] = item
|
||||||
|
|
|
@ -11,7 +11,7 @@ class CalendarSubscriptions::Tickets
|
||||||
def all
|
def all
|
||||||
|
|
||||||
events_data = []
|
events_data = []
|
||||||
return events_data if @preferences.empty?
|
return events_data if @preferences.blank?
|
||||||
|
|
||||||
events_data += new_open
|
events_data += new_open
|
||||||
events_data += pending
|
events_data += pending
|
||||||
|
@ -24,7 +24,7 @@ class CalendarSubscriptions::Tickets
|
||||||
|
|
||||||
alarm = false
|
alarm = false
|
||||||
|
|
||||||
return alarm if @preferences.empty?
|
return alarm if @preferences.blank?
|
||||||
return alarm if !@preferences[:alarm]
|
return alarm if !@preferences[:alarm]
|
||||||
|
|
||||||
@preferences[:alarm]
|
@preferences[:alarm]
|
||||||
|
@ -34,11 +34,11 @@ class CalendarSubscriptions::Tickets
|
||||||
|
|
||||||
owner_ids = []
|
owner_ids = []
|
||||||
|
|
||||||
return owner_ids if @preferences.empty?
|
return owner_ids if @preferences.blank?
|
||||||
return owner_ids if !@preferences[ method ]
|
return owner_ids if !@preferences[method]
|
||||||
return owner_ids if @preferences[ method ].empty?
|
return owner_ids if @preferences[method].blank?
|
||||||
|
|
||||||
preferences = @preferences[ method ]
|
preferences = @preferences[method]
|
||||||
|
|
||||||
if preferences[:own]
|
if preferences[:own]
|
||||||
owner_ids = [ @user.id ]
|
owner_ids = [ @user.id ]
|
||||||
|
@ -54,7 +54,7 @@ class CalendarSubscriptions::Tickets
|
||||||
|
|
||||||
events_data = []
|
events_data = []
|
||||||
owner_ids = owner_ids(:new_open)
|
owner_ids = owner_ids(:new_open)
|
||||||
return events_data if owner_ids.empty?
|
return events_data if owner_ids.blank?
|
||||||
|
|
||||||
condition = {
|
condition = {
|
||||||
'ticket.owner_id' => {
|
'ticket.owner_id' => {
|
||||||
|
@ -76,7 +76,7 @@ class CalendarSubscriptions::Tickets
|
||||||
condition: condition,
|
condition: condition,
|
||||||
)
|
)
|
||||||
|
|
||||||
user_locale = @user.preferences['locale'] || 'en'
|
user_locale = @user.preferences['locale'] || Setting.get('locale_default') || 'en-us'
|
||||||
translated_ticket = Translation.translate(user_locale, 'ticket')
|
translated_ticket = Translation.translate(user_locale, 'ticket')
|
||||||
|
|
||||||
events_data = []
|
events_data = []
|
||||||
|
@ -101,7 +101,7 @@ class CalendarSubscriptions::Tickets
|
||||||
|
|
||||||
events_data = []
|
events_data = []
|
||||||
owner_ids = owner_ids(:pending)
|
owner_ids = owner_ids(:pending)
|
||||||
return events_data if owner_ids.empty?
|
return events_data if owner_ids.blank?
|
||||||
|
|
||||||
condition = {
|
condition = {
|
||||||
'ticket.owner_id' => {
|
'ticket.owner_id' => {
|
||||||
|
@ -126,7 +126,7 @@ class CalendarSubscriptions::Tickets
|
||||||
condition: condition,
|
condition: condition,
|
||||||
)
|
)
|
||||||
|
|
||||||
user_locale = @user.preferences['locale'] || 'en'
|
user_locale = @user.preferences['locale'] || Setting.get('locale_default') || 'en-us'
|
||||||
translated_ticket = Translation.translate(user_locale, 'ticket')
|
translated_ticket = Translation.translate(user_locale, 'ticket')
|
||||||
customer = Translation.translate(user_locale, 'customer')
|
customer = Translation.translate(user_locale, 'customer')
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ class CalendarSubscriptions::Tickets
|
||||||
|
|
||||||
events_data = []
|
events_data = []
|
||||||
owner_ids = owner_ids(:escalation)
|
owner_ids = owner_ids(:escalation)
|
||||||
return events_data if owner_ids.empty?
|
return events_data if owner_ids.blank?
|
||||||
|
|
||||||
condition = {
|
condition = {
|
||||||
'ticket.owner_id' => {
|
'ticket.owner_id' => {
|
||||||
|
@ -183,7 +183,7 @@ class CalendarSubscriptions::Tickets
|
||||||
condition: condition,
|
condition: condition,
|
||||||
)
|
)
|
||||||
|
|
||||||
user_locale = @user.preferences['locale'] || 'en'
|
user_locale = @user.preferences['locale'] || Setting.get('locale_default') || 'en-us'
|
||||||
translated_ticket_escalation = Translation.translate(user_locale, 'ticket escalation')
|
translated_ticket_escalation = Translation.translate(user_locale, 'ticket escalation')
|
||||||
customer = Translation.translate(user_locale, 'customer')
|
customer = Translation.translate(user_locale, 'customer')
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ returns
|
||||||
|
|
||||||
template_subject = nil
|
template_subject = nil
|
||||||
template_body = ''
|
template_body = ''
|
||||||
locale = data[:locale] || 'en'
|
locale = data[:locale] || Setting.get('locale_default') || 'en-us'
|
||||||
template = data[:template]
|
template = data[:template]
|
||||||
format = data[:format]
|
format = data[:format]
|
||||||
type = data[:type]
|
type = data[:type]
|
||||||
|
|
|
@ -264,7 +264,7 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
template = NotificationFactory.template_read(
|
template = NotificationFactory.template_read(
|
||||||
locale: data[:locale] || 'en',
|
locale: data[:locale] || Setting.get('locale_default') || 'en-us',
|
||||||
template: data[:template],
|
template: data[:template],
|
||||||
format: 'html',
|
format: 'html',
|
||||||
type: 'mailer',
|
type: 'mailer',
|
||||||
|
|
|
@ -25,7 +25,7 @@ examples how to use
|
||||||
|
|
||||||
def initialize(objects, locale, template, escape = true)
|
def initialize(objects, locale, template, escape = true)
|
||||||
@objects = objects
|
@objects = objects
|
||||||
@locale = locale || 'en-us'
|
@locale = locale || Setting.get('locale_default') || 'en-us'
|
||||||
@template = NotificationFactory::Template.new(template, escape)
|
@template = NotificationFactory::Template.new(template, escape)
|
||||||
@escape = escape
|
@escape = escape
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,7 +27,7 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
template = NotificationFactory.template_read(
|
template = NotificationFactory.template_read(
|
||||||
locale: data[:locale] || 'en',
|
locale: data[:locale] || Setting.get('locale_default') || 'en-us',
|
||||||
template: data[:template],
|
template: data[:template],
|
||||||
format: 'md',
|
format: 'md',
|
||||||
type: 'slack',
|
type: 'slack',
|
||||||
|
|
|
@ -201,6 +201,66 @@ class NotificationFactoryMailerTemplateTest < ActiveSupport::TestCase
|
||||||
assert_no_match('longname', result[:body])
|
assert_no_match('longname', result[:body])
|
||||||
assert_match('Current User', result[:body])
|
assert_match('Current User', result[:body])
|
||||||
|
|
||||||
|
Setting.set('locale_default', 'de-de')
|
||||||
|
result = NotificationFactory::Mailer.template(
|
||||||
|
template: 'ticket_update',
|
||||||
|
objects: {
|
||||||
|
ticket: ticket,
|
||||||
|
article: article,
|
||||||
|
recipient: agent1,
|
||||||
|
current_user: agent_current_user,
|
||||||
|
changes: changes,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert_match('Ticket aktualisiert', result[:subject])
|
||||||
|
assert_match('Notification<b>xxx</b>', result[:body])
|
||||||
|
assert_match('wurde von', result[:body])
|
||||||
|
assert_match('<b>test123</b>', result[:body])
|
||||||
|
assert_match('Benachrichtigungseinstellungen Verwalten', result[:body])
|
||||||
|
assert_no_match('Your', result[:body])
|
||||||
|
assert_no_match('longname', result[:body])
|
||||||
|
assert_match('Current User', result[:body])
|
||||||
|
|
||||||
|
Setting.set('locale_default', 'not_existing')
|
||||||
|
result = NotificationFactory::Mailer.template(
|
||||||
|
template: 'ticket_update',
|
||||||
|
objects: {
|
||||||
|
ticket: ticket,
|
||||||
|
article: article,
|
||||||
|
recipient: agent1,
|
||||||
|
current_user: agent_current_user,
|
||||||
|
changes: changes,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert_match('Updated Ticket', result[:subject])
|
||||||
|
assert_match('Notification<b>xxx</b>', result[:body])
|
||||||
|
assert_match('has been updated by', result[:body])
|
||||||
|
assert_match('<b>test123</b>', result[:body])
|
||||||
|
assert_match('Manage your notifications settings', result[:body])
|
||||||
|
assert_no_match('Dein', result[:body])
|
||||||
|
assert_no_match('longname', result[:body])
|
||||||
|
assert_match('Current User', result[:body])
|
||||||
|
|
||||||
|
Setting.set('locale_default', 'pt-br')
|
||||||
|
result = NotificationFactory::Mailer.template(
|
||||||
|
template: 'ticket_update',
|
||||||
|
objects: {
|
||||||
|
ticket: ticket,
|
||||||
|
article: article,
|
||||||
|
recipient: agent1,
|
||||||
|
current_user: agent_current_user,
|
||||||
|
changes: changes,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert_match('Chamado atualizado', result[:subject])
|
||||||
|
assert_match('Notification<b>xxx</b>', result[:body])
|
||||||
|
assert_match('foi atualizado por', result[:body])
|
||||||
|
assert_match('<b>test123</b>', result[:body])
|
||||||
|
assert_match('Manage your notifications settings', result[:body])
|
||||||
|
assert_no_match('Dein', result[:body])
|
||||||
|
assert_no_match('longname', result[:body])
|
||||||
|
assert_match('Current User', result[:body])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue