Maintenance: Improved wording of translatable source strings.

This commit is contained in:
Martin Gruner 2022-01-25 10:11:47 +01:00
parent c04a599f21
commit 344d647079
27 changed files with 662 additions and 404 deletions

View file

@ -0,0 +1,17 @@
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
module RuboCop
module Cop
module Zammad
class ForbidTranslatableMarker < Base
MSG = <<~ERROR_MESSAGE.freeze
Don't use __() in Zammad core migrations. Translatable strings should be marked where they are defined, e.g. in the DB seeds.
ERROR_MESSAGE
def on_send(node)
add_offense(node) if node.method_name.eql? :__
end
end
end
end
end

View file

@ -335,6 +335,11 @@ Zammad/DetectTranslatableString:
- "lib/import/**/*.rb" - "lib/import/**/*.rb"
- "lib/tasks/**/*.rb" - "lib/tasks/**/*.rb"
Zammad/ForbidTranslatableMarker:
Enabled: true
Include:
- "db/migrate/*.rb"
Zammad/ExistsDbStrategy: Zammad/ExistsDbStrategy:
Include: Include:
- "spec/**/*.rb" - "spec/**/*.rb"

View file

@ -11,3 +11,4 @@ require_relative 'cop/zammad/no_to_sym_on_string'
require_relative 'cop/zammad/prefer_negated_if_over_unless' require_relative 'cop/zammad/prefer_negated_if_over_unless'
require_relative 'cop/zammad/update_copyright' require_relative 'cop/zammad/update_copyright'
require_relative 'cop/zammad/forbid_rand' require_relative 'cop/zammad/forbid_rand'
require_relative 'cop/zammad/forbid_translatable_marker'

View file

@ -212,7 +212,7 @@ class FirstStepsController < ApplicationController
private private
def test_overview def test_overview
Overview.find_by(name: __('Unassigned & Open')) Overview.find_by(name: __('Unassigned & Open Tickets'))
end end
def test_customer def test_customer

View file

@ -7,10 +7,10 @@ class Issue3924ConfirmationDialog < ActiveRecord::Migration[6.0]
return if !Setting.exists?(name: 'system_init_done') return if !Setting.exists?(name: 'system_init_done')
Setting.create_if_not_exists( Setting.create_if_not_exists(
title: __('Note - visibility confirmation dialog'), title: 'Note - visibility confirmation dialog',
name: 'ui_ticket_zoom_article_visibility_confirmation_dialog', name: 'ui_ticket_zoom_article_visibility_confirmation_dialog',
area: 'UI::TicketZoom', area: 'UI::TicketZoom',
description: __('Defines if the agent has to accept a confirmation dialog when changing the article visibility to "public".'), description: 'Defines if the agent has to accept a confirmation dialog when changing the article visibility to "public".',
options: { options: {
form: [ form: [
{ {

View file

@ -1,328 +1,328 @@
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/ # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
class SettingUpdates < ActiveRecord::Migration[6.0] class SettingUpdates < ActiveRecord::Migration[6.0]
def change # rubocop:disable Metrics/AbcSize def change
return if !Setting.exists?(name: 'system_init_done') return if !Setting.exists?(name: 'system_init_done')
settings_update = [ settings_update = [
{ {
title: __('2 lower case and 2 upper case characters'), title: '2 lower case and 2 upper case characters',
name: 'password_min_2_lower_2_upper_characters', name: 'password_min_2_lower_2_upper_characters',
description: __('Password needs to contain 2 lower case and 2 upper case characters.'), description: 'Password needs to contain 2 lower case and 2 upper case characters.',
}, },
{ {
title: __('User email for multiple users'), title: 'User email for multiple users',
name: 'user_email_multiple_use', name: 'user_email_multiple_use',
description: __('Allow using one email address for multiple users.'), description: 'Allow using one email address for multiple users.',
}, },
{ {
title: __('sipgate.io alternative FQDN'), title: 'sipgate.io alternative FQDN',
name: 'sipgate_alternative_fqdn', name: 'sipgate_alternative_fqdn',
description: __('Alternative FQDN for callbacks if you operate Zammad in an internal network.'), description: 'Alternative FQDN for callbacks if you operate Zammad in an internal network.',
}, },
{ {
title: __('Auto Assignment'), title: 'Auto Assignment',
name: 'ticket_auto_assignment', name: 'ticket_auto_assignment',
}, },
{ {
title: __('BCC address for all outgoing emails'), title: 'BCC address for all outgoing emails',
name: 'system_bcc', name: 'system_bcc',
description: __('To archive all outgoing emails from Zammad to external, you can store a BCC email address here.'), description: 'To archive all outgoing emails from Zammad to external, you can store a BCC email address here.',
}, },
{ {
title: __('Additional follow-up detection'), title: 'Additional follow-up detection',
name: 'postmaster_follow_up_search_in', name: 'postmaster_follow_up_search_in',
description: __('By default, the follow-up check is done via the subject of an email. This setting lets you add more fields for which the follow-up check will be executed.'), description: 'By default, the follow-up check is done via the subject of an email. This setting lets you add more fields for which the follow-up check will be executed.',
}, },
{ {
title: __('Note - default visibility'), title: 'Note - default visibility',
name: 'ui_ticket_zoom_article_note_new_internal', name: 'ui_ticket_zoom_article_note_new_internal',
description: __('Defines the default visibility for new notes.'), description: 'Defines the default visibility for new notes.',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '0014_postmaster_filter_own_notification_loop_detection', name: '0014_postmaster_filter_own_notification_loop_detection',
description: __('Defines postmaster filter to check if the email is a self-created notification email, then ignore it to prevent email loops.'), description: 'Defines postmaster filter to check if the email is a self-created notification email, then ignore it to prevent email loops.',
}, },
{ {
title: __('HTTP type'), title: 'HTTP type',
name: 'http_type', name: 'http_type',
description: __('Defines the HTTP protocol of your instance.'), description: 'Defines the HTTP protocol of your instance.',
}, },
{ {
title: __('Defines the timeframe during which a self-created note can be deleted.'), title: 'Defines the timeframe during which a self-created note can be deleted.',
name: 'ui_ticket_zoom_article_delete_timeframe', name: 'ui_ticket_zoom_article_delete_timeframe',
}, },
{ {
title: __('Import Endpoint'), title: 'Import Endpoint',
name: 'import_freshdesk_endpoint', name: 'import_freshdesk_endpoint',
description: __('Defines a Freshdesk endpoint to import users, tickets, states, and articles.'), description: 'Defines a Freshdesk endpoint to import users, tickets, states, and articles.',
}, },
{ {
title: __('Import Endpoint'), title: 'Import Endpoint',
name: 'import_kayako_endpoint', name: 'import_kayako_endpoint',
description: __('Defines a Kayako endpoint to import users, tickets, states, and articles.'), description: 'Defines a Kayako endpoint to import users, tickets, states, and articles.',
}, },
{ {
title: __('Import Endpoint'), title: 'Import Endpoint',
name: 'import_otrs_endpoint', name: 'import_otrs_endpoint',
description: __('Defines an OTRS endpoint to import users, tickets, states, and articles.'), description: 'Defines an OTRS endpoint to import users, tickets, states, and articles.',
}, },
{ {
title: __('Import Endpoint'), title: 'Import Endpoint',
name: 'import_zendesk_endpoint', name: 'import_zendesk_endpoint',
description: __('Defines a Zendesk endpoint to import users, tickets, states, and articles.'), description: 'Defines a Zendesk endpoint to import users, tickets, states, and articles.',
}, },
{ {
title: __('Stats Backend'), title: 'Stats Backend',
name: 'Stats::TicketWaitingTime', name: 'Stats::TicketWaitingTime',
description: __('Defines a dashboard stats backend that gets scheduled automatically.'), description: 'Defines a dashboard stats backend that gets scheduled automatically.',
}, },
{ {
title: __('Stats Backend'), title: 'Stats Backend',
name: 'Stats::TicketEscalation', name: 'Stats::TicketEscalation',
description: __('Defines a dashboard stats backend that gets scheduled automatically.'), description: 'Defines a dashboard stats backend that gets scheduled automatically.',
}, },
{ {
title: __('Stats Backend'), title: 'Stats Backend',
name: 'Stats::TicketChannelDistribution', name: 'Stats::TicketChannelDistribution',
description: __('Defines a dashboard stats backend that gets scheduled automatically.'), description: 'Defines a dashboard stats backend that gets scheduled automatically.',
}, },
{ {
title: __('Stats Backend'), title: 'Stats Backend',
name: 'Stats::TicketLoadMeasure', name: 'Stats::TicketLoadMeasure',
description: __('Defines a dashboard stats backend that gets scheduled automatically.'), description: 'Defines a dashboard stats backend that gets scheduled automatically.',
}, },
{ {
title: __('Stats Backend'), title: 'Stats Backend',
name: 'Stats::TicketInProcess', name: 'Stats::TicketInProcess',
description: __('Defines a dashboard stats backend that gets scheduled automatically.'), description: 'Defines a dashboard stats backend that gets scheduled automatically.',
}, },
{ {
title: __('Stats Backend'), title: 'Stats Backend',
name: 'Stats::TicketReopen', name: 'Stats::TicketReopen',
description: __('Defines a dashboard stats backend that gets scheduled automatically.'), description: 'Defines a dashboard stats backend that gets scheduled automatically.',
}, },
{ {
title: __('Import Password for HTTP basic authentication'), title: 'Import Password for HTTP basic authentication',
name: 'import_otrs_password', name: 'import_otrs_password',
description: __('Defines HTTP basic authentication password (only if OTRS is protected via HTTP basic auth).'), description: 'Defines HTTP basic authentication password (only if OTRS is protected via HTTP basic auth).',
}, },
{ {
title: __('Developer System'), title: 'Developer System',
name: 'developer_mode', name: 'developer_mode',
description: __('Defines if the application is in developer mode (all users have the same password and password reset will work without email delivery).'), description: 'Defines if the application is in developer mode (all users have the same password and password reset will work without email delivery).',
}, },
{ {
title: __('Group selection for ticket creation'), title: 'Group selection for ticket creation',
name: 'form_ticket_create_group_id', name: 'form_ticket_create_group_id',
description: __('Defines the group of tickets created via web form.'), description: 'Defines the group of tickets created via web form.',
}, },
{ {
title: __('Limit tickets by IP per day'), title: 'Limit tickets by IP per day',
name: 'form_ticket_create_by_ip_per_day', name: 'form_ticket_create_by_ip_per_day',
description: __('Defines a limit for how many tickets can be created via web form from one IP address per day.'), description: 'Defines a limit for how many tickets can be created via web form from one IP address per day.',
}, },
{ {
title: __('Limit tickets by IP per hour'), title: 'Limit tickets by IP per hour',
name: 'form_ticket_create_by_ip_per_hour', name: 'form_ticket_create_by_ip_per_hour',
description: __('Defines a limit for how many tickets can be created via web form from one IP address per hour.'), description: 'Defines a limit for how many tickets can be created via web form from one IP address per hour.',
}, },
{ {
title: __('Limit tickets per day'), title: 'Limit tickets per day',
name: 'form_ticket_create_per_day', name: 'form_ticket_create_per_day',
description: __('Defines a limit for how many tickets can be created via web form per day.'), description: 'Defines a limit for how many tickets can be created via web form per day.',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '5400_postmaster_filter_jira_check', name: '5400_postmaster_filter_jira_check',
description: __('Defines postmaster filter to identify Jira mails for correct follow-ups.'), description: 'Defines postmaster filter to identify Jira mails for correct follow-ups.',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '5401_postmaster_filter_jira_check', name: '5401_postmaster_filter_jira_check',
description: __('Defines postmaster filter to identify Jira mails for correct follow-ups.'), description: 'Defines postmaster filter to identify Jira mails for correct follow-ups.',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '0950_postmaster_filter_bounce_delivery_permanent_failed', name: '0950_postmaster_filter_bounce_delivery_permanent_failed',
description: __('Defines postmaster filter to identify postmaster bounces; and disables sending notification if delivery fails permanently.'), description: 'Defines postmaster filter to identify postmaster bounces; and disables sending notification if delivery fails permanently.',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '0955_postmaster_filter_bounce_delivery_temporary_failed', name: '0955_postmaster_filter_bounce_delivery_temporary_failed',
description: __('Defines postmaster filter to identify postmaster bounces; and reopens tickets if delivery fails permanently.'), description: 'Defines postmaster filter to identify postmaster bounces; and reopens tickets if delivery fails permanently.',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '0900_postmaster_filter_bounce_follow_up_check', name: '0900_postmaster_filter_bounce_follow_up_check',
description: __('Defines postmaster filter to identify postmaster bounces; and handles them as follow-up of the original tickets'), description: 'Defines postmaster filter to identify postmaster bounces; and handles them as follow-up of the original tickets',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '5400_postmaster_filter_service_now_check', name: '5400_postmaster_filter_service_now_check',
description: __('Defines postmaster filter to identify ServiceNow mails for correct follow-ups.'), description: 'Defines postmaster filter to identify ServiceNow mails for correct follow-ups.',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '5401_postmaster_filter_service_now_check', name: '5401_postmaster_filter_service_now_check',
description: __('Defines postmaster filter to identify ServiceNow mails for correct follow-ups.'), description: 'Defines postmaster filter to identify ServiceNow mails for correct follow-ups.',
}, },
{ {
title: __('Defines postmaster filter.'), title: 'Defines postmaster filter.',
name: '0005_postmaster_filter_trusted', name: '0005_postmaster_filter_trusted',
description: __('Defines postmaster filter to remove X-Zammad headers from untrustworthy sources.'), description: 'Defines postmaster filter to remove X-Zammad headers from untrustworthy sources.',
}, },
{ {
title: __('HTML Email CSS Font'), title: 'HTML Email CSS Font',
name: 'html_email_css_font', name: 'html_email_css_font',
description: __('Defines the CSS font information for HTML emails.'), description: 'Defines the CSS font information for HTML emails.',
}, },
{ {
title: __('Geo IP Service'), title: 'Geo IP Service',
name: 'geo_ip_backend', name: 'geo_ip_backend',
description: __('Defines the backend for geo IP lookups. Also shows location of an IP address if it is traceable.'), description: 'Defines the backend for geo IP lookups. Also shows location of an IP address if it is traceable.',
}, },
{ {
title: __('CTI config'), title: 'CTI config',
name: 'cti_config', name: 'cti_config',
description: __('Defines the CTI config.'), description: 'Defines the CTI config.',
}, },
{ {
title: __('Set agent limit'), title: 'Set agent limit',
name: 'system_agent_limit', name: 'system_agent_limit',
description: __('Defines the agent limit.'), description: 'Defines the agent limit.',
}, },
{ {
title: __('Product Name'), title: 'Product Name',
name: 'product_name', name: 'product_name',
description: __('Defines the name of the application, shown in the web interface, tabs, and title bar of the web browser.'), description: 'Defines the name of the application, shown in the web interface, tabs, and title bar of the web browser.',
}, },
{ {
title: __('Define postmaster filter.'), title: 'Define postmaster filter.',
name: '5500_postmaster_internal_article_check', name: '5500_postmaster_internal_article_check',
description: __('Defines postmaster filter which sets the articles visibility to internal if it is a rely to an internal article or the last outgoing email is internal.'), description: 'Defines postmaster filter which sets the articles visibility to internal if it is a rely to an internal article or the last outgoing email is internal.',
}, },
{ {
title: __('CTI customer last activity'), title: 'CTI customer last activity',
name: 'cti_customer_last_activity', name: 'cti_customer_last_activity',
description: __('Defines the duration of customer activity (in seconds) on a call until the user profile dialog is shown.'), description: 'Defines the duration of customer activity (in seconds) on a call until the user profile dialog is shown.',
}, },
{ {
title: __('Slack config'), title: 'Slack config',
name: 'slack_config', name: 'slack_config',
description: __('Defines the Slack config.'), description: 'Defines the Slack config.',
}, },
{ {
title: __('Auto-close state'), title: 'Auto-close state',
name: 'icinga_auto_close_state_id', name: 'icinga_auto_close_state_id',
description: __('Defines the state of auto-closed tickets.'), description: 'Defines the state of auto-closed tickets.',
}, },
{ {
title: __('Auto-close state'), title: 'Auto-close state',
name: 'nagios_auto_close_state_id', name: 'nagios_auto_close_state_id',
description: __('Defines the state of auto-closed tickets.'), description: 'Defines the state of auto-closed tickets.',
}, },
{ {
title: __('Auto-close state'), title: 'Auto-close state',
name: 'check_mk_auto_close_state_id', name: 'check_mk_auto_close_state_id',
description: __('Defines the state of auto-closed tickets.'), description: 'Defines the state of auto-closed tickets.',
}, },
{ {
title: __('Auto-close state'), title: 'Auto-close state',
name: 'check_mk_auto_close_state_id', name: 'check_mk_auto_close_state_id',
description: __('Defines the state of auto-closed tickets.'), description: 'Defines the state of auto-closed tickets.',
}, },
{ {
title: __('Locale'), title: 'Locale',
name: 'locale_default', name: 'locale_default',
description: __('Defines the default system language.'), description: 'Defines the default system language.',
}, },
{ {
title: __('Timezone'), title: 'Timezone',
name: 'timezone_default', name: 'timezone_default',
description: __('Defines the default system timezone.'), description: 'Defines the default system timezone.',
}, },
{ {
title: __('Defines transaction backend.'), title: 'Defines transaction backend.',
name: '9100_cti_caller_id_detection', name: '9100_cti_caller_id_detection',
description: __('Defines the transaction backend which detects caller IDs in objects and stores them for CTI lookups.'), description: 'Defines the transaction backend which detects caller IDs in objects and stores them for CTI lookups.',
}, },
{ {
title: __('User Organization Selector - email'), title: 'User Organization Selector - email',
name: 'ui_user_organization_selector_with_email', name: 'ui_user_organization_selector_with_email',
description: __('Defines if the email should be displayed in the result of the user/organization widget.'), description: 'Defines if the email should be displayed in the result of the user/organization widget.',
}, },
{ {
title: __('GitHub App Credentials'), title: 'GitHub App Credentials',
name: 'auth_github_credentials', name: 'auth_github_credentials',
description: __('Enables user authentication via GitHub.'), description: 'Enables user authentication via GitHub.',
}, },
{ {
title: __('Customer selection based on sender and receiver list'), title: 'Customer selection based on sender and receiver list',
name: 'postmaster_sender_is_agent_search_for_customer', name: 'postmaster_sender_is_agent_search_for_customer',
description: __('If the sender is an agent, set the first user in the recipient list as the customer.'), description: 'If the sender is an agent, set the first user in the recipient list as the customer.',
}, },
{ {
title: __('Import API key for requesting the Freshdesk API'), title: 'Import API key for requesting the Freshdesk API',
name: 'import_freshdesk_endpoint_key', name: 'import_freshdesk_endpoint_key',
description: __('Defines Freshdesk endpoint authentication API key.'), description: 'Defines Freshdesk endpoint authentication API key.',
}, },
{ {
title: __('Import API key for requesting the Zendesk API'), title: 'Import API key for requesting the Zendesk API',
name: 'import_zendesk_endpoint_key', name: 'import_zendesk_endpoint_key',
description: __('Defines Zendesk endpoint authentication API key.'), description: 'Defines Zendesk endpoint authentication API key.',
}, },
{ {
title: __('Knowledge Base active'), title: 'Knowledge Base active',
name: 'kb_active', name: 'kb_active',
description: __('Defines if Knowledge Base navbar button is enabled.'), description: 'Defines if Knowledge Base navbar button is enabled.',
}, },
{ {
title: __('Knowledge Base active publicly'), title: 'Knowledge Base active publicly',
name: 'kb_active_publicly', name: 'kb_active_publicly',
description: __('Defines if Knowledge Base navbar button is enabled for users without Knowledge Base permission.'), description: 'Defines if Knowledge Base navbar button is enabled for users without Knowledge Base permission.',
}, },
{ {
title: __('Knowledge Base multilingual support'), title: 'Knowledge Base multilingual support',
name: 'kb_multi_lingual_support', name: 'kb_multi_lingual_support',
description: __('Support of multilingual Knowledge Base.'), description: 'Support of multilingual Knowledge Base.',
}, },
{ {
title: __('Maximum Email Size'), title: 'Maximum Email Size',
name: 'postmaster_max_size', name: 'postmaster_max_size',
description: __('Defines the maximum accepted email size in MB.'), description: 'Defines the maximum accepted email size in MB.',
}, },
{ {
title: __('Maximum failed logins'), title: 'Maximum failed logins',
name: 'password_max_login_failed', name: 'password_max_login_failed',
description: __('Defines after how many failed logins accounts will be deactivated.'), description: 'Defines after how many failed logins accounts will be deactivated.',
}, },
{ {
title: __('Sender based on Reply-To header'), title: 'Sender based on Reply-To header',
name: 'postmaster_sender_based_on_reply_to', name: 'postmaster_sender_based_on_reply_to',
description: __('Set/overwrite sender/from of email based on "Reply-To" header. Useful to set correct customer if email is received from a third-party system on behalf of a customer.'), description: 'Set/overwrite sender/from of email based on "Reply-To" header. Useful to set correct customer if email is received from a third-party system on behalf of a customer.',
}, },
{ {
title: __('Ticket Last Contact Behaviour'), title: 'Ticket Last Contact Behaviour',
name: 'ticket_last_contact_behaviour', name: 'ticket_last_contact_behaviour',
description: __('Sets the last customer contact based on either the last contact of the customer in general or on the last contact of the customer that has not received a response.'), description: 'Sets the last customer contact based on either the last contact of the customer in general or on the last contact of the customer that has not received a response.',
}, },
{ {
title: __('CTI Token'), title: 'CTI Token',
name: 'cti_token', name: 'cti_token',
description: __('Token for CTI.'), description: 'Token for CTI.',
}, },
{ {
title: __('CTI integration'), title: 'CTI integration',
name: 'cti_integration', name: 'cti_integration',
description: __('Defines if generic CTI integration is enabled or not.'), description: 'Defines if generic CTI integration is enabled or not.',
}, },
{ {
title: __('Placetel Token'), title: 'Placetel Token',
name: 'placetel_token', name: 'placetel_token',
description: __('Defines the token for Placetel.'), description: 'Defines the token for Placetel.',
}, },
] ]

View file

@ -0,0 +1,73 @@
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
class SettingUpdates2 < ActiveRecord::Migration[6.0]
def change # rubocop:disable Metrics/AbcSize
return if !Setting.exists?(name: 'system_init_done')
settings_update = [
{
title: 'Ticket Last Contact Behaviour',
name: 'ticket_last_contact_behaviour',
description: 'Defines how the last customer contact time of tickets should be calculated.',
options: {
form: [
{
display: '',
null: true,
name: 'ticket_last_contact_behaviour',
tag: 'select',
translate: true,
options: {
'based_on_customer_reaction' => 'Use the time of the very last customer article.',
'check_if_agent_already_replied' => 'Use the start time of the last customer thread (which may consist of multiple articles).',
},
},
],
},
},
{
title: 'Sender based on Reply-To header',
name: 'postmaster_sender_based_on_reply_to',
description: 'Set/overwrite sender/from of email based on "Reply-To" header. Useful to set correct customer if email is received from a third-party system on behalf of a customer.',
options: {
form: [
{
display: '',
null: true,
name: 'postmaster_sender_based_on_reply_to',
tag: 'select',
options: {
'' => '-',
'as_sender_of_email' => 'Take Reply-To header as sender/from of email.',
'as_sender_of_email_use_from_realname' => 'Take Reply-To header as sender/from of email and use the real name of origin from.',
},
},
],
},
},
]
settings_update.each do |setting|
fetched_setting = Setting.find_by(name: setting[:name])
next if !fetched_setting
if setting[:title]
# "Updating title of #{setting[:name]} to #{setting[:title]}"
fetched_setting.title = setting[:title]
end
if setting[:description]
# "Updating description of #{setting[:name]} to #{setting[:description]}"
fetched_setting.description = setting[:description]
end
if setting[:options]
# "Updating description of #{setting[:name]} to #{setting[:description]}"
fetched_setting.options = setting[:options]
end
fetched_setting.save!
end
end
end

View file

@ -0,0 +1,76 @@
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
class UpdateObjectAttributes < ActiveRecord::Migration[6.0]
def change
return if !Setting.exists?(name: 'system_init_done')
# rubocop:disable Lint/BooleanSymbol
object_attributes_update = [
{
object: 'Organization',
name: 'domain_assignment',
data_option: {
null: true,
default: false,
note: 'Assign users based on user domain.',
item_class: 'formGroup--halfSize',
options: {
true: 'yes',
false: 'no',
},
translate: true,
permission: ['admin.organization'],
},
},
{
object: 'TicketArticle',
name: 'cc',
display: 'CC',
},
{
object: 'Organization',
name: 'shared',
data_option: {
null: true,
default: true,
note: "Customers in the organization can view each other's items.",
item_class: 'formGroup--halfSize',
options: {
true: 'yes',
false: 'no',
},
translate: true,
permission: ['admin.organization'],
},
},
{
object: 'User',
name: 'firstname',
display: 'First name',
},
{
object: 'User',
name: 'lastname',
display: 'Last name',
},
]
# rubocop:enable Lint/BooleanSymbol
object_attributes_update.each do |attribute|
fetched_attribute = ObjectManager::Attribute.get(name: attribute[:name], object: attribute[:object])
next if !fetched_attribute
if attribute[:display]
# p "Updating display of #{attribute[:name]} to #{attribute[:display]}"
fetched_attribute.display = attribute[:display]
end
if attribute[:data_option]
# p "Updating data_option of #{attribute[:name]} to #{attribute[:data_option]}"
fetched_attribute.data_option = attribute[:data_option]
end
fetched_attribute.save!
end
end
end

View file

@ -0,0 +1,37 @@
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
class PermissionUpdates < ActiveRecord::Migration[6.0]
def change
return if !Setting.exists?(name: 'system_init_done')
permissions_update = [
{
name: 'admin.channel_formular',
preferences: {
translations: ['Channel - Form']
},
},
{
name: 'admin.knowledge_base',
note: 'Create and set up %s',
},
]
permissions_update.each do |permission|
fetched_permission = Permission.find_by(name: permission[:name])
next if !fetched_permission
if permission[:note]
# p "Updating note of #{permission[:name]} to #{permission[:note]}"
fetched_permission.note = permission[:note]
end
if permission[:preferences]
# p "Updating preferences of #{permission[:name]} to #{permission[:preferences]}"
fetched_permission.preferences = permission[:preferences]
end
fetched_permission.save!
end
end
end

View file

@ -0,0 +1,94 @@
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
class SchedulerUpdates < ActiveRecord::Migration[6.0]
def change
return if !Setting.exists?(name: 'system_init_done')
schedulers_update = [
{
name: 'Clean up ActiveJob locks.',
method: 'ActiveJobLockCleanupJob.perform_now',
},
{
name: "Clean up 'HttpLog'.",
method: 'HttpLog.cleanup',
},
{
name: 'Clean up closed sessions.',
method: 'Chat.cleanup',
},
{
name: 'Clean up dead sessions.',
method: 'SessionTimeoutJob.perform_now',
},
{
name: 'Clean up expired sessions.',
method: 'SessionHelper.cleanup_expired',
},
{
name: 'Close chat sessions where participants are offline.',
method: 'Chat.cleanup_close',
},
{
name: "Generate 'Session' data.",
method: 'Sessions.jobs',
},
{
name: 'Generate user-based stats.',
method: 'Stats.generate',
},
{
name: 'Sync calendars with iCal feeds.',
method: 'Calendar.sync',
},
{
name: "Clean up 'Cti::Log.'",
method: 'Cti::Log.cleanup',
},
{
name: 'Execute import jobs.',
method: 'ImportJob.start_registered',
},
{
name: 'Process pending tickets.',
method: 'Ticket.process_pending',
},
{
name: 'Process ticket escalations.',
method: 'Ticket.process_escalation',
},
{
name: 'Process automatic ticket unassignments.',
method: 'Ticket.process_auto_unassign',
},
{
name: 'Check channels.',
method: 'Channel.fetch',
},
{
name: "Check 'Channel' streams.",
method: 'Channel.stream',
},
{
name: 'Execute planned jobs.',
method: 'Job.run',
},
{
name: "Delete old 'RecentView' entries.",
method: 'RecentView.cleanup',
},
]
schedulers_update.each do |scheduler|
fetched_scheduler = Scheduler.find_by(method: scheduler[:method])
next if !fetched_scheduler
if scheduler[:name]
# p "Updating name of #{scheduler[:name]} to #{scheduler[:name]}"
fetched_scheduler.name = scheduler[:name]
end
fetched_scheduler.save!
end
end
end

View file

@ -0,0 +1,63 @@
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
class OverviewUpdates < ActiveRecord::Migration[6.0]
def change
return if !Setting.exists?(name: 'system_init_done')
# Only update overviews that still have the original/default name and link.
overviews_update = [
{
name: 'My Assigned Tickets',
link: 'my_assigned',
old_name: 'My assigned Tickets',
},
{
name: 'Unassigned & Open Tickets',
link: 'all_unassigned',
old_name: 'Unassigned & Open',
},
{
name: 'My Pending Reached Tickets',
link: 'my_pending_reached',
old_name: 'My pending reached Tickets',
},
{
name: 'My Subscribed Tickets',
link: 'my_subscribed_tickets',
old_name: 'My subscribed Tickets',
},
{
name: 'Open Tickets',
link: 'all_open',
old_name: 'Open',
},
{
name: 'Pending Reached Tickets',
link: 'all_pending_reached',
old_name: 'Pending reached',
},
{
name: 'Escalated Tickets',
link: 'all_escalated',
old_name: 'Escalated',
},
{
name: 'My Replacement Tickets',
link: 'my_replacement_tickets',
old_name: 'My replacement Tickets',
},
]
overviews_update.each do |overview|
fetched_overview = Overview.find_by(link: overview[:link], name: overview[:old_name])
next if !fetched_overview
if overview[:name]
# p "Updating name of #{overview[:link]} to #{overview[:name]}"
fetched_overview.name = overview[:name]
end
fetched_overview.save!
end
end
end

View file

@ -469,7 +469,7 @@ ObjectManager::Attribute.add(
force: true, force: true,
object: 'TicketArticle', object: 'TicketArticle',
name: 'cc', name: 'cc',
display: __('Cc'), display: __('CC'),
data_type: 'input', data_type: 'input',
data_option: { data_option: {
type: 'text', type: 'text',
@ -1414,7 +1414,7 @@ ObjectManager::Attribute.add(
data_option: { data_option: {
null: true, null: true,
default: true, default: true,
note: __('Customers in the organization can view each other items.'), note: __("Customers in the organization can view each other's items."),
item_class: 'formGroup--halfSize', item_class: 'formGroup--halfSize',
options: { options: {
true: 'yes', true: 'yes',
@ -1457,7 +1457,7 @@ ObjectManager::Attribute.add(
data_option: { data_option: {
null: true, null: true,
default: false, default: false,
note: __('Assign Users based on users domain.'), note: __('Assign users based on user domain.'),
item_class: 'formGroup--halfSize', item_class: 'formGroup--halfSize',
options: { options: {
true: 'yes', true: 'yes',

View file

@ -2,7 +2,7 @@
overview_role = Role.find_by(name: 'Agent') overview_role = Role.find_by(name: 'Agent')
Overview.create_if_not_exists( Overview.create_if_not_exists(
name: __('My assigned Tickets'), name: __('My Assigned Tickets'),
link: 'my_assigned', link: 'my_assigned',
prio: 1000, prio: 1000,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -29,7 +29,7 @@ Overview.create_if_not_exists(
) )
Overview.create_if_not_exists( Overview.create_if_not_exists(
name: __('Unassigned & Open'), name: __('Unassigned & Open Tickets'),
link: 'all_unassigned', link: 'all_unassigned',
prio: 1010, prio: 1010,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -56,7 +56,7 @@ Overview.create_if_not_exists(
) )
Overview.create_if_not_exists( Overview.create_if_not_exists(
name: __('My pending reached Tickets'), name: __('My Pending Reached Tickets'),
link: 'my_pending_reached', link: 'my_pending_reached',
prio: 1020, prio: 1020,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -88,7 +88,7 @@ Overview.create_if_not_exists(
) )
Overview.create_if_not_exists( Overview.create_if_not_exists(
name: __('My subscribed Tickets'), name: __('My Subscribed Tickets'),
link: 'my_subscribed_tickets', link: 'my_subscribed_tickets',
prio: 1025, prio: 1025,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -106,7 +106,7 @@ Overview.create_if_not_exists(
) )
Overview.create_if_not_exists( Overview.create_if_not_exists(
name: __('Open'), name: __('Open Tickets'),
link: 'all_open', link: 'all_open',
prio: 1030, prio: 1030,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -129,7 +129,7 @@ Overview.create_if_not_exists(
) )
Overview.create_if_not_exists( Overview.create_if_not_exists(
name: __('Pending reached'), name: __('Pending Reached Tickets'),
link: 'all_pending_reached', link: 'all_pending_reached',
prio: 1040, prio: 1040,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -157,7 +157,7 @@ Overview.create_if_not_exists(
) )
Overview.create_if_not_exists( Overview.create_if_not_exists(
name: __('Escalated'), name: __('Escalated Tickets'),
link: 'all_escalated', link: 'all_escalated',
prio: 1050, prio: 1050,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -181,7 +181,7 @@ Overview.create_if_not_exists(
) )
Overview.create_if_not_exists( Overview.create_if_not_exists(
name: __('My replacement Tickets'), name: __('My Replacement Tickets'),
link: 'my_replacement_tickets', link: 'my_replacement_tickets',
prio: 1080, prio: 1080,
role_ids: [overview_role.id], role_ids: [overview_role.id],

View file

@ -114,7 +114,7 @@ Permission.create_if_not_exists(
name: 'admin.channel_formular', name: 'admin.channel_formular',
note: __('Manage %s'), note: __('Manage %s'),
preferences: { preferences: {
translations: [__('Channel - Formular')] translations: [__('Channel - Form')]
}, },
) )
Permission.create_if_not_exists( Permission.create_if_not_exists(

View file

@ -1,28 +1,28 @@
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/ # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Process pending tickets'), name: __('Process pending tickets.'),
method: 'Ticket.process_pending', method: 'Ticket.process_pending',
period: 15.minutes, period: 15.minutes,
prio: 1, prio: 1,
active: true, active: true,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Process escalation tickets'), name: __('Process ticket escalations.'),
method: 'Ticket.process_escalation', method: 'Ticket.process_escalation',
period: 5.minutes, period: 5.minutes,
prio: 1, prio: 1,
active: true, active: true,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Process auto unassign tickets'), name: __('Process automatic ticket unassignments.'),
method: 'Ticket.process_auto_unassign', method: 'Ticket.process_auto_unassign',
period: 10.minutes, period: 10.minutes,
prio: 1, prio: 1,
active: true, active: true,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Check Channels'), name: __('Check channels.'),
method: 'Channel.fetch', method: 'Channel.fetch',
period: 30.seconds, period: 30.seconds,
prio: 1, prio: 1,
@ -31,7 +31,7 @@ Scheduler.create_if_not_exists(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Check streams for Channel'), name: __("Check 'Channel' streams."),
method: 'Channel.stream', method: 'Channel.stream',
period: 60.seconds, period: 60.seconds,
prio: 1, prio: 1,
@ -40,7 +40,7 @@ Scheduler.create_if_not_exists(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Generate Session data'), name: __("Generate 'Session' data."),
method: 'Sessions.jobs', method: 'Sessions.jobs',
period: 60.seconds, period: 60.seconds,
prio: 1, prio: 1,
@ -49,7 +49,7 @@ Scheduler.create_if_not_exists(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Execute jobs'), name: __('Execute planned jobs.'),
method: 'Job.run', method: 'Job.run',
period: 5.minutes, period: 5.minutes,
prio: 2, prio: 2,
@ -58,7 +58,7 @@ Scheduler.create_if_not_exists(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Cleanup expired sessions'), name: __('Clean up expired sessions.'),
method: 'SessionHelper.cleanup_expired', method: 'SessionHelper.cleanup_expired',
period: 60 * 60 * 12, period: 60 * 60 * 12,
prio: 2, prio: 2,
@ -76,7 +76,7 @@ Scheduler.create_if_not_exists(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Delete old entries.'), name: __("Delete old 'RecentView' entries."),
method: 'RecentView.cleanup', method: 'RecentView.cleanup',
period: 1.day, period: 1.day,
prio: 2, prio: 2,
@ -103,7 +103,7 @@ Scheduler.create_or_update(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_or_update( Scheduler.create_or_update(
name: __('Closed chat sessions where participients are offline.'), name: __('Close chat sessions where participants are offline.'),
method: 'Chat.cleanup_close', method: 'Chat.cleanup_close',
period: 15.minutes, period: 15.minutes,
prio: 2, prio: 2,
@ -139,7 +139,7 @@ Scheduler.create_or_update(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_or_update( Scheduler.create_or_update(
name: __('Sync calendars with ical feeds.'), name: __('Sync calendars with iCal feeds.'),
method: 'Calendar.sync', method: 'Calendar.sync',
period: 1.day, period: 1.day,
prio: 2, prio: 2,
@ -148,7 +148,7 @@ Scheduler.create_or_update(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_or_update( Scheduler.create_or_update(
name: __('Generate user based stats.'), name: __('Generate user-based stats.'),
method: 'Stats.generate', method: 'Stats.generate',
period: 11.minutes, period: 11.minutes,
prio: 2, prio: 2,
@ -166,7 +166,7 @@ Scheduler.create_or_update(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Cleanup HttpLog'), name: __("Clean up 'HttpLog'."),
method: 'HttpLog.cleanup', method: 'HttpLog.cleanup',
period: 1.day, period: 1.day,
prio: 2, prio: 2,
@ -175,7 +175,7 @@ Scheduler.create_if_not_exists(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Cleanup Cti::Log'), name: __("Clean up 'Cti::Log.'"),
method: 'Cti::Log.cleanup', method: 'Cti::Log.cleanup',
period: 1.month, period: 1.month,
prio: 2, prio: 2,
@ -193,7 +193,7 @@ Scheduler.create_or_update(
created_by_id: 1, created_by_id: 1,
) )
Scheduler.create_if_not_exists( Scheduler.create_if_not_exists(
name: __('Import Jobs'), name: __('Execute import jobs.'),
method: 'ImportJob.start_registered', method: 'ImportJob.start_registered',
period: 1.hour, period: 1.hour,
prio: 1, prio: 1,

View file

@ -2106,7 +2106,7 @@ Setting.create_if_not_exists(
title: __('Ticket Last Contact Behaviour'), title: __('Ticket Last Contact Behaviour'),
name: 'ticket_last_contact_behaviour', name: 'ticket_last_contact_behaviour',
area: 'Ticket::Base', area: 'Ticket::Base',
description: __('Sets the last customer contact based on either the last contact of the customer in general or on the last contact of the customer that has not received a response.'), description: __('Defines how the last customer contact time of tickets should be calculated.'),
options: { options: {
form: [ form: [
{ {
@ -2116,8 +2116,8 @@ Setting.create_if_not_exists(
tag: 'select', tag: 'select',
translate: true, translate: true,
options: { options: {
'based_on_customer_reaction' => __('Last customer contact (without consideration an agent has replied to it)'), 'based_on_customer_reaction' => __('Use the time of the very last customer article.'),
'check_if_agent_already_replied' => __('Last customer contact (with consideration an agent has replied to it)'), 'check_if_agent_already_replied' => __('Use the start time of the last customer thread (which may consist of multiple articles).'),
}, },
}, },
], ],
@ -2810,8 +2810,8 @@ Setting.create_if_not_exists(
tag: 'select', tag: 'select',
options: { options: {
'' => '-', '' => '-',
'as_sender_of_email' => __('Take reply-to header as sender/from of email.'), 'as_sender_of_email' => __('Take Reply-To header as sender/from of email.'),
'as_sender_of_email_use_from_realname' => __('Take reply-to header as sender/from of email and use realname of origin from.'), 'as_sender_of_email_use_from_realname' => __('Take Reply-To header as sender/from of email and use the real name of origin from.'),
}, },
}, },
], ],

File diff suppressed because it is too large Load diff

View file

@ -120,7 +120,7 @@ RSpec.describe Import::OTRS::StateFactory do
end end
it 'updates Overviews' do it 'updates Overviews' do
name = 'My pending reached Tickets' name = 'My Pending Reached Tickets'
overview = Overview.find_by(name: name) overview = Overview.find_by(name: name)
expect do expect do
described_class.import(state_backend_param) described_class.import(state_backend_param)

View file

@ -23,7 +23,7 @@ RSpec.describe Ticket::Overviews do
context 'when Agent' do context 'when Agent' do
let(:current_user) { create(:agent) } let(:current_user) { create(:agent) }
it_behaves_like 'containing', 'Open' it_behaves_like 'containing', 'Open Tickets'
it_behaves_like 'not containing', 'My Tickets' it_behaves_like 'not containing', 'My Tickets'
it_behaves_like 'not containing', 'My Organization Tickets' it_behaves_like 'not containing', 'My Organization Tickets'
end end
@ -31,7 +31,7 @@ RSpec.describe Ticket::Overviews do
context 'when Agent is also Customer' do context 'when Agent is also Customer' do
let(:current_user) { create(:agent_and_customer, :with_org) } let(:current_user) { create(:agent_and_customer, :with_org) }
it_behaves_like 'containing', 'Open' it_behaves_like 'containing', 'Open Tickets'
it_behaves_like 'containing', 'My Tickets' it_behaves_like 'containing', 'My Tickets'
it_behaves_like 'containing', 'My Organization Tickets' it_behaves_like 'containing', 'My Organization Tickets'
end end
@ -39,7 +39,7 @@ RSpec.describe Ticket::Overviews do
context 'when Customer' do context 'when Customer' do
let(:current_user) { create(:customer, :with_org) } let(:current_user) { create(:customer, :with_org) }
it_behaves_like 'not containing', 'Open' it_behaves_like 'not containing', 'Open Tickets'
it_behaves_like 'containing', 'My Tickets' it_behaves_like 'containing', 'My Tickets'
it_behaves_like 'containing', 'My Organization Tickets' it_behaves_like 'containing', 'My Organization Tickets'
end end

View file

@ -26,8 +26,8 @@ RSpec.describe 'Dashboard', type: :system do
visit 'dashboard' visit 'dashboard'
find('div.tab[data-area=first-steps-widgets]').click find('div.tab[data-area=first-steps-widgets]').click
find('.js-inviteCustomer').click find('.js-inviteCustomer').click
fill_in 'Firstname', with: 'Nick' fill_in 'firstname', with: 'Nick'
fill_in 'Lastname', with: 'Braun' fill_in 'lastname', with: 'Braun'
fill_in 'Email', with: 'nick.braun@zammad.org' fill_in 'Email', with: 'nick.braun@zammad.org'
click_on 'Invite' click_on 'Invite'
expect(User.find_by(firstname: 'Nick').roles).to eq([Role.find_by(name: 'Public')]) expect(User.find_by(firstname: 'Nick').roles).to eq([Role.find_by(name: 'Public')])

View file

@ -22,7 +22,7 @@ RSpec.describe 'Keyboard Shortcuts', type: :system do
end end
it 'shows Overviews page' do it 'shows Overviews page' do
expect(page).to have_title('My assigned Tickets') expect(page).to have_title('My Assigned Tickets')
end end
end end

View file

@ -143,8 +143,8 @@ RSpec.describe 'Manage > Users', type: :system do
it 'allows to update a user with no email/first/last/phone if login is present' do it 'allows to update a user with no email/first/last/phone if login is present' do
in_modal do in_modal do
fill_in 'Firstname', with: '' fill_in 'firstname', with: ''
fill_in 'Lastname', with: '' fill_in 'lastname', with: ''
fill_in 'Email', with: '' fill_in 'Email', with: ''
fill_in 'Phone', with: '' fill_in 'Phone', with: ''
@ -161,8 +161,8 @@ RSpec.describe 'Manage > Users', type: :system do
it 'does not allow to update a user with no email/first/last/phone' do it 'does not allow to update a user with no email/first/last/phone' do
in_modal disappears: false do in_modal disappears: false do
fill_in 'Firstname', with: '' fill_in 'firstname', with: ''
fill_in 'Lastname', with: '' fill_in 'lastname', with: ''
fill_in 'Email', with: '' fill_in 'Email', with: ''
fill_in 'Phone', with: '' fill_in 'Phone', with: ''

View file

@ -105,7 +105,7 @@ RSpec.describe 'Profile > Language', type: :system do
context 'with overview page visited' do context 'with overview page visited' do
let(:path) { 'ticket/view' } let(:path) { 'ticket/view' }
let(:translated_content) { 'My assigned Tickets' } let(:translated_content) { 'My Assigned Tickets' }
it_behaves_like 'having translated content in the page title' it_behaves_like 'having translated content in the page title'
it_behaves_like 'having translated content in', :active_content it_behaves_like 'having translated content in', :active_content
@ -196,7 +196,7 @@ RSpec.describe 'Profile > Language', type: :system do
context 'with overview page visited' do context 'with overview page visited' do
let(:path) { 'ticket/view' } let(:path) { 'ticket/view' }
let(:translated_content) { 'Meine zugewiesenen Tickets' } let(:translated_content) { Translation.translate('de-de', 'My Assigned Tickets') }
it_behaves_like 'having translated content in the page title' it_behaves_like 'having translated content in the page title'
it_behaves_like 'having translated content in', :active_content it_behaves_like 'having translated content in', :active_content

View file

@ -316,7 +316,7 @@ RSpec.describe 'Ticket views', type: :system, authenticated_as: :authenticate do
custom_attribute custom_attribute
ObjectManager::Attribute.migration_execute ObjectManager::Attribute.migration_execute
tickets tickets
Overview.find_by(name: 'Open').update(group_by: custom_attribute.name) Overview.find_by(name: 'Open Tickets').update(group_by: custom_attribute.name)
Setting.set('ui_table_group_by_show_count', true) Setting.set('ui_table_group_by_show_count', true)
true true
end end

View file

@ -93,7 +93,7 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
}, },
) )
@overview2 = Overview.create_if_not_exists( @overview2 = Overview.create_if_not_exists(
name: 'My assigned Tickets', name: 'My Assigned Tickets',
link: 'my_assigned', link: 'my_assigned',
prio: 900, prio: 900,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -155,13 +155,13 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
current_user: @agent1, current_user: @agent1,
) )
assert_equal(1, result.count) assert_equal(1, result.count)
assert_equal('My assigned Tickets', result[0].name) assert_equal('My Assigned Tickets', result[0].name)
result = Ticket::Overviews.all( result = Ticket::Overviews.all(
current_user: @agent2, current_user: @agent2,
) )
assert_equal(1, result.count) assert_equal(1, result.count)
assert_equal('My assigned Tickets', result[0].name) assert_equal('My Assigned Tickets', result[0].name)
result = Ticket::Overviews.all( result = Ticket::Overviews.all(
current_user: @customer1, current_user: @customer1,
@ -178,13 +178,13 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
current_user: @agent1, current_user: @agent1,
) )
assert_equal(1, result.count) assert_equal(1, result.count)
assert_equal('My assigned Tickets', result[0].name) assert_equal('My Assigned Tickets', result[0].name)
result = Ticket::Overviews.all( result = Ticket::Overviews.all(
current_user: @agent2, current_user: @agent2,
) )
assert_equal(2, result.count) assert_equal(2, result.count)
assert_equal('My assigned Tickets', result[0].name) assert_equal('My Assigned Tickets', result[0].name)
assert_equal('My replacement Tickets', result[1].name) assert_equal('My replacement Tickets', result[1].name)
result = Ticket::Overviews.all( result = Ticket::Overviews.all(
@ -197,7 +197,7 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
test 'overview shown' do test 'overview shown' do
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert(result[0]) assert(result[0])
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -205,7 +205,7 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert(result[0]) assert(result[0])
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -231,7 +231,7 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert(result[0]) assert(result[0])
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -239,7 +239,7 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert(result[0]) assert(result[0])
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -285,7 +285,7 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert(result[0]) assert(result[0])
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 1) assert_equal(result[0][:count], 1)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -294,7 +294,7 @@ class TicketOverviewOutOfOfficeTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert(result[0]) assert(result[0])
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)

View file

@ -88,7 +88,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
UserInfo.current_user_id = 1 UserInfo.current_user_id = 1
overview_role = Role.find_by(name: 'Agent') overview_role = Role.find_by(name: 'Agent')
@overview1 = Overview.create_or_update( @overview1 = Overview.create_or_update(
name: 'My assigned Tickets', name: 'My Assigned Tickets',
link: 'my_assigned', link: 'my_assigned',
prio: 1000, prio: 1000,
role_ids: [overview_role.id], role_ids: [overview_role.id],
@ -310,7 +310,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
) )
assert_equal(3, result.count) assert_equal(3, result.count)
assert_equal('My assigned Tickets', result[0].name) assert_equal('My Assigned Tickets', result[0].name)
assert_equal('Unassigned & Open', result[1].name) assert_equal('Unassigned & Open', result[1].name)
assert_equal('My Tickets only with Note', result[2].name) assert_equal('My Tickets only with Note', result[2].name)
@ -318,7 +318,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
current_user: @agent2, current_user: @agent2,
) )
assert_equal(3, result.count) assert_equal(3, result.count)
assert_equal('My assigned Tickets', result[0].name) assert_equal('My Assigned Tickets', result[0].name)
assert_equal('Unassigned & Open', result[1].name) assert_equal('Unassigned & Open', result[1].name)
assert_equal('My Tickets 2', result[2].name) assert_equal('My Tickets 2', result[2].name)
@ -385,7 +385,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
Ticket.destroy_all Ticket.destroy_all
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -402,7 +402,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
assert_equal(result[2][:count], 0) assert_equal(result[2][:count], 0)
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -441,7 +441,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
) )
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -459,7 +459,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
assert_equal(result[2][:count], 0) assert_equal(result[2][:count], 0)
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -499,7 +499,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
) )
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -518,7 +518,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
assert_equal(result[2][:count], 0) assert_equal(result[2][:count], 0)
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -537,7 +537,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
ticket2.save! ticket2.save!
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
assert_equal(result[0][:tickets][0][:id], ticket2.id) assert_equal(result[0][:tickets][0][:id], ticket2.id)
@ -556,7 +556,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
assert_equal(result[2][:count], 1) assert_equal(result[2][:count], 1)
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -598,7 +598,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
assert_equal(result[0][:tickets][0][:id], ticket2.id) assert_equal(result[0][:tickets][0][:id], ticket2.id)
@ -621,7 +621,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -646,7 +646,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
assert_equal(result[0][:tickets][0][:id], ticket2.id) assert_equal(result[0][:tickets][0][:id], ticket2.id)
@ -669,7 +669,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -694,7 +694,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
assert_equal(result[0][:tickets][0][:id], ticket2.id) assert_equal(result[0][:tickets][0][:id], ticket2.id)
@ -717,7 +717,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -742,7 +742,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
assert_equal(result[0][:tickets][0][:id], ticket2.id) assert_equal(result[0][:tickets][0][:id], ticket2.id)
@ -765,7 +765,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -790,7 +790,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
assert_equal(result[0][:tickets][0][:id], ticket2.id) assert_equal(result[0][:tickets][0][:id], ticket2.id)
@ -813,7 +813,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
@ -838,7 +838,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent1) result = Ticket::Overviews.index(@agent1)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)
assert_equal(result[0][:tickets][0][:id], ticket2.id) assert_equal(result[0][:tickets][0][:id], ticket2.id)
@ -861,7 +861,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
result = Ticket::Overviews.index(@agent2) result = Ticket::Overviews.index(@agent2)
assert_equal(result[0][:overview][:id], @overview1.id) assert_equal(result[0][:overview][:id], @overview1.id)
assert_equal(result[0][:overview][:name], 'My assigned Tickets') assert_equal(result[0][:overview][:name], 'My Assigned Tickets')
assert_equal(result[0][:overview][:view], 'my_assigned') assert_equal(result[0][:overview][:view], 'my_assigned')
assert_equal(result[0][:count], 0) assert_equal(result[0][:count], 0)
assert_equal(result[0][:tickets].class, Array) assert_equal(result[0][:tickets].class, Array)