Fixes #2709, fixes #2666, fixes #2665, fixes #556, fixes #3275 - Refactoring: Implement new translation toolchain based on gettext.
- Translations are no longer fetched from the cloud. - Instead, they are extracted from the codebase and stored in i18n/zammad.pot. - Translations will be managed via a public Weblate instance soon. - The translated .po files are fed to the database as before. - It is now possible to change "translation" strings for en-us locally via the admin GUI. - It is no longer possible to submit local changes.
This commit is contained in:
parent
6a6b19b4e6
commit
64a87b1c67
481 changed files with 534434 additions and 3442 deletions
91
.coffeelint/rules/detect_translatable_string.coffee
Normal file
91
.coffeelint/rules/detect_translatable_string.coffee
Normal file
|
@ -0,0 +1,91 @@
|
|||
module.exports = class DetectTranslatableString
|
||||
|
||||
# coffeelint: disable=detect_translatable_string
|
||||
rule:
|
||||
name: 'detect_translatable_string'
|
||||
level: 'ignore'
|
||||
message: 'The following string looks like it should be marked as translatable via __(...)'
|
||||
description: '''
|
||||
'''
|
||||
|
||||
constructor: ->
|
||||
@callTokens = []
|
||||
|
||||
tokens: ['STRING', 'CALL_START', 'CALL_END']
|
||||
|
||||
lintToken: (token, tokenApi) ->
|
||||
[type, tokenValue] = token
|
||||
|
||||
if type in ['CALL_START', 'CALL_END']
|
||||
@trackCall token, tokenApi
|
||||
return
|
||||
|
||||
return false if @isInIgnoredMethod()
|
||||
|
||||
return @lintString(token, tokenApi)
|
||||
|
||||
lintString: (token, tokenApi) ->
|
||||
[type, tokenValue] = token
|
||||
|
||||
# Remove quotes.
|
||||
string = tokenValue[1..-2]
|
||||
|
||||
# Ignore strings with less than two words.
|
||||
return false if string.split(' ').length < 2
|
||||
|
||||
# Ignore strings that are being used as exception; unlike Ruby exceptions, these should not reach the user.
|
||||
return false if tokenApi.peek(-3)[1] == 'throw'
|
||||
return false if tokenApi.peek(-2)[1] == 'throw'
|
||||
return false if tokenApi.peek(-1)[1] == 'throw'
|
||||
|
||||
# Ignore strings that are being used for comparison
|
||||
return false if tokenApi.peek(-1)[1] == '=='
|
||||
|
||||
# String interpolation is handled via concatenation, ignore such strings.
|
||||
return false if tokenApi.peek(1)[1] == '+'
|
||||
return false if tokenApi.peek(2)[1] == '+'
|
||||
|
||||
BLOCKLIST = [
|
||||
# Only look at strings starting with upper case letters
|
||||
/^[^A-Z]/,
|
||||
# # Ignore strings starting with three upper case letters like SELECT, POST etc.
|
||||
# /^[A-Z]{3}/,
|
||||
]
|
||||
|
||||
return false if BLOCKLIST.some (entry) ->
|
||||
#console.log([string, entry, string.match(entry), token, tokenApi.peek(-1), tokenApi.peek(1)])
|
||||
string.match(entry)
|
||||
|
||||
# console.log(tokenApi.peek(-3))
|
||||
# console.log(tokenApi.peek(-2))
|
||||
# console.log(tokenApi.peek(-1))
|
||||
# console.log(token)
|
||||
|
||||
return { context: "Found: #{token[1]}" }
|
||||
|
||||
ignoredMethods: {
|
||||
'__': true,
|
||||
'log': true,
|
||||
'T': true,
|
||||
'controllerBind': true,
|
||||
'error': true, # App.Log.error
|
||||
'set': true, # App.Config.set
|
||||
'translateInline': true,
|
||||
'translateContent': true,
|
||||
'translatePlain': true,
|
||||
}
|
||||
|
||||
isInIgnoredMethod: ->
|
||||
#console.log(@callTokens)
|
||||
for t in @callTokens
|
||||
return true if t.isIgnoredMethod
|
||||
return false
|
||||
|
||||
trackCall: (token, tokenApi) ->
|
||||
if token[0] is 'CALL_START'
|
||||
p = tokenApi.peek(-1)
|
||||
token.isIgnoredMethod = p and @ignoredMethods[p[1]]
|
||||
@callTokens.push(token)
|
||||
else
|
||||
@callTokens.pop()
|
||||
return null
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -37,8 +37,8 @@
|
|||
/db/*.sqlite3
|
||||
/db/schema.rb
|
||||
|
||||
# translation cache files
|
||||
/config/locales*.yml
|
||||
# legacy translation cache files
|
||||
/config/locales-*.yml
|
||||
/config/translations/*.yml
|
||||
|
||||
# NPM / Yarn
|
||||
|
|
|
@ -22,7 +22,26 @@ shellcheck:
|
|||
script:
|
||||
- shellcheck -S warning $(find . -name "*.sh" -o -name "functions" | grep -v "/vendor/")
|
||||
|
||||
zeitwerk_check:
|
||||
gettext lint:
|
||||
<<: *template_pre
|
||||
before_script:
|
||||
- echo "Disable default before_script."
|
||||
script:
|
||||
- for FILE in i18n/*.pot i18n/*.po; do echo "Checking $FILE"; msgfmt -o /dev/null -c $FILE; done
|
||||
|
||||
gettext catalog consistency:
|
||||
<<: *template_pre
|
||||
extends:
|
||||
- .tags_docker
|
||||
- .services_postgresql
|
||||
script:
|
||||
- bundle install -j $(nproc) --path vendor
|
||||
- bundle exec ruby .gitlab/configure_environment.rb
|
||||
- source .gitlab/environment.env
|
||||
- bundle exec rake zammad:db:init
|
||||
- bundle exec rails generate translation_catalog --check
|
||||
|
||||
zeitwerk:check:
|
||||
<<: *template_pre
|
||||
extends:
|
||||
- .tags_docker
|
||||
|
@ -48,7 +67,7 @@ brakeman:
|
|||
coffeelint:
|
||||
<<: *template_pre
|
||||
script:
|
||||
- coffeelint app/
|
||||
- coffeelint --rules ./.coffeelint/rules/* app/
|
||||
|
||||
stylelint:
|
||||
<<: *template_pre
|
||||
|
|
|
@ -9,10 +9,18 @@ PreCommit:
|
|||
enabled: false
|
||||
RuboCop:
|
||||
enabled: true
|
||||
on_warn: fail # Treat all warnings as failures
|
||||
on_warn: fail
|
||||
CoffeeLint:
|
||||
# .coffeelint/rules/* not supported in YAML, specify all rules separately.
|
||||
flags: ['--reporter=csv', '--rules', './.coffeelint/rules/detect_translatable_string.coffee']
|
||||
enabled: true
|
||||
on_warn: fail # Treat all warnings as failures
|
||||
on_warn: fail
|
||||
exclude: public/assets/chat/**/*
|
||||
CustomScript:
|
||||
enabled: true
|
||||
description: 'Check if translation catalog is up-to-date'
|
||||
required_executable: 'rails'
|
||||
flags: ['generate', 'translation_catalog', '--check']
|
||||
Stylelint:
|
||||
enabled: true
|
||||
|
||||
|
@ -43,4 +51,3 @@ PreRebase:
|
|||
PrepareCommitMsg:
|
||||
ALL:
|
||||
enabled: false
|
||||
|
||||
|
|
90
.rubocop/cop/zammad/detect_translatable_string.rb
Normal file
90
.rubocop/cop/zammad/detect_translatable_string.rb
Normal file
|
@ -0,0 +1,90 @@
|
|||
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Zammad
|
||||
class DetectTranslatableString < Base
|
||||
extend AutoCorrector
|
||||
|
||||
MSG = 'This string looks like it should be marked as translatable via __(...).'.freeze
|
||||
|
||||
def on_str(node)
|
||||
# Constants like __FILE__ are handled as strings, but don't respond to begin.
|
||||
return if !node.loc.respond_to?(:begin) || !node.loc.begin
|
||||
return if part_of_ignored_node?(node)
|
||||
|
||||
return if !offense?(node)
|
||||
|
||||
add_offense(node) do |corrector|
|
||||
corrector.replace(node, "__(#{node.source})")
|
||||
end
|
||||
end
|
||||
|
||||
def on_regexp(node)
|
||||
ignore_node(node)
|
||||
end
|
||||
|
||||
METHOD_NAME_BLOCKLIST = %i[
|
||||
__ translate
|
||||
include? eql? parse
|
||||
debug info warn error fatal unknown log log_error
|
||||
].freeze
|
||||
|
||||
def on_send(node)
|
||||
ignore_node(node) if METHOD_NAME_BLOCKLIST.include? node.method_name
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
PARENT_SOURCE_BLOCKLIST = [
|
||||
# Ignore logged strings
|
||||
'Rails.logger'
|
||||
].freeze
|
||||
|
||||
NODE_START_BLOCKLIST = [
|
||||
# Only look at strings starting with upper case letters
|
||||
%r{[^A-Z]},
|
||||
# Ignore strings starting with three upper case letters like SELECT, POST etc.
|
||||
%r{[A-Z]{3}},
|
||||
].freeze
|
||||
|
||||
NODE_CONTAIN_BLOCKLIST = [
|
||||
# Ignore strings with interpolation.
|
||||
'#{',
|
||||
# Ignore Email addresses
|
||||
'@'
|
||||
].freeze
|
||||
|
||||
def offense?(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
||||
|
||||
# Ignore Hash Keys
|
||||
return false if node.parent.type.eql?(:pair) && node.parent.children.first.equal?(node)
|
||||
|
||||
# Ignore equality checks like ... == 'My String'
|
||||
return false if node.left_sibling.eql?(:==)
|
||||
|
||||
# Remove quotes
|
||||
node_source = node.source[1..-2]
|
||||
|
||||
# Only match strings with at least two words
|
||||
return false if node_source.split.count < 2
|
||||
|
||||
NODE_START_BLOCKLIST.each do |entry|
|
||||
return false if node_source.start_with? entry
|
||||
end
|
||||
|
||||
NODE_CONTAIN_BLOCKLIST.each do |entry|
|
||||
return false if node_source.include? entry
|
||||
end
|
||||
|
||||
parent_source = node.parent.source
|
||||
PARENT_SOURCE_BLOCKLIST.each do |entry|
|
||||
return false if parent_source.include? entry
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -317,6 +317,20 @@ Zammad/ExistsResetColumnInformation:
|
|||
- 'db/migrate/201*_*.rb'
|
||||
- 'db/migrate/2020*_*.rb'
|
||||
|
||||
Zammad/DetectTranslatableString:
|
||||
Enabled: true
|
||||
Include:
|
||||
- "app/**/*.rb"
|
||||
- "db/**/*.rb"
|
||||
- "lib/**/*.rb"
|
||||
Exclude:
|
||||
- "db/migrate/**/*.rb"
|
||||
- "db/addon/**/*.rb"
|
||||
- "lib/generators/**/*.rb"
|
||||
- "lib/sequencer/**/*.rb"
|
||||
- "lib/import/**/*.rb"
|
||||
- "lib/tasks/**/*.rb"
|
||||
|
||||
Zammad/ExistsDbStrategy:
|
||||
Include:
|
||||
- "spec/**/*.rb"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
require_relative 'cop/zammad/exists_condition'
|
||||
require_relative 'cop/zammad/detect_translatable_string'
|
||||
require_relative 'cop/zammad/exists_date_time_precision'
|
||||
require_relative 'cop/zammad/exists_db_strategy'
|
||||
require_relative 'cop/zammad/exists_reset_column_information'
|
||||
|
|
3
Gemfile
3
Gemfile
|
@ -149,6 +149,9 @@ gem 'viewpoint', require: false
|
|||
# integrations - S/MIME
|
||||
gem 'openssl'
|
||||
|
||||
# Translation sync
|
||||
gem 'PoParser', require: false
|
||||
|
||||
# Gems used only for develop/test and not required
|
||||
# in production environments by default.
|
||||
group :development, :test do
|
||||
|
|
|
@ -19,6 +19,8 @@ GIT
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
PoParser (3.2.5)
|
||||
simple_po_parser (~> 1.1.2)
|
||||
aasm (5.2.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
actioncable (6.0.4.1)
|
||||
|
@ -555,6 +557,7 @@ GEM
|
|||
shoulda-matchers (5.0.0)
|
||||
activesupport (>= 5.2.0)
|
||||
simple_oauth (0.3.1)
|
||||
simple_po_parser (1.1.5)
|
||||
simplecov (0.21.2)
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
|
@ -655,6 +658,7 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
PoParser
|
||||
aasm
|
||||
activerecord-import
|
||||
activerecord-nulldb-adapter
|
||||
|
|
|
@ -114,7 +114,7 @@ class App.Controller extends Spine.Controller
|
|||
if window.clipboardData # IE
|
||||
window.clipboardData.setData('Text', text)
|
||||
else
|
||||
window.prompt('Copy to clipboard: Ctrl+C, Enter', text)
|
||||
window.prompt(__('Copy to clipboard: Ctrl+C, Enter'), text)
|
||||
|
||||
# disable all delay's and interval's
|
||||
disconnectClient: ->
|
||||
|
|
|
@ -59,7 +59,7 @@ class App.ControllerModal extends App.Controller
|
|||
false
|
||||
|
||||
content: ->
|
||||
'You need to implement a one @content()!'
|
||||
__('You need to implement a one @content()!')
|
||||
|
||||
update: =>
|
||||
if @message
|
||||
|
@ -106,7 +106,7 @@ class App.ControllerModal extends App.Controller
|
|||
if @buttonSubmit is true
|
||||
@buttonSubmit = 'Submit'
|
||||
if @buttonCancel is true
|
||||
@buttonCancel = 'Cancel & Go Back'
|
||||
@buttonCancel = __('Cancel & Go Back')
|
||||
|
||||
@update()
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class App.ControllerForm extends App.Controller
|
||||
fullFormSubmitLabel: 'Submit'
|
||||
fullFormSubmitLabel: __('Submit')
|
||||
fullFormSubmitAdditionalClasses: ''
|
||||
fullFormButtonsContainerClass: ''
|
||||
fullFormAdditionalButtons: [] # [{className: 'js-class', text: 'Label'}]
|
||||
|
@ -173,7 +173,7 @@ class App.ControllerForm extends App.Controller
|
|||
# input text field with max. 100 size
|
||||
attribute_config = {
|
||||
name: 'subject'
|
||||
display: 'Subject'
|
||||
display: __('Subject')
|
||||
tag: 'input'
|
||||
type: 'text'
|
||||
limit: 100
|
||||
|
@ -185,7 +185,7 @@ class App.ControllerForm extends App.Controller
|
|||
# colection as relation with auto completion
|
||||
attribute_config = {
|
||||
name: 'customer_id'
|
||||
display: 'Customer'
|
||||
display: __('Customer')
|
||||
tag: 'autocompletion'
|
||||
# auto completion params, endpoints, ui,...
|
||||
type: 'text'
|
||||
|
@ -193,7 +193,7 @@ class App.ControllerForm extends App.Controller
|
|||
null: false
|
||||
relation: 'User'
|
||||
autocapitalize: false
|
||||
help: 'Select the customer of the ticket or create one.'
|
||||
help: __('Select the customer of the ticket or create one.')
|
||||
helpLink: '<a href="" class="customer_new">»</a>'
|
||||
callback: @userInfo
|
||||
class: 'span7'
|
||||
|
@ -202,7 +202,7 @@ class App.ControllerForm extends App.Controller
|
|||
# colection as relation
|
||||
attribute_config = {
|
||||
name: 'priority_id'
|
||||
display: 'Priority'
|
||||
display: __('Priority')
|
||||
tag: 'select'
|
||||
multiple: false
|
||||
null: false
|
||||
|
@ -216,7 +216,7 @@ class App.ControllerForm extends App.Controller
|
|||
# colection as options
|
||||
attribute_config = {
|
||||
name: 'priority_id'
|
||||
display: 'Priority'
|
||||
display: __('Priority')
|
||||
tag: 'select'
|
||||
multiple: false
|
||||
null: false
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
class App.ControllerGenericDescription extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: false
|
||||
buttonSubmit: 'Close'
|
||||
head: 'Description'
|
||||
buttonSubmit: __('Close')
|
||||
head: __('Description')
|
||||
|
||||
content: =>
|
||||
marked(App.i18n.translateContent(@description))
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class App.ControllerGenericDestroyConfirm extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: 'delete'
|
||||
buttonSubmit: __('delete')
|
||||
buttonClass: 'btn--danger'
|
||||
head: 'Confirm'
|
||||
head: __('Confirm')
|
||||
small: true
|
||||
|
||||
content: ->
|
||||
|
@ -23,9 +23,9 @@ class App.ControllerGenericDestroyConfirm extends App.ControllerModal
|
|||
class App.ControllerConfirm extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: 'yes'
|
||||
buttonSubmit: __('yes')
|
||||
buttonClass: 'btn--danger'
|
||||
head: 'Confirm'
|
||||
head: __('Confirm')
|
||||
small: true
|
||||
|
||||
content: ->
|
||||
|
|
|
@ -51,5 +51,5 @@ class App.ControllerGenericEdit extends App.ControllerModal
|
|||
App[ ui.genericObject ].fetch(id: @id)
|
||||
ui.log 'errors'
|
||||
ui.formEnable(e)
|
||||
ui.controller.showAlert(details.error_human || details.error || 'Unable to update object!')
|
||||
ui.controller.showAlert(details.error_human || details.error || __('Unable to update object!'))
|
||||
)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class App.ControllerErrorModal extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: false
|
||||
buttonSubmit: 'Close'
|
||||
buttonSubmit: __('Close')
|
||||
#buttonClass: 'btn--danger'
|
||||
head: 'Error'
|
||||
head: __('Error')
|
||||
#small: true
|
||||
#shown: true
|
||||
showTrySupport: true
|
||||
|
|
|
@ -5,7 +5,7 @@ class App.GenericHistory extends App.ControllerModal
|
|||
buttonClose: true
|
||||
buttonCancel: false
|
||||
buttonSubmit: false
|
||||
head: 'History'
|
||||
head: __('History')
|
||||
shown: false
|
||||
|
||||
constructor: ->
|
||||
|
|
|
@ -51,5 +51,5 @@ class App.ControllerGenericNew extends App.ControllerModal
|
|||
fail: (settings, details) ->
|
||||
ui.log 'errors', details
|
||||
ui.formEnable(e)
|
||||
ui.controller.showAlert(details.error_human || details.error || 'Unable to create object!')
|
||||
ui.controller.showAlert(details.error_human || details.error || __('Unable to create object!'))
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class App.ControllerReorderModal extends App.ControllerModal
|
||||
head: 'Drag to reorder'
|
||||
head: __('Drag to reorder')
|
||||
content: ->
|
||||
view = $(App.view('reorder_modal')())
|
||||
|
||||
|
@ -10,7 +10,7 @@ class App.ControllerReorderModal extends App.ControllerModal
|
|||
true
|
||||
overview: ['title']
|
||||
attribute_list: [
|
||||
{ name: 'title', display: 'Name' }
|
||||
{ name: 'title', display: __('Name') }
|
||||
]
|
||||
objects: @items
|
||||
)
|
||||
|
@ -49,4 +49,3 @@ class App.ControllerReorderModal extends App.ControllerModal
|
|||
onSubmit: ->
|
||||
super
|
||||
@save()
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
# add new header item
|
||||
attribute =
|
||||
name: 'some name'
|
||||
display: 'Some Name'
|
||||
display: __('Some Name')
|
||||
headers.push attribute
|
||||
console.log('new header is', headers)
|
||||
headers
|
||||
|
@ -78,12 +78,12 @@
|
|||
el: element
|
||||
overview: ['time', 'area', 'level', 'browser', 'location', 'data']
|
||||
attribute_list: [
|
||||
{ name: 'time', display: 'Time', tag: 'datetime' },
|
||||
{ name: 'area', display: 'Area', type: 'text' },
|
||||
{ name: 'level', display: 'Level', type: 'text' },
|
||||
{ name: 'browser', display: 'Browser', type: 'text' },
|
||||
{ name: 'location', display: 'Location', type: 'text' },
|
||||
{ name: 'data', display: 'Data', type: 'text' },
|
||||
{ name: 'time', display: __('Time'), tag: 'datetime' },
|
||||
{ name: 'area', display: __('Area'), type: 'text' },
|
||||
{ name: 'level', display: __('Level'), type: 'text' },
|
||||
{ name: 'browser', display: __('Browser'), type: 'text' },
|
||||
{ name: 'location', display: __('Location'), type: 'text' },
|
||||
{ name: 'data', display: __('Data'), type: 'text' },
|
||||
]
|
||||
objects: data
|
||||
)
|
||||
|
@ -641,7 +641,7 @@ class App.ControllerTable extends App.Controller
|
|||
if @clone
|
||||
@actions.push
|
||||
name: 'clone'
|
||||
display: 'Clone'
|
||||
display: __('Clone')
|
||||
icon: 'clipboard'
|
||||
class: 'create js-clone'
|
||||
callback: (id) =>
|
||||
|
@ -660,7 +660,7 @@ class App.ControllerTable extends App.Controller
|
|||
if @destroy
|
||||
@actions.push
|
||||
name: 'delete'
|
||||
display: 'Delete'
|
||||
display: __('Delete')
|
||||
icon: 'trash'
|
||||
class: 'danger js-delete'
|
||||
callback: (id) =>
|
||||
|
@ -672,7 +672,7 @@ class App.ControllerTable extends App.Controller
|
|||
if @actions.length
|
||||
@headers.push
|
||||
name: 'action'
|
||||
display: 'Action'
|
||||
display: __('Action')
|
||||
width: '50px'
|
||||
displayWidth: 50
|
||||
align: 'right'
|
||||
|
|
|
@ -11,7 +11,7 @@ class App.ChannelEmailFilter extends App.Controller
|
|||
|
||||
template = $( '<div><div class="overview"></div><a data-type="new" class="btn btn--success">' + App.i18n.translateContent('New') + '</a></div>' )
|
||||
|
||||
description = 'With filters you can e. g. dispatch new tickets into certain groups or set a certain priority for tickets of a VIP customer.'
|
||||
description = __('With filters you can e. g. dispatch new tickets into certain groups or set a certain priority for tickets of a VIP customer.')
|
||||
|
||||
new App.ControllerTable(
|
||||
el: template.find('.overview')
|
||||
|
@ -28,7 +28,7 @@ class App.ChannelEmailFilter extends App.Controller
|
|||
e.preventDefault()
|
||||
new App.ControllerGenericNew(
|
||||
pageData:
|
||||
object: 'Postmaster Filter'
|
||||
object: __('Postmaster Filter')
|
||||
genericObject: 'PostmasterFilter'
|
||||
container: @el.closest('.content')
|
||||
callback: @load
|
||||
|
@ -40,7 +40,7 @@ class App.ChannelEmailFilter extends App.Controller
|
|||
new App.ControllerGenericEdit(
|
||||
id: id,
|
||||
pageData:
|
||||
object: 'Postmaster Filter'
|
||||
object: __('Postmaster Filter')
|
||||
genericObject: 'PostmasterFilter'
|
||||
container: @el.closest('.content')
|
||||
callback: @load
|
||||
|
|
|
@ -11,11 +11,11 @@ class App.ChannelEmailSignature extends App.Controller
|
|||
|
||||
template = $( '<div><div class="overview"></div><a data-type="new" class="btn btn--success">' + App.i18n.translateContent('New') + '</a></div>' )
|
||||
|
||||
description = '''
|
||||
description = __('''
|
||||
You can define different signatures for each group. So you can have different email signatures for different departments.
|
||||
|
||||
Once you have created a signature here, you need also to edit the groups where you want to use it.
|
||||
'''
|
||||
''')
|
||||
|
||||
new App.ControllerTable(
|
||||
el: template.find('.overview')
|
||||
|
@ -46,7 +46,7 @@ class ChannelEmailSignatureEdit extends App.ControllerModal
|
|||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: true
|
||||
head: 'Signature'
|
||||
head: __('Signature')
|
||||
|
||||
content: =>
|
||||
if @object
|
||||
|
@ -90,5 +90,5 @@ class ChannelEmailSignatureEdit extends App.ControllerModal
|
|||
fail: (settings, details) =>
|
||||
@log 'errors', details
|
||||
@formEnable(e)
|
||||
@form.showAlert(details.error_human || details.error || 'Unable to create object!')
|
||||
@form.showAlert(details.error_human || details.error || __('Unable to create object!'))
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ChannelChat extends App.ControllerSubContent
|
||||
requiredPermission: 'admin.channel_chat'
|
||||
header: 'Chat'
|
||||
header: __('Chat')
|
||||
events:
|
||||
'change .js-params': 'updateParams'
|
||||
'input .js-params': 'updateParams'
|
||||
|
@ -32,74 +32,74 @@ class ChannelChat extends App.ControllerSubContent
|
|||
name: 'chatId'
|
||||
default: '1'
|
||||
type: 'Number'
|
||||
description: 'Identifier of the chat-topic.'
|
||||
description: __('Identifier of the chat-topic.')
|
||||
}
|
||||
{
|
||||
name: 'show'
|
||||
default: true
|
||||
type: 'Boolean'
|
||||
description: 'Show the chat when ready.'
|
||||
description: __('Show the chat when ready.')
|
||||
}
|
||||
{
|
||||
name: 'target'
|
||||
default: "$('body')"
|
||||
type: 'jQuery Object'
|
||||
description: 'Where to append the chat to.'
|
||||
description: __('Where to append the chat to.')
|
||||
}
|
||||
{
|
||||
name: 'host'
|
||||
default: '(Empty)'
|
||||
type: 'String'
|
||||
description: "If left empty, the host gets auto-detected - in this case %s. The auto-detection reads out the host from the <script> tag. If you don't include it via a <script> tag you need to specify the host."
|
||||
description: __("If left empty, the host gets auto-detected - in this case %s. The auto-detection reads out the host from the <script> tag. If you don't include it via a <script> tag you need to specify the host.")
|
||||
descriptionSubstitute: window.location.origin
|
||||
}
|
||||
{
|
||||
name: 'debug'
|
||||
default: false
|
||||
type: 'Boolean'
|
||||
description: 'Enables console logging.'
|
||||
description: __('Enables console logging.')
|
||||
}
|
||||
{
|
||||
name: 'title'
|
||||
default: "'<strong>Chat</strong> with us!'"
|
||||
type: 'String'
|
||||
description: 'Welcome Title shown on the closed chat. Can contain HTML.'
|
||||
description: __('Welcome Title shown on the closed chat. Can contain HTML.')
|
||||
}
|
||||
{
|
||||
name: 'fontSize'
|
||||
default: 'undefined'
|
||||
type: 'String'
|
||||
description: 'CSS font-size with a unit like 12px, 1.5em. If left to undefined it inherits the font-size of the website.'
|
||||
description: __('CSS font-size with a unit like 12px, 1.5em. If left to undefined it inherits the font-size of the website.')
|
||||
}
|
||||
{
|
||||
name: 'flat'
|
||||
default: 'false'
|
||||
type: 'Boolean'
|
||||
description: 'Removes the shadows for a flat look.'
|
||||
description: __('Removes the shadows for a flat look.')
|
||||
}
|
||||
{
|
||||
name: 'buttonClass'
|
||||
default: "'open-zammad-chat'"
|
||||
type: 'String'
|
||||
description: 'Add this class to a button on your page that should open the chat.'
|
||||
description: __('Add this class to a button on your page that should open the chat.')
|
||||
}
|
||||
{
|
||||
name: 'inactiveClass'
|
||||
default: "'is-inactive'"
|
||||
type: 'String'
|
||||
description: 'This class gets added to the button on initialization and gets removed once the chat connection got established.'
|
||||
description: __('This class gets added to the button on initialization and gets removed once the chat connection got established.')
|
||||
}
|
||||
{
|
||||
name: 'cssAutoload'
|
||||
default: 'true'
|
||||
type: 'Boolean'
|
||||
description: 'Automatically loads the chat.css file. If you want to use your own css, just set it to false.'
|
||||
description: __('Automatically loads the chat.css file. If you want to use your own css, just set it to false.')
|
||||
}
|
||||
{
|
||||
name: 'cssUrl'
|
||||
default: 'undefined'
|
||||
type: 'String'
|
||||
description: 'Location of an external chat.css file.'
|
||||
description: __('Location of an external chat.css file.')
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -353,7 +353,7 @@ class ChannelChat extends App.ControllerSubContent
|
|||
@code.each (i, block) ->
|
||||
hljs.highlightBlock block
|
||||
|
||||
App.Config.set('Chat', { prio: 4000, name: 'Chat', parent: '#channels', target: '#channels/chat', controller: ChannelChat, permission: ['admin.channel_chat'] }, 'NavBarAdmin')
|
||||
App.Config.set('Chat', { prio: 4000, name: __('Chat'), parent: '#channels', target: '#channels/chat', controller: ChannelChat, permission: ['admin.channel_chat'] }, 'NavBarAdmin')
|
||||
|
||||
class Topics extends App.Controller
|
||||
events:
|
||||
|
@ -373,9 +373,9 @@ class Topics extends App.Controller
|
|||
new: (e) =>
|
||||
new App.ControllerGenericNew(
|
||||
pageData:
|
||||
title: 'Chats'
|
||||
object: 'Chat'
|
||||
objects: 'Chats'
|
||||
title: __('Chats')
|
||||
object: __('Chat')
|
||||
objects: __('Chats')
|
||||
genericObject: 'Chat'
|
||||
callback: @render
|
||||
container: @el.closest('.content')
|
||||
|
@ -389,7 +389,7 @@ class Topics extends App.Controller
|
|||
id: id
|
||||
genericObject: 'Chat'
|
||||
pageData:
|
||||
object: 'Chat'
|
||||
object: __('Chat')
|
||||
container: @el.closest('.content')
|
||||
callback: @render
|
||||
)
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
class ChannelEmail extends App.ControllerTabs
|
||||
requiredPermission: 'admin.channel_email'
|
||||
header: 'Email'
|
||||
header: __('Email')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title 'Email', true
|
||||
@title __('Email'), true
|
||||
|
||||
@tabs = [
|
||||
{
|
||||
name: 'Accounts',
|
||||
name: __('Accounts'),
|
||||
target: 'c-account',
|
||||
controller: ChannelEmailAccountOverview,
|
||||
},
|
||||
{
|
||||
name: 'Filter',
|
||||
name: __('Filter'),
|
||||
target: 'c-filter',
|
||||
controller: App.ChannelEmailFilter,
|
||||
},
|
||||
{
|
||||
name: 'Signatures',
|
||||
name: __('Signatures'),
|
||||
target: 'c-signature',
|
||||
controller: App.ChannelEmailSignature,
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
name: __('Settings'),
|
||||
target: 'c-setting',
|
||||
controller: App.SettingsArea,
|
||||
params: { area: 'Email::Base' },
|
||||
|
@ -142,7 +142,7 @@ class ChannelEmailAccountOverview extends App.Controller
|
|||
e.preventDefault()
|
||||
id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerConfirm(
|
||||
message: 'Sure?'
|
||||
message: __('Sure?')
|
||||
callback: =>
|
||||
@ajax(
|
||||
id: 'email_delete'
|
||||
|
@ -197,7 +197,7 @@ class ChannelEmailAccountOverview extends App.Controller
|
|||
channel_id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerGenericNew(
|
||||
pageData:
|
||||
object: 'Email Address'
|
||||
object: __('Email Address')
|
||||
genericObject: 'EmailAddress'
|
||||
container: @el.closest('.content')
|
||||
item:
|
||||
|
@ -210,7 +210,7 @@ class ChannelEmailAccountOverview extends App.Controller
|
|||
id = $(e.target).closest('li').data('id')
|
||||
new App.ControllerGenericEdit(
|
||||
pageData:
|
||||
object: 'Email Address'
|
||||
object: __('Email Address')
|
||||
genericObject: 'EmailAddress'
|
||||
container: @el.closest('.content')
|
||||
id: id
|
||||
|
@ -254,11 +254,11 @@ class ChannelEmailEdit extends App.ControllerModal
|
|||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: true
|
||||
head: 'Channel'
|
||||
head: __('Channel')
|
||||
|
||||
content: =>
|
||||
configureAttributesBase = [
|
||||
{ name: 'group_id', display: 'Destination Group', tag: 'select', null: false, relation: 'Group', nulloption: true, filter: { active: true } },
|
||||
{ name: 'group_id', display: __('Destination Group'), tag: 'select', null: false, relation: 'Group', nulloption: true, filter: { active: true } },
|
||||
]
|
||||
@form = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -298,7 +298,7 @@ class ChannelEmailEdit extends App.ControllerModal
|
|||
error: (xhr) =>
|
||||
data = JSON.parse(xhr.responseText)
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to save changes.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to save changes.'))
|
||||
)
|
||||
|
||||
class ChannelEmailAccountWizard extends App.ControllerWizardModal
|
||||
|
@ -371,10 +371,10 @@ class ChannelEmailAccountWizard extends App.ControllerWizardModal
|
|||
|
||||
# base
|
||||
configureAttributesBase = [
|
||||
{ name: 'realname', display: 'Organization & Department Name', tag: 'input', type: 'text', limit: 160, null: false, placeholder: 'Organization Support', autocomplete: 'off' },
|
||||
{ name: 'email', display: 'Email', tag: 'input', type: 'email', limit: 120, null: false, placeholder: 'support@example.com', autocapitalize: false, autocomplete: 'off' },
|
||||
{ name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||
{ name: 'group_id', display: 'Destination Group', tag: 'select', null: false, relation: 'Group', nulloption: true },
|
||||
{ name: 'realname', display: __('Organization & Department Name'), tag: 'input', type: 'text', limit: 160, null: false, placeholder: __('Organization Support'), autocomplete: 'off' },
|
||||
{ name: 'email', display: __('Email'), tag: 'input', type: 'email', limit: 120, null: false, placeholder: 'support@example.com', autocapitalize: false, autocomplete: 'off' },
|
||||
{ name: 'password', display: __('Password'), tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||
{ name: 'group_id', display: __('Destination Group'), tag: 'select', null: false, relation: 'Group', nulloption: true },
|
||||
]
|
||||
@formMeta = new App.ControllerForm(
|
||||
el: @$('.base-settings'),
|
||||
|
@ -386,7 +386,7 @@ class ChannelEmailAccountWizard extends App.ControllerWizardModal
|
|||
|
||||
# outbound
|
||||
configureAttributesOutbound = [
|
||||
{ name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: @channelDriver.email.outbound },
|
||||
{ name: 'adapter', display: __('Send Mails via'), tag: 'select', multiple: false, null: false, options: @channelDriver.email.outbound },
|
||||
]
|
||||
new App.ControllerForm(
|
||||
el: @$('.base-outbound-type')
|
||||
|
@ -400,22 +400,22 @@ class ChannelEmailAccountWizard extends App.ControllerWizardModal
|
|||
|
||||
# inbound
|
||||
configureAttributesInbound = [
|
||||
{ name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: @channelDriver.email.inbound },
|
||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autocomplete: 'off' },
|
||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||
{ name: 'options::ssl', display: 'SSL/STARTTLS', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, default: true, translate: true, item_class: 'formGroup--halfSize' },
|
||||
{ name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false, default: '993', item_class: 'formGroup--halfSize' },
|
||||
{ name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, item_class: 'formGroup--halfSize' },
|
||||
{ name: 'options::keep_on_server', display: 'Keep messages on server', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, translate: true, default: false, item_class: 'formGroup--halfSize' },
|
||||
{ name: 'adapter', display: __('Type'), tag: 'select', multiple: false, null: false, options: @channelDriver.email.inbound },
|
||||
{ name: 'options::host', display: __('Host'), tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
|
||||
{ name: 'options::user', display: __('User'), tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autocomplete: 'off' },
|
||||
{ name: 'options::password', display: __('Password'), tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||
{ name: 'options::ssl', display: __('SSL/STARTTLS'), tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, default: true, translate: true, item_class: 'formGroup--halfSize' },
|
||||
{ name: 'options::port', display: __('Port'), tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false, default: '993', item_class: 'formGroup--halfSize' },
|
||||
{ name: 'options::folder', display: __('Folder'), tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, item_class: 'formGroup--halfSize' },
|
||||
{ name: 'options::keep_on_server', display: __('Keep messages on server'), tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, translate: true, default: false, item_class: 'formGroup--halfSize' },
|
||||
]
|
||||
|
||||
if !@channel
|
||||
#Email Inbound form opened from new email wizard, show full settings
|
||||
configureAttributesInbound = [
|
||||
{ name: 'options::realname', display: 'Organization & Department Name', tag: 'input', type: 'text', limit: 160, null: false, placeholder: 'Organization Support', autocomplete: 'off' },
|
||||
{ name: 'options::email', display: 'Email', tag: 'input', type: 'email', limit: 120, null: false, placeholder: 'support@example.com', autocapitalize: false, autocomplete: 'off' },
|
||||
{ name: 'options::group_id', display: 'Destination Group', tag: 'select', null: false, relation: 'Group', nulloption: true },
|
||||
{ name: 'options::realname', display: __('Organization & Department Name'), tag: 'input', type: 'text', limit: 160, null: false, placeholder: __('Organization Support'), autocomplete: 'off' },
|
||||
{ name: 'options::email', display: __('Email'), tag: 'input', type: 'email', limit: 120, null: false, placeholder: 'support@example.com', autocapitalize: false, autocomplete: 'off' },
|
||||
{ name: 'options::group_id', display: __('Destination Group'), tag: 'select', null: false, relation: 'Group', nulloption: true },
|
||||
].concat(configureAttributesInbound)
|
||||
|
||||
|
||||
|
@ -468,10 +468,10 @@ class ChannelEmailAccountWizard extends App.ControllerWizardModal
|
|||
adapter = @$('.js-outbound [name=adapter]').val()
|
||||
if adapter is 'smtp'
|
||||
configureAttributesOutbound = [
|
||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
|
||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off', },
|
||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||
{ name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false },
|
||||
{ name: 'options::host', display: __('Host'), tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
|
||||
{ name: 'options::user', display: __('User'), tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off', },
|
||||
{ name: 'options::password', display: __('Password'), tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||
{ name: 'options::port', display: __('Port'), tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false },
|
||||
]
|
||||
@form = new App.ControllerForm(
|
||||
el: @$('.base-outbound-settings')
|
||||
|
@ -525,10 +525,10 @@ class ChannelEmailAccountWizard extends App.ControllerWizardModal
|
|||
|
||||
else if data.result is 'duplicate'
|
||||
@showSlide('js-intro')
|
||||
@showAlert('js-intro', 'Account already exists!')
|
||||
@showAlert('js-intro', __('Account already exists!'))
|
||||
else
|
||||
@showSlide('js-inbound')
|
||||
@showAlert('js-inbound', 'Unable to detect your server settings. Manual configuration needed.')
|
||||
@showAlert('js-inbound', __('Unable to detect your server settings. Manual configuration needed.'))
|
||||
@$('.js-inbound [name="options::user"]').val(@account['meta']['email'])
|
||||
@$('.js-inbound [name="options::password"]').val(@account['meta']['password'])
|
||||
@$('.js-inbound [name="options::email"]').val(@account['meta']['email'])
|
||||
|
@ -749,7 +749,7 @@ class ChannelEmailAccountWizard extends App.ControllerWizardModal
|
|||
@delay(
|
||||
=>
|
||||
@showSlide('js-intro')
|
||||
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.')
|
||||
@showAlert('js-intro', __('Unable to verify sending and receiving. Please check your settings.'))
|
||||
|
||||
2300
|
||||
)
|
||||
|
@ -759,7 +759,7 @@ class ChannelEmailAccountWizard extends App.ControllerWizardModal
|
|||
@verify(@account, count + 1)
|
||||
error: =>
|
||||
@showSlide('js-intro')
|
||||
@showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.')
|
||||
@showAlert('js-intro', __('Unable to verify sending and receiving. Please check your settings.'))
|
||||
)
|
||||
|
||||
hide: (e) =>
|
||||
|
@ -830,7 +830,7 @@ class ChannelEmailNotificationWizard extends App.ControllerWizardModal
|
|||
|
||||
# outbound
|
||||
configureAttributesOutbound = [
|
||||
{ name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: @channelDriver.email.outbound },
|
||||
{ name: 'adapter', display: __('Send Mails via'), tag: 'select', multiple: false, null: false, options: @channelDriver.email.outbound },
|
||||
]
|
||||
new App.ControllerForm(
|
||||
el: @$('.base-outbound-type')
|
||||
|
@ -849,10 +849,10 @@ class ChannelEmailNotificationWizard extends App.ControllerWizardModal
|
|||
adapter = @$('.js-outbound [name=adapter]').val()
|
||||
if adapter is 'smtp'
|
||||
configureAttributesOutbound = [
|
||||
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
|
||||
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off' },
|
||||
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||
{ name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false },
|
||||
{ name: 'options::host', display: __('Host'), tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
|
||||
{ name: 'options::user', display: __('User'), tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off' },
|
||||
{ name: 'options::password', display: __('Password'), tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true },
|
||||
{ name: 'options::port', display: __('Port'), tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false },
|
||||
]
|
||||
@form = new App.ControllerForm(
|
||||
el: @$('.base-outbound-settings')
|
||||
|
@ -900,4 +900,4 @@ class ChannelEmailNotificationWizard extends App.ControllerWizardModal
|
|||
@enable(e)
|
||||
)
|
||||
|
||||
App.Config.set('Email', { prio: 3000, name: 'Email', parent: '#channels', target: '#channels/email', controller: ChannelEmail, permission: ['admin.channel_email'] }, 'NavBarAdmin')
|
||||
App.Config.set('Email', { prio: 3000, name: __('Email'), parent: '#channels', target: '#channels/email', controller: ChannelEmail, permission: ['admin.channel_email'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ChannelFacebook extends App.ControllerSubContent
|
||||
requiredPermission: 'admin.channel_facebook'
|
||||
header: 'Facebook'
|
||||
header: __('Facebook')
|
||||
events:
|
||||
'click .js-new': 'new'
|
||||
'click .js-edit': 'edit'
|
||||
|
@ -95,7 +95,7 @@ class ChannelFacebook extends App.ControllerSubContent
|
|||
e.preventDefault()
|
||||
id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerConfirm(
|
||||
message: 'Sure?'
|
||||
message: __('Sure?')
|
||||
callback: =>
|
||||
@ajax(
|
||||
id: 'facebook_delete'
|
||||
|
@ -136,7 +136,7 @@ class ChannelFacebook extends App.ControllerSubContent
|
|||
)
|
||||
|
||||
class AppConfig extends App.ControllerModal
|
||||
head: 'Connect Facebook App'
|
||||
head: __('Connect Facebook App')
|
||||
shown: true
|
||||
button: 'Connect'
|
||||
buttonCancel: true
|
||||
|
@ -178,15 +178,15 @@ class AppConfig extends App.ControllerModal
|
|||
@isChanged = true
|
||||
@close()
|
||||
fail: =>
|
||||
@el.find('.alert').removeClass('hidden').text('Unable to create entry.')
|
||||
@el.find('.alert').removeClass('hidden').text(__('Unable to create entry.'))
|
||||
)
|
||||
return
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to verify App.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to verify App.'))
|
||||
)
|
||||
|
||||
class AccountEdit extends App.ControllerModal
|
||||
head: 'Facebook Account'
|
||||
head: __('Facebook Account')
|
||||
shown: true
|
||||
buttonCancel: true
|
||||
|
||||
|
@ -242,7 +242,7 @@ class AccountEdit extends App.ControllerModal
|
|||
error: (xhr) =>
|
||||
data = JSON.parse(xhr.responseText)
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to save changes.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to save changes.'))
|
||||
)
|
||||
|
||||
App.Config.set('Facebook', { prio: 5100, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: ChannelFacebook, permission: ['admin.channel_facebook'] }, 'NavBarAdmin')
|
||||
App.Config.set('Facebook', { prio: 5100, name: __('Facebook'), parent: '#channels', target: '#channels/facebook', controller: ChannelFacebook, permission: ['admin.channel_facebook'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# coffeelint: disable=no_unnecessary_double_quotes
|
||||
class ChannelForm extends App.ControllerSubContent
|
||||
requiredPermission: 'admin.channel_formular'
|
||||
header: 'Form'
|
||||
header: __('Form')
|
||||
events:
|
||||
'change form.js-paramsDesigner': 'updateParamsDesigner'
|
||||
'keyup form.js-paramsDesigner': 'updateParamsDesigner'
|
||||
|
@ -88,4 +88,4 @@ class ChannelForm extends App.ControllerSubContent
|
|||
value = @paramsSetting.find('[name=group_id]').val()
|
||||
App.Setting.set('form_ticket_create_group_id', value)
|
||||
|
||||
App.Config.set('Form', { prio: 2000, name: 'Form', parent: '#channels', target: '#channels/form', controller: ChannelForm, permission: ['admin.channel_formular'] }, 'NavBarAdmin')
|
||||
App.Config.set('Form', { prio: 2000, name: __('Form'), parent: '#channels', target: '#channels/form', controller: ChannelForm, permission: ['admin.channel_formular'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
class App.ChannelGoogle extends App.ControllerTabs
|
||||
requiredPermission: 'admin.channel_google'
|
||||
header: 'Google'
|
||||
header: __('Google')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title 'Google', true
|
||||
@title __('Google'), true
|
||||
|
||||
@tabs = [
|
||||
{
|
||||
name: 'Accounts',
|
||||
name: __('Accounts'),
|
||||
target: 'c-account',
|
||||
controller: ChannelAccountOverview,
|
||||
},
|
||||
{
|
||||
name: 'Filter',
|
||||
name: __('Filter'),
|
||||
target: 'c-filter',
|
||||
controller: App.ChannelEmailFilter,
|
||||
},
|
||||
{
|
||||
name: 'Signatures',
|
||||
name: __('Signatures'),
|
||||
target: 'c-signature',
|
||||
controller: App.ChannelEmailSignature,
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
name: __('Settings'),
|
||||
target: 'c-setting',
|
||||
controller: App.SettingsArea,
|
||||
params: { area: 'Email::Base' },
|
||||
|
@ -145,7 +145,7 @@ class ChannelAccountOverview extends App.ControllerSubContent
|
|||
e.preventDefault()
|
||||
id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerConfirm(
|
||||
message: 'Sure?'
|
||||
message: __('Sure?')
|
||||
callback: =>
|
||||
@ajax(
|
||||
id: 'google_delete'
|
||||
|
@ -215,11 +215,11 @@ class ChannelAccountOverview extends App.ControllerSubContent
|
|||
@load()
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: 'Rollback of channel migration succeeded!'
|
||||
msg: __('Rollback of channel migration succeeded!')
|
||||
error: (data) =>
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Failed to rollback migration of the channel!'
|
||||
msg: __('Failed to rollback migration of the channel!')
|
||||
)
|
||||
|
||||
groupChange: (e) =>
|
||||
|
@ -237,7 +237,7 @@ class ChannelAccountOverview extends App.ControllerSubContent
|
|||
channel_id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerGenericNew(
|
||||
pageData:
|
||||
object: 'Email Address'
|
||||
object: __('Email Address')
|
||||
genericObject: 'EmailAddress'
|
||||
container: @el.closest('.content')
|
||||
item:
|
||||
|
@ -250,7 +250,7 @@ class ChannelAccountOverview extends App.ControllerSubContent
|
|||
id = $(e.target).closest('li').data('id')
|
||||
new App.ControllerGenericEdit(
|
||||
pageData:
|
||||
object: 'Email Address'
|
||||
object: __('Email Address')
|
||||
genericObject: 'EmailAddress'
|
||||
container: @el.closest('.content')
|
||||
id: id
|
||||
|
@ -271,12 +271,12 @@ class ChannelInboundEdit extends App.ControllerModal
|
|||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: true
|
||||
head: 'Channel'
|
||||
head: __('Channel')
|
||||
|
||||
content: =>
|
||||
configureAttributesBase = [
|
||||
{ name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, placeholder: 'optional' },
|
||||
{ name: 'options::keep_on_server', display: 'Keep messages on server', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, translate: true, default: false },
|
||||
{ name: 'options::folder', display: __('Folder'), tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, placeholder: __('optional') },
|
||||
{ name: 'options::keep_on_server', display: __('Keep messages on server'), tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, translate: true, default: false },
|
||||
]
|
||||
@form = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -323,7 +323,7 @@ class ChannelInboundEdit extends App.ControllerModal
|
|||
details = xhr.responseJSON || {}
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to save changes.')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to save changes.'))
|
||||
timeout: 6000
|
||||
)
|
||||
|
||||
|
@ -331,11 +331,11 @@ class ChannelGroupEdit extends App.ControllerModal
|
|||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: true
|
||||
head: 'Channel'
|
||||
head: __('Channel')
|
||||
|
||||
content: =>
|
||||
configureAttributesBase = [
|
||||
{ name: 'group_id', display: 'Destination Group', tag: 'select', null: false, relation: 'Group', nulloption: true, filter: { active: true } },
|
||||
{ name: 'group_id', display: __('Destination Group'), tag: 'select', null: false, relation: 'Group', nulloption: true, filter: { active: true } },
|
||||
]
|
||||
@form = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -375,11 +375,11 @@ class ChannelGroupEdit extends App.ControllerModal
|
|||
error: (xhr) =>
|
||||
data = JSON.parse(xhr.responseText)
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to save changes.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to save changes.'))
|
||||
)
|
||||
|
||||
class AppConfig extends App.ControllerModal
|
||||
head: 'Connect Google App'
|
||||
head: __('Connect Google App')
|
||||
shown: true
|
||||
button: 'Connect'
|
||||
buttonCancel: true
|
||||
|
@ -421,11 +421,11 @@ class AppConfig extends App.ControllerModal
|
|||
@isChanged = true
|
||||
@close()
|
||||
fail: =>
|
||||
@el.find('.alert').removeClass('hidden').text('Unable to create entry.')
|
||||
@el.find('.alert').removeClass('hidden').text(__('Unable to create entry.'))
|
||||
)
|
||||
return
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to verify App.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to verify App.'))
|
||||
)
|
||||
|
||||
App.Config.set('google', { prio: 5000, name: 'Google', parent: '#channels', target: '#channels/google', controller: App.ChannelGoogle, permission: ['admin.channel_google'] }, 'NavBarAdmin')
|
||||
App.Config.set('google', { prio: 5000, name: __('Google'), parent: '#channels', target: '#channels/google', controller: App.ChannelGoogle, permission: ['admin.channel_google'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
class App.ChannelMicrosoft365 extends App.ControllerTabs
|
||||
requiredPermission: 'admin.channel_microsoft365'
|
||||
header: 'Microsoft 365'
|
||||
header: __('Microsoft 365')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title 'Microsoft 365', true
|
||||
@title __('Microsoft 365'), true
|
||||
|
||||
@tabs = [
|
||||
{
|
||||
name: 'Accounts',
|
||||
name: __('Accounts'),
|
||||
target: 'c-account',
|
||||
controller: ChannelAccountOverview,
|
||||
},
|
||||
{
|
||||
name: 'Filter',
|
||||
name: __('Filter'),
|
||||
target: 'c-filter',
|
||||
controller: App.ChannelEmailFilter,
|
||||
},
|
||||
{
|
||||
name: 'Signatures',
|
||||
name: __('Signatures'),
|
||||
target: 'c-signature',
|
||||
controller: App.ChannelEmailSignature,
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
name: __('Settings'),
|
||||
target: 'c-setting',
|
||||
controller: App.SettingsArea,
|
||||
params: { area: 'Email::Base' },
|
||||
|
@ -136,7 +136,7 @@ class ChannelAccountOverview extends App.ControllerSubContent
|
|||
e.preventDefault()
|
||||
id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerConfirm(
|
||||
message: 'Sure?'
|
||||
message: __('Sure?')
|
||||
callback: =>
|
||||
@ajax(
|
||||
id: 'microsoft365_delete'
|
||||
|
@ -206,11 +206,11 @@ class ChannelAccountOverview extends App.ControllerSubContent
|
|||
@load()
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: 'Rollback of channel migration succeeded!'
|
||||
msg: __('Rollback of channel migration succeeded!')
|
||||
error: (data) =>
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Failed to rollback migration of the channel!'
|
||||
msg: __('Failed to rollback migration of the channel!')
|
||||
)
|
||||
|
||||
groupChange: (e) =>
|
||||
|
@ -228,7 +228,7 @@ class ChannelAccountOverview extends App.ControllerSubContent
|
|||
channel_id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerGenericNew(
|
||||
pageData:
|
||||
object: 'Email Address'
|
||||
object: __('Email Address')
|
||||
genericObject: 'EmailAddress'
|
||||
container: @el.closest('.content')
|
||||
item:
|
||||
|
@ -241,7 +241,7 @@ class ChannelAccountOverview extends App.ControllerSubContent
|
|||
id = $(e.target).closest('li').data('id')
|
||||
new App.ControllerGenericEdit(
|
||||
pageData:
|
||||
object: 'Email Address'
|
||||
object: __('Email Address')
|
||||
genericObject: 'EmailAddress'
|
||||
container: @el.closest('.content')
|
||||
id: id
|
||||
|
@ -262,12 +262,12 @@ class ChannelInboundEdit extends App.ControllerModal
|
|||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: true
|
||||
head: 'Channel'
|
||||
head: __('Channel')
|
||||
|
||||
content: =>
|
||||
configureAttributesBase = [
|
||||
{ name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false },
|
||||
{ name: 'options::keep_on_server', display: 'Keep messages on server', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, translate: true, default: false },
|
||||
{ name: 'options::folder', display: __('Folder'), tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false },
|
||||
{ name: 'options::keep_on_server', display: __('Keep messages on server'), tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, translate: true, default: false },
|
||||
]
|
||||
@form = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -314,7 +314,7 @@ class ChannelInboundEdit extends App.ControllerModal
|
|||
details = xhr.responseJSON || {}
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to save changes.')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to save changes.'))
|
||||
timeout: 6000
|
||||
)
|
||||
|
||||
|
@ -322,11 +322,11 @@ class ChannelGroupEdit extends App.ControllerModal
|
|||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: true
|
||||
head: 'Channel'
|
||||
head: __('Channel')
|
||||
|
||||
content: =>
|
||||
configureAttributesBase = [
|
||||
{ name: 'group_id', display: 'Destination Group', tag: 'select', null: false, relation: 'Group', nulloption: true, filter: { active: true } },
|
||||
{ name: 'group_id', display: __('Destination Group'), tag: 'select', null: false, relation: 'Group', nulloption: true, filter: { active: true } },
|
||||
]
|
||||
@form = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -366,11 +366,11 @@ class ChannelGroupEdit extends App.ControllerModal
|
|||
error: (xhr) =>
|
||||
data = JSON.parse(xhr.responseText)
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to save changes.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to save changes.'))
|
||||
)
|
||||
|
||||
class AppConfig extends App.ControllerModal
|
||||
head: 'Connect Microsoft 365 App'
|
||||
head: __('Connect Microsoft 365 App')
|
||||
shown: true
|
||||
button: 'Connect'
|
||||
buttonCancel: true
|
||||
|
@ -412,11 +412,11 @@ class AppConfig extends App.ControllerModal
|
|||
@isChanged = true
|
||||
@close()
|
||||
fail: =>
|
||||
@el.find('.alert').removeClass('hidden').text('Unable to create entry.')
|
||||
@el.find('.alert').removeClass('hidden').text(__('Unable to create entry.'))
|
||||
)
|
||||
return
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to verify App.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to verify App.'))
|
||||
)
|
||||
|
||||
App.Config.set('microsoft365', { prio: 5000, name: 'Microsoft 365', parent: '#channels', target: '#channels/microsoft365', controller: App.ChannelMicrosoft365, permission: ['admin.channel_microsoft365'] }, 'NavBarAdmin')
|
||||
App.Config.set('microsoft365', { prio: 5000, name: __('Microsoft 365'), parent: '#channels', target: '#channels/microsoft365', controller: App.ChannelMicrosoft365, permission: ['admin.channel_microsoft365'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
class ChannelSms extends App.ControllerTabs
|
||||
requiredPermission: 'admin.channel_sms'
|
||||
header: 'SMS'
|
||||
header: __('SMS')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title 'SMS', true
|
||||
@title __('SMS'), true
|
||||
@tabs = [
|
||||
{
|
||||
name: 'Accounts',
|
||||
name: __('Accounts'),
|
||||
target: 'c-account',
|
||||
controller: ChannelSmsAccountOverview,
|
||||
},
|
||||
|
@ -136,11 +136,11 @@ class ChannelSmsAccountOverview extends App.Controller
|
|||
)
|
||||
|
||||
class ChannelSmsAccount extends App.ControllerModal
|
||||
head: 'SMS Account'
|
||||
head: __('SMS Account')
|
||||
buttonCancel: true
|
||||
centerButtons: [
|
||||
{
|
||||
text: 'Test'
|
||||
text: __('Test')
|
||||
className: 'js-test'
|
||||
}
|
||||
]
|
||||
|
@ -164,7 +164,7 @@ class ChannelSmsAccount extends App.ControllerModal
|
|||
el: el.find('.js-channelAdapterSelector')
|
||||
model:
|
||||
configure_attributes: [
|
||||
{ name: 'options::adapter', display: 'Provider', tag: 'select', null: false, options: options, nulloption: true }
|
||||
{ name: 'options::adapter', display: __('Provider'), tag: 'select', null: false, options: options, nulloption: true }
|
||||
]
|
||||
className: ''
|
||||
params: @channel
|
||||
|
@ -198,7 +198,7 @@ class ChannelSmsAccount extends App.ControllerModal
|
|||
el: el.find('.js-channelWebhook')
|
||||
model:
|
||||
configure_attributes: [
|
||||
{ name: 'options::webhook', display: 'Webhook', tag: 'input', type: 'text', limit: 200, null: false, default: webhook, disabled: true },
|
||||
{ name: 'options::webhook', display: __('Webhook'), tag: 'input', type: 'text', limit: 200, null: false, default: webhook, disabled: true },
|
||||
]
|
||||
className: ''
|
||||
params: @channel
|
||||
|
@ -262,7 +262,7 @@ class ChannelSmsAccount extends App.ControllerModal
|
|||
fail: (settings, details) ->
|
||||
ui.log 'errors', details
|
||||
ui.formEnable(e)
|
||||
ui.showAlert(details.error_human || details.error || 'Unable to update object!')
|
||||
ui.showAlert(details.error_human || details.error || __('Unable to update object!'))
|
||||
)
|
||||
|
||||
onTest: (e) ->
|
||||
|
@ -273,11 +273,11 @@ class ChannelSmsAccount extends App.ControllerModal
|
|||
)
|
||||
|
||||
class ChannelSmsNotification extends App.ControllerModal
|
||||
head: 'SMS Notification'
|
||||
head: __('SMS Notification')
|
||||
buttonCancel: true
|
||||
centerButtons: [
|
||||
{
|
||||
text: 'Test'
|
||||
text: __('Test')
|
||||
className: 'js-test'
|
||||
}
|
||||
]
|
||||
|
@ -303,7 +303,7 @@ class ChannelSmsNotification extends App.ControllerModal
|
|||
el: el.find('.js-channelAdapterSelector')
|
||||
model:
|
||||
configure_attributes: [
|
||||
{ name: 'options::adapter', display: 'Provider', tag: 'select', null: false, options: options, nulloption: true }
|
||||
{ name: 'options::adapter', display: __('Provider'), tag: 'select', null: false, options: options, nulloption: true }
|
||||
]
|
||||
className: ''
|
||||
params: @channel
|
||||
|
@ -376,7 +376,7 @@ class ChannelSmsNotification extends App.ControllerModal
|
|||
fail: (settings, details) ->
|
||||
ui.log 'errors', details
|
||||
ui.formEnable(e)
|
||||
ui.showAlert(details.error_human || details.error || 'Unable to update object!')
|
||||
ui.showAlert(details.error_human || details.error || __('Unable to update object!'))
|
||||
)
|
||||
|
||||
onTest: (e) ->
|
||||
|
@ -387,15 +387,15 @@ class ChannelSmsNotification extends App.ControllerModal
|
|||
)
|
||||
|
||||
class TestModal extends App.ControllerModal
|
||||
head: 'Test SMS provider'
|
||||
head: __('Test SMS provider')
|
||||
buttonCancel: true
|
||||
|
||||
content: ->
|
||||
form = new App.ControllerForm(
|
||||
model:
|
||||
configure_attributes: [
|
||||
{ name: 'recipient', display: 'Recipient', tag: 'input', null: false }
|
||||
{ name: 'message', display: 'Message', tag: 'input', null: false, default: 'Test message from Zammad' }
|
||||
{ name: 'recipient', display: __('Recipient'), tag: 'input', null: false }
|
||||
{ name: 'message', display: __('Message'), tag: 'input', null: false, default: __('Test message from Zammad') }
|
||||
]
|
||||
className: ''
|
||||
)
|
||||
|
@ -435,8 +435,8 @@ class TestModal extends App.ControllerModal
|
|||
data = JSON.parse(xhr.responseText)
|
||||
@formEnable(@el)
|
||||
@el.find('.js-danger')
|
||||
.text(@T(data.error || 'Unable to perform test'))
|
||||
.text(@T(data.error || __('Unable to perform test')))
|
||||
.removeClass('hide')
|
||||
)
|
||||
|
||||
App.Config.set('SMS', { prio: 3100, name: 'SMS', parent: '#channels', target: '#channels/sms', controller: ChannelSms, permission: ['admin.channel_sms'] }, 'NavBarAdmin')
|
||||
App.Config.set('SMS', { prio: 3100, name: __('SMS'), parent: '#channels', target: '#channels/sms', controller: ChannelSms, permission: ['admin.channel_sms'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -63,7 +63,7 @@ class ChannelTelegram extends App.ControllerSubContent
|
|||
e.preventDefault()
|
||||
id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerConfirm(
|
||||
message: 'Sure?'
|
||||
message: __('Sure?')
|
||||
callback: =>
|
||||
@ajax(
|
||||
id: 'telegram_delete'
|
||||
|
@ -104,7 +104,7 @@ class ChannelTelegram extends App.ControllerSubContent
|
|||
)
|
||||
|
||||
class BotAdd extends App.ControllerModal
|
||||
head: 'Add Telegram Bot'
|
||||
head: __('Add Telegram Bot')
|
||||
shown: true
|
||||
button: 'Add'
|
||||
buttonCancel: true
|
||||
|
@ -149,12 +149,12 @@ class BotAdd extends App.ControllerModal
|
|||
error: (xhr) =>
|
||||
data = JSON.parse(xhr.responseText)
|
||||
@formEnable(e)
|
||||
error_message = App.i18n.translateContent(data.error || 'Unable to save Bot.')
|
||||
error_message = App.i18n.translateContent(data.error || __('Unable to save Bot.'))
|
||||
@el.find('.alert').removeClass('hidden').text(error_message)
|
||||
)
|
||||
|
||||
class BotEdit extends App.ControllerModal
|
||||
head: 'Telegram Account'
|
||||
head: __('Telegram Account')
|
||||
shown: true
|
||||
buttonCancel: true
|
||||
|
||||
|
@ -197,8 +197,8 @@ class BotEdit extends App.ControllerModal
|
|||
error: (xhr) =>
|
||||
data = JSON.parse(xhr.responseText)
|
||||
@formEnable(e)
|
||||
error_message = App.i18n.translateContent(data.error || 'Unable to save changes.')
|
||||
error_message = App.i18n.translateContent(data.error || __('Unable to save changes.'))
|
||||
@el.find('.alert').removeClass('hidden').text(error_message)
|
||||
)
|
||||
|
||||
App.Config.set('Telegram', { prio: 5100, name: 'Telegram', parent: '#channels', target: '#channels/telegram', controller: ChannelTelegram, permission: ['admin.channel_telegram'] }, 'NavBarAdmin')
|
||||
App.Config.set('Telegram', { prio: 5100, name: __('Telegram'), parent: '#channels', target: '#channels/telegram', controller: ChannelTelegram, permission: ['admin.channel_telegram'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -102,7 +102,7 @@ class ChannelTwitter extends App.ControllerSubContent
|
|||
e.preventDefault()
|
||||
id = $(e.target).closest('.action').data('id')
|
||||
new App.ControllerConfirm(
|
||||
message: 'Sure?'
|
||||
message: __('Sure?')
|
||||
callback: =>
|
||||
@ajax(
|
||||
id: 'twitter_delete'
|
||||
|
@ -143,7 +143,7 @@ class ChannelTwitter extends App.ControllerSubContent
|
|||
)
|
||||
|
||||
class AppConfig extends App.ControllerModal
|
||||
head: 'Connect Twitter App'
|
||||
head: __('Connect Twitter App')
|
||||
shown: true
|
||||
button: 'Connect'
|
||||
buttonCancel: true
|
||||
|
@ -185,15 +185,15 @@ class AppConfig extends App.ControllerModal
|
|||
@isChanged = true
|
||||
@close()
|
||||
fail: =>
|
||||
@el.find('.alert').removeClass('hidden').text('Unable to create entry.')
|
||||
@el.find('.alert').removeClass('hidden').text(__('Unable to create entry.'))
|
||||
)
|
||||
return
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to verify App.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to verify App.'))
|
||||
)
|
||||
|
||||
class AccountEdit extends App.ControllerModal
|
||||
head: 'Twitter Account'
|
||||
head: __('Twitter Account')
|
||||
shown: true
|
||||
buttonCancel: true
|
||||
|
||||
|
@ -296,7 +296,7 @@ class AccountEdit extends App.ControllerModal
|
|||
error: (xhr) =>
|
||||
data = JSON.parse(xhr.responseText)
|
||||
@formEnable(e)
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || 'Unable to save changes.')
|
||||
@el.find('.alert').removeClass('hidden').text(data.error || __('Unable to save changes.'))
|
||||
)
|
||||
|
||||
App.Config.set('Twitter', { prio: 5000, name: 'Twitter', parent: '#channels', target: '#channels/twitter', controller: ChannelTwitter, permission: ['admin.channel_twitter'] }, 'NavBarAdmin')
|
||||
App.Config.set('Twitter', { prio: 5000, name: __('Twitter'), parent: '#channels', target: '#channels/twitter', controller: ChannelTwitter, permission: ['admin.channel_twitter'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
class ChannelWeb extends App.ControllerTabs
|
||||
requiredPermission: 'admin.channel_web'
|
||||
header: 'Web'
|
||||
header: __('Web')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title 'Web', true
|
||||
@title __('Web'), true
|
||||
|
||||
@tabs = [
|
||||
{
|
||||
name: 'Settings',
|
||||
name: __('Settings'),
|
||||
target: 'w-setting',
|
||||
controller: App.SettingsArea, params: { area: 'CustomerWeb::Base' },
|
||||
},
|
||||
|
@ -16,4 +16,4 @@ class ChannelWeb extends App.ControllerTabs
|
|||
|
||||
@render()
|
||||
|
||||
App.Config.set('Web', { prio: 1000, name: 'Web', parent: '#channels', target: '#channels/web', controller: ChannelWeb, permission: ['admin.channel_web'] }, 'NavBarAdmin')
|
||||
App.Config.set('Web', { prio: 1000, name: __('Web'), parent: '#channels', target: '#channels/web', controller: ChannelWeb, permission: ['admin.channel_web'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -38,7 +38,7 @@ class App.DashboardFirstSteps extends App.Controller
|
|||
e.preventDefault()
|
||||
new App.InviteUser(
|
||||
#container: @el.closest('.content')
|
||||
head: 'Invite Colleagues'
|
||||
head: __('Invite Colleagues')
|
||||
screen: 'invite_agent'
|
||||
)
|
||||
|
||||
|
@ -46,7 +46,7 @@ class App.DashboardFirstSteps extends App.Controller
|
|||
e.preventDefault()
|
||||
new App.InviteUser(
|
||||
#container: @el.closest('.content')
|
||||
head: 'Invite Customer'
|
||||
head: __('Invite Customer')
|
||||
screen: 'invite_customer'
|
||||
signup: true
|
||||
)
|
||||
|
@ -82,7 +82,7 @@ class App.DashboardFirstSteps extends App.Controller
|
|||
e.preventDefault()
|
||||
|
||||
modal = new App.ControllerModal(
|
||||
head: 'Test Ticket'
|
||||
head: __('Test Ticket')
|
||||
#container: @el.parents('.content')
|
||||
content: @testTicketLoading
|
||||
shown: true
|
||||
|
|
|
@ -2,22 +2,22 @@ class App.FirstStepsClues extends App.Controller
|
|||
clues: [
|
||||
{
|
||||
container: '.js-dashboardMenuItem'
|
||||
headline: 'Dashboard'
|
||||
text: 'Here you see a quick overview of your and other agents\' performance.'
|
||||
headline: __('Dashboard')
|
||||
text: __('Here you see a quick overview of your and other agents\' performance.')
|
||||
actions: [
|
||||
'hover'
|
||||
]
|
||||
}
|
||||
{
|
||||
container: '.search-holder'
|
||||
headline: 'Search'
|
||||
text: 'Here you can search for tickets, 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"§.'
|
||||
headline: __('Search')
|
||||
text: __('Here you can search for tickets, 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"§.')
|
||||
actions: []
|
||||
}
|
||||
{
|
||||
container: '.user-menu .add'
|
||||
headline: 'Create'
|
||||
text: 'Here you can create new tickets. Also if you have the permissions you can create new customers and organizations.'
|
||||
headline: __('Create')
|
||||
text: __('Here you can create new tickets. Also if you have the permissions you can create new customers and organizations.')
|
||||
actions: [
|
||||
'hover .navigation',
|
||||
'hover .user-menu .add'
|
||||
|
@ -25,8 +25,8 @@ class App.FirstStepsClues extends App.Controller
|
|||
}
|
||||
{
|
||||
container: '.user-menu .user .dropdown-menu'
|
||||
headline: 'Personal Settings'
|
||||
text: 'Here you can sign out, change the frontend language and see your last viewed items.'
|
||||
headline: __('Personal Settings')
|
||||
text: __('Here you can sign out, change the frontend language and see your last viewed items.')
|
||||
actions: [
|
||||
'hover .navigation',
|
||||
'click .user-menu .user .js-action',
|
||||
|
@ -35,8 +35,8 @@ class App.FirstStepsClues extends App.Controller
|
|||
}
|
||||
{
|
||||
container: '.js-overviewsMenuItem'
|
||||
headline: 'Overviews'
|
||||
text: 'Here you find your ticket overviews for open, assigned and escalated tickets.'
|
||||
headline: __('Overviews')
|
||||
text: __('Here you find your ticket overviews for open, assigned and escalated tickets.')
|
||||
actions: [
|
||||
'hover'
|
||||
]
|
||||
|
|
|
@ -24,7 +24,7 @@ class Stats extends App.ControllerDashboardStatsBase
|
|||
for id, channel of data.StatsTicketChannelDistribution.channels
|
||||
channel.overal_percentage = Math.round((channel.inbound + channel.outbound) / totalTickets * 100) || 0
|
||||
|
||||
data.StatsTicketChannelDistribution.description = 'How many of your tickets are coming from email, phone, Twitter, or Facebook? (Shows percentages for both inbound and outbound tickets.)'
|
||||
data.StatsTicketChannelDistribution.description = __('How many of your tickets are coming from email, phone, Twitter, or Facebook? (Shows percentages for both inbound and outbound tickets.)')
|
||||
|
||||
content = App.view('dashboard/stats/ticket_channel_distribution')(data)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ class Stats extends App.ControllerDashboardStatsBase
|
|||
own: 0
|
||||
total: 0
|
||||
|
||||
data.StatsTicketEscalation.description = 'How many escalated tickets do you have open? (Mr. Bubbles gets grumpy if you have too many…)'
|
||||
data.StatsTicketEscalation.description = __('How many escalated tickets do you have open? (Mr. Bubbles gets grumpy if you have too many…)')
|
||||
|
||||
content = App.view('dashboard/stats/ticket_escalation')(data)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ class Stats extends App.ControllerDashboardStatsBase
|
|||
in_process: 0
|
||||
average_per_agent: 0
|
||||
|
||||
data.StatsTicketInProcess.description = 'What percentage of your tickets have you responded to, updated, or modified in some way today?'
|
||||
data.StatsTicketInProcess.description = __('What percentage of your tickets have you responded to, updated, or modified in some way today?')
|
||||
|
||||
content = App.view('dashboard/stats/ticket_in_process')(data)
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ class Stats extends App.ControllerDashboardStatsBase
|
|||
total: 0
|
||||
average_per_agent: 0
|
||||
|
||||
data.StatsTicketLoadMeasure.description = 'Out of all open tickets (company-wide), how many are assigned to you?'
|
||||
data.StatsTicketLoadMeasure.description = __('Out of all open tickets (company-wide), how many are assigned to you?')
|
||||
|
||||
content = App.view('dashboard/stats/ticket_load_measure')(data)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ class Stats extends App.ControllerDashboardStatsBase
|
|||
percent: 0
|
||||
average_per_agent: 0
|
||||
|
||||
data.StatsTicketReopen.description = 'How many of your tickets have been re-opened after being marked “closed”?'
|
||||
data.StatsTicketReopen.description = __('How many of your tickets have been re-opened after being marked “closed”?')
|
||||
|
||||
content = App.view('dashboard/stats/ticket_reopen')(data)
|
||||
if @$('.ticket_reopen').length > 0
|
||||
|
|
|
@ -7,7 +7,7 @@ class Stats extends App.ControllerDashboardStatsBase
|
|||
state: 'supergood'
|
||||
average_per_agent: 0
|
||||
|
||||
data.StatsTicketWaitingTime.description = 'How long has each customer had to wait, on average, to get a response from you today?'
|
||||
data.StatsTicketWaitingTime.description = __('How long has each customer had to wait, on average, to get a response from you today?')
|
||||
|
||||
content = App.view('dashboard/stats/ticket_waiting_time')(data)
|
||||
if @$('.ticket_waiting_time').length > 0
|
||||
|
|
|
@ -10,9 +10,9 @@ App.Config.set('User', {
|
|||
class: 'user'
|
||||
}, 'NavBarRight' )
|
||||
|
||||
App.Config.set('Admin', { prio: 9000, parent: '', name: 'Admin', translate: true, target: '#manage', icon: 'cog', permission: ['admin.*'] }, 'NavBarRight')
|
||||
App.Config.set('New', { prio: 20000, parent: '', name: 'New', translate: true, target: '#new', class: 'add', icon: 'plus' }, 'NavBarRight')
|
||||
App.Config.set('Misc', { prio: 90000, parent: '', name: 'Tools', translate: true, target: '#tools', child: true, class: 'tools' }, 'NavBar')
|
||||
App.Config.set('Admin', { prio: 9000, parent: '', name: __('Admin'), translate: true, target: '#manage', icon: 'cog', permission: ['admin.*'] }, 'NavBarRight')
|
||||
App.Config.set('New', { prio: 20000, parent: '', name: __('New'), translate: true, target: '#new', class: 'add', icon: 'plus' }, 'NavBarRight')
|
||||
App.Config.set('Misc', { prio: 90000, parent: '', name: __('Tools'), translate: true, target: '#tools', child: true, class: 'tools' }, 'NavBar')
|
||||
# only for testing
|
||||
#App.Config.set('Misc1', { prio: 1600, parent: '#tools', name: 'Test 1', target: '#test1', permission: ['admin'] }, 'NavBar')
|
||||
#App.Config.set('Misc2', { prio: 1700, parent: '#tools', name: 'Test 2', target: '#test2', permission: ['admin'] }, 'NavBar')
|
||||
#App.Config.set('Misc1', { prio: 1600, parent: '#tools', name: __('Test 1'), target: '#test1', permission: ['admin'] }, 'NavBar')
|
||||
#App.Config.set('Misc2', { prio: 1700, parent: '#tools', name: __('Test 2'), target: '#test2', permission: ['admin'] }, 'NavBar')
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
class CheckMk extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'check_mk_integration'
|
||||
featureName: 'Checkmk'
|
||||
featureName: __('Checkmk')
|
||||
featureConfig: 'check_mk_config'
|
||||
description: [
|
||||
['This service receives http requests or emails from %s and creates tickets with host and service.', 'Checkmk']
|
||||
['If the host and service has recovered, the ticket can be closed automatically.']
|
||||
[__('This service receives http requests or emails from %s and creates tickets with host and service.'), 'Checkmk']
|
||||
[__('If the host and service has recovered, the ticket can be closed automatically.')]
|
||||
]
|
||||
|
||||
render: =>
|
||||
|
@ -52,9 +52,9 @@ class Form extends App.Controller
|
|||
App.Config.set(
|
||||
'IntegrationCheckMk'
|
||||
{
|
||||
name: 'Checkmk'
|
||||
name: __('Checkmk')
|
||||
target: '#system/integration/check_mk'
|
||||
description: 'An open source monitoring tool.'
|
||||
description: __('An open source monitoring tool.')
|
||||
controller: CheckMk
|
||||
state: State
|
||||
permission: ['admin.integration.check_mk']
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
class Clearbit extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'clearbit_integration'
|
||||
featureName: 'Clearbit'
|
||||
featureName: __('Clearbit')
|
||||
featureConfig: 'clearbit_config'
|
||||
description: [
|
||||
['Automatically enrich your customers and organizations with fresh, up-to-date intel. Map data directly to object fields.
|
||||
']
|
||||
[__('Automatically enrich your customers and organizations with fresh, up-to-date intel. Map data directly to object fields.')]
|
||||
]
|
||||
|
||||
render: =>
|
||||
|
@ -62,9 +61,9 @@ class Form extends App.Controller
|
|||
if !@config
|
||||
@config = @currentConfig()
|
||||
settings = [
|
||||
{ name: 'api_key', display: 'API Key', tag: 'input', type: 'text', limit: 100, null: false, placeholder: '...', note: 'Your api key.' },
|
||||
{ name: 'organization_autocreate', display: 'Auto create', tag: 'boolean', type: 'boolean', null: false, note: 'Create organizations automatically if record has one.' },
|
||||
{ name: 'organization_shared', display: 'Shared', tag: 'boolean', type: 'boolean', null: false, note: 'New organizations are shared.' },
|
||||
{ name: 'api_key', display: __('API Key'), tag: 'input', type: 'text', limit: 100, null: false, placeholder: '...', note: __('Your api key.') },
|
||||
{ name: 'organization_autocreate', display: __('Auto create'), tag: 'boolean', type: 'boolean', null: false, note: __('Create organizations automatically if record has one.') },
|
||||
{ name: 'organization_shared', display: __('Shared'), tag: 'boolean', type: 'boolean', null: false, note: __('New organizations are shared.') },
|
||||
]
|
||||
|
||||
@html App.view('integration/clearbit')(
|
||||
|
@ -152,9 +151,9 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationClearbit'
|
||||
{
|
||||
name: 'Clearbit'
|
||||
name: __('Clearbit')
|
||||
target: '#system/integration/clearbit'
|
||||
description: 'A powerful service to get more information about your customers.'
|
||||
description: __('A powerful service to get more information about your customers.')
|
||||
controller: Clearbit
|
||||
state: State
|
||||
permission: ['admin.integration.clearbit']
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
class Cti extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'cti_integration'
|
||||
featureName: 'CTI (generic)'
|
||||
featureName: __('CTI (generic)')
|
||||
featureConfig: 'cti_config'
|
||||
description: [
|
||||
['This service shows you contacts of incoming calls and a caller list in realtime.']
|
||||
['Also caller id of outbound calls can be changed.']
|
||||
[__('This service shows you contacts of incoming calls and a caller list in realtime.')]
|
||||
[__('Also caller id of outbound calls can be changed.')]
|
||||
]
|
||||
events:
|
||||
'click .js-select': 'selectAll'
|
||||
|
@ -259,9 +259,9 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationCti'
|
||||
{
|
||||
name: 'CTI (generic)'
|
||||
name: __('CTI (generic)')
|
||||
target: '#system/integration/cti'
|
||||
description: 'Generic API to integrate VoIP service provider with realtime push.'
|
||||
description: __('Generic API to integrate VoIP service provider with realtime push.')
|
||||
controller: Cti
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class Exchange extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'exchange_integration'
|
||||
featureName: 'Exchange'
|
||||
featureName: __('Exchange')
|
||||
featureConfig: 'exchange_config'
|
||||
description: [
|
||||
['This service enables Zammad to connect with your Exchange server.']
|
||||
[__('This service enables Zammad to connect with your Exchange server.')]
|
||||
]
|
||||
events:
|
||||
'change .js-switch input': 'switch'
|
||||
|
@ -282,7 +282,7 @@ class ConnectionWizard extends App.ControllerWizardModal
|
|||
if !_.isEmpty(detailsRaw)
|
||||
details = JSON.parse(detailsRaw)
|
||||
@showSlide('js-discover')
|
||||
@showAlert('js-discover', details.error || 'Unable to perform backend.')
|
||||
@showAlert('js-discover', details.error || __('Unable to perform backend.'))
|
||||
)
|
||||
|
||||
folders: (e) =>
|
||||
|
@ -323,7 +323,7 @@ class ConnectionWizard extends App.ControllerWizardModal
|
|||
if !_.isEmpty(detailsRaw)
|
||||
details = JSON.parse(detailsRaw)
|
||||
@showSlide('js-bind')
|
||||
@showAlert('js-bind', details.error || 'Unable to perform backend.')
|
||||
@showAlert('js-bind', details.error || __('Unable to perform backend.'))
|
||||
)
|
||||
|
||||
foldersShow: (alreadyShown) =>
|
||||
|
@ -429,7 +429,7 @@ class ConnectionWizard extends App.ControllerWizardModal
|
|||
if !_.isEmpty(detailsRaw)
|
||||
details = JSON.parse(detailsRaw)
|
||||
@showSlide('js-folders')
|
||||
@showAlert('js-folders', details.error || 'Unable to perform backend.')
|
||||
@showAlert('js-folders', details.error || __('Unable to perform backend.'))
|
||||
)
|
||||
|
||||
mappingShow: (alreadyShown) =>
|
||||
|
@ -554,9 +554,9 @@ class ConnectionWizard extends App.ControllerWizardModal
|
|||
App.Config.set(
|
||||
'IntegrationExchange'
|
||||
{
|
||||
name: 'Exchange'
|
||||
name: __('Exchange')
|
||||
target: '#system/integration/exchange'
|
||||
description: 'Exchange integration for contacts management.'
|
||||
description: __('Exchange integration for contacts management.')
|
||||
controller: Exchange
|
||||
state: State
|
||||
permission: ['admin.integration.exchange']
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class GitHub extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'github_integration'
|
||||
featureName: 'GitHub'
|
||||
featureName: __('GitHub')
|
||||
featureConfig: 'github_config'
|
||||
description: [
|
||||
['This service allows you to connect %s with %s.', 'GitHub', 'Zammad']
|
||||
[__('This service allows you to connect %s with %s.'), 'GitHub', 'Zammad']
|
||||
]
|
||||
events:
|
||||
'change .js-switch input': 'switch'
|
||||
|
@ -60,7 +60,7 @@ class Form extends App.Controller
|
|||
details = data.responseJSON || {}
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to save!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to save!'))
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -71,9 +71,9 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationGitHub'
|
||||
{
|
||||
name: 'GitHub'
|
||||
name: __('GitHub')
|
||||
target: '#system/integration/github'
|
||||
description: 'Link GitHub issues to your tickets.'
|
||||
description: __('Link GitHub issues to your tickets.')
|
||||
controller: GitHub
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class GitLab extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'gitlab_integration'
|
||||
featureName: 'GitLab'
|
||||
featureName: __('GitLab')
|
||||
featureConfig: 'gitlab_config'
|
||||
description: [
|
||||
['This service allows you to connect %s with %s.', 'GitLab', 'Zammad']
|
||||
[__('This service allows you to connect %s with %s.'), 'GitLab', 'Zammad']
|
||||
]
|
||||
events:
|
||||
'change .js-switch input': 'switch'
|
||||
|
@ -60,7 +60,7 @@ class Form extends App.Controller
|
|||
details = data.responseJSON || {}
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to save!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to save!'))
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -71,9 +71,9 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationGitLab'
|
||||
{
|
||||
name: 'GitLab'
|
||||
name: __('GitLab')
|
||||
target: '#system/integration/gitlab'
|
||||
description: 'Link GitLab issues to your tickets.'
|
||||
description: __('Link GitLab issues to your tickets.')
|
||||
controller: GitLab
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
class Icinga extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'icinga_integration'
|
||||
featureName: 'Icinga'
|
||||
featureName: __('Icinga')
|
||||
featureConfig: 'icinga_config'
|
||||
description: [
|
||||
['This service receives emails from %s and creates tickets with host and service.', 'Icinga']
|
||||
['If the host and service is recovered again, the ticket will be closed automatically.']
|
||||
[__('This service receives emails from %s and creates tickets with host and service.'), 'Icinga']
|
||||
[__('If the host and service is recovered again, the ticket will be closed automatically.')]
|
||||
]
|
||||
|
||||
render: =>
|
||||
|
@ -21,9 +21,9 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationIcinga'
|
||||
{
|
||||
name: 'Icinga'
|
||||
name: __('Icinga')
|
||||
target: '#system/integration/icinga'
|
||||
description: 'An open source monitoring tool.'
|
||||
description: __('An open source monitoring tool.')
|
||||
controller: Icinga
|
||||
state: State
|
||||
permission: ['admin.integration.icinga']
|
||||
|
|
|
@ -3,7 +3,7 @@ class Idoit extends App.ControllerIntegrationBase
|
|||
featureName: 'i-doit'
|
||||
featureConfig: 'idoit_config'
|
||||
description: [
|
||||
['This service allows you to connect %s with %s.', 'i-doit', 'Zammad']
|
||||
[__('This service allows you to connect %s with %s.'), 'i-doit', 'Zammad']
|
||||
]
|
||||
events:
|
||||
'change .js-switch input': 'switch'
|
||||
|
@ -73,7 +73,7 @@ class Form extends App.Controller
|
|||
details = data.responseJSON || {}
|
||||
@notify(
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to save!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to save!'))
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -86,7 +86,7 @@ App.Config.set(
|
|||
{
|
||||
name: 'i-doit'
|
||||
target: '#system/integration/idoit'
|
||||
description: 'CMDB to document complex relations of your network components.'
|
||||
description: __('CMDB to document complex relations of your network components.')
|
||||
controller: Idoit
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class Ldap extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'ldap_integration'
|
||||
featureName: 'LDAP'
|
||||
featureName: __('LDAP')
|
||||
featureConfig: 'ldap_config'
|
||||
description: [
|
||||
['This service enables Zammad to connect with your LDAP server.']
|
||||
[__('This service enables Zammad to connect with your LDAP server.')]
|
||||
]
|
||||
events:
|
||||
'change .js-switch input': 'switch'
|
||||
|
@ -315,7 +315,7 @@ class ConnectionWizard extends App.ControllerWizardModal
|
|||
if !_.isEmpty(detailsRaw)
|
||||
details = JSON.parse(detailsRaw)
|
||||
@showSlide('js-discover')
|
||||
@showAlert('js-discover', details.error || 'Unable to perform backend.')
|
||||
@showAlert('js-discover', details.error || __('Unable to perform backend.'))
|
||||
)
|
||||
|
||||
|
||||
|
@ -345,12 +345,12 @@ class ConnectionWizard extends App.ControllerWizardModal
|
|||
|
||||
if _.isEmpty(data.user_attributes)
|
||||
@showSlide('js-bind')
|
||||
@showAlert('js-bind', 'Unable to retrive user information, please check your bind user permissions.')
|
||||
@showAlert('js-bind', __('Unable to retrive user information, please check your bind user permissions.'))
|
||||
return
|
||||
|
||||
if _.isEmpty(data.groups)
|
||||
@showSlide('js-bind')
|
||||
@showAlert('js-bind', 'Unable to retrive group information, please check your bind user permissions.')
|
||||
@showAlert('js-bind', __('Unable to retrive group information, please check your bind user permissions.'))
|
||||
return
|
||||
|
||||
# update config if successful
|
||||
|
@ -384,7 +384,7 @@ class ConnectionWizard extends App.ControllerWizardModal
|
|||
if !_.isEmpty(detailsRaw)
|
||||
details = JSON.parse(detailsRaw)
|
||||
@showSlide('js-bind')
|
||||
@showAlert('js-bind', details.error || 'Unable to perform backend.')
|
||||
@showAlert('js-bind', details.error || __('Unable to perform backend.'))
|
||||
)
|
||||
|
||||
mappingShow: (alreadyShown) =>
|
||||
|
@ -572,9 +572,9 @@ class ConnectionWizard extends App.ControllerWizardModal
|
|||
App.Config.set(
|
||||
'IntegrationLDAP'
|
||||
{
|
||||
name: 'LDAP'
|
||||
name: __('LDAP')
|
||||
target: '#system/integration/ldap'
|
||||
description: 'LDAP integration for user management.'
|
||||
description: __('LDAP integration for user management.')
|
||||
controller: Ldap
|
||||
state: State
|
||||
permission: ['admin.integration.ldap']
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
class Monit extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'monit_integration'
|
||||
featureName: 'Monit'
|
||||
featureName: __('Monit')
|
||||
featureConfig: 'monit_config'
|
||||
description: [
|
||||
['This service receives emails from %s and creates tickets with host and service.', 'Monit']
|
||||
['If the host and service is recovered again, the ticket will be closed automatically.']
|
||||
[__('This service receives emails from %s and creates tickets with host and service.'), 'Monit']
|
||||
[__('If the host and service is recovered again, the ticket will be closed automatically.')]
|
||||
]
|
||||
|
||||
render: =>
|
||||
|
@ -21,9 +21,9 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationMonit'
|
||||
{
|
||||
name: 'Monit'
|
||||
name: __('Monit')
|
||||
target: '#system/integration/monit'
|
||||
description: 'An open source monitoring tool.'
|
||||
description: __('An open source monitoring tool.')
|
||||
controller: Monit
|
||||
state: State
|
||||
permission: ['admin.integration.monit']
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
class Nagios extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'nagios_integration'
|
||||
featureName: 'Nagios'
|
||||
featureName: __('Nagios')
|
||||
featureConfig: 'nagios_config'
|
||||
description: [
|
||||
['This service receives emails from %s and creates tickets with host and service.', 'Nagios']
|
||||
['If the host and service is recovered again, the ticket will be closed automatically.']
|
||||
[__('This service receives emails from %s and creates tickets with host and service.'), 'Nagios']
|
||||
[__('If the host and service is recovered again, the ticket will be closed automatically.')]
|
||||
]
|
||||
|
||||
render: =>
|
||||
|
@ -21,9 +21,9 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationNagios'
|
||||
{
|
||||
name: 'Nagios'
|
||||
name: __('Nagios')
|
||||
target: '#system/integration/nagios'
|
||||
description: 'An open source monitoring tool.'
|
||||
description: __('An open source monitoring tool.')
|
||||
controller: Nagios
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
class Placetel extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'placetel_integration'
|
||||
featureName: 'Placetel'
|
||||
featureName: __('Placetel')
|
||||
featureConfig: 'placetel_config'
|
||||
description: [
|
||||
['This service shows you contacts of incoming calls and a caller list in realtime.']
|
||||
['Also caller id of outbound calls can be changed.']
|
||||
[__('This service shows you contacts of incoming calls and a caller list in realtime.')]
|
||||
[__('Also caller id of outbound calls can be changed.')]
|
||||
]
|
||||
events:
|
||||
'click .js-select': 'selectAll'
|
||||
|
@ -185,9 +185,9 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationPlacetel'
|
||||
{
|
||||
name: 'Placetel'
|
||||
name: __('Placetel')
|
||||
target: '#system/integration/placetel'
|
||||
description: 'VoIP service provider with realtime push.'
|
||||
description: __('VoIP service provider with realtime push.')
|
||||
controller: Placetel
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ class SipgateIo extends App.ControllerIntegrationBase
|
|||
featureName: 'sipgate.io'
|
||||
featureConfig: 'sipgate_config'
|
||||
description: [
|
||||
['This service shows you contacts of incoming calls and a caller list in realtime.']
|
||||
['Also caller id of outbound calls can be changed.']
|
||||
[__('This service shows you contacts of incoming calls and a caller list in realtime.')]
|
||||
[__('Also caller id of outbound calls can be changed.')]
|
||||
]
|
||||
events:
|
||||
'click .js-select': 'selectAll'
|
||||
|
@ -187,7 +187,7 @@ App.Config.set(
|
|||
{
|
||||
name: 'sipgate.io'
|
||||
target: '#system/integration/sipgate'
|
||||
description: 'VoIP service provider with realtime push.'
|
||||
description: __('VoIP service provider with realtime push.')
|
||||
controller: SipgateIo
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
class Slack extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'slack_integration'
|
||||
featureName: 'Slack'
|
||||
featureName: __('Slack')
|
||||
featureConfig: 'slack_config'
|
||||
description: [
|
||||
['This service sends notifications to your %s channel.', 'Slack']
|
||||
['To set up this service you need to create a new |"Incoming webhook"| in your %s integration panel, and enter the web hook URL below.', 'Slack']
|
||||
[__('This service sends notifications to your %s channel.'), 'Slack']
|
||||
[__('To set up this service you need to create a new |"Incoming webhook"| in your %s integration panel, and enter the web hook URL below.'), 'Slack']
|
||||
]
|
||||
events:
|
||||
'click .js-submit': 'update'
|
||||
|
@ -26,12 +26,12 @@ class Slack extends App.ControllerIntegrationBase
|
|||
escalation_warning: '5. Ticket Escalation Warning'
|
||||
|
||||
configureAttributes = [
|
||||
{ name: 'types', display: 'Trigger', tag: 'checkbox', options: options, 'null': false, class: 'vertical', note: 'When notification is being sent.' },
|
||||
{ name: 'group_ids', display: 'Group', tag: 'select', relation: 'Group', multiple: true, 'null': false, note: 'Only for these groups.' },
|
||||
{ name: 'webhook', display: 'Webhook', tag: 'input', type: 'url', limit: 200, 'null': false, placeholder: 'https://hooks.slack.com/services/...' },
|
||||
{ name: 'username', display: 'Username', tag: 'input', type: 'text', limit: 100, 'null': false, placeholder: 'username' },
|
||||
{ name: 'channel', display: 'Channel', tag: 'input', type: 'text', limit: 100, 'null': true, placeholder: '#channel' },
|
||||
{ name: 'icon_url', display: 'Icon Url', tag: 'input', type: 'url', limit: 200, 'null': true, placeholder: 'https://example.com/logo.png' },
|
||||
{ name: 'types', display: __('Trigger'), tag: 'checkbox', options: options, 'null': false, class: 'vertical', note: __('When notification is being sent.') },
|
||||
{ name: 'group_ids', display: __('Group'), tag: 'select', relation: 'Group', multiple: true, 'null': false, note: __('Only for these groups.') },
|
||||
{ name: 'webhook', display: __('Webhook'), tag: 'input', type: 'url', limit: 200, 'null': false, placeholder: 'https://hooks.slack.com/services/...' },
|
||||
{ name: 'username', display: __('Username'), tag: 'input', type: 'text', limit: 100, 'null': false, placeholder: 'username' },
|
||||
{ name: 'channel', display: __('Channel'), tag: 'input', type: 'text', limit: 100, 'null': true, placeholder: '#channel' },
|
||||
{ name: 'icon_url', display: __('Icon Url'), tag: 'input', type: 'url', limit: 200, 'null': true, placeholder: 'https://example.com/logo.png' },
|
||||
]
|
||||
|
||||
settings = []
|
||||
|
@ -81,10 +81,10 @@ class State
|
|||
App.Config.set(
|
||||
'IntegrationSlack'
|
||||
{
|
||||
name: 'Slack'
|
||||
name: __('Slack')
|
||||
target: '#system/integration/slack'
|
||||
description: 'A team communication tool for the 21st century. Compatible with tools like %s.'
|
||||
descriptionSubstitute: 'Mattermost, RocketChat'
|
||||
description: __('A team communication tool for the 21st century. Compatible with tools like %s.')
|
||||
descriptionSubstitute: __('Mattermost, RocketChat')
|
||||
controller: Slack
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class Index extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'smime_integration'
|
||||
featureName: 'S/MIME'
|
||||
featureName: __('S/MIME')
|
||||
featureConfig: 'smime_config'
|
||||
description: [
|
||||
['S/MIME (Secure/Multipurpose Internet Mail Extensions) is a widely accepted method (or more precisely, a protocol) for sending digitally signed and encrypted messages.']
|
||||
[__('S/MIME (Secure/Multipurpose Internet Mail Extensions) is a widely accepted method (or more precisely, a protocol) for sending digitally signed and encrypted messages.')]
|
||||
]
|
||||
events:
|
||||
'change .js-switch input': 'switch'
|
||||
|
@ -70,16 +70,16 @@ class Form extends App.Controller
|
|||
class Certificate extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: 'Add'
|
||||
buttonSubmit: __('Add')
|
||||
autoFocusOnFirstInput: false
|
||||
head: 'Add Certificate'
|
||||
head: __('Add Certificate')
|
||||
large: true
|
||||
|
||||
content: ->
|
||||
|
||||
# show start dialog
|
||||
content = $(App.view('integration/smime_certificate_add')(
|
||||
head: 'Add Certificate'
|
||||
head: __('Add Certificate')
|
||||
))
|
||||
content
|
||||
|
||||
|
@ -106,23 +106,23 @@ class Certificate extends App.ControllerModal
|
|||
details = data.responseJSON || {}
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to import!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to import!'))
|
||||
timeout: 6000
|
||||
)
|
||||
|
||||
class PrivateKey extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: 'Add'
|
||||
buttonSubmit: __('Add')
|
||||
autoFocusOnFirstInput: false
|
||||
head: 'Add Private Key'
|
||||
head: __('Add Private Key')
|
||||
large: true
|
||||
|
||||
content: ->
|
||||
|
||||
# show start dialog
|
||||
content = $(App.view('integration/smime_private_key_add')(
|
||||
head: 'Add Private Key'
|
||||
head: __('Add Private Key')
|
||||
))
|
||||
content
|
||||
|
||||
|
@ -149,7 +149,7 @@ class PrivateKey extends App.ControllerModal
|
|||
details = data.responseJSON || {}
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to import!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to import!'))
|
||||
timeout: 6000
|
||||
)
|
||||
|
||||
|
@ -178,7 +178,7 @@ class List extends App.Controller
|
|||
details = data.responseJSON || {}
|
||||
@notify(
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to load list of certificates!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to load list of certificates!'))
|
||||
)
|
||||
|
||||
# do something
|
||||
|
@ -210,7 +210,7 @@ class List extends App.Controller
|
|||
details = data.responseJSON || {}
|
||||
@notify(
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to save!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to save!'))
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -246,9 +246,9 @@ class State
|
|||
App.Config.set(
|
||||
'Integrationsmime'
|
||||
{
|
||||
name: 'S/MIME'
|
||||
name: __('S/MIME')
|
||||
target: '#system/integration/smime'
|
||||
description: 'S/MIME enables you to send digitally signed and encrypted messages.'
|
||||
description: __('S/MIME enables you to send digitally signed and encrypted messages.')
|
||||
controller: Index
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
class Branding extends App.ControllerTabs
|
||||
requiredPermission: 'admin.branding'
|
||||
header: 'Branding'
|
||||
header: __('Branding')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title 'Branding', true
|
||||
@title __('Branding'), true
|
||||
@tabs = [
|
||||
{ name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Branding' } }
|
||||
{ name: __('Base'), 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Branding' } }
|
||||
]
|
||||
@render()
|
||||
|
||||
App.Config.set('SettingBranding', { prio: 1200, parent: '#settings', name: 'Branding', target: '#settings/branding', controller: Branding, permission: ['admin.branding'] }, 'NavBarAdmin')
|
||||
App.Config.set('SettingBranding', { prio: 1200, parent: '#settings', name: __('Branding'), target: '#settings/branding', controller: Branding, permission: ['admin.branding'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class App.ManageKnowledgeBase extends App.ControllerTabs
|
||||
header: 'Knowledge Base'
|
||||
header: __('Knowledge Base')
|
||||
headerSwitchName: 'kb-activate'
|
||||
|
||||
events:
|
||||
|
@ -59,7 +59,7 @@ class App.ManageKnowledgeBase extends App.ControllerTabs
|
|||
@renderNonExistant()
|
||||
|
||||
renderNonExistant: ->
|
||||
@renderScreenError(detail: 'No Knowledge Base. Please create first Knowledge Base', el: @$('.page-content'))
|
||||
@renderScreenError(detail: __('No Knowledge Base. Please create first Knowledge Base'), el: @$('.page-content'))
|
||||
@headerSwitchInput.prop('checked', false)
|
||||
|
||||
@modal = new App.KnowledgeBaseNewModal(
|
||||
|
@ -96,22 +96,22 @@ class App.ManageKnowledgeBase extends App.ControllerTabs
|
|||
|
||||
@tabs = [
|
||||
{
|
||||
name: 'Theme'
|
||||
name: __('Theme')
|
||||
target: 'style'
|
||||
controller: App.KnowledgeBaseForm
|
||||
params: _.extend({}, params, { screen: 'style', split: true })
|
||||
},{
|
||||
name: 'Languages'
|
||||
name: __('Languages')
|
||||
target: 'languages'
|
||||
controller: App.KnowledgeBaseForm
|
||||
params: _.extend({}, params, { screen: 'languages' })
|
||||
},{
|
||||
name: 'Public Menu'
|
||||
name: __('Public Menu')
|
||||
target: 'public_menu'
|
||||
controller: App.KnowledgeBasePublicMenuManager
|
||||
params: _.extend({}, params, { screen: 'public_menu' })
|
||||
},{
|
||||
name: 'Delete'
|
||||
name: __('Delete')
|
||||
target: 'delete'
|
||||
controller: App.KnowledgeBaseDelete
|
||||
params: params
|
||||
|
@ -120,7 +120,7 @@ class App.ManageKnowledgeBase extends App.ControllerTabs
|
|||
|
||||
if !App.Config.get('system_online_service')
|
||||
@tabs.splice(-1, 0, {
|
||||
name: 'Custom URL'
|
||||
name: __('Custom URL')
|
||||
target: 'custom_address'
|
||||
controller: App.KnowledgeBaseCustomAddressForm,
|
||||
params: _.extend({}, params, { screen: 'custom_address' })
|
||||
|
@ -130,4 +130,4 @@ class App.ManageKnowledgeBase extends App.ControllerTabs
|
|||
|
||||
@headerSwitchInput.prop('checked', App.KnowledgeBase.find(@knowledge_base_id).active)
|
||||
|
||||
App.Config.set('KnowledgeBase', { prio: 10000, name: 'Knowledge Base', parent: '#manage', target: '#manage/knowledge_base', controller: App.ManageKnowledgeBase, permission: ['admin.knowledge_base'] }, 'NavBarAdmin')
|
||||
App.Config.set('KnowledgeBase', { prio: 10000, name: __('Knowledge Base'), parent: '#manage', target: '#manage/knowledge_base', controller: App.ManageKnowledgeBase, permission: ['admin.knowledge_base'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
class Security extends App.ControllerTabs
|
||||
requiredPermission: 'admin.security'
|
||||
header: 'Security'
|
||||
header: __('Security')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title 'Security', true
|
||||
@title __('Security'), true
|
||||
@tabs = [
|
||||
{ name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Security::Base' } }
|
||||
{ name: 'Password', 'target': 'password', controller: App.SettingsArea, params: { area: 'Security::Password' } }
|
||||
#{ name: 'Authentication', 'target': 'auth', controller: App.SettingsArea, params: { area: 'Security::Authentication' } }
|
||||
{ name: 'Third-party Applications', 'target': 'third_party_auth', controller: App.SettingsArea, params: { area: 'Security::ThirdPartyAuthentication' } }
|
||||
{ name: __('Base'), 'target': 'base', controller: App.SettingsArea, params: { area: 'Security::Base' } }
|
||||
{ name: __('Password'), 'target': 'password', controller: App.SettingsArea, params: { area: 'Security::Password' } }
|
||||
#{ name: __('Authentication'), 'target': 'auth', controller: App.SettingsArea, params: { area: 'Security::Authentication' } }
|
||||
{ name: __('Third-party Applications'), 'target': 'third_party_auth', controller: App.SettingsArea, params: { area: 'Security::ThirdPartyAuthentication' } }
|
||||
]
|
||||
@render()
|
||||
|
||||
App.Config.set('SettingSecurity', { prio: 1600, parent: '#settings', name: 'Security', target: '#settings/security', controller: Security, permission: ['admin.security'] }, 'NavBarAdmin')
|
||||
|
||||
App.Config.set('SettingSecurity', { prio: 1600, parent: '#settings', name: __('Security'), target: '#settings/security', controller: Security, permission: ['admin.security'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
class System extends App.ControllerTabs
|
||||
requiredPermission: 'admin.setting_system'
|
||||
header: 'System'
|
||||
header: __('System')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title 'System', true
|
||||
@title __('System'), true
|
||||
@tabs = []
|
||||
if !App.Config.get('system_online_service')
|
||||
@tabs.push { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Base' } }
|
||||
@tabs.push { name: 'Services', 'target': 'services', controller: App.SettingsArea, params: { area: 'System::Services' } }
|
||||
@tabs.push { name: __('Base'), 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Base' } }
|
||||
@tabs.push { name: __('Services'), 'target': 'services', controller: App.SettingsArea, params: { area: 'System::Services' } }
|
||||
if !App.Config.get('system_online_service')
|
||||
@tabs.push { name: 'Storage', 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } }
|
||||
@tabs.push { name: __('Storage'), 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } }
|
||||
if !App.Config.get('system_online_service')
|
||||
@tabs.push { name: 'Network', 'target': 'network', controller: App.SettingsArea, params: { area: 'System::Network' } }
|
||||
@tabs.push { name: 'Frontend', 'target': 'ui', controller: App.SettingsArea, params: { area: 'System::UI' } }
|
||||
@tabs.push { name: __('Network'), 'target': 'network', controller: App.SettingsArea, params: { area: 'System::Network' } }
|
||||
@tabs.push { name: __('Frontend'), 'target': 'ui', controller: App.SettingsArea, params: { area: 'System::UI' } }
|
||||
@render()
|
||||
|
||||
App.Config.set('SettingSystem', { prio: 1400, parent: '#settings', name: 'System', target: '#settings/system', controller: System, permission: ['admin.setting_system'] }, 'NavBarAdmin')
|
||||
App.Config.set('SettingSystem', { prio: 1400, parent: '#settings', name: __('System'), target: '#settings/system', controller: System, permission: ['admin.setting_system'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
class Ticket extends App.ControllerTabs
|
||||
requiredPermission: 'admin.ticket'
|
||||
header: 'Ticket'
|
||||
header: __('Ticket')
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@title('Ticket', true)
|
||||
@tabs = [
|
||||
{ name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Ticket::Base' } }
|
||||
{ name: 'Number', 'target': 'number', controller: App.SettingsArea, params: { area: 'Ticket::Number' } }
|
||||
{ name: 'Auto Assignment', 'target': 'auto_assignment', controller: App.SettingTicketAutoAssignment }
|
||||
{ name: __('Base'), 'target': 'base', controller: App.SettingsArea, params: { area: 'Ticket::Base' } }
|
||||
{ name: __('Number'), 'target': 'number', controller: App.SettingsArea, params: { area: 'Ticket::Number' } }
|
||||
{ name: __('Auto Assignment'), 'target': 'auto_assignment', controller: App.SettingTicketAutoAssignment }
|
||||
]
|
||||
@render()
|
||||
|
||||
App.Config.set('SettingTicket', { prio: 1700, parent: '#settings', name: 'Ticket', target: '#settings/ticket', controller: Ticket, permission: ['admin.ticket'] }, 'NavBarAdmin')
|
||||
App.Config.set('SettingTicket', { prio: 1700, parent: '#settings', name: __('Ticket'), target: '#settings/ticket', controller: Ticket, permission: ['admin.ticket'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -22,7 +22,7 @@ class App.SettingTicketAutoAssignment extends App.ControllerSubContent
|
|||
@html(App.view('settings/ticket_auto_assignment')())
|
||||
|
||||
configure_attributes = [
|
||||
{ name: 'condition', display: 'Conditions for effected objects', tag: 'ticket_selector', null: false, preview: false, action: false, hasChanged: false, article: false },
|
||||
{ name: 'condition', display: __('Conditions for effected objects'), tag: 'ticket_selector', null: false, preview: false, action: false, hasChanged: false, article: false },
|
||||
]
|
||||
|
||||
ticket_auto_assignment_selector = App.Setting.get('ticket_auto_assignment_selector')
|
||||
|
@ -36,7 +36,7 @@ class App.SettingTicketAutoAssignment extends App.ControllerSubContent
|
|||
)
|
||||
|
||||
configure_attributes = [
|
||||
{ name: 'user_ids', display: 'Exception users', tag: 'column_select', multiple: true, null: true, relation: 'User', sortBy: 'firstname' },
|
||||
{ name: 'user_ids', display: __('Exception users'), tag: 'column_select', multiple: true, null: true, relation: 'User', sortBy: 'firstname' },
|
||||
]
|
||||
|
||||
ticket_auto_assignment_user_ids_ignore = App.Setting.get('ticket_auto_assignment_user_ids_ignore')
|
||||
|
|
|
@ -23,19 +23,19 @@ class ElectronEvents extends App.Controller
|
|||
createDefault = ->
|
||||
menu = new Menu()
|
||||
menu.append(new MenuItem(
|
||||
label: 'Cut',
|
||||
label: __('Cut'),
|
||||
role: 'cut'
|
||||
))
|
||||
menu.append(new MenuItem(
|
||||
label: 'Copy',
|
||||
label: __('Copy'),
|
||||
role: 'copy'
|
||||
))
|
||||
menu.append(new MenuItem(
|
||||
label: 'Paste',
|
||||
label: __('Paste'),
|
||||
role: 'paste'
|
||||
))
|
||||
menu.append(new MenuItem(
|
||||
label: 'Select All',
|
||||
label: __('Select All'),
|
||||
role: 'selectall'
|
||||
))
|
||||
menu
|
||||
|
@ -81,7 +81,7 @@ class ElectronEvents extends App.Controller
|
|||
dataURL = badgeDataURL(content.toString())
|
||||
sendBadge(dataURL, 'You have unread messages (' + content + ')')
|
||||
else
|
||||
sendBadge(null, 'You have no unread messages')
|
||||
sendBadge(null, __('You have no unread messages'))
|
||||
|
||||
setBadgeOSX = (content) ->
|
||||
remote.app.dock.setBadge(content)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class App.KeyboardShortcutModal extends App.ControllerModal
|
||||
authenticateRequired: true
|
||||
large: true
|
||||
head: 'Keyboard Shortcuts'
|
||||
head: __('Keyboard Shortcuts')
|
||||
buttonClose: true
|
||||
buttonCancel: false
|
||||
buttonSubmit: false
|
||||
|
@ -82,16 +82,16 @@ App.Config.set(
|
|||
'keyboard_shortcuts',
|
||||
[
|
||||
{
|
||||
headline: 'Navigation'
|
||||
headline: __('Navigation')
|
||||
location: 'left'
|
||||
content: [
|
||||
{
|
||||
where: 'Used anywhere'
|
||||
where: __('Used anywhere')
|
||||
shortcuts: [
|
||||
{
|
||||
key: 'd'
|
||||
hotkeys: true
|
||||
description: 'Dashboard'
|
||||
description: __('Dashboard')
|
||||
globalEvent: 'dashboard'
|
||||
callback: ->
|
||||
$('#global-search').blur()
|
||||
|
@ -101,7 +101,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'o'
|
||||
hotkeys: true
|
||||
description: 'Overviews'
|
||||
description: __('Overviews')
|
||||
globalEvent: 'overview'
|
||||
callback: ->
|
||||
$('#global-search').blur()
|
||||
|
@ -111,7 +111,7 @@ App.Config.set(
|
|||
{
|
||||
key: 's'
|
||||
hotkeys: true
|
||||
description: 'Search'
|
||||
description: __('Search')
|
||||
globalEvent: 'search'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -120,7 +120,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'a'
|
||||
hotkeys: true
|
||||
description: 'Notifications'
|
||||
description: __('Notifications')
|
||||
globalEvent: 'notification'
|
||||
callback: ->
|
||||
$('#global-search').blur()
|
||||
|
@ -130,7 +130,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'n'
|
||||
hotkeys: true
|
||||
description: 'New Ticket'
|
||||
description: __('New Ticket')
|
||||
globalEvent: 'new-ticket'
|
||||
callback: ->
|
||||
$('#global-search').blur()
|
||||
|
@ -140,7 +140,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'e'
|
||||
hotkeys: true
|
||||
description: 'Logout'
|
||||
description: __('Logout')
|
||||
globalEvent: 'logout'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -149,7 +149,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'h'
|
||||
hotkeys: true
|
||||
description: 'List of shortcuts'
|
||||
description: __('List of shortcuts')
|
||||
globalEvent: 'list-of-shortcuts'
|
||||
callback: =>
|
||||
if window.location.hash is '#keyboard_shortcuts'
|
||||
|
@ -164,7 +164,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'w'
|
||||
hotkeys: true
|
||||
description: 'Close current tab'
|
||||
description: __('Close current tab')
|
||||
globalEvent: 'close-current-tab'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -173,7 +173,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'tab'
|
||||
hotkeys: true
|
||||
description: 'Next in tab'
|
||||
description: __('Next in tab')
|
||||
globalEvent: 'next-in-tab'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -196,7 +196,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'shift+tab'
|
||||
hotkeys: true
|
||||
description: 'Previous tab'
|
||||
description: __('Previous tab')
|
||||
globalEvent: 'previous-in-tab'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -219,7 +219,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'return'
|
||||
hotkeys: true
|
||||
description: 'Confirm/submit dialog'
|
||||
description: __('Confirm/submit dialog')
|
||||
globalEvent: 'submit'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -250,29 +250,29 @@ App.Config.set(
|
|||
]
|
||||
}
|
||||
{
|
||||
where: 'Used in lists (views and results)'
|
||||
where: __('Used in lists (views and results)')
|
||||
shortcuts: [
|
||||
{
|
||||
key: ['▲', '▼']
|
||||
description: 'Move up and down'
|
||||
description: __('Move up and down')
|
||||
}
|
||||
{
|
||||
key: ['◀', '▶']
|
||||
description: 'Move left and right'
|
||||
description: __('Move left and right')
|
||||
}
|
||||
{
|
||||
key: 'enter'
|
||||
description: 'Select item',
|
||||
description: __('Select item'),
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
where: 'Used in object views'
|
||||
where: __('Used in object views')
|
||||
shortcuts: [
|
||||
{
|
||||
key: '.'
|
||||
hotkeys: true
|
||||
description: 'Copy current object number (e. g. Ticket#) to clipboard'
|
||||
description: __('Copy current object number (e. g. Ticket#) to clipboard')
|
||||
callback: (shortcut, lastKey, modifier) ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
text = $('.active.content .js-objectNumber').first().data('number') || ''
|
||||
|
@ -298,30 +298,30 @@ App.Config.set(
|
|||
keyPrefix: '2x'
|
||||
key: '.'
|
||||
hotkeys: true
|
||||
description: '...add object title'
|
||||
description: __('...add object title')
|
||||
}
|
||||
{
|
||||
keyPrefix: '3x'
|
||||
key: '.'
|
||||
hotkeys: true
|
||||
description: '...add object link URL'
|
||||
description: __('...add object link URL')
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
headline: 'Translations'
|
||||
headline: __('Translations')
|
||||
location: 'left'
|
||||
content: [
|
||||
{
|
||||
where: 'Used anywhere (admin only)'
|
||||
where: __('Used anywhere (admin only)')
|
||||
shortcuts: [
|
||||
{
|
||||
admin: true
|
||||
key: 't'
|
||||
hotkeys: true
|
||||
description: 'Enable/disable inline translations'
|
||||
description: __('Enable/disable inline translations')
|
||||
globalEvent: 'translation-mode'
|
||||
}
|
||||
]
|
||||
|
@ -329,16 +329,16 @@ App.Config.set(
|
|||
]
|
||||
}
|
||||
{
|
||||
headline: 'Tickets'
|
||||
headline: __('Tickets')
|
||||
location: 'right'
|
||||
content: [
|
||||
{
|
||||
where: 'Used when viewing a Ticket'
|
||||
where: __('Used when viewing a Ticket')
|
||||
shortcuts: [
|
||||
{
|
||||
key: 'm'
|
||||
hotkeys: true
|
||||
description: 'Open note box'
|
||||
description: __('Open note box')
|
||||
globalEvent: 'article-note-open'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -348,7 +348,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'g'
|
||||
hotkeys: true
|
||||
description: 'Reply to last article'
|
||||
description: __('Reply to last article')
|
||||
globalEvent: 'article-reply'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -362,7 +362,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'j'
|
||||
hotkeys: true
|
||||
description: 'Set article to internal/public'
|
||||
description: __('Set article to internal/public')
|
||||
globalEvent: 'article-internal-public'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -371,7 +371,7 @@ App.Config.set(
|
|||
#{
|
||||
# key: 'm'
|
||||
# hotkeys: true
|
||||
# description: 'Open macro selection'
|
||||
# description: __('Open macro selection')
|
||||
# globalEvent: 'macro-open'
|
||||
# callback: ->
|
||||
# window.location.hash = '#ticket/create'
|
||||
|
@ -379,7 +379,7 @@ App.Config.set(
|
|||
{
|
||||
key: 'c'
|
||||
hotkeys: true
|
||||
description: 'Update as closed'
|
||||
description: __('Update as closed')
|
||||
globalEvent: 'task-update-close'
|
||||
callback: ->
|
||||
App.Event.trigger('keyboard_shortcuts_close')
|
||||
|
@ -390,29 +390,29 @@ App.Config.set(
|
|||
{
|
||||
key: ['◀', '▶']
|
||||
hotkeys: true
|
||||
description: 'Navigate through article'
|
||||
description: __('Navigate through article')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
where: 'Used when composing a Ticket article'
|
||||
where: __('Used when composing a Ticket article')
|
||||
shortcuts: [
|
||||
{
|
||||
key: '::'
|
||||
hotkeys: false
|
||||
description: 'Inserts Text module'
|
||||
description: __('Inserts Text module')
|
||||
globalEvent: 'richtext-insert-text-module'
|
||||
}
|
||||
{
|
||||
key: '??'
|
||||
hotkeys: false
|
||||
description: 'Inserts Knowledge Base answer'
|
||||
description: __('Inserts Knowledge Base answer')
|
||||
globalEvent: 'richtext-insert-kb-answer'
|
||||
}
|
||||
{
|
||||
key: '@@'
|
||||
hotkeys: false
|
||||
description: 'Inserts a mention for a user'
|
||||
description: __('Inserts a mention for a user')
|
||||
globalEvent: 'richtext-insert-mention-user'
|
||||
}
|
||||
]
|
||||
|
@ -421,101 +421,101 @@ App.Config.set(
|
|||
]
|
||||
}
|
||||
{
|
||||
headline: 'Text editing'
|
||||
headline: __('Text editing')
|
||||
location: 'right'
|
||||
content: [
|
||||
{
|
||||
where: 'Used when composing a text'
|
||||
where: __('Used when composing a text')
|
||||
shortcuts: [
|
||||
{
|
||||
key: 'u'
|
||||
magicKey: true
|
||||
description: 'Format as _underlined_'
|
||||
description: __('Format as _underlined_')
|
||||
globalEvent: 'richtext-underline'
|
||||
}
|
||||
{
|
||||
key: 'b'
|
||||
magicKey: true
|
||||
description: 'Format as |bold|'
|
||||
description: __('Format as |bold|')
|
||||
globalEvent: 'richtext-bold'
|
||||
}
|
||||
{
|
||||
key: 'i'
|
||||
magicKey: true
|
||||
description: 'Format as ||italic||'
|
||||
description: __('Format as ||italic||')
|
||||
globalEvent: 'richtext-italic'
|
||||
}
|
||||
{
|
||||
key: 's'
|
||||
magicKey: true
|
||||
description: 'Format as //strikethrough//'
|
||||
description: __('Format as //strikethrough//')
|
||||
globalEvent: 'richtext-strikethrough'
|
||||
}
|
||||
{
|
||||
key: 'v'
|
||||
magicKey: true
|
||||
description: 'Paste from clipboard'
|
||||
description: __('Paste from clipboard')
|
||||
globalEvent: 'clipboard-paste'
|
||||
}
|
||||
{
|
||||
key: 'v'
|
||||
magicKey: true
|
||||
shiftKey: true
|
||||
description: 'Paste from clipboard (plain text)'
|
||||
description: __('Paste from clipboard (plain text)')
|
||||
globalEvent: 'clipboard-paste-plain-text'
|
||||
}
|
||||
{
|
||||
key: 'f'
|
||||
hotkeys: true
|
||||
description: 'Removes the formatting'
|
||||
description: __('Removes the formatting')
|
||||
globalEvent: 'richtext-remove-formating'
|
||||
}
|
||||
{
|
||||
key: 'y'
|
||||
hotkeys: true
|
||||
description: '...of whole textarea'
|
||||
description: __('...of whole textarea')
|
||||
globalEvent: 'richtext-remove-formating-textarea'
|
||||
}
|
||||
{
|
||||
key: 'z'
|
||||
hotkeys: true,
|
||||
description: 'Inserts a horizontal rule'
|
||||
description: __('Inserts a horizontal rule')
|
||||
globalEvent: 'richtext-hr'
|
||||
}
|
||||
{
|
||||
key: 'l'
|
||||
hotkeys: true,
|
||||
description: 'Format as unordered list'
|
||||
description: __('Format as unordered list')
|
||||
globalEvent: 'richtext-ul'
|
||||
}
|
||||
{
|
||||
key: 'k'
|
||||
hotkeys: true,
|
||||
description: 'Format as ordered list'
|
||||
description: __('Format as ordered list')
|
||||
globalEvent: 'richtext-ol'
|
||||
}
|
||||
{
|
||||
key: '1'
|
||||
hotkeys: true,
|
||||
description: 'Format as h1 heading'
|
||||
description: __('Format as h1 heading')
|
||||
globalEvent: 'richtext-h1'
|
||||
}
|
||||
{
|
||||
key: '2'
|
||||
hotkeys: true,
|
||||
description: 'Format as h2 heading'
|
||||
description: __('Format as h2 heading')
|
||||
globalEvent: 'richtext-h2'
|
||||
}
|
||||
{
|
||||
key: '3'
|
||||
hotkeys: true,
|
||||
description: 'Format as h3 heading'
|
||||
description: __('Format as h3 heading')
|
||||
globalEvent: 'richtext-h3'
|
||||
}
|
||||
{
|
||||
key: 'x'
|
||||
hotkeys: true,
|
||||
description: 'Removes any hyperlink'
|
||||
description: __('Removes any hyperlink')
|
||||
globalEvent: 'richtext-remove-hyperlink'
|
||||
}
|
||||
]
|
||||
|
|
|
@ -22,9 +22,9 @@ class Maintenance extends App.Controller
|
|||
showMessage: (message = {}) =>
|
||||
if message.reload
|
||||
@disconnectClient()
|
||||
button = 'Continue session'
|
||||
button = __('Continue session')
|
||||
else
|
||||
button = 'Close'
|
||||
button = __('Close')
|
||||
|
||||
new App.SessionMessage(
|
||||
head: message.head
|
||||
|
@ -62,7 +62,7 @@ class Maintenance extends App.Controller
|
|||
maintanaceRestartManual: (data) =>
|
||||
return if @messageRestartManual
|
||||
@messageRestartManual = new App.SessionMessage(
|
||||
head: App.i18n.translateInline('Zammad need a restart!')
|
||||
head: App.i18n.translateInline('Zammad requires a restart!')
|
||||
contentInline: App.i18n.translateInline('Some system settings have changed, please restart all Zammad processes! If you want to do this automatically, set environment variable APP_RESTART_CMD="/path/to/your_app_script.sh restart".')
|
||||
keyboard: false
|
||||
backdrop: false
|
||||
|
@ -82,7 +82,7 @@ class Maintenance extends App.Controller
|
|||
keyboard: false
|
||||
backdrop: true
|
||||
buttonClose: false
|
||||
buttonSubmit: 'Continue session'
|
||||
buttonSubmit: __('Continue session')
|
||||
forceReload: true
|
||||
)
|
||||
|
||||
|
@ -102,7 +102,7 @@ class Maintenance extends App.Controller
|
|||
keyboard: false
|
||||
backdrop: true
|
||||
buttonClose: false
|
||||
buttonSubmit: 'Continue session'
|
||||
buttonSubmit: __('Continue session')
|
||||
forceReload: true
|
||||
)
|
||||
@delay(message, 2000)
|
||||
|
|
|
@ -483,7 +483,7 @@ class Navigation extends App.Controller
|
|||
navheader = false
|
||||
if prio is 80
|
||||
divider = true
|
||||
navheader = 'Recently viewed'
|
||||
navheader = __('Recently viewed')
|
||||
|
||||
prio++
|
||||
NavBarRight['RecendViewed::' + item.o_id + item.object + '-' + prio ] = {
|
||||
|
|
|
@ -35,12 +35,12 @@ class SessionTakeOver extends App.Controller
|
|||
# only if new client id isn't own client id
|
||||
if data.taskbar_id isnt App.TaskManager.TaskbarId()
|
||||
@error = new App.SessionMessage(
|
||||
head: 'Session'
|
||||
message: 'A new session was created with your account. This session will be stopped to prevent a conflict.'
|
||||
head: __('Session')
|
||||
message: __('A new session was created with your account. This session will be stopped to prevent a conflict.')
|
||||
keyboard: false
|
||||
backdrop: true
|
||||
buttonClose: false
|
||||
buttonSubmit: 'Continue session'
|
||||
buttonSubmit: __('Continue session')
|
||||
forceReload: true
|
||||
)
|
||||
@disconnectClient()
|
||||
|
|
|
@ -95,12 +95,12 @@ class SessionTimeout extends App.Controller
|
|||
return if @warningDialog
|
||||
|
||||
@warningDialog = new App.ControllerModal(
|
||||
head: 'Session'
|
||||
message: 'Due to inactivity are automatically logged out within the next 30 seconds.'
|
||||
head: __('Session')
|
||||
message: __('Due to inactivity are automatically logged out within the next 30 seconds.')
|
||||
keyboard: true
|
||||
backdrop: true
|
||||
buttonClose: true
|
||||
buttonSubmit: 'Continue session'
|
||||
buttonSubmit: __('Continue session')
|
||||
onSubmit: =>
|
||||
@lastEvent = @currentTime()
|
||||
@checkLogout()
|
||||
|
|
|
@ -7,8 +7,8 @@ class TranslationSupport extends App.Controller
|
|||
# only show if system is already up and running
|
||||
return if !@Config.get('system_init_done')
|
||||
|
||||
# to not translate en
|
||||
return if !App.i18n.notTranslatedFeatureEnabled(App.i18n.get())
|
||||
# do not show for English locales
|
||||
return if App.i18n.get().substr(0,2) is 'en'
|
||||
|
||||
# only show for admins
|
||||
return if !@permissionCheck('admin.translation')
|
||||
|
@ -30,13 +30,13 @@ class TranslationSupport extends App.Controller
|
|||
if App.Session.get() isnt undefined
|
||||
@delay(check, 2500, 'translation_support')
|
||||
|
||||
App.Config.set( 'translaton_support', TranslationSupport, 'Plugins' )
|
||||
App.Config.set( 'translation_support', TranslationSupport, 'Plugins' )
|
||||
|
||||
class Modal extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: 'No Thanks!'
|
||||
buttonSubmit: 'Complete translations'
|
||||
head: 'Help to improve Zammad!'
|
||||
buttonCancel: __('No Thanks!')
|
||||
buttonSubmit: __('Complete translations')
|
||||
head: __('Help to improve Zammad!')
|
||||
shown: false
|
||||
|
||||
constructor: ->
|
||||
|
@ -45,12 +45,8 @@ class Modal extends App.ControllerModal
|
|||
@render()
|
||||
|
||||
content: =>
|
||||
better = false
|
||||
if @percent > 80
|
||||
better = true
|
||||
App.view('translation/support')(
|
||||
percent: @percent
|
||||
better: better
|
||||
)
|
||||
|
||||
onCancel: =>
|
||||
|
|
|
@ -31,11 +31,11 @@ class UserSignupCheck extends App.Controller
|
|||
class Modal extends App.ControllerModal
|
||||
backdrop: false
|
||||
keyboard: false
|
||||
head: 'Account not verified'
|
||||
head: __('Account not verified')
|
||||
small: true
|
||||
buttonClose: false
|
||||
buttonCancel: false
|
||||
buttonSubmit: 'Resend verification email'
|
||||
buttonSubmit: __('Resend verification email')
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ProfileAvatar extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.avatar'
|
||||
header: 'Avatar'
|
||||
header: __('Avatar')
|
||||
elements:
|
||||
'.js-upload': 'fileInput'
|
||||
'.avatar-gallery': 'avatarGallery'
|
||||
|
@ -145,13 +145,13 @@ class ProfileAvatar extends App.ControllerSubContent
|
|||
|
||||
reader.readAsDataURL(@)
|
||||
|
||||
App.Config.set('Avatar', { prio: 1100, name: 'Avatar', parent: '#profile', target: '#profile/avatar', controller: ProfileAvatar, permission: ['user_preferences.avatar'] }, 'NavBarProfile')
|
||||
App.Config.set('Avatar', { prio: 1100, name: __('Avatar'), parent: '#profile', target: '#profile/avatar', controller: ProfileAvatar, permission: ['user_preferences.avatar'] }, 'NavBarProfile')
|
||||
|
||||
class ImageCropper extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: 'Save'
|
||||
head: 'Crop Image'
|
||||
buttonSubmit: __('Save')
|
||||
head: __('Crop Image')
|
||||
|
||||
elements:
|
||||
'.imageCropper-image': 'image'
|
||||
|
@ -229,13 +229,13 @@ class ImageCropper extends App.ControllerModal
|
|||
class Camera extends App.ControllerModal
|
||||
buttonClose: true
|
||||
buttonCancel: true
|
||||
buttonSubmit: 'Save'
|
||||
buttonSubmit: __('Save')
|
||||
buttonClass: 'btn--success is-disabled'
|
||||
centerButtons: [{
|
||||
className: 'btn--success js-shoot is-disabled',
|
||||
text: 'Shoot'
|
||||
text: __('Shoot')
|
||||
}]
|
||||
head: 'Camera'
|
||||
head: __('Camera')
|
||||
|
||||
elements:
|
||||
'.js-shoot': 'shootButton'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ProfileCalendarSubscriptions extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.calendar+ticket.agent'
|
||||
header: 'Calendar'
|
||||
header: __('Calendar')
|
||||
elements:
|
||||
'input[type=checkbox]': 'options'
|
||||
'output': 'output'
|
||||
|
@ -90,4 +90,4 @@ class ProfileCalendarSubscriptions extends App.ControllerSubContent
|
|||
msg: App.i18n.translateContent(data.message)
|
||||
)
|
||||
|
||||
App.Config.set('CalendarSubscriptions', { prio: 3000, name: 'Calendar', parent: '#profile', target: '#profile/calendar_subscriptions', permission: ['user_preferences.calendar+ticket.agent'], controller: ProfileCalendarSubscriptions }, 'NavBarProfile')
|
||||
App.Config.set('CalendarSubscriptions', { prio: 3000, name: __('Calendar'), parent: '#profile', target: '#profile/calendar_subscriptions', permission: ['user_preferences.calendar+ticket.agent'], controller: ProfileCalendarSubscriptions }, 'NavBarProfile')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ProfileDevices extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.device'
|
||||
header: 'Devices'
|
||||
header: __('Devices')
|
||||
events:
|
||||
'click [data-type=delete]': 'delete'
|
||||
|
||||
|
@ -55,4 +55,4 @@ class ProfileDevices extends App.ControllerSubContent
|
|||
msg: App.i18n.translateContent(data.message)
|
||||
)
|
||||
|
||||
App.Config.set('Devices', { prio: 3100, name: 'Devices', parent: '#profile', target: '#profile/devices', controller: ProfileDevices, permission: ['user_preferences.device'] }, 'NavBarProfile')
|
||||
App.Config.set('Devices', { prio: 3100, name: __('Devices'), parent: '#profile', target: '#profile/devices', controller: ProfileDevices, permission: ['user_preferences.device'] }, 'NavBarProfile')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ProfileLanguage extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.language'
|
||||
header: 'Language'
|
||||
header: __('Language')
|
||||
events:
|
||||
'submit form': 'update'
|
||||
|
||||
|
@ -69,4 +69,4 @@ class ProfileLanguage extends App.ControllerSubContent
|
|||
msg: App.i18n.translateContent(data.message)
|
||||
)
|
||||
|
||||
App.Config.set('Language', { prio: 1000, name: 'Language', parent: '#profile', target: '#profile/language', controller: ProfileLanguage, permission: ['user_preferences.language'] }, 'NavBarProfile')
|
||||
App.Config.set('Language', { prio: 1000, name: __('Language'), parent: '#profile', target: '#profile/language', controller: ProfileLanguage, permission: ['user_preferences.language'] }, 'NavBarProfile')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ProfileLinkedAccounts extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.linked_accounts'
|
||||
header: 'Linked Accounts'
|
||||
header: __('Linked Accounts')
|
||||
events:
|
||||
'click .js-add': 'add'
|
||||
'click .js-remove': 'remove'
|
||||
|
@ -59,56 +59,56 @@ class ProfileLinkedAccounts extends App.ControllerSubContent
|
|||
msg: App.i18n.translateContent(data.message)
|
||||
)
|
||||
|
||||
App.Config.set('LinkedAccounts', { prio: 4000, name: 'Linked Accounts', parent: '#profile', target: '#profile/linked', controller: ProfileLinkedAccounts, permission: ['user_preferences.linked_accounts'] }, 'NavBarProfile')
|
||||
App.Config.set('LinkedAccounts', { prio: 4000, name: __('Linked Accounts'), parent: '#profile', target: '#profile/linked', controller: ProfileLinkedAccounts, permission: ['user_preferences.linked_accounts'] }, 'NavBarProfile')
|
||||
App.Config.set('auth_provider_all', {
|
||||
facebook:
|
||||
url: '/auth/facebook'
|
||||
name: 'Facebook'
|
||||
name: __('Facebook')
|
||||
config: 'auth_facebook'
|
||||
class: 'facebook'
|
||||
twitter:
|
||||
url: '/auth/twitter'
|
||||
name: 'Twitter'
|
||||
name: __('Twitter')
|
||||
config: 'auth_twitter'
|
||||
class: 'twitter'
|
||||
linkedin:
|
||||
url: '/auth/linkedin'
|
||||
name: 'LinkedIn'
|
||||
name: __('LinkedIn')
|
||||
config: 'auth_linkedin'
|
||||
class: 'linkedin'
|
||||
github:
|
||||
url: '/auth/github'
|
||||
name: 'GitHub'
|
||||
name: __('GitHub')
|
||||
config: 'auth_github'
|
||||
class: 'github'
|
||||
gitlab:
|
||||
url: '/auth/gitlab'
|
||||
name: 'GitLab'
|
||||
name: __('GitLab')
|
||||
config: 'auth_gitlab'
|
||||
class: 'gitlab'
|
||||
microsoft_office365:
|
||||
url: '/auth/microsoft_office365'
|
||||
name: 'Office 365'
|
||||
name: __('Office 365')
|
||||
config: 'auth_microsoft_office365'
|
||||
class: 'office365'
|
||||
google_oauth2:
|
||||
url: '/auth/google_oauth2'
|
||||
name: 'Google'
|
||||
name: __('Google')
|
||||
config: 'auth_google_oauth2'
|
||||
class: 'google'
|
||||
weibo:
|
||||
url: '/auth/weibo'
|
||||
name: 'Weibo'
|
||||
name: __('Weibo')
|
||||
config: 'auth_weibo'
|
||||
class: 'weibo'
|
||||
saml:
|
||||
url: '/auth/saml'
|
||||
name: 'SAML'
|
||||
name: __('SAML')
|
||||
config: 'auth_saml'
|
||||
class: 'saml'
|
||||
sso:
|
||||
url: '/auth/sso'
|
||||
name: 'SSO'
|
||||
name: __('SSO')
|
||||
config: 'auth_sso'
|
||||
class: 'sso'
|
||||
})
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
class ProfileNotification extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.notifications+ticket.agent'
|
||||
header: 'Notifications'
|
||||
header: __('Notifications')
|
||||
events:
|
||||
'submit form': 'update'
|
||||
'change .js-notificationSound': 'previewSound'
|
||||
|
||||
sounds: [
|
||||
{
|
||||
name: 'Bell'
|
||||
name: __('Bell')
|
||||
file: 'Bell.mp3'
|
||||
},
|
||||
{
|
||||
name: 'Kalimba'
|
||||
name: __('Kalimba')
|
||||
file: 'Kalimba.mp3'
|
||||
},
|
||||
{
|
||||
name: 'Marimba'
|
||||
name: __('Marimba')
|
||||
file: 'Marimba.mp3'
|
||||
},
|
||||
{
|
||||
name: 'Peep'
|
||||
name: __('Peep')
|
||||
file: 'Peep.mp3'
|
||||
},
|
||||
{
|
||||
name: 'Plop'
|
||||
name: __('Plop')
|
||||
file: 'Plop.mp3'
|
||||
},
|
||||
{
|
||||
name: 'Ring'
|
||||
name: __('Ring')
|
||||
file: 'Ring.mp3'
|
||||
},
|
||||
{
|
||||
name: 'Space'
|
||||
name: __('Space')
|
||||
file: 'Space.mp3'
|
||||
},
|
||||
{
|
||||
name: 'Wood'
|
||||
name: __('Wood')
|
||||
file: 'Wood.mp3'
|
||||
},
|
||||
{
|
||||
name: 'Xylo'
|
||||
name: __('Xylo')
|
||||
file: 'Xylo.mp3'
|
||||
}
|
||||
]
|
||||
|
@ -52,13 +52,13 @@ class ProfileNotification extends App.ControllerSubContent
|
|||
|
||||
matrix =
|
||||
create:
|
||||
name: 'New Ticket'
|
||||
name: __('New Ticket')
|
||||
update:
|
||||
name: 'Ticket update'
|
||||
name: __('Ticket update')
|
||||
reminder_reached:
|
||||
name: 'Ticket reminder reached'
|
||||
name: __('Ticket reminder reached')
|
||||
escalation:
|
||||
name: 'Ticket escalation'
|
||||
name: __('Ticket escalation')
|
||||
|
||||
config =
|
||||
group_ids: []
|
||||
|
@ -196,4 +196,4 @@ class ProfileNotification extends App.ControllerSubContent
|
|||
return if !params.notification_sound.file
|
||||
App.OnlineNotification.play(params.notification_sound.file)
|
||||
|
||||
App.Config.set('Notifications', { prio: 2600, name: 'Notifications', parent: '#profile', target: '#profile/notifications', permission: ['user_preferences.notifications+ticket.agent'], controller: ProfileNotification }, 'NavBarProfile')
|
||||
App.Config.set('Notifications', { prio: 2600, name: __('Notifications'), parent: '#profile', target: '#profile/notifications', permission: ['user_preferences.notifications+ticket.agent'], controller: ProfileNotification }, 'NavBarProfile')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ProfileOutOfOffice extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.out_of_office+ticket.agent'
|
||||
header: 'Out of Office'
|
||||
header: __('Out of Office')
|
||||
events:
|
||||
'submit form': 'submit'
|
||||
'click .js-disabled': 'disable'
|
||||
|
@ -70,7 +70,7 @@ class ProfileOutOfOffice extends App.ControllerSubContent
|
|||
multiple: false
|
||||
limit: 30
|
||||
minLengt: 2
|
||||
placeholder: 'Enter Person or Organization/Company'
|
||||
placeholder: __('Enter Person or Organization/Company')
|
||||
null: false
|
||||
translate: false
|
||||
disableCreateObject: true
|
||||
|
@ -131,7 +131,7 @@ class ProfileOutOfOffice extends App.ControllerSubContent
|
|||
@render()
|
||||
@notify(
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent('Successfully!')
|
||||
msg: App.i18n.translateContent('Update successful.')
|
||||
timeout: 1000
|
||||
)
|
||||
else
|
||||
|
@ -143,7 +143,7 @@ class ProfileOutOfOffice extends App.ControllerSubContent
|
|||
else
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Please contact your administrator.'
|
||||
msg: __('Please contact your administrator.')
|
||||
removeAll: true
|
||||
@formEnable( @$('form') )
|
||||
|
||||
|
@ -168,4 +168,4 @@ class ProfileOutOfOffice extends App.ControllerSubContent
|
|||
msg: App.i18n.translateContent(message)
|
||||
removeAll: true
|
||||
|
||||
App.Config.set('OutOfOffice', { prio: 2800, name: 'Out of Office', parent: '#profile', target: '#profile/out_of_office', permission: ['user_preferences.out_of_office+ticket.agent'], controller: ProfileOutOfOffice }, 'NavBarProfile')
|
||||
App.Config.set('OutOfOffice', { prio: 2800, name: __('Out of Office'), parent: '#profile', target: '#profile/out_of_office', permission: ['user_preferences.out_of_office+ticket.agent'], controller: ProfileOutOfOffice }, 'NavBarProfile')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ProfilePassword extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.password'
|
||||
header: 'Password'
|
||||
header: __('Password')
|
||||
events:
|
||||
'submit form': 'update'
|
||||
|
||||
|
@ -14,8 +14,8 @@ class ProfilePassword extends App.ControllerSubContent
|
|||
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(
|
||||
|
@ -37,14 +37,14 @@ class ProfilePassword extends App.ControllerSubContent
|
|||
@$('[name=password_new_confirm]').val('')
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Can\'t update password, your new passwords do not match. Please try again!'
|
||||
msg: __('Can\'t update password, your new passwords do not match. Please try again!')
|
||||
removeAll: true
|
||||
return
|
||||
if !params['password_new']
|
||||
@formEnable(e)
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Please supply your new password!'
|
||||
msg: __('Please supply your new password!')
|
||||
removeAll: true
|
||||
return
|
||||
|
||||
|
@ -74,8 +74,8 @@ class ProfilePassword extends App.ControllerSubContent
|
|||
else
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Unable to set password. Please contact your administrator.'
|
||||
msg: __('Unable to set password. Please contact your administrator.')
|
||||
removeAll: true
|
||||
@formEnable( @$('form') )
|
||||
|
||||
App.Config.set('Password', { prio: 2000, name: 'Password', parent: '#profile', target: '#profile/password', controller: ProfilePassword, permission: ['user_preferences.password'] }, 'NavBarProfile')
|
||||
App.Config.set('Password', { prio: 2000, name: __('Password'), parent: '#profile', target: '#profile/password', controller: ProfilePassword, permission: ['user_preferences.password'] }, 'NavBarProfile')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ProfileTokenAccess extends App.ControllerSubContent
|
||||
requiredPermission: 'user_preferences.access_token'
|
||||
header: 'Token Access'
|
||||
header: __('Token Access')
|
||||
events:
|
||||
'click .js-delete': 'delete'
|
||||
'click .js-create': 'create'
|
||||
|
@ -63,7 +63,7 @@ class ProfileTokenAccess extends App.ControllerSubContent
|
|||
)
|
||||
|
||||
new App.ControllerConfirm(
|
||||
message: 'Sure?'
|
||||
message: __('Sure?')
|
||||
callback: callback
|
||||
container: @el.closest('.content')
|
||||
)
|
||||
|
@ -76,8 +76,8 @@ class ProfileTokenAccess extends App.ControllerSubContent
|
|||
)
|
||||
|
||||
class Create extends App.ControllerModal
|
||||
head: 'Add a Personal Access Token'
|
||||
buttonSubmit: 'Create'
|
||||
head: __('Add a Personal Access Token')
|
||||
buttonSubmit: __('Create')
|
||||
buttonCancel: true
|
||||
shown: true
|
||||
|
||||
|
@ -125,8 +125,8 @@ class Create extends App.ControllerModal
|
|||
return if !@newToken
|
||||
ui = @
|
||||
new App.ControllerModal(
|
||||
head: 'Your New Personal Access Token'
|
||||
buttonSubmit: "OK, I've copied my token"
|
||||
head: __('Your New Personal Access Token')
|
||||
buttonSubmit: __("OK, I've copied my token")
|
||||
content: ->
|
||||
App.view('profile/token_access_created')(
|
||||
name: ui.newToken.name
|
||||
|
@ -149,7 +149,7 @@ class Create extends App.ControllerModal
|
|||
|
||||
App.Config.set('Token Access', {
|
||||
prio: 3200,
|
||||
name: 'Token Access',
|
||||
name: __('Token Access'),
|
||||
parent: '#profile',
|
||||
target: '#profile/token_access',
|
||||
controller: ProfileTokenAccess,
|
||||
|
|
|
@ -48,12 +48,11 @@ class App.SettingsAreaProxy extends App.Controller
|
|||
}
|
||||
return
|
||||
new App.ControllerConfirm(
|
||||
head: 'Error'
|
||||
head: __('Error')
|
||||
message: data.message
|
||||
buttonClass: 'btn--success'
|
||||
buttonCancel: false
|
||||
buttonSubmit: 'Close'
|
||||
buttonSubmit: __('Close')
|
||||
container: @el.closest('.content')
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ class App.SettingsAreaSwitch extends App.Controller
|
|||
ui.formEnable(e)
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update object!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to update object!'))
|
||||
timeout: 2000
|
||||
}
|
||||
)
|
||||
|
|
|
@ -126,7 +126,7 @@ class App.SettingsAreaTicketNumber extends App.Controller
|
|||
ui.formEnable(e)
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update object!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to update object!'))
|
||||
timeout: 2000
|
||||
}
|
||||
)
|
||||
|
|
|
@ -88,7 +88,7 @@ class App.SettingsForm extends App.Controller
|
|||
fail: (settings, details) ->
|
||||
App.Event.trigger('notify', {
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update object!')
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || __('Unable to update object!'))
|
||||
timeout: 2000
|
||||
})
|
||||
)
|
||||
|
|
|
@ -5,59 +5,59 @@ class App.UiElement.ApplicationSelector
|
|||
|
||||
groups =
|
||||
ticket:
|
||||
name: 'Ticket'
|
||||
name: __('Ticket')
|
||||
model: 'Ticket'
|
||||
article:
|
||||
name: 'Article'
|
||||
name: __('Article')
|
||||
model: 'TicketArticle'
|
||||
customer:
|
||||
name: 'Customer'
|
||||
name: __('Customer')
|
||||
model: 'User'
|
||||
organization:
|
||||
name: 'Organization'
|
||||
name: __('Organization')
|
||||
model: 'Organization'
|
||||
|
||||
if attribute.executionTime
|
||||
groups.execution_time =
|
||||
name: 'Execution Time'
|
||||
name: __('Execution Time')
|
||||
|
||||
operators_type =
|
||||
'^datetime$': ['before (absolute)', 'after (absolute)', 'before (relative)', 'after (relative)', 'within next (relative)', 'within last (relative)', 'till (relative)', 'from (relative)']
|
||||
'^timestamp$': ['before (absolute)', 'after (absolute)', 'before (relative)', 'after (relative)', 'within next (relative)', 'within last (relative)', 'till (relative)', 'from (relative)']
|
||||
'^datetime$': [__('before (absolute)'), __('after (absolute)'), __('before (relative)'), __('after (relative)'), __('within next (relative)'), __('within last (relative)'), __('till (relative)'), __('from (relative)')]
|
||||
'^timestamp$': [__('before (absolute)'), __('after (absolute)'), __('before (relative)'), __('after (relative)'), __('within next (relative)'), __('within last (relative)'), __('till (relative)'), __('from (relative)')]
|
||||
'^date$': ['before (absolute)', 'after (absolute)', 'before (relative)', 'after (relative)', 'within next (relative)', 'within last (relative)']
|
||||
'boolean$': ['is', 'is not']
|
||||
'integer$': ['is', 'is not']
|
||||
'^radio$': ['is', 'is not']
|
||||
'^select$': ['is', 'is not']
|
||||
'^tree_select$': ['is', 'is not']
|
||||
'^input$': ['contains', 'contains not']
|
||||
'^richtext$': ['contains', 'contains not']
|
||||
'^textarea$': ['contains', 'contains not']
|
||||
'^tag$': ['contains all', 'contains one', 'contains all not', 'contains one not']
|
||||
'boolean$': [__('is'), __('is not')]
|
||||
'integer$': [__('is'), __('is not')]
|
||||
'^radio$': [__('is'), __('is not')]
|
||||
'^select$': [__('is'), __('is not')]
|
||||
'^tree_select$': [__('is'), __('is not')]
|
||||
'^input$': [__('contains'), __('contains not')]
|
||||
'^richtext$': [__('contains'), __('contains not')]
|
||||
'^textarea$': [__('contains'), __('contains not')]
|
||||
'^tag$': [__('contains all'), __('contains one'), __('contains all not'), __('contains one not')]
|
||||
|
||||
if attribute.hasChanged
|
||||
operators_type =
|
||||
'^datetime$': ['before (absolute)', 'after (absolute)', 'before (relative)', 'after (relative)', 'within next (relative)', 'within last (relative)', 'till (relative)', 'from (relative)', 'has changed']
|
||||
'^timestamp$': ['before (absolute)', 'after (absolute)', 'before (relative)', 'after (relative)', 'within next (relative)', 'within last (relative)', 'till (relative)', 'from (relative)', 'has changed']
|
||||
'^date$': ['before (absolute)', 'after (absolute)', 'before (relative)', 'after (relative)', 'within next (relative)', 'within last (relative)', 'till (relative)', 'from (relative)', 'has changed']
|
||||
'boolean$': ['is', 'is not', 'has changed']
|
||||
'integer$': ['is', 'is not', 'has changed']
|
||||
'^radio$': ['is', 'is not', 'has changed']
|
||||
'^select$': ['is', 'is not', 'has changed']
|
||||
'^tree_select$': ['is', 'is not', 'has changed']
|
||||
'^input$': ['contains', 'contains not', 'has changed']
|
||||
'^richtext$': ['contains', 'contains not', 'has changed']
|
||||
'^textarea$': ['contains', 'contains not', 'has changed']
|
||||
'^tag$': ['contains all', 'contains one', 'contains all not', 'contains one not']
|
||||
'^datetime$': [__('before (absolute)'), __('after (absolute)'), __('before (relative)'), __('after (relative)'), __('within next (relative)'), __('within last (relative)'), __('till (relative)'), __('from (relative)'), __('has changed')]
|
||||
'^timestamp$': [__('before (absolute)'), __('after (absolute)'), __('before (relative)'), __('after (relative)'), __('within next (relative)'), __('within last (relative)'), __('till (relative)'), __('from (relative)'), __('has changed')]
|
||||
'^date$': [__('before (absolute)'), __('after (absolute)'), __('before (relative)'), __('after (relative)'), __('within next (relative)'), __('within last (relative)'), __('till (relative)'), __('from (relative)'), __('has changed')]
|
||||
'boolean$': [__('is'), __('is not'), __('has changed')]
|
||||
'integer$': [__('is'), __('is not'), __('has changed')]
|
||||
'^radio$': [__('is'), __('is not'), __('has changed')]
|
||||
'^select$': [__('is'), __('is not'), __('has changed')]
|
||||
'^tree_select$': [__('is'), __('is not'), __('has changed')]
|
||||
'^input$': [__('contains'), __('contains not'), __('has changed')]
|
||||
'^richtext$': [__('contains'), __('contains not'), __('has changed')]
|
||||
'^textarea$': [__('contains'), __('contains not'), __('has changed')]
|
||||
'^tag$': [__('contains all'), __('contains one'), __('contains all not'), __('contains one not')]
|
||||
|
||||
operators_name =
|
||||
'_id$': ['is', 'is not']
|
||||
'_ids$': ['is', 'is not']
|
||||
'_id$': [__('is'), __('is not')]
|
||||
'_ids$': [__('is'), __('is not')]
|
||||
|
||||
if attribute.hasChanged
|
||||
operators_name =
|
||||
'_id$': ['is', 'is not', 'has changed']
|
||||
'_ids$': ['is', 'is not', 'has changed']
|
||||
'_id$': [__('is'), __('is not'), __('has changed')]
|
||||
'_ids$': [__('is'), __('is not'), __('has changed')]
|
||||
|
||||
# merge config
|
||||
elements = {}
|
||||
|
@ -68,7 +68,7 @@ class App.UiElement.ApplicationSelector
|
|||
if attribute.action
|
||||
elements['ticket.action'] =
|
||||
name: 'action'
|
||||
display: 'Action'
|
||||
display: __('Action')
|
||||
tag: 'select'
|
||||
null: false
|
||||
translate: true
|
||||
|
@ -77,19 +77,19 @@ class App.UiElement.ApplicationSelector
|
|||
update: 'updated'
|
||||
'update.merged_into': 'merged into'
|
||||
'update.received_merge': 'received merge'
|
||||
operator: ['is', 'is not']
|
||||
operator: [__('is'), __('is not')]
|
||||
|
||||
for groupKey, groupMeta of groups
|
||||
if groupKey is 'execution_time'
|
||||
if attribute.executionTime
|
||||
elements['execution_time.calendar_id'] =
|
||||
name: 'calendar_id'
|
||||
display: 'Calendar'
|
||||
display: __('Calendar')
|
||||
tag: 'select'
|
||||
relation: 'Calendar'
|
||||
null: false
|
||||
translate: false
|
||||
operator: ['is in working time', 'is not in working time']
|
||||
operator: [__('is in working time'), __('is not in working time')]
|
||||
|
||||
else
|
||||
for row in App[groupMeta.model].configure_attributes
|
||||
|
@ -115,12 +115,12 @@ class App.UiElement.ApplicationSelector
|
|||
if attribute.out_of_office
|
||||
elements['ticket.out_of_office_replacement_id'] =
|
||||
name: 'out_of_office_replacement_id'
|
||||
display: 'Out of office replacement'
|
||||
display: __('Out of office replacement')
|
||||
tag: 'autocompletion_ajax'
|
||||
relation: 'User'
|
||||
null: false
|
||||
translate: true
|
||||
operator: ['is', 'is not']
|
||||
operator: [__('is'), __('is not')]
|
||||
|
||||
# Remove 'has changed' operator from attributes which don't support the operator.
|
||||
['ticket.created_at', 'ticket.updated_at'].forEach (element_name) ->
|
||||
|
@ -128,12 +128,12 @@ class App.UiElement.ApplicationSelector
|
|||
|
||||
elements['ticket.mention_user_ids'] =
|
||||
name: 'mention_user_ids'
|
||||
display: 'Subscribe'
|
||||
display: __('Subscribe')
|
||||
tag: 'autocompletion_ajax'
|
||||
relation: 'User'
|
||||
null: false
|
||||
translate: true
|
||||
operator: ['is', 'is not']
|
||||
operator: [__('is'), __('is not')]
|
||||
|
||||
[defaults, groups, elements]
|
||||
|
||||
|
@ -350,6 +350,9 @@ class App.UiElement.ApplicationSelector
|
|||
|
||||
@buildOperator(elementFull, elementRow, groupAndAttribute, elements, meta, attribute)
|
||||
|
||||
@mapOperatorDisplayName: (operator) ->
|
||||
return operator
|
||||
|
||||
@buildOperator: (elementFull, elementRow, groupAndAttribute, elements, meta, attribute) ->
|
||||
currentOperator = elementRow.find('.js-operator option:selected').attr('value')
|
||||
|
||||
|
@ -376,7 +379,7 @@ class App.UiElement.ApplicationSelector
|
|||
break
|
||||
|
||||
for operator in attributeConfig.operator
|
||||
operatorName = App.i18n.translateInline(operator.replace(/_/g, ' '))
|
||||
operatorName = App.i18n.translateInline(@mapOperatorDisplayName(operator))
|
||||
selected = ''
|
||||
if !groupAndAttribute.match(/^ticket/) && operator is 'has changed'
|
||||
# do nothing, only show "has changed" in ticket attributes
|
||||
|
|
|
@ -8,8 +8,8 @@ class App.UiElement.active extends App.UiElement.ApplicationUiElement
|
|||
|
||||
# build options list
|
||||
attribute.options = [
|
||||
{ name: 'active', value: true }
|
||||
{ name: 'inactive', value: false }
|
||||
{ name: __('active'), value: true }
|
||||
{ name: __('inactive'), value: false }
|
||||
]
|
||||
|
||||
# build options list based on config
|
||||
|
|
|
@ -145,14 +145,14 @@ class App.UiElement.basedate
|
|||
|
||||
@buildCustomDates: ->
|
||||
data = {
|
||||
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||||
daysMin: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
months: ['January', 'February', 'March', 'April', 'May', 'June',
|
||||
'July', 'August', 'September', 'October', 'November', 'December'],
|
||||
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
today: 'today',
|
||||
clear: 'clear'
|
||||
days: [__('Sunday'), __('Monday'), __('Tuesday'), __('Wednesday'), __('Thursday'), __('Friday'), __('Saturday')],
|
||||
daysMin: [__('Sun'), __('Mon'), __('Tue'), __('Wed'), __('Thu'), __('Fri'), __('Sat')],
|
||||
daysShort: [__('Sun'), __('Mon'), __('Tue'), __('Wed'), __('Thu'), __('Fri'), __('Sat')],
|
||||
months: [__('January'), __('February'), __('March'), __('April'), __('May'), __('June'),
|
||||
__('July'), __('August'), __('September'), __('October'), __('November'), __('December')],
|
||||
monthsShort: [__('Jan'), __('Feb'), __('Mar'), __('Apr'), __('May'), __('Jun'), __('Jul'), __('Aug'), __('Sep'), __('Oct'), __('Nov'), __('Dec')],
|
||||
today: __('today'),
|
||||
clear: __('clear')
|
||||
}
|
||||
|
||||
App.i18n.translateDeep(data)
|
||||
|
|
|
@ -5,8 +5,8 @@ class App.UiElement.boolean extends App.UiElement.ApplicationUiElement
|
|||
# build options list
|
||||
if _.isEmpty(attribute.options)
|
||||
attribute.options = [
|
||||
{ name: 'yes', value: true }
|
||||
{ name: 'no', value: false }
|
||||
{ name: __('yes'), value: true }
|
||||
{ name: __('no'), value: false }
|
||||
]
|
||||
attribute.translate = true
|
||||
|
||||
|
|
|
@ -5,38 +5,38 @@ class App.UiElement.core_workflow_condition extends App.UiElement.ApplicationSel
|
|||
|
||||
groups =
|
||||
ticket:
|
||||
name: 'Ticket'
|
||||
name: __('Ticket')
|
||||
model: 'Ticket'
|
||||
model_show: ['Ticket']
|
||||
group:
|
||||
name: 'Group'
|
||||
name: __('Group')
|
||||
model: 'Group'
|
||||
model_show: ['Group']
|
||||
user:
|
||||
name: 'User'
|
||||
name: __('User')
|
||||
model: 'User'
|
||||
model_show: ['User']
|
||||
customer:
|
||||
name: 'Customer'
|
||||
name: __('Customer')
|
||||
model: 'User'
|
||||
model_show: ['Ticket']
|
||||
organization:
|
||||
name: 'Organization'
|
||||
name: __('Organization')
|
||||
model: 'Organization'
|
||||
model_show: ['User', 'Organization']
|
||||
'customer.organization':
|
||||
name: 'Organization'
|
||||
name: __('Organization')
|
||||
model: 'Organization'
|
||||
model_show: ['Ticket']
|
||||
session:
|
||||
name: 'Session'
|
||||
name: __('Session')
|
||||
model: 'User'
|
||||
model_show: ['Ticket']
|
||||
|
||||
showCustomModules = @coreWorkflowCustomModulesActive()
|
||||
if showCustomModules
|
||||
groups['custom'] =
|
||||
name: 'Custom'
|
||||
name: __('Custom')
|
||||
model_show: ['Ticket', 'User', 'Organization', 'Sla']
|
||||
|
||||
currentObject = params.object
|
||||
|
@ -49,16 +49,16 @@ class App.UiElement.core_workflow_condition extends App.UiElement.ApplicationSel
|
|||
delete groups[key]
|
||||
|
||||
operatorsType =
|
||||
'active$': ['is']
|
||||
'boolean$': ['is', 'is not', 'is set', 'not set', 'has changed', 'changed to']
|
||||
'integer$': ['is', 'is not', 'is set', 'not set', 'has changed', 'changed to']
|
||||
'^select$': ['is', 'is not', 'is set', 'not set', 'has changed', 'changed to']
|
||||
'^tree_select$': ['is', 'is not', 'is set', 'not set', 'has changed', 'changed to']
|
||||
'^(input|textarea|richtext)$': ['is', 'is not', 'is set', 'not set', 'has changed', 'changed to', 'regex match', 'regex mismatch']
|
||||
'active$': [__('is')]
|
||||
'boolean$': [__('is'), __('is not'), __('is set'), __('not set'), _('has changed'), __('changed to')]
|
||||
'integer$': [__('is'), __('is not'), __('is set'), __('not set'), _('has changed'), __('changed to')]
|
||||
'^select$': [__('is'), __('is not'), __('is set'), __('not set'), _('has changed'), __('changed to')]
|
||||
'^tree_select$': [__('is'), __('is not'), __('is set'), __('not set'), _('has changed'), __('changed to')]
|
||||
'^(input|textarea|richtext)$': [__('is'), __('is not'), __('is set'), __('not set'), _('has changed'), __('changed to'), __('regex match'), __('regex mismatch')]
|
||||
|
||||
operatorsName =
|
||||
'_id$': ['is', 'is not', 'is set', 'not set', 'has changed', 'changed to']
|
||||
'_ids$': ['is', 'is not', 'is set', 'not set', 'has changed', 'changed to']
|
||||
'_id$': [__('is'), __('is not'), __('is set'), __('not set'), _('has changed'), __('changed to')]
|
||||
'_ids$': [__('is'), __('is not'), __('is set'), __('not set'), _('has changed'), __('changed to')]
|
||||
|
||||
# merge config
|
||||
elements = {}
|
||||
|
@ -73,76 +73,76 @@ class App.UiElement.core_workflow_condition extends App.UiElement.ApplicationSel
|
|||
|
||||
elements['custom.module'] = {
|
||||
name: 'module',
|
||||
display: 'Module',
|
||||
display: __('Module'),
|
||||
tag: 'select',
|
||||
multiple: true,
|
||||
options: options,
|
||||
null: false,
|
||||
operator: ['match one module', 'match all modules', 'match no modules']
|
||||
operator: [__('match one module'), __('match all modules'), __('match no modules')]
|
||||
}
|
||||
continue
|
||||
if groupKey is 'session'
|
||||
elements['session.role_ids'] = {
|
||||
name: 'role_ids',
|
||||
display: 'Role',
|
||||
display: __('Role'),
|
||||
tag: 'select',
|
||||
relation: 'Role',
|
||||
null: false,
|
||||
operator: ['is', 'is not'],
|
||||
operator: [__('is'), __('is not')],
|
||||
multiple: true
|
||||
}
|
||||
elements['session.group_ids_read'] = {
|
||||
name: 'group_ids_read',
|
||||
display: 'Group (read)',
|
||||
display: __('Group (read)'),
|
||||
tag: 'select',
|
||||
relation: 'Group',
|
||||
null: false,
|
||||
operator: ['is', 'is not'],
|
||||
operator: [__('is'), __('is not')],
|
||||
multiple: true
|
||||
}
|
||||
elements['session.group_ids_create'] = {
|
||||
name: 'group_ids_create',
|
||||
display: 'Group (create)',
|
||||
display: __('Group (create)'),
|
||||
tag: 'select',
|
||||
relation: 'Group',
|
||||
null: false,
|
||||
operator: ['is', 'is not'],
|
||||
operator: [__('is'), __('is not')],
|
||||
multiple: true
|
||||
}
|
||||
elements['session.group_ids_change'] = {
|
||||
name: 'group_ids_change',
|
||||
display: 'Group (change)',
|
||||
display: __('Group (change)'),
|
||||
tag: 'select',
|
||||
relation: 'Group',
|
||||
null: false,
|
||||
operator: ['is', 'is not'],
|
||||
operator: [__('is'), __('is not')],
|
||||
multiple: true
|
||||
}
|
||||
elements['session.group_ids_overview'] = {
|
||||
name: 'group_ids_overview',
|
||||
display: 'Group (overview)',
|
||||
display: __('Group (overview)'),
|
||||
tag: 'select',
|
||||
relation: 'Group',
|
||||
null: false,
|
||||
operator: ['is', 'is not'],
|
||||
operator: [__('is'), __('is not')],
|
||||
multiple: true
|
||||
}
|
||||
elements['session.group_ids_full'] = {
|
||||
name: 'group_ids_full',
|
||||
display: 'Group (full)',
|
||||
display: __('Group (full)'),
|
||||
tag: 'select',
|
||||
relation: 'Group',
|
||||
null: false,
|
||||
operator: ['is', 'is not'],
|
||||
operator: [__('is'), __('is not')],
|
||||
multiple: true
|
||||
}
|
||||
elements['session.permission_ids'] = {
|
||||
name: 'permission_ids',
|
||||
display: 'Permissions',
|
||||
display: __('Permissions'),
|
||||
tag: 'select',
|
||||
relation: 'Permission',
|
||||
null: false,
|
||||
operator: ['is', 'is not'],
|
||||
operator: [__('is'), __('is not')],
|
||||
multiple: true
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class App.UiElement.core_workflow_perform extends App.UiElement.ApplicationSelec
|
|||
options = {}
|
||||
for module in App.CoreWorkflowCustomModule.all()
|
||||
options[module.name] = module.name
|
||||
elements['custom.module'] = { name: 'module', display: 'Module', tag: 'select', multiple: true, options: options, null: false, operator: ['execute'] }
|
||||
elements['custom.module'] = { name: 'module', display: __('Module'), tag: 'select', multiple: true, options: options, null: false, operator: ['execute'] }
|
||||
continue
|
||||
|
||||
for row in App[groupMeta.model].configure_attributes
|
||||
|
@ -136,6 +136,24 @@ class App.UiElement.core_workflow_perform extends App.UiElement.ApplicationSelec
|
|||
config.nulloption = false
|
||||
return config
|
||||
|
||||
@mapOperatorDisplayName: (operator) ->
|
||||
names =
|
||||
'show': __('show')
|
||||
'hide': __('hide')
|
||||
'remove': __('remove')
|
||||
'set_mandatory': __('set mandatory')
|
||||
'set_optional': __('set optional')
|
||||
'set_readonly': __('set readonly')
|
||||
'unset_readonly': __('unset readonly')
|
||||
'add_option': __('add option')
|
||||
'remove_option': __('remove option')
|
||||
'set_fixed_to': __('set fixed to')
|
||||
'select': __('select')
|
||||
'auto_select': __('auto select')
|
||||
'fill_in': __('fill in')
|
||||
'fill_in_empty': __('fill in empty')
|
||||
return names[operator] || operator
|
||||
|
||||
@HasPreCondition: ->
|
||||
return false
|
||||
|
||||
|
|
|
@ -30,13 +30,13 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
localItem.find('.js-dataScreens').html(@dataScreens(attribute, localParams, params))
|
||||
|
||||
options =
|
||||
datetime: 'Datetime'
|
||||
date: 'Date'
|
||||
input: 'Text'
|
||||
select: 'Select'
|
||||
tree_select: 'Tree Select'
|
||||
boolean: 'Boolean'
|
||||
integer: 'Integer'
|
||||
datetime: __('Datetime')
|
||||
date: __('Date')
|
||||
input: __('Text')
|
||||
select: __('Select')
|
||||
tree_select: __('Tree Select')
|
||||
boolean: __('Boolean')
|
||||
integer: __('Integer')
|
||||
|
||||
# if attribute already exists, do not allow to change it anymore
|
||||
if params.data_type
|
||||
|
@ -173,7 +173,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
|
||||
@input: (item, localParams, params) ->
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::default', display: 'Default', tag: 'input', type: 'text', null: true, default: '' },
|
||||
{ name: 'data_option::default', display: __('Default'), tag: 'input', type: 'text', null: true, default: '' },
|
||||
]
|
||||
inputDefault = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -182,7 +182,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
params: params
|
||||
)
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::type', display: 'Type', tag: 'select', null: false, default: 'text', options: {text: 'Text', tel: 'Phone', email: 'Email', url: 'Url'}, translate: true },
|
||||
{ name: 'data_option::type', display: __('Type'), tag: 'select', null: false, default: 'text', options: {text: __('Text'), tel: 'Phone', email: 'Email', url: 'Url'}, translate: true },
|
||||
]
|
||||
inputType = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -191,7 +191,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
params: params
|
||||
)
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::maxlength', display: 'Maxlength', tag: 'integer', null: false, default: 120 },
|
||||
{ name: 'data_option::maxlength', display: __('Maxlength'), tag: 'integer', null: false, default: 120 },
|
||||
]
|
||||
inputMaxlength = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -201,7 +201,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
)
|
||||
configureAttributes = [
|
||||
# coffeelint: disable=no_interpolation_in_single_quotes
|
||||
{ name: 'data_option::linktemplate', display: 'Link-Template', tag: 'input', type: 'text', null: true, default: '', placeholder: 'https://example.com/?q=#{object.attribute_name} - use ticket, user or organization as object' },
|
||||
{ name: 'data_option::linktemplate', display: __('Link-Template'), tag: 'input', type: 'text', null: true, default: '', placeholder: 'https://example.com/?q=#{object.attribute_name} - use ticket, user or organization as object' },
|
||||
# coffeelint: enable=no_interpolation_in_single_quotes
|
||||
]
|
||||
inputLinkTemplate = new App.ControllerForm(
|
||||
|
@ -226,7 +226,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
|
||||
@datetime: (item, localParams, params) ->
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::future', display: 'Allow future', tag: 'boolean', null: false, default: true },
|
||||
{ name: 'data_option::future', display: __('Allow future'), tag: 'boolean', null: false, default: true },
|
||||
]
|
||||
datetimeFuture = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -235,7 +235,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
params: params
|
||||
)
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::past', display: 'Allow past', tag: 'boolean', null: false, default: true },
|
||||
{ name: 'data_option::past', display: __('Allow past'), tag: 'boolean', null: false, default: true },
|
||||
]
|
||||
datetimePast = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -244,7 +244,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
params: params
|
||||
)
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::diff', display: 'Default time Diff (minutes)', tag: 'integer', null: true },
|
||||
{ name: 'data_option::diff', display: __('Default time Diff (minutes)'), tag: 'integer', null: true },
|
||||
]
|
||||
datetimeDiff = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -258,7 +258,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
|
||||
@date: (item, localParams, params) ->
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::diff', display: 'Default time Diff (hours)', tag: 'integer', null: true },
|
||||
{ name: 'data_option::diff', display: __('Default time Diff (hours)'), tag: 'integer', null: true },
|
||||
]
|
||||
dateDiff = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -270,7 +270,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
|
||||
@integer: (item, localParams, params) ->
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::default', display: 'Default', tag: 'integer', null: true, default: '', min: 1 },
|
||||
{ name: 'data_option::default', display: __('Default'), tag: 'integer', null: true, default: '', min: 1 },
|
||||
]
|
||||
integerDefault = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -279,7 +279,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
params: params
|
||||
)
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::min', display: 'Minimal', tag: 'integer', null: false, default: 0, min: -2147483647, max: 2147483647 },
|
||||
{ name: 'data_option::min', display: __('Minimal'), tag: 'integer', null: false, default: 0, min: -2147483647, max: 2147483647 },
|
||||
]
|
||||
integerMin = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -288,7 +288,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
params: params
|
||||
)
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::max', display: 'Maximal', tag: 'integer', null: false, min: -2147483647, max: 2147483647, default: 999999999 },
|
||||
{ name: 'data_option::max', display: __('Maximal'), tag: 'integer', null: false, min: -2147483647, max: 2147483647, default: 999999999 },
|
||||
]
|
||||
integerMax = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -339,7 +339,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
)
|
||||
configureAttributes = [
|
||||
# coffeelint: disable=no_interpolation_in_single_quotes
|
||||
{ name: 'data_option::linktemplate', display: 'Link-Template', tag: 'input', type: 'text', null: true, default: '', placeholder: 'https://example.com/?q=#{ticket.attribute_name}' },
|
||||
{ name: 'data_option::linktemplate', display: __('Link-Template'), tag: 'input', type: 'text', null: true, default: '', placeholder: 'https://example.com/?q=#{ticket.attribute_name}' },
|
||||
# coffeelint: enable=no_interpolation_in_single_quotes
|
||||
]
|
||||
inputLinkTemplate = new App.ControllerForm(
|
||||
|
@ -441,7 +441,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
|
||||
@autocompletion: (item, localParams, params) ->
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::default', display: 'Default', tag: 'input', type: 'text', null: true, default: '' },
|
||||
{ name: 'data_option::default', display: __('Default'), tag: 'input', type: 'text', null: true, default: '' },
|
||||
]
|
||||
autocompletionDefault = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -450,7 +450,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
params: params
|
||||
)
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::url', display: 'Url (AJAX Endpoint)', tag: 'input', type: 'url', null: false, default: '', placeholder: 'https://example.com/serials' },
|
||||
{ name: 'data_option::url', display: __('Url (AJAX Endpoint)'), tag: 'input', type: 'url', null: false, default: '', placeholder: 'https://example.com/serials' },
|
||||
]
|
||||
autocompletionUrl = new App.ControllerForm(
|
||||
model:
|
||||
|
@ -459,7 +459,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
|
|||
params: params
|
||||
)
|
||||
configureAttributes = [
|
||||
{ name: 'data_option::method', display: 'Method (AJAX Endpoint)', tag: 'input', type: 'url', null: false, default: '', placeholder: 'GET' },
|
||||
{ name: 'data_option::method', display: __('Method (AJAX Endpoint)'), tag: 'input', type: 'url', null: false, default: '', placeholder: __('GET') },
|
||||
]
|
||||
autocompletionMethod = new App.ControllerForm(
|
||||
model:
|
||||
|
|
|
@ -3,35 +3,35 @@ class App.UiElement.postmaster_match
|
|||
@defaults: ->
|
||||
groups =
|
||||
general:
|
||||
name: 'Basic Settings'
|
||||
name: __('Basic Settings')
|
||||
options: [
|
||||
{
|
||||
value: 'from'
|
||||
name: 'From'
|
||||
name: __('From')
|
||||
},
|
||||
{
|
||||
value: 'to'
|
||||
name: 'To'
|
||||
name: __('To')
|
||||
},
|
||||
{
|
||||
value: 'cc'
|
||||
name: 'Cc'
|
||||
name: __('Cc')
|
||||
},
|
||||
{
|
||||
value: 'x-any-recipient'
|
||||
name: 'Any Recipient'
|
||||
name: __('Any Recipient')
|
||||
},
|
||||
{
|
||||
value: 'subject'
|
||||
name: 'Subject'
|
||||
name: __('Subject')
|
||||
},
|
||||
{
|
||||
value: 'body'
|
||||
name: 'Body'
|
||||
name: __('Body')
|
||||
},
|
||||
]
|
||||
expert:
|
||||
name: 'Expert Settings'
|
||||
name: __('Expert Settings')
|
||||
options: [
|
||||
{
|
||||
value: 'x-spam'
|
||||
|
|
|
@ -8,34 +8,34 @@ class App.UiElement.postmaster_set
|
|||
options: [
|
||||
{
|
||||
value: 'priority_id'
|
||||
name: 'Priority'
|
||||
name: __('Priority')
|
||||
relation: 'TicketPriority'
|
||||
}
|
||||
{
|
||||
value: 'state_id'
|
||||
name: 'State'
|
||||
name: __('State')
|
||||
relation: 'TicketState'
|
||||
}
|
||||
{
|
||||
value: 'tags'
|
||||
name: 'Tag'
|
||||
name: __('Tag')
|
||||
tag: 'tag'
|
||||
}
|
||||
{
|
||||
value: 'customer_id'
|
||||
name: 'Customer'
|
||||
name: __('Customer')
|
||||
relation: 'User'
|
||||
tag: 'user_autocompletion'
|
||||
disableCreateObject: true
|
||||
}
|
||||
{
|
||||
value: 'group_id'
|
||||
name: 'Group'
|
||||
name: __('Group')
|
||||
relation: 'Group'
|
||||
}
|
||||
{
|
||||
value: 'owner_id'
|
||||
name: 'Owner'
|
||||
name: __('Owner')
|
||||
relation: 'User'
|
||||
tag: 'user_autocompletion'
|
||||
disableCreateObject: true
|
||||
|
@ -46,17 +46,17 @@ class App.UiElement.postmaster_set
|
|||
options: [
|
||||
{
|
||||
value: 'x-zammad-article-internal'
|
||||
name: 'Internal'
|
||||
name: __('Internal')
|
||||
options: { true: 'yes', false: 'no'}
|
||||
}
|
||||
{
|
||||
value: 'x-zammad-article-type_id'
|
||||
name: 'Type'
|
||||
name: __('Type')
|
||||
relation: 'TicketArticleType'
|
||||
}
|
||||
{
|
||||
value: 'x-zammad-article-sender_id'
|
||||
name: 'Sender'
|
||||
name: __('Sender')
|
||||
relation: 'TicketArticleSender'
|
||||
}
|
||||
]
|
||||
|
@ -65,7 +65,7 @@ class App.UiElement.postmaster_set
|
|||
options: [
|
||||
{
|
||||
value: 'x-zammad-ignore'
|
||||
name: 'Ignore Message'
|
||||
name: __('Ignore Message')
|
||||
options: { true: 'yes', false: 'no'}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# coffeelint: disable=camel_case_classes
|
||||
class App.UiElement.richtext.toolButtons.embed_video extends App.UiElement.richtext.additions.RichTextToolButton
|
||||
@icon: 'cloud'
|
||||
@text: 'Video'
|
||||
@text: __('Video')
|
||||
@klass: -> App.UiElement.richtext.additions.RichTextToolPopupVideo
|
||||
@initializeAttributes:
|
||||
model:
|
||||
configure_attributes: [
|
||||
{
|
||||
name: 'link'
|
||||
display: 'Link'
|
||||
display: __('Link')
|
||||
tag: 'input'
|
||||
placeholder: 'Youtube or Vimeo address'
|
||||
placeholder: __('Youtube or Vimeo address')
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# coffeelint: disable=camel_case_classes
|
||||
class App.UiElement.richtext.toolButtons.insert_image extends App.UiElement.richtext.additions.RichTextToolButton
|
||||
@icon: 'web'
|
||||
@text: 'Image'
|
||||
@text: __('Image')
|
||||
@klass: -> App.UiElement.richtext.additions.RichTextToolPopupImage
|
||||
@initializeAttributes:
|
||||
model:
|
||||
configure_attributes: [
|
||||
{
|
||||
name: 'link'
|
||||
display: 'Image'
|
||||
display: __('Image')
|
||||
tag: 'input'
|
||||
type: 'file'
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# coffeelint: disable=camel_case_classes
|
||||
class App.UiElement.richtext.toolButtons.link_answer extends App.UiElement.richtext.additions.RichTextToolButtonLink
|
||||
@icon: 'knowledge-base-answer'
|
||||
@text: 'Link Answer'
|
||||
@text: __('Link Answer')
|
||||
@klass: -> App.UiElement.richtext.additions.RichTextToolPopupAnswer
|
||||
@initializeAttributes:
|
||||
model:
|
||||
configure_attributes: [
|
||||
{
|
||||
name: 'link'
|
||||
display: 'Answer'
|
||||
display: __('Answer')
|
||||
relation: 'KnowledgeBaseAnswerTranslation'
|
||||
tag: 'autocompletion_ajax'
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# coffeelint: disable=camel_case_classes
|
||||
class App.UiElement.richtext.toolButtons.link extends App.UiElement.richtext.additions.RichTextToolButtonLink
|
||||
@icon: 'chain'
|
||||
@text: 'Weblink'
|
||||
@text: __('Weblink')
|
||||
@klass: -> App.UiElement.richtext.additions.RichTextToolPopupLink
|
||||
@initializeAttributes:
|
||||
model:
|
||||
configure_attributes: [
|
||||
{
|
||||
name: 'link'
|
||||
display: 'Link'
|
||||
display: __('Link')
|
||||
tag: 'input'
|
||||
placeholder: 'http://'
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class App.UiElement.richtext.additions.RichTextToolPopupVideo extends App.UiElem
|
|||
|
||||
if !markup
|
||||
new App.ControllerErrorModal(
|
||||
message: 'Invalid video URL'
|
||||
message: __('Invalid video URL')
|
||||
)
|
||||
|
||||
return
|
||||
|
|
|
@ -5,15 +5,15 @@ class App.UiElement.ticket_perform_action
|
|||
|
||||
groups =
|
||||
ticket:
|
||||
name: 'Ticket'
|
||||
name: __('Ticket')
|
||||
model: 'Ticket'
|
||||
article:
|
||||
name: 'Article'
|
||||
name: __('Article')
|
||||
model: 'Article'
|
||||
|
||||
if attribute.notification
|
||||
groups.notification =
|
||||
name: 'Notification'
|
||||
name: __('Notification')
|
||||
model: 'Notification'
|
||||
|
||||
# merge config
|
||||
|
@ -21,11 +21,11 @@ class App.UiElement.ticket_perform_action
|
|||
for groupKey, groupMeta of groups
|
||||
if !groupMeta.model || !App[groupMeta.model]
|
||||
if groupKey is 'notification'
|
||||
elements["#{groupKey}.email"] = { name: 'email', display: 'Email' }
|
||||
elements["#{groupKey}.sms"] = { name: 'sms', display: 'SMS' }
|
||||
elements["#{groupKey}.webhook"] = { name: 'webhook', display: 'Webhook' }
|
||||
elements["#{groupKey}.email"] = { name: 'email', display: __('Email') }
|
||||
elements["#{groupKey}.sms"] = { name: 'sms', display: __('SMS') }
|
||||
elements["#{groupKey}.webhook"] = { name: 'webhook', display: __('Webhook') }
|
||||
else if groupKey is 'article'
|
||||
elements["#{groupKey}.note"] = { name: 'note', display: 'Note' }
|
||||
elements["#{groupKey}.note"] = { name: 'note', display: __('Note') }
|
||||
else
|
||||
|
||||
for row in App[groupMeta.model].configure_attributes
|
||||
|
@ -49,7 +49,7 @@ class App.UiElement.ticket_perform_action
|
|||
if attribute.ticket_delete
|
||||
elements['ticket.action'] =
|
||||
name: 'action'
|
||||
display: 'Action'
|
||||
display: __('Action')
|
||||
tag: 'select'
|
||||
null: false
|
||||
translate: true
|
||||
|
@ -362,10 +362,10 @@ class App.UiElement.ticket_perform_action
|
|||
elementRow.find('.js-setNotification').empty()
|
||||
|
||||
options =
|
||||
'article_last_sender': 'Article Last Sender'
|
||||
'ticket_owner': 'Owner'
|
||||
'ticket_customer': 'Customer'
|
||||
'ticket_agents': 'All Agents'
|
||||
'article_last_sender': __('Article Last Sender')
|
||||
'ticket_owner': __('Owner')
|
||||
'ticket_customer': __('Customer')
|
||||
'ticket_agents': __('All Agents')
|
||||
|
||||
name = "#{attribute.name}::notification.#{notificationType}"
|
||||
|
||||
|
@ -399,11 +399,11 @@ class App.UiElement.ticket_perform_action
|
|||
name: "#{name}::recipient"
|
||||
options: [
|
||||
{
|
||||
label: 'Variables',
|
||||
label: __('Variables'),
|
||||
group: columnSelectOptions
|
||||
},
|
||||
{
|
||||
label: 'User',
|
||||
label: __('User'),
|
||||
group: columnSelectRecipientUserOptions
|
||||
},
|
||||
]
|
||||
|
@ -459,7 +459,7 @@ class App.UiElement.ticket_perform_action
|
|||
name: "#{name}::include_attachments"
|
||||
multiple: false
|
||||
null: false
|
||||
options: { true: 'Yes', false: 'No' }
|
||||
options: { true: __('Yes'), false: __('No') }
|
||||
value: meta.include_attachments || 'false'
|
||||
translate: true
|
||||
)
|
||||
|
@ -469,7 +469,7 @@ class App.UiElement.ticket_perform_action
|
|||
|
||||
notificationElement.find('.js-body div[contenteditable="true"]').ce(
|
||||
mode: 'richtext'
|
||||
placeholder: 'message'
|
||||
placeholder: __('message')
|
||||
maxlength: messageLength
|
||||
)
|
||||
new App.WidgetPlaceholder(
|
||||
|
@ -478,17 +478,17 @@ class App.UiElement.ticket_perform_action
|
|||
{
|
||||
prefix: 'ticket'
|
||||
object: 'Ticket'
|
||||
display: 'Ticket'
|
||||
display: __('Ticket')
|
||||
},
|
||||
{
|
||||
prefix: 'article'
|
||||
object: 'TicketArticle'
|
||||
display: 'Article'
|
||||
display: __('Article')
|
||||
},
|
||||
{
|
||||
prefix: 'user'
|
||||
object: 'User'
|
||||
display: 'Current User'
|
||||
display: __('Current User')
|
||||
},
|
||||
]
|
||||
)
|
||||
|
@ -500,9 +500,9 @@ class App.UiElement.ticket_perform_action
|
|||
name: "#{name}::sign"
|
||||
multiple: false
|
||||
options: {
|
||||
'no': 'Do not sign email'
|
||||
'discard': 'Sign email (if not possible, discard notification)'
|
||||
'always': 'Sign email (if not possible, send notification anyway)'
|
||||
'no': __('Do not sign email')
|
||||
'discard': __('Sign email (if not possible, discard notification)')
|
||||
'always': __('Sign email (if not possible, send notification anyway)')
|
||||
}
|
||||
value: meta.sign
|
||||
translate: true
|
||||
|
@ -514,9 +514,9 @@ class App.UiElement.ticket_perform_action
|
|||
name: "#{name}::encryption"
|
||||
multiple: false
|
||||
options: {
|
||||
'no': 'Do not encrypt email'
|
||||
'discard': 'Encrypt email (if not possible, discard notification)'
|
||||
'always': 'Encrypt email (if not possible, send notification anyway)'
|
||||
'no': __('Do not encrypt email')
|
||||
'discard': __('Encrypt email (if not possible, discard notification)')
|
||||
'always': __('Encrypt email (if not possible, send notification anyway)')
|
||||
}
|
||||
value: meta.encryption
|
||||
translate: true
|
||||
|
@ -535,7 +535,7 @@ class App.UiElement.ticket_perform_action
|
|||
name: "#{name}::internal"
|
||||
multiple: false
|
||||
null: false
|
||||
label: 'Visibility'
|
||||
label: __('Visibility')
|
||||
options: { true: 'internal', false: 'public' }
|
||||
value: meta.internal
|
||||
translate: true
|
||||
|
@ -549,7 +549,7 @@ class App.UiElement.ticket_perform_action
|
|||
articleElement.find('.js-internal').html(selection)
|
||||
articleElement.find('.js-body div[contenteditable="true"]').ce(
|
||||
mode: 'richtext'
|
||||
placeholder: 'message'
|
||||
placeholder: __('message')
|
||||
maxlength: 200000
|
||||
)
|
||||
new App.WidgetPlaceholder(
|
||||
|
@ -558,17 +558,17 @@ class App.UiElement.ticket_perform_action
|
|||
{
|
||||
prefix: 'ticket'
|
||||
object: 'Ticket'
|
||||
display: 'Ticket'
|
||||
display: __('Ticket')
|
||||
},
|
||||
{
|
||||
prefix: 'article'
|
||||
object: 'TicketArticle'
|
||||
display: 'Article'
|
||||
display: __('Article')
|
||||
},
|
||||
{
|
||||
prefix: 'user'
|
||||
object: 'User'
|
||||
display: 'Current User'
|
||||
display: __('Current User')
|
||||
},
|
||||
]
|
||||
)
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
class App.UiElement.time_range
|
||||
@render: (attribute) ->
|
||||
ranges =
|
||||
minute: 'Minute(s)'
|
||||
hour: 'Hour(s)'
|
||||
day: 'Day(s)'
|
||||
month: 'Month(s)'
|
||||
year: 'Year(s)'
|
||||
minute: __('Minute(s)')
|
||||
hour: __('Hour(s)')
|
||||
day: __('Day(s)')
|
||||
month: __('Month(s)')
|
||||
year: __('Year(s)')
|
||||
for key, value of ranges
|
||||
ranges[key] = App.i18n.translateInline(value)
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
class App.UiElement.timer
|
||||
@render: (attribute) ->
|
||||
days =
|
||||
Mon: 'Monday'
|
||||
Tue: 'Tuesday'
|
||||
Wed: 'Wednesday'
|
||||
Thu: 'Thursday'
|
||||
Fri: 'Friday'
|
||||
Sat: 'Saturday'
|
||||
Sun: 'Sunday'
|
||||
Mon: __('Monday')
|
||||
Tue: __('Tuesday')
|
||||
Wed: __('Wednesday')
|
||||
Thu: __('Thursday')
|
||||
Fri: __('Friday')
|
||||
Sat: __('Saturday')
|
||||
Sun: __('Sunday')
|
||||
hours =
|
||||
0: '12 am'
|
||||
1: '1 am'
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue