From c35edc9c490586562da4aec0454bb08668092c3f Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Thu, 3 Apr 2025 04:18:42 +0530 Subject: [PATCH] chore(i18n): Improvements in automation and macros (#11231) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request Template ## Description This PR includes, 1. **Sort Accounts List** – Orders the accounts list alphabetically for better organization. 2. **Add Missing Translations in Automation** – Includes missing translations for actions, events, and conditions dropdown. 3. **Fix Missing Translation in Macros** – Adds missing translations in the macros action select dropdown. 4. Translate "Automation System" Username – Ensures the "Automation System" username is properly translated. Fixes: https://linear.app/chatwoot/issue/CW-4198/issues-[converso] ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --- .../sidebar/SidebarAccountSwitcher.vue | 8 +- .../helper/specs/macrosHelper.spec.js | 2 +- .../dashboard/i18n/locale/en/automation.json | 40 ++- .../dashboard/i18n/locale/en/macros.json | 15 + .../settings/automation/AddAutomationRule.vue | 39 ++- .../automation/EditAutomationRule.vue | 39 ++- .../settings/automation/constants.js | 285 +++++++----------- .../dashboard/settings/macros/MacroEditor.vue | 10 +- .../dashboard/settings/macros/MacroNode.vue | 2 +- .../dashboard/settings/macros/constants.js | 26 +- .../concerns/activity_message_handler.rb | 4 +- .../priority_activity_message_handler.rb | 2 +- config/locales/en.yml | 2 + 13 files changed, 258 insertions(+), 216 deletions(-) diff --git a/app/javascript/dashboard/components-next/sidebar/SidebarAccountSwitcher.vue b/app/javascript/dashboard/components-next/sidebar/SidebarAccountSwitcher.vue index e3b20897f..6ef69b92c 100644 --- a/app/javascript/dashboard/components-next/sidebar/SidebarAccountSwitcher.vue +++ b/app/javascript/dashboard/components-next/sidebar/SidebarAccountSwitcher.vue @@ -26,6 +26,12 @@ const showAccountSwitcher = computed( () => userAccounts.value.length > 1 && currentAccount.value.name ); +const sortedCurrentUserAccounts = computed(() => { + return [...(currentUser.value.accounts || [])].sort((a, b) => + a.name.localeCompare(b.name) + ); +}); + const onChangeAccount = newId => { const accountUrl = `/app/accounts/${newId}/dashboard`; window.location.href = accountUrl; @@ -70,7 +76,7 @@ const emitNewAccount = () => { { expect(resolveActionName(MACRO_ACTION_TYPES[1].key)).not.toEqual( MACRO_ACTION_TYPES[0].label ); - expect(resolveActionName('change_priority')).toEqual('Change Priority'); + expect(resolveActionName('change_priority')).toEqual('CHANGE_PRIORITY'); // Translated }); }); diff --git a/app/javascript/dashboard/i18n/locale/en/automation.json b/app/javascript/dashboard/i18n/locale/en/automation.json index bb4946416..86ec0b58b 100644 --- a/app/javascript/dashboard/i18n/locale/en/automation.json +++ b/app/javascript/dashboard/i18n/locale/en/automation.json @@ -126,6 +126,44 @@ "ATLEAST_ONE_CONDITION_REQUIRED": "At least one condition is required", "ATLEAST_ONE_ACTION_REQUIRED": "At least one action is required" }, - "NONE_OPTION": "None" + "NONE_OPTION": "None", + "EVENTS": { + "CONVERSATION_CREATED": "Conversation Created", + "CONVERSATION_UPDATED": "Conversation Updated", + "MESSAGE_CREATED": "Message Created", + "CONVERSATION_OPENED": "Conversation Opened" + }, + "ACTIONS": { + "ASSIGN_AGENT": "Assign to Agent", + "ASSIGN_TEAM": "Assign a Team", + "ADD_LABEL": "Add a Label", + "REMOVE_LABEL": "Remove a Label", + "SEND_EMAIL_TO_TEAM": "Send an Email to Team", + "SEND_EMAIL_TRANSCRIPT": "Send an Email Transcript", + "MUTE_CONVERSATION": "Mute Conversation", + "SNOOZE_CONVERSATION": "Snooze Conversation", + "RESOLVE_CONVERSATION": "Resolve Conversation", + "SEND_WEBHOOK_EVENT": "Send Webhook Event", + "SEND_ATTACHMENT": "Send Attachment", + "SEND_MESSAGE": "Send a Message", + "CHANGE_PRIORITY": "Change Priority", + "ADD_SLA": "Add SLA" + }, + "ATTRIBUTES": { + "MESSAGE_TYPE": "Message Type", + "MESSAGE_CONTAINS": "Message Contains", + "EMAIL": "Email", + "INBOX": "Inbox", + "CONVERSATION_LANGUAGE": "Conversation Language", + "PHONE_NUMBER": "Phone Number", + "STATUS": "Status", + "BROWSER_LANGUAGE": "Browser Language", + "MAIL_SUBJECT": "Email Subject", + "COUNTRY_NAME": "Country", + "REFERER_LINK": "Referrer Link", + "ASSIGNEE_NAME": "Assignee", + "TEAM_NAME": "Team", + "PRIORITY": "Priority" + } } } diff --git a/app/javascript/dashboard/i18n/locale/en/macros.json b/app/javascript/dashboard/i18n/locale/en/macros.json index 95e02fe94..ed68d2798 100644 --- a/app/javascript/dashboard/i18n/locale/en/macros.json +++ b/app/javascript/dashboard/i18n/locale/en/macros.json @@ -83,6 +83,21 @@ "ACTION_PARAMETERS_REQUIRED": "Action parameters are required", "ATLEAST_ONE_CONDITION_REQUIRED": "At least one condition is required", "ATLEAST_ONE_ACTION_REQUIRED": "At least one action is required" + }, + "ACTIONS": { + "ASSIGN_TEAM": "Assign a Team", + "ASSIGN_AGENT": "Assign an Agent", + "ADD_LABEL": "Add a Label", + "REMOVE_LABEL": "Remove a Label", + "REMOVE_ASSIGNED_TEAM": "Remove Assigned Team", + "SEND_EMAIL_TRANSCRIPT": "Send an Email Transcript", + "MUTE_CONVERSATION": "Mute Conversation", + "SNOOZE_CONVERSATION": "Snooze Conversation", + "RESOLVE_CONVERSATION": "Resolve Conversation", + "SEND_ATTACHMENT": "Send Attachment", + "SEND_MESSAGE": "Send a Message", + "CHANGE_PRIORITY": "Change Priority", + "ADD_PRIVATE_NOTE": "Add a Private Note" } } } diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/AddAutomationRule.vue b/app/javascript/dashboard/routes/dashboard/settings/automation/AddAutomationRule.vue index ceeb84ca4..c92d0b1c8 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/AddAutomationRule.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/AddAutomationRule.vue @@ -82,7 +82,6 @@ export default { data() { return { automationRuleEvent: AUTOMATION_RULE_EVENTS[0].key, - automationRuleEvents: AUTOMATION_RULE_EVENTS, automationMutated: false, show: true, showDeleteConfirmationModal: false, @@ -96,6 +95,12 @@ export default { accountId: 'getCurrentAccountId', isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount', }), + automationRuleEvents() { + return AUTOMATION_RULE_EVENTS.map(event => ({ + ...event, + value: this.$t(`AUTOMATION.EVENTS.${event.value}`), + })); + }, hasAutomationMutated() { if ( this.automation.conditions[0].values || @@ -105,10 +110,14 @@ export default { return false; }, automationActionTypes() { - const isSLAEnabled = this.isFeatureEnabled('sla'); - return isSLAEnabled + const actionTypes = this.isFeatureEnabled('sla') ? AUTOMATION_ACTION_TYPES - : AUTOMATION_ACTION_TYPES.filter(action => action.key !== 'add_sla'); + : AUTOMATION_ACTION_TYPES.filter(({ key }) => key !== 'add_sla'); + + return actionTypes.map(action => ({ + ...action, + label: this.$t(`AUTOMATION.ACTIONS.${action.label}`), + })); }, }, mounted() { @@ -137,6 +146,26 @@ export default { this.$emit('saveAutomation', automation, this.mode); } }, + getTranslatedAttributes(type, event) { + return getAttributes(type, event).map(attribute => { + // Skip translation + // 1. If customAttributeType key is present then its rendering attributes from API + // 2. If contact_custom_attribute or conversation_custom_attribute is present then its rendering section title + const skipTranslation = + attribute.customAttributeType || + [ + 'contact_custom_attribute', + 'conversation_custom_attribute', + ].includes(attribute.key); + + return { + ...attribute, + name: skipTranslation + ? attribute.name + : this.$t(`AUTOMATION.ATTRIBUTES.${attribute.name}`), + }; + }); + }, }, }; @@ -204,7 +233,7 @@ export default { :key="i" v-model="automation.conditions[i]" :filter-attributes=" - getAttributes(automationTypes, automation.event_name) + getTranslatedAttributes(automationTypes, automation.event_name) " :input-type=" getInputType( diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue b/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue index f2ec9d7c7..208fcf7ec 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue @@ -70,7 +70,6 @@ export default { data() { return { automationRuleEvent: AUTOMATION_RULE_EVENTS[0].key, - automationRuleEvents: AUTOMATION_RULE_EVENTS, automationMutated: false, show: true, showDeleteConfirmationModal: false, @@ -84,6 +83,12 @@ export default { accountId: 'getCurrentAccountId', isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount', }), + automationRuleEvents() { + return AUTOMATION_RULE_EVENTS.map(event => ({ + ...event, + value: this.$t(`AUTOMATION.EVENTS.${event.value}`), + })); + }, hasAutomationMutated() { if ( this.automation.conditions[0].values || @@ -93,10 +98,14 @@ export default { return false; }, automationActionTypes() { - const isSLAEnabled = this.isFeatureEnabled('sla'); - return isSLAEnabled + const actionTypes = this.isFeatureEnabled('sla') ? AUTOMATION_ACTION_TYPES - : AUTOMATION_ACTION_TYPES.filter(action => action.key !== 'add_sla'); + : AUTOMATION_ACTION_TYPES.filter(({ key }) => key !== 'add_sla'); + + return actionTypes.map(action => ({ + ...action, + label: this.$t(`AUTOMATION.ACTIONS.${action.label}`), + })); }, }, mounted() { @@ -127,6 +136,26 @@ export default { this.$emit('saveAutomation', automation, this.mode); } }, + getTranslatedAttributes(type, event) { + return getAttributes(type, event).map(attribute => { + // Skip translation + // 1. If customAttributeType key is present then its rendering attributes from API + // 2. If contact_custom_attribute or conversation_custom_attribute is present then its rendering section title + const skipTranslation = + attribute.customAttributeType || + [ + 'contact_custom_attribute', + 'conversation_custom_attribute', + ].includes(attribute.key); + + return { + ...attribute, + name: skipTranslation + ? attribute.name + : this.$t(`AUTOMATION.ATTRIBUTES.${attribute.name}`), + }; + }); + }, }, }; @@ -187,7 +216,7 @@ export default { :key="i" v-model="automation.conditions[i]" :filter-attributes=" - getAttributes(automationTypes, automation.event_name) + getTranslatedAttributes(automationTypes, automation.event_name) " :input-type=" getInputType( diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js b/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js index c8d67745c..18468e3ad 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js @@ -10,43 +10,37 @@ export const AUTOMATIONS = { conditions: [ { key: 'message_type', - name: 'Message Type', - attributeI18nKey: 'MESSAGE_TYPE', + name: 'MESSAGE_TYPE', inputType: 'search_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'content', - name: 'Message Content', - attributeI18nKey: 'MESSAGE_CONTAINS', + name: 'MESSAGE_CONTAINS', inputType: 'comma_separated_plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'email', - name: 'Email', - attributeI18nKey: 'EMAIL', + name: 'EMAIL', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'inbox_id', - name: 'Inbox', - attributeI18nKey: 'INBOX', + name: 'INBOX', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'conversation_language', - name: 'Conversation Language', - attributeI18nKey: 'CONVERSATION_LANGUAGE', + name: 'CONVERSATION_LANGUAGE', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'phone_number', - name: 'Phone Number', - attributeI18nKey: 'PHONE_NUMBER', + name: 'PHONE_NUMBER', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_6, }, @@ -54,64 +48,52 @@ export const AUTOMATIONS = { actions: [ { key: 'assign_agent', - name: 'Assign to agent', - attributeI18nKey: 'ASSIGN_AGENT', + name: 'ASSIGN_AGENT', }, { key: 'assign_team', - name: 'Assign a team', - attributeI18nKey: 'ASSIGN_TEAM', + name: 'ASSIGN_TEAM', }, { key: 'add_label', - name: 'Add a label', - attributeI18nKey: 'ADD_LABEL', + name: 'ADD_LABEL', }, { key: 'remove_label', - name: 'Remove a label', - attributeI18nKey: 'REMOVE_LABEL', + name: 'REMOVE_LABEL', }, { key: 'send_email_to_team', - name: 'Send an email to team', - attributeI18nKey: 'SEND_EMAIL_TO_TEAM', + name: 'SEND_EMAIL_TO_TEAM', }, { key: 'send_message', - name: 'Send a message', - attributeI18nKey: 'SEND_MESSAGE', + name: 'SEND_MESSAGE', }, { key: 'send_email_transcript', - name: 'Send an email transcript', - attributeI18nKey: 'SEND_EMAIL_TRANSCRIPT', + name: 'SEND_EMAIL_TRANSCRIPT', }, { key: 'mute_conversation', - name: 'Mute conversation', - attributeI18nKey: 'MUTE_CONVERSATION', + name: 'MUTE_CONVERSATION', }, { key: 'snooze_conversation', - name: 'Snooze conversation', - attributeI18nKey: 'MUTE_CONVERSATION', + name: 'SNOOZE_CONVERSATION', }, { key: 'resolve_conversation', - name: 'Resolve conversation', - attributeI18nKey: 'RESOLVE_CONVERSATION', + name: 'RESOLVE_CONVERSATION', }, { key: 'send_webhook_event', - name: 'Send Webhook Event', - attributeI18nKey: 'SEND_WEBHOOK_EVENT', + name: 'SEND_WEBHOOK_EVENT', }, { key: 'send_attachment', - name: 'Send Attachment', - attributeI18nKey: 'SEND_ATTACHMENT', + name: 'SEND_ATTACHMENT', }, ], }, @@ -119,71 +101,61 @@ export const AUTOMATIONS = { conditions: [ { key: 'status', - name: 'Status', - attributeI18nKey: 'STATUS', + name: 'STATUS', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'browser_language', - name: 'Browser Language', - attributeI18nKey: 'BROWSER_LANGUAGE', + name: 'BROWSER_LANGUAGE', inputType: 'search_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'mail_subject', - name: 'Email Subject', - attributeI18nKey: 'MAIL_SUBJECT', + name: 'MAIL_SUBJECT', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'country_code', - name: 'Country', - attributeI18nKey: 'COUNTRY_NAME', + name: 'COUNTRY_NAME', inputType: 'search_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'phone_number', - name: 'Phone Number', - attributeI18nKey: 'PHONE_NUMBER', + name: 'PHONE_NUMBER', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_6, }, { key: 'referer', - name: 'Referrer Link', - attributeI18nKey: 'REFERER_LINK', + name: 'REFERER_LINK', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'email', - name: 'Email', - attributeI18nKey: 'EMAIL', + name: 'EMAIL', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'inbox_id', - name: 'Inbox', - attributeI18nKey: 'INBOX', + name: 'INBOX', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'conversation_language', - name: 'Conversation Language', - attributeI18nKey: 'CONVERSATION_LANGUAGE', + name: 'CONVERSATION_LANGUAGE', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'priority', - name: 'Priority', - attributeI18nKey: 'PRIORITY', + name: 'PRIORITY', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, @@ -191,58 +163,47 @@ export const AUTOMATIONS = { actions: [ { key: 'assign_agent', - name: 'Assign to agent', - attributeI18nKey: 'ASSIGN_AGENT', + name: 'ASSIGN_AGENT', }, { key: 'assign_team', - name: 'Assign a team', - attributeI18nKey: 'ASSIGN_TEAM', + name: 'ASSIGN_TEAM', }, { key: 'assign_agent', - name: 'Assign an agent', - attributeI18nKey: 'ASSIGN_AGENT', + name: 'ASSIGN_AGENT', }, { key: 'send_email_to_team', - name: 'Send an email to team', - attributeI18nKey: 'SEND_EMAIL_TO_TEAM', + name: 'SEND_EMAIL_TO_TEAM', }, { key: 'send_message', - name: 'Send a message', - attributeI18nKey: 'SEND_MESSAGE', + name: 'SEND_MESSAGE', }, { key: 'send_email_transcript', - name: 'Send an email transcript', - attributeI18nKey: 'SEND_EMAIL_TRANSCRIPT', + name: 'SEND_EMAIL_TRANSCRIPT', }, { key: 'mute_conversation', - name: 'Mute conversation', - attributeI18nKey: 'MUTE_CONVERSATION', + name: 'MUTE_CONVERSATION', }, { key: 'snooze_conversation', - name: 'Snooze conversation', - attributeI18nKey: 'MUTE_CONVERSATION', + name: 'SNOOZE_CONVERSATION', }, { key: 'resolve_conversation', - name: 'Resolve conversation', - attributeI18nKey: 'RESOLVE_CONVERSATION', + name: 'RESOLVE_CONVERSATION', }, { key: 'send_webhook_event', - name: 'Send Webhook Event', - attributeI18nKey: 'SEND_WEBHOOK_EVENT', + name: 'SEND_WEBHOOK_EVENT', }, { key: 'send_attachment', - name: 'Send Attachment', - attributeI18nKey: 'SEND_ATTACHMENT', + name: 'SEND_ATTACHMENT', }, ], }, @@ -250,85 +211,73 @@ export const AUTOMATIONS = { conditions: [ { key: 'status', - name: 'Status', - attributeI18nKey: 'STATUS', + name: 'STATUS', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'browser_language', - name: 'Browser Language', - attributeI18nKey: 'BROWSER_LANGUAGE', + name: 'BROWSER_LANGUAGE', inputType: 'search_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'mail_subject', - name: 'Email Subject', - attributeI18nKey: 'MAIL_SUBJECT', + name: 'MAIL_SUBJECT', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'country_code', - name: 'Country', - attributeI18nKey: 'COUNTRY_NAME', + name: 'COUNTRY_NAME', inputType: 'search_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'referer', - name: 'Referrer Link', - attributeI18nKey: 'REFERER_LINK', + name: 'REFERER_LINK', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'phone_number', - name: 'Phone Number', - attributeI18nKey: 'PHONE_NUMBER', + name: 'PHONE_NUMBER', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_6, }, { key: 'assignee_id', - name: 'Assignee', - attributeI18nKey: 'ASSIGNEE_NAME', + name: 'ASSIGNEE_NAME', inputType: 'search_select', filterOperators: OPERATOR_TYPES_3, }, { key: 'team_id', - name: 'Team', - attributeI18nKey: 'TEAM_NAME', + name: 'TEAM_NAME', inputType: 'search_select', filterOperators: OPERATOR_TYPES_3, }, { key: 'email', - name: 'Email', - attributeI18nKey: 'EMAIL', + name: 'EMAIL', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'inbox_id', - name: 'Inbox', - attributeI18nKey: 'INBOX', + name: 'INBOX', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'conversation_language', - name: 'Conversation Language', - attributeI18nKey: 'CONVERSATION_LANGUAGE', + name: 'CONVERSATION_LANGUAGE', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'priority', - name: 'Priority', - attributeI18nKey: 'PRIORITY', + name: 'PRIORITY', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, @@ -336,58 +285,47 @@ export const AUTOMATIONS = { actions: [ { key: 'assign_agent', - name: 'Assign to agent', - attributeI18nKey: 'ASSIGN_AGENT', + name: 'ASSIGN_AGENT', }, { key: 'assign_team', - name: 'Assign a team', - attributeI18nKey: 'ASSIGN_TEAM', + name: 'ASSIGN_TEAM', }, { key: 'assign_agent', - name: 'Assign an agent', - attributeI18nKey: 'ASSIGN_AGENT', + name: 'ASSIGN_AGENT', }, { key: 'send_email_to_team', - name: 'Send an email to team', - attributeI18nKey: 'SEND_EMAIL_TO_TEAM', + name: 'SEND_EMAIL_TO_TEAM', }, { key: 'send_message', - name: 'Send a message', - attributeI18nKey: 'SEND_MESSAGE', + name: 'SEND_MESSAGE', }, { key: 'send_email_transcript', - name: 'Send an email transcript', - attributeI18nKey: 'SEND_EMAIL_TRANSCRIPT', + name: 'SEND_EMAIL_TRANSCRIPT', }, { key: 'mute_conversation', - name: 'Mute conversation', - attributeI18nKey: 'MUTE_CONVERSATION', + name: 'MUTE_CONVERSATION', }, { key: 'snooze_conversation', - name: 'Snooze conversation', - attributeI18nKey: 'MUTE_CONVERSATION', + name: 'SNOOZE_CONVERSATION', }, { key: 'resolve_conversation', - name: 'Resolve conversation', - attributeI18nKey: 'RESOLVE_CONVERSATION', + name: 'RESOLVE_CONVERSATION', }, { key: 'send_webhook_event', - name: 'Send Webhook Event', - attributeI18nKey: 'SEND_WEBHOOK_EVENT', + name: 'SEND_WEBHOOK_EVENT', }, { key: 'send_attachment', - name: 'Send Attachment', - attributeI18nKey: 'SEND_ATTACHMENT', + name: 'SEND_ATTACHMENT', }, ], }, @@ -395,78 +333,67 @@ export const AUTOMATIONS = { conditions: [ { key: 'browser_language', - name: 'Browser Language', - attributeI18nKey: 'BROWSER_LANGUAGE', + name: 'BROWSER_LANGUAGE', inputType: 'search_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'email', - name: 'Email', - attributeI18nKey: 'EMAIL', + name: 'EMAIL', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'mail_subject', - name: 'Email Subject', - attributeI18nKey: 'MAIL_SUBJECT', + name: 'MAIL_SUBJECT', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'country_code', - name: 'Country', - attributeI18nKey: 'COUNTRY_NAME', + name: 'COUNTRY_NAME', inputType: 'search_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'referer', - name: 'Referrer Link', - attributeI18nKey: 'REFERER_LINK', + name: 'REFERER_LINK', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_2, }, { key: 'assignee_id', - name: 'Assignee', - attributeI18nKey: 'ASSIGNEE_NAME', + name: 'ASSIGNEE_NAME', inputType: 'search_select', filterOperators: OPERATOR_TYPES_3, }, { key: 'phone_number', - name: 'Phone Number', - attributeI18nKey: 'PHONE_NUMBER', + name: 'PHONE_NUMBER', inputType: 'plain_text', filterOperators: OPERATOR_TYPES_6, }, { key: 'team_id', - name: 'Team', - attributeI18nKey: 'TEAM_NAME', + name: 'TEAM_NAME', inputType: 'search_select', filterOperators: OPERATOR_TYPES_3, }, { key: 'inbox_id', - name: 'Inbox', - attributeI18nKey: 'INBOX', + name: 'INBOX', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'conversation_language', - name: 'Conversation Language', - attributeI18nKey: 'CONVERSATION_LANGUAGE', + name: 'CONVERSATION_LANGUAGE', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, { key: 'priority', - name: 'Priority', - attributeI18nKey: 'PRIORITY', + name: 'PRIORITY', inputType: 'multi_select', filterOperators: OPERATOR_TYPES_1, }, @@ -474,53 +401,43 @@ export const AUTOMATIONS = { actions: [ { key: 'assign_agent', - name: 'Assign to agent', - attributeI18nKey: 'ASSIGN_AGENT', + name: 'ASSIGN_AGENT', }, { key: 'assign_team', - name: 'Assign a team', - attributeI18nKey: 'ASSIGN_TEAM', + name: 'ASSIGN_TEAM', }, { key: 'assign_agent', - name: 'Assign an agent', - attributeI18nKey: 'ASSIGN_AGENT', + name: 'ASSIGN_AGENT', }, { key: 'send_email_to_team', - name: 'Send an email to team', - attributeI18nKey: 'SEND_EMAIL_TO_TEAM', + name: 'SEND_EMAIL_TO_TEAM', }, { key: 'send_message', - name: 'Send a message', - attributeI18nKey: 'SEND_MESSAGE', + name: 'SEND_MESSAGE', }, { key: 'send_email_transcript', - name: 'Send an email transcript', - attributeI18nKey: 'SEND_EMAIL_TRANSCRIPT', + name: 'SEND_EMAIL_TRANSCRIPT', }, { key: 'mute_conversation', - name: 'Mute conversation', - attributeI18nKey: 'MUTE_CONVERSATION', + name: 'MUTE_CONVERSATION', }, { key: 'snooze_conversation', - name: 'Snooze conversation', - attributeI18nKey: 'MUTE_CONVERSATION', + name: 'SNOOZE_CONVERSATION', }, { key: 'send_webhook_event', - name: 'Send Webhook Event', - attributeI18nKey: 'SEND_WEBHOOK_EVENT', + name: 'SEND_WEBHOOK_EVENT', }, { key: 'send_attachment', - name: 'Send Attachment', - attributeI18nKey: 'SEND_ATTACHMENT', + name: 'SEND_ATTACHMENT', }, ], }, @@ -529,91 +446,91 @@ export const AUTOMATIONS = { export const AUTOMATION_RULE_EVENTS = [ { key: 'conversation_created', - value: 'Conversation Created', + value: 'CONVERSATION_CREATED', }, { key: 'conversation_updated', - value: 'Conversation Updated', + value: 'CONVERSATION_UPDATED', }, { key: 'message_created', - value: 'Message Created', + value: 'MESSAGE_CREATED', }, { key: 'conversation_opened', - value: 'Conversation Opened', + value: 'CONVERSATION_OPENED', }, ]; export const AUTOMATION_ACTION_TYPES = [ { key: 'assign_agent', - label: 'Assign to agent', + label: 'ASSIGN_AGENT', inputType: 'search_select', }, { key: 'assign_team', - label: 'Assign a team', + label: 'ASSIGN_TEAM', inputType: 'search_select', }, { key: 'add_label', - label: 'Add a label', + label: 'ADD_LABEL', inputType: 'multi_select', }, { key: 'remove_label', - label: 'Remove a label', + label: 'REMOVE_LABEL', inputType: 'multi_select', }, { key: 'send_email_to_team', - label: 'Send an email to team', + label: 'SEND_EMAIL_TO_TEAM', inputType: 'team_message', }, { key: 'send_email_transcript', - label: 'Send an email transcript', + label: 'SEND_EMAIL_TRANSCRIPT', inputType: 'email', }, { key: 'mute_conversation', - label: 'Mute conversation', + label: 'MUTE_CONVERSATION', inputType: null, }, { key: 'snooze_conversation', - label: 'Snooze conversation', + label: 'SNOOZE_CONVERSATION', inputType: null, }, { key: 'resolve_conversation', - label: 'Resolve conversation', + label: 'RESOLVE_CONVERSATION', inputType: null, }, { key: 'send_webhook_event', - label: 'Send Webhook Event', + label: 'SEND_WEBHOOK_EVENT', inputType: 'url', }, { key: 'send_attachment', - label: 'Send Attachment', + label: 'SEND_ATTACHMENT', inputType: 'attachment', }, { key: 'send_message', - label: 'Send a message', + label: 'SEND_MESSAGE', inputType: 'textarea', }, { key: 'change_priority', - label: 'Change Priority', + label: 'CHANGE_PRIORITY', inputType: 'search_select', }, { key: 'add_sla', - label: 'Add SLA', + label: 'ADD_SLA', inputType: 'search_select', }, ]; diff --git a/app/javascript/dashboard/routes/dashboard/settings/macros/MacroEditor.vue b/app/javascript/dashboard/routes/dashboard/settings/macros/MacroEditor.vue index a808adf23..c974ef4d6 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/macros/MacroEditor.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/macros/MacroEditor.vue @@ -21,7 +21,13 @@ const { getMacroDropdownValues } = useMacros(); const macro = ref(null); const mode = ref('CREATE'); -const macroActionTypes = MACRO_ACTION_TYPES; + +const macroActionTypes = computed(() => { + return MACRO_ACTION_TYPES.map(type => ({ + ...type, + label: t(`MACROS.ACTIONS.${type.label}`), + })); +}); provide('macroActionTypes', macroActionTypes); @@ -38,7 +44,7 @@ const formatMacro = macroData => { const formattedActions = macroData.actions.map(action => { let actionParams = []; if (action.action_params.length) { - const inputType = macroActionTypes.find( + const inputType = macroActionTypes.value.find( item => item.key === action.action_name ).inputType; if (inputType === 'multi_select' || inputType === 'search_select') { diff --git a/app/javascript/dashboard/routes/dashboard/settings/macros/MacroNode.vue b/app/javascript/dashboard/routes/dashboard/settings/macros/MacroNode.vue index e1fc2d2e7..e010b270c 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/macros/MacroNode.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/macros/MacroNode.vue @@ -42,7 +42,7 @@ const showActionInput = computed(() => { actionData.value.action_name === 'send_message' ) return false; - const type = macroActionTypes.find( + const type = macroActionTypes.value.find( action => action.key === actionData.value.action_name ).inputType; return !!type; diff --git a/app/javascript/dashboard/routes/dashboard/settings/macros/constants.js b/app/javascript/dashboard/routes/dashboard/settings/macros/constants.js index 111a3632d..6178065ec 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/macros/constants.js +++ b/app/javascript/dashboard/routes/dashboard/settings/macros/constants.js @@ -1,67 +1,67 @@ export const MACRO_ACTION_TYPES = [ { key: 'assign_team', - label: 'Assign a team', + label: 'ASSIGN_TEAM', inputType: 'search_select', }, { key: 'assign_agent', - label: 'Assign an agent', + label: 'ASSIGN_AGENT', inputType: 'search_select', }, { key: 'add_label', - label: 'Add a label', + label: 'ADD_LABEL', inputType: 'multi_select', }, { key: 'remove_label', - label: 'Remove a label', + label: 'REMOVE_LABEL', inputType: 'multi_select', }, { key: 'remove_assigned_team', - label: 'Remove Assigned Team', + label: 'REMOVE_ASSIGNED_TEAM', inputType: null, }, { key: 'send_email_transcript', - label: 'Send an email transcript', + label: 'SEND_EMAIL_TRANSCRIPT', inputType: 'email', }, { key: 'mute_conversation', - label: 'Mute conversation', + label: 'MUTE_CONVERSATION', inputType: null, }, { key: 'snooze_conversation', - label: 'Snooze conversation', + label: 'SNOOZE_CONVERSATION', inputType: null, }, { key: 'resolve_conversation', - label: 'Resolve conversation', + label: 'RESOLVE_CONVERSATION', inputType: null, }, { key: 'send_attachment', - label: 'Send Attachment', + label: 'SEND_ATTACHMENT', inputType: 'attachment', }, { key: 'send_message', - label: 'Send a message', + label: 'SEND_MESSAGE', inputType: 'textarea', }, { key: 'add_private_note', - label: 'Add a private note', + label: 'ADD_PRIVATE_NOTE', inputType: 'textarea', }, { key: 'change_priority', - label: 'Change Priority', + label: 'CHANGE_PRIORITY', inputType: 'search_select', }, ]; diff --git a/app/models/concerns/activity_message_handler.rb b/app/models/concerns/activity_message_handler.rb index d49442f10..a20eef565 100644 --- a/app/models/concerns/activity_message_handler.rb +++ b/app/models/concerns/activity_message_handler.rb @@ -68,7 +68,7 @@ module ActivityMessageHandler def automation_status_change_activity_content if Current.executed_by.instance_of?(AutomationRule) - I18n.t("conversations.activity.status.#{status}", user_name: 'Automation System') + I18n.t("conversations.activity.status.#{status}", user_name: I18n.t('automation.system_name')) elsif Current.executed_by.instance_of?(Contact) Current.executed_by = nil I18n.t('conversations.activity.status.system_auto_open') @@ -111,7 +111,7 @@ module ActivityMessageHandler end def activity_message_owner(user_name) - user_name = 'Automation System' if !user_name && Current.executed_by.present? + user_name = I18n.t('automation.system_name') if !user_name && Current.executed_by.present? user_name end end diff --git a/app/models/concerns/priority_activity_message_handler.rb b/app/models/concerns/priority_activity_message_handler.rb index 748c41bdc..391173a94 100644 --- a/app/models/concerns/priority_activity_message_handler.rb +++ b/app/models/concerns/priority_activity_message_handler.rb @@ -7,7 +7,7 @@ module PriorityActivityMessageHandler old_priority, new_priority = previous_changes.values_at('priority')[0] return unless priority_change?(old_priority, new_priority) - user = Current.executed_by.instance_of?(AutomationRule) ? 'Automation System' : user_name + user = Current.executed_by.instance_of?(AutomationRule) ? I18n.t('automation.system_name') : user_name content = build_priority_change_content(user, old_priority, new_priority) ::Conversations::ActivityMessageJob.perform_later(self, activity_message_params(content)) if content diff --git a/config/locales/en.yml b/config/locales/en.yml index 4a66a4bc2..a4341927e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -294,3 +294,5 @@ en: seconds: one: '%{count} second' other: '%{count} seconds' + automation: + system_name: 'Automation System'