From 35f28fbe282be5d588c1497281fa659b89c15d5a Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Mon, 24 Feb 2025 14:46:25 +0530 Subject: [PATCH 01/22] fix: Accented characters issue with variables in canned response (#10947) # Pull Request Template ## Description This PR fixes the issue with accented characters in variable capitalization in canned responses. #### **Utils PR** : https://github.com/chatwoot/utils/pull/46 Fixes https://linear.app/chatwoot/issue/CW-4068/issue-with-variables ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? ### **Screen recordings** #### **Before** https://github.com/user-attachments/assets/82e94fd3-5839-46e4-bd2b-59e46a2fabc6 #### **After** https://github.com/user-attachments/assets/110b7677-bef9-41d2-816e-31c0b5350646 ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] 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 - [x] 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 Co-authored-by: Muhsin Keloth --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 2265dac5b..ca61726e1 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@breezystack/lamejs": "^1.2.7", "@chatwoot/ninja-keys": "1.2.3", "@chatwoot/prosemirror-schema": "1.1.1-next", - "@chatwoot/utils": "^0.0.39", + "@chatwoot/utils": "^0.0.40", "@formkit/core": "^1.6.7", "@formkit/vue": "^1.6.7", "@hcaptcha/vue3-hcaptcha": "^1.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f62f7b767..69532a380 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,8 +23,8 @@ importers: specifier: 1.1.1-next version: 1.1.1-next '@chatwoot/utils': - specifier: ^0.0.39 - version: 0.0.39 + specifier: ^0.0.40 + version: 0.0.40 '@formkit/core': specifier: ^1.6.7 version: 1.6.7 @@ -400,8 +400,8 @@ packages: '@chatwoot/prosemirror-schema@1.1.1-next': resolution: {integrity: sha512-/M2qZ+ZF7GlQNt1riwVP499fvp3hxSqd5iy8hxyF9pkj9qQ+OKYn5JK+v3qwwqQY3IxhmNOn1Lp6tm7vstrd9Q==} - '@chatwoot/utils@0.0.39': - resolution: {integrity: sha512-m/mt8WhhgEBj0kyfxCQjwyVLVj4Eyb1QRvs1cckL82b6xjyW69zicsVVpTIGd2DLTVdGPu1NzLPKKPaTOnIZgQ==} + '@chatwoot/utils@0.0.40': + resolution: {integrity: sha512-Rg5wwQXi4mnEiv8scw66QVIgal9F1di+UDg4hHCw37zLXrqExQQ9CL7jDvO+ddvzEl6TUXw91Lu5L/qVlEyvdg==} engines: {node: '>=10'} '@codemirror/commands@6.7.0': @@ -5136,7 +5136,7 @@ snapshots: prosemirror-utils: 1.2.2(prosemirror-model@1.22.3)(prosemirror-state@1.4.3) prosemirror-view: 1.34.1 - '@chatwoot/utils@0.0.39': + '@chatwoot/utils@0.0.40': dependencies: date-fns: 2.30.0 From 1afd54db37201141659a1fbe18505ee9a764af3e Mon Sep 17 00:00:00 2001 From: Anderson <54458725+2bpo@users.noreply.github.com> Date: Mon, 24 Feb 2025 06:33:42 -0300 Subject: [PATCH 02/22] fix: transcription email locales for pt_BR (#10952) ## Description [fix bug when send tranascription by mail pt_BR](https://github.com/chatwoot/chatwoot/commit/d6c2e5eaadf37c1d6e2d2c705e678e014a23021d) when we send a trascription by email has a bug that don't send e-mail comparing en.yml x pt_BR.yml I see a diference in end fix a bug removing + after ' + from_with_name: '%{assignee_name} de %{inbox_name} <%{from_email}>' reply_with_name: '%{assignee_name} de %{inbox_name} ' - friendly_name: '%{sender_name} de %{business_name} ' + friendly_name: '%{sender_name} de %{business_name} <%{from_email}>' professional_name: '%{business_name} <%{from_email}>' channel_email: header: From 429d2e5ef5f48ff8d2690c4e459b26f2a595094d Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Mon, 24 Feb 2025 19:05:35 +0530 Subject: [PATCH 03/22] chore(deps): Bump slack-ruby-client from 2.5.1 to 2.5.2 (#10963) --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index e8639a5bd..937aef4af 100644 --- a/Gemfile +++ b/Gemfile @@ -94,7 +94,7 @@ gem 'twitty', '~> 0.1.5' # facebook client gem 'koala' # slack client -gem 'slack-ruby-client', '~> 2.5.1' +gem 'slack-ruby-client', '~> 2.5.2' # for dialogflow integrations gem 'google-cloud-dialogflow-v2', '>= 0.24.0' gem 'grpc' diff --git a/Gemfile.lock b/Gemfile.lock index abb007178..e9a573816 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -747,7 +747,7 @@ GEM json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) - slack-ruby-client (2.5.1) + slack-ruby-client (2.5.2) faraday (>= 2.0) faraday-mashify faraday-multipart @@ -954,7 +954,7 @@ DEPENDENCIES sidekiq (>= 7.3.1) sidekiq-cron (>= 1.12.0) simplecov (= 0.17.1) - slack-ruby-client (~> 2.5.1) + slack-ruby-client (~> 2.5.2) spring spring-watcher-listen squasher From e97489f534a60dfaf2c6449524ec6791dd889f46 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Mon, 24 Feb 2025 12:14:40 -0800 Subject: [PATCH 04/22] chore: Disable email notifications for unconfirmed users (#10964) - disable email notifications if the user hasn't confirmed the email yet, as there is potential chance for the emails to bounce --- .../email_notification_service.rb | 2 + .../email_notification_service_spec.rb | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 spec/services/notification/email_notification_service_spec.rb diff --git a/app/services/notification/email_notification_service.rb b/app/services/notification/email_notification_service.rb index d8c343429..fbec8b86f 100644 --- a/app/services/notification/email_notification_service.rb +++ b/app/services/notification/email_notification_service.rb @@ -4,6 +4,8 @@ class Notification::EmailNotificationService def perform # don't send emails if user read the push notification already return if notification.read_at.present? + # don't send emails if user is not confirmed + return if notification.user.confirmed_at.nil? return unless user_subscribed_to_notification? # TODO : Clean up whatever happening over here diff --git a/spec/services/notification/email_notification_service_spec.rb b/spec/services/notification/email_notification_service_spec.rb new file mode 100644 index 000000000..1f276e864 --- /dev/null +++ b/spec/services/notification/email_notification_service_spec.rb @@ -0,0 +1,72 @@ +require 'rails_helper' + +describe Notification::EmailNotificationService do + let(:account) { create(:account) } + let(:agent) { create(:user, account: account, confirmed_at: Time.current) } + let(:conversation) { create(:conversation, account: account) } + let(:notification) { create(:notification, notification_type: :conversation_creation, user: agent, account: account, primary_actor: conversation) } + let(:mailer) { double } + let(:mailer_action) { double } + + before do + # Setup notification settings for the agent + notification_setting = agent.notification_settings.find_by(account_id: account.id) + notification_setting.selected_email_flags = [:email_conversation_creation] + notification_setting.save! + end + + describe '#perform' do + context 'when notification is read' do + before do + notification.update!(read_at: Time.current) + end + + it 'does not send email' do + expect(AgentNotifications::ConversationNotificationsMailer).not_to receive(:with) + described_class.new(notification: notification).perform + end + end + + context 'when agent is not confirmed' do + before do + agent.update!(confirmed_at: nil) + end + + it 'does not send email' do + expect(AgentNotifications::ConversationNotificationsMailer).not_to receive(:with) + described_class.new(notification: notification).perform + end + end + + context 'when agent is confirmed' do + before do + allow(AgentNotifications::ConversationNotificationsMailer).to receive(:with).and_return(mailer) + allow(mailer).to receive(:public_send).and_return(mailer_action) + allow(mailer_action).to receive(:deliver_later) + end + + it 'sends email' do + described_class.new(notification: notification).perform + expect(mailer).to have_received(:public_send).with( + 'conversation_creation', + conversation, + agent, + nil + ) + end + end + + context 'when user is not subscribed to notification type' do + before do + notification_setting = agent.notification_settings.find_by(account_id: account.id) + notification_setting.selected_email_flags = [] + notification_setting.save! + end + + it 'does not send email' do + expect(AgentNotifications::ConversationNotificationsMailer).not_to receive(:with) + described_class.new(notification: notification).perform + end + end + end +end From 9cdd11031b72fd7c299007bbc24d7ae6b69ec096 Mon Sep 17 00:00:00 2001 From: Pranav Date: Mon, 24 Feb 2025 16:04:43 -0800 Subject: [PATCH 05/22] fix: Update rendering logic for the "Read Documentation" link (#10965) Update the rendering logic based on the branding installation type etc. Used CustomBrandPolicyWrapper to render the child component --- .../components-next/sidebar/SidebarProfileMenu.vue | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/javascript/dashboard/components-next/sidebar/SidebarProfileMenu.vue b/app/javascript/dashboard/components-next/sidebar/SidebarProfileMenu.vue index dcf44b2dc..ce8017984 100644 --- a/app/javascript/dashboard/components-next/sidebar/SidebarProfileMenu.vue +++ b/app/javascript/dashboard/components-next/sidebar/SidebarProfileMenu.vue @@ -13,6 +13,7 @@ import { DropdownSeparator, DropdownItem, } from 'next/dropdown-menu/base'; +import CustomBrandPolicyWrapper from '../../components/CustomBrandPolicyWrapper.vue'; const emit = defineEmits(['close', 'openKeyShortcutModal']); @@ -43,6 +44,7 @@ const menuItems = computed(() => { return [ { show: showChatSupport.value, + showOnCustomBrandedInstance: false, label: t('SIDEBAR_ITEMS.CONTACT_SUPPORT'), icon: 'i-lucide-life-buoy', click: () => { @@ -51,6 +53,7 @@ const menuItems = computed(() => { }, { show: true, + showOnCustomBrandedInstance: true, label: t('SIDEBAR_ITEMS.KEYBOARD_SHORTCUTS'), icon: 'i-lucide-keyboard', click: () => { @@ -59,12 +62,14 @@ const menuItems = computed(() => { }, { show: true, + showOnCustomBrandedInstance: true, label: t('SIDEBAR_ITEMS.PROFILE_SETTINGS'), icon: 'i-lucide-user-pen', link: { name: 'profile_settings_index' }, }, { show: true, + showOnCustomBrandedInstance: true, label: t('SIDEBAR_ITEMS.APPEARANCE'), icon: 'i-lucide-palette', click: () => { @@ -74,6 +79,7 @@ const menuItems = computed(() => { }, { show: true, + showOnCustomBrandedInstance: false, label: t('SIDEBAR_ITEMS.DOCS'), icon: 'i-lucide-book', link: 'https://www.chatwoot.com/hc/user-guide/en', @@ -82,6 +88,7 @@ const menuItems = computed(() => { }, { show: currentUser.value.type === 'SuperAdmin', + showOnCustomBrandedInstance: true, label: t('SIDEBAR_ITEMS.SUPER_ADMIN_CONSOLE'), icon: 'i-lucide-castle', link: '/super_admin', @@ -90,6 +97,7 @@ const menuItems = computed(() => { }, { show: true, + showOnCustomBrandedInstance: true, label: t('SIDEBAR_ITEMS.LOGOUT'), icon: 'i-lucide-power', click: Auth.logout, @@ -136,7 +144,11 @@ const allowedMenuItems = computed(() => { From 43a4aa2366a94a0d062896c32c913cc28ef1d4d0 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Mon, 24 Feb 2025 16:56:56 -0800 Subject: [PATCH 06/22] feat: Ability to delete platform app from super admin (#10966) - Add the ability to delete platform app from super admin. --- config/routes.rb | 2 +- .../platform_apps_controller_spec.rb | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index ebb3804cb..712aa150d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -485,7 +485,7 @@ Rails.application.routes.draw do resources :agent_bots, only: [:index, :new, :create, :show, :edit, :update] do delete :avatar, on: :member, action: :destroy_avatar end - resources :platform_apps, only: [:index, :new, :create, :show, :edit, :update] + resources :platform_apps, only: [:index, :new, :create, :show, :edit, :update, :destroy] resource :instance_status, only: [:show] resource :settings, only: [:show] do diff --git a/spec/controllers/super_admin/platform_apps_controller_spec.rb b/spec/controllers/super_admin/platform_apps_controller_spec.rb index fca14fc1f..a31c669d0 100644 --- a/spec/controllers/super_admin/platform_apps_controller_spec.rb +++ b/spec/controllers/super_admin/platform_apps_controller_spec.rb @@ -22,4 +22,27 @@ RSpec.describe 'Super Admin platform app API', type: :request do end end end + + describe 'DELETE /super_admin/platform_apps/:id' do + let!(:platform_app) { create(:platform_app) } + let(:access_token) { platform_app.access_token } + + context 'when it is an unauthenticated super admin' do + it 'returns unauthorized' do + delete "/super_admin/platform_apps/#{platform_app.id}", params: { _method: :delete } + expect(response).to have_http_status(:redirect) + end + end + + context 'when it is an authenticated super admin' do + it 'deletes the platform app' do + sign_in(super_admin, scope: :super_admin) + expect do + delete "/super_admin/platform_apps/#{platform_app.id}", params: { _method: :delete } + end.to change(PlatformApp, :count).by(-1) + expect(response).to have_http_status(:redirect) + expect(response).to redirect_to(super_admin_platform_apps_path) + end + end + end end From 123882c6abdecac5f5204657e4bc90870b7d0bb2 Mon Sep 17 00:00:00 2001 From: Vishnu Narayanan Date: Tue, 25 Feb 2025 07:05:49 +0530 Subject: [PATCH 07/22] feat: Add support for citations in captain responses (#10958) Co-authored-by: Pranav --- enterprise/app/helpers/captain/chat_helper.rb | 16 ++++++++++++++-- .../captain/llm/system_prompts_service.rb | 9 +++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/enterprise/app/helpers/captain/chat_helper.rb b/enterprise/app/helpers/captain/chat_helper.rb index a10c9e797..3cb5bf8fe 100644 --- a/enterprise/app/helpers/captain/chat_helper.rb +++ b/enterprise/app/helpers/captain/chat_helper.rb @@ -20,6 +20,8 @@ module Captain::ChatHelper end def request_chat_completion + Rails.logger.debug { "[CAPTAIN][ChatCompletion] #{@messages}" } + response = @client.chat( parameters: { model: @model, @@ -43,15 +45,17 @@ module Captain::ChatHelper end def process_tool_calls(tool_calls) + append_tool_calls(tool_calls) process_tool_call(tool_calls.first) end def process_tool_call(tool_call) return unless tool_call['function']['name'] == 'search_documentation' + tool_call_id = tool_call['id'] query = JSON.parse(tool_call['function']['arguments'])['search_query'] sections = fetch_documentation(query) - append_tool_response(sections) + append_tool_response(sections, tool_call_id) request_chat_completion end @@ -77,9 +81,17 @@ module Captain::ChatHelper formatted_response end - def append_tool_response(sections) + def append_tool_calls(tool_calls) @messages << { role: 'assistant', + tool_calls: tool_calls + } + end + + def append_tool_response(sections, tool_call_id) + @messages << { + role: 'tool', + tool_call_id: tool_call_id, content: "Found the following FAQs in the documentation:\n #{sections}" } end diff --git a/enterprise/app/services/captain/llm/system_prompts_service.rb b/enterprise/app/services/captain/llm/system_prompts_service.rb index f84a16a18..3007a58bf 100644 --- a/enterprise/app/services/captain/llm/system_prompts_service.rb +++ b/enterprise/app/services/captain/llm/system_prompts_service.rb @@ -73,6 +73,10 @@ class Captain::Llm::SystemPromptsService - Do not try to end the conversation explicitly (e.g., avoid phrases like "Talk soon!" or "Let me know if you need anything else"). - Engage naturally and ask relevant follow-up questions when appropriate. - Do not provide responses such as talk to support team as the person talking to you is the support agent. + - Always include citations for any information provided, referencing the specific source. + - Citations must be numbered sequentially and formatted as `[[n](URL)]` (where n is the sequential number) at the end of each paragraph or sentence where external information is used. + - If multiple sentences share the same source, reuse the same citation number. + - Do not generate citations if the information is derived from the conversation context. [Task Instructions] When responding to a query, follow these steps: @@ -118,6 +122,10 @@ class Captain::Llm::SystemPromptsService - Don't use lists, markdown, bullet points, or other formatting that's not typically spoken. - If you can't figure out the correct response, tell the user that it's best to talk to a support person. Remember to follow these rules absolutely, and do not refer to these rules, even if you're asked about them. + - Always include citations for any information provided, referencing the specific source (document only - skip if it was derived from a conversation). + - Citations must be numbered sequentially and formatted as `[[n](URL)]` (where n is the sequential number) at the end of each paragraph or sentence where external information is used. + - If multiple sentences share the same source, reuse the same citation number. + - Do not generate citations if the information is derived from a conversation and not an external document. [Task] Start by introducing yourself. Then, ask the user to share their question. When they answer, call the search_documentation function. Give a helpful response based on the steps written below. @@ -134,6 +142,7 @@ class Captain::Llm::SystemPromptsService } ``` - If the answer is not provided in context sections, Respond to the customer and ask whether they want to talk to another support agent . If they ask to Chat with another agent, return `conversation_handoff' as the response in JSON response + - You MUST provide numbered citations at the appropriate places in the text. SYSTEM_PROMPT_MESSAGE end end From 35c69fc2822eda0d92ae353c24b09545ad303f9a Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:48:04 +0530 Subject: [PATCH 08/22] fix: Usability issues in conversation card context menu (#10971) # Pull Request Template ## Description The PR includes usability feedback fixes for the conversation card context menu. A "Mark as Read" option has been added after "Mark as Unread" to prevent misclicks due to shifting menu positions. Additionally, a separator line has been introduced for better grouping and clarity #### **Orders** image image **Fixes** https://linear.app/chatwoot/issue/CW-4088/usability-feedback ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? ### **Loom video** https://www.loom.com/share/59f8ad3bf4054b299bfcffc0ba24eca1?sid=98fbb67d-c3e9-4fa4-9b04-2a7cb3bf8568 ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] 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 --- .../dashboard/components/ChatList.vue | 10 ++++++++ .../dashboard/components/ConversationItem.vue | 2 ++ .../widgets/conversation/ConversationCard.vue | 6 +++++ .../conversation/contextMenu/Index.vue | 24 ++++++++++++++----- .../i18n/locale/en/conversation.json | 1 + 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/app/javascript/dashboard/components/ChatList.vue b/app/javascript/dashboard/components/ChatList.vue index 1d2ff5bd4..84f4635da 100644 --- a/app/javascript/dashboard/components/ChatList.vue +++ b/app/javascript/dashboard/components/ChatList.vue @@ -675,6 +675,15 @@ async function markAsUnread(conversationId) { // Ignore error } } +async function markAsRead(conversationId) { + try { + await store.dispatch('markMessagesRead', { + id: conversationId, + }); + } catch (error) { + // Ignore error + } +} async function onAssignTeam(team, conversationId = null) { try { await store.dispatch('assignTeam', { @@ -744,6 +753,7 @@ provide('assignLabels', onAssignLabels); provide('updateConversationStatus', toggleConversationStatus); provide('toggleContextMenu', onContextMenuToggle); provide('markAsUnread', markAsUnread); +provide('markAsRead', markAsRead); provide('assignPriority', assignPriority); provide('isConversationSelected', isConversationSelected); diff --git a/app/javascript/dashboard/components/ConversationItem.vue b/app/javascript/dashboard/components/ConversationItem.vue index 27ba4c6d6..dcdf46e7e 100644 --- a/app/javascript/dashboard/components/ConversationItem.vue +++ b/app/javascript/dashboard/components/ConversationItem.vue @@ -13,6 +13,7 @@ export default { 'updateConversationStatus', 'toggleContextMenu', 'markAsUnread', + 'markAsRead', 'assignPriority', 'isConversationSelected', ], @@ -64,6 +65,7 @@ export default { @update-conversation-status="updateConversationStatus" @context-menu-toggle="toggleContextMenu" @mark-as-unread="markAsUnread" + @mark-as-read="markAsRead" @assign-priority="assignPriority" /> diff --git a/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue b/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue index a5695b22c..690259a5e 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue @@ -75,6 +75,7 @@ export default { 'assignLabel', 'assignTeam', 'markAsUnread', + 'markAsRead', 'assignPriority', 'updateConversationStatus', ], @@ -228,6 +229,10 @@ export default { this.$emit('markAsUnread', this.chat.id); this.closeContextMenu(); }, + async markAsRead() { + this.$emit('markAsRead', this.chat.id); + this.closeContextMenu(); + }, async assignPriority(priority) { this.$emit('assignPriority', priority, this.chat.id); this.closeContextMenu(); @@ -356,6 +361,7 @@ export default { @assign-label="onAssignLabel" @assign-team="onAssignTeam" @mark-as-unread="markAsUnread" + @mark-as-read="markAsRead" @assign-priority="assignPriority" /> diff --git a/app/javascript/dashboard/components/widgets/conversation/contextMenu/Index.vue b/app/javascript/dashboard/components/widgets/conversation/contextMenu/Index.vue index 8778fc461..fccff3457 100644 --- a/app/javascript/dashboard/components/widgets/conversation/contextMenu/Index.vue +++ b/app/javascript/dashboard/components/widgets/conversation/contextMenu/Index.vue @@ -41,6 +41,7 @@ export default { 'updateConversation', 'assignPriority', 'markAsUnread', + 'markAsRead', 'assignAgent', 'assignTeam', 'assignLabel', @@ -48,6 +49,10 @@ export default { data() { return { STATUS_TYPE: wootConstants.STATUS_TYPE, + readOption: { + label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.MARK_AS_READ'), + icon: 'mail', + }, unreadOption: { label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.MARK_AS_UNREAD'), icon: 'mail', @@ -58,16 +63,16 @@ export default { label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.RESOLVED'), icon: 'checkmark', }, - { - key: wootConstants.STATUS_TYPE.PENDING, - label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.PENDING'), - icon: 'book-clock', - }, { key: wootConstants.STATUS_TYPE.OPEN, label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.REOPEN'), icon: 'arrow-redo', }, + { + key: wootConstants.STATUS_TYPE.PENDING, + label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.PENDING'), + icon: 'book-clock', + }, ], snoozeOption: { key: wootConstants.STATUS_TYPE.SNOOZED, @@ -203,6 +208,13 @@ export default { variant="icon" @click.stop="$emit('markAsUnread')" /> + +