diff --git a/app/builders/contact_inbox_builder.rb b/app/builders/contact_inbox_builder.rb index 4d51700a8..ffa45db2e 100644 --- a/app/builders/contact_inbox_builder.rb +++ b/app/builders/contact_inbox_builder.rb @@ -12,11 +12,50 @@ class ContactInboxBuilder private def generate_source_id - ContactInbox::SourceIdService.new( - contact: @contact, - channel_type: @inbox.channel_type, - medium: @inbox.channel.try(:medium) - ).generate + case @inbox.channel_type + when 'Channel::TwilioSms' + twilio_source_id + when 'Channel::Whatsapp' + wa_source_id + when 'Channel::Email' + email_source_id + when 'Channel::Sms' + phone_source_id + when 'Channel::Api', 'Channel::WebWidget' + SecureRandom.uuid + else + raise "Unsupported operation for this channel: #{@inbox.channel_type}" + end + end + + def email_source_id + raise ActionController::ParameterMissing, 'contact email' unless @contact.email + + @contact.email + end + + def phone_source_id + raise ActionController::ParameterMissing, 'contact phone number' unless @contact.phone_number + + @contact.phone_number + end + + def wa_source_id + raise ActionController::ParameterMissing, 'contact phone number' unless @contact.phone_number + + # whatsapp doesn't want the + in e164 format + @contact.phone_number.delete('+').to_s + end + + def twilio_source_id + raise ActionController::ParameterMissing, 'contact phone number' unless @contact.phone_number + + case @inbox.channel.medium + when 'sms' + @contact.phone_number + when 'whatsapp' + "whatsapp:#{@contact.phone_number}" + end end def create_contact_inbox @@ -52,7 +91,7 @@ class ContactInboxBuilder def new_source_id if @inbox.whatsapp? || @inbox.sms? || @inbox.twilio? - "#{@source_id}#{rand(100)}" + "whatsapp:#{@source_id}#{rand(100)}" else "#{rand(10)}#{@source_id}" end diff --git a/app/controllers/api/v1/accounts/contacts/contact_inboxes_controller.rb b/app/controllers/api/v1/accounts/contacts/contact_inboxes_controller.rb index bde9a4f0c..d985c8a73 100644 --- a/app/controllers/api/v1/accounts/contacts/contact_inboxes_controller.rb +++ b/app/controllers/api/v1/accounts/contacts/contact_inboxes_controller.rb @@ -9,8 +9,6 @@ class Api::V1::Accounts::Contacts::ContactInboxesController < Api::V1::Accounts: source_id: params[:source_id], hmac_verified: hmac_verified? ).perform - rescue ArgumentError => e - render json: { error: e.message }, status: :unprocessable_entity end private diff --git a/app/javascript/dashboard/components-next/NewConversation/helpers/composeConversationHelper.js b/app/javascript/dashboard/components-next/NewConversation/helpers/composeConversationHelper.js index 45abef1e0..57e819245 100644 --- a/app/javascript/dashboard/components-next/NewConversation/helpers/composeConversationHelper.js +++ b/app/javascript/dashboard/components-next/NewConversation/helpers/composeConversationHelper.js @@ -25,11 +25,6 @@ export const generateLabelForContactableInboxesList = ({ channelType === INBOX_TYPES.TWILIO || channelType === INBOX_TYPES.WHATSAPP ) { - // Handled separately for Twilio Inbox where phone number is not mandatory. - // You can send message to a contact with Messaging Service Id. - if (!phoneNumber) { - return name; - } return `${name} (${phoneNumber})`; } return name; diff --git a/app/javascript/dashboard/components-next/NewConversation/helpers/specs/composeConversationHelper.spec.js b/app/javascript/dashboard/components-next/NewConversation/helpers/specs/composeConversationHelper.spec.js index 37ae5fe29..3de1fad0d 100644 --- a/app/javascript/dashboard/components-next/NewConversation/helpers/specs/composeConversationHelper.spec.js +++ b/app/javascript/dashboard/components-next/NewConversation/helpers/specs/composeConversationHelper.spec.js @@ -8,8 +8,8 @@ vi.mock('dashboard/api/contacts'); describe('composeConversationHelper', () => { describe('generateLabelForContactableInboxesList', () => { const contact = { - name: 'Priority Inbox', - email: 'hello@example.com', + name: 'John Doe', + email: 'john@example.com', phoneNumber: '+1234567890', }; @@ -19,7 +19,7 @@ describe('composeConversationHelper', () => { ...contact, channelType: INBOX_TYPES.EMAIL, }) - ).toBe('Priority Inbox (hello@example.com)'); + ).toBe('John Doe (john@example.com)'); }); it('generates label for twilio inbox', () => { @@ -28,14 +28,7 @@ describe('composeConversationHelper', () => { ...contact, channelType: INBOX_TYPES.TWILIO, }) - ).toBe('Priority Inbox (+1234567890)'); - - expect( - helpers.generateLabelForContactableInboxesList({ - name: 'Priority Inbox', - channelType: INBOX_TYPES.TWILIO, - }) - ).toBe('Priority Inbox'); + ).toBe('John Doe (+1234567890)'); }); it('generates label for whatsapp inbox', () => { @@ -44,7 +37,7 @@ describe('composeConversationHelper', () => { ...contact, channelType: INBOX_TYPES.WHATSAPP, }) - ).toBe('Priority Inbox (+1234567890)'); + ).toBe('John Doe (+1234567890)'); }); it('generates label for other inbox types', () => { @@ -53,7 +46,7 @@ describe('composeConversationHelper', () => { ...contact, channelType: 'Channel::Api', }) - ).toBe('Priority Inbox'); + ).toBe('John Doe'); }); }); diff --git a/app/javascript/dashboard/components/ChatList.vue b/app/javascript/dashboard/components/ChatList.vue index a0b86176d..dc18ddd66 100644 --- a/app/javascript/dashboard/components/ChatList.vue +++ b/app/javascript/dashboard/components/ChatList.vue @@ -61,6 +61,7 @@ import { getUserPermissions, filterItemsByPermission, } from 'dashboard/helper/permissionsHelper.js'; +import { matchesFilters } from '../store/modules/conversations/helpers/filterHelpers'; import { CONVERSATION_EVENTS } from '../helper/AnalyticsHelper/events'; import { ASSIGNEE_TYPE_TAB_PERMISSIONS } from 'dashboard/constants/permissions.js'; @@ -105,7 +106,7 @@ const advancedFilterTypes = ref( ); const currentUser = useMapGetter('getCurrentUser'); -const chatLists = useMapGetter('getAllConversations'); +const chatLists = useMapGetter('getFilteredConversations'); const mineChatsList = useMapGetter('getMineChats'); const allChatList = useMapGetter('getAllStatusChats'); const unAssignedChatsList = useMapGetter('getUnAssignedChats'); @@ -324,6 +325,14 @@ const conversationList = computed(() => { } else { localConversationList = [...chatLists.value]; } + + if (activeFolder.value) { + const { payload } = activeFolder.value.query; + localConversationList = localConversationList.filter(conversation => { + return matchesFilters(conversation, payload); + }); + } + return localConversationList; }); @@ -460,6 +469,12 @@ function setParamsForEditFolderModal() { campaigns: campaigns.value, languages: languages, countries: countries, + priority: [ + { id: 'low', name: t('CONVERSATION.PRIORITY.OPTIONS.LOW') }, + { id: 'medium', name: t('CONVERSATION.PRIORITY.OPTIONS.MEDIUM') }, + { id: 'high', name: t('CONVERSATION.PRIORITY.OPTIONS.HIGH') }, + { id: 'urgent', name: t('CONVERSATION.PRIORITY.OPTIONS.URGENT') }, + ], filterTypes: advancedFilterTypes.value, allCustomAttributes: conversationCustomAttributes.value, }; diff --git a/app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/index.js b/app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/index.js index a3e8e2c10..08b456002 100644 --- a/app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/index.js +++ b/app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/index.js @@ -22,6 +22,14 @@ const filterTypes = [ filterOperators: OPERATOR_TYPES_2, attributeModel: 'standard', }, + { + attributeKey: 'priority', + attributeI18nKey: 'PRIORITY', + inputType: 'multi_select', + dataType: 'text', + filterOperators: OPERATOR_TYPES_1, + attributeModel: 'standard', + }, { attributeKey: 'inbox_id', attributeI18nKey: 'INBOX_NAME', diff --git a/app/javascript/dashboard/helper/customViewsHelper.js b/app/javascript/dashboard/helper/customViewsHelper.js index f3ed8a3a7..c837ce613 100644 --- a/app/javascript/dashboard/helper/customViewsHelper.js +++ b/app/javascript/dashboard/helper/customViewsHelper.js @@ -21,6 +21,7 @@ export const getAttributeInputType = (key, allCustomAttributes) => { const customAttribute = allCustomAttributes.find( attr => attr.attribute_key === key ); + const { attribute_display_type } = customAttribute; const filterInputTypes = generateCustomAttributesInputType( attribute_display_type @@ -68,10 +69,22 @@ const getValuesForCountries = (values, countries) => { })); }; +const getValuesForPriority = (values, priority) => { + return priority.filter(option => values.includes(option.id)); +}; + export const getValuesForFilter = (filter, params) => { const { attribute_key, values } = filter; - const { languages, countries, agents, inboxes, teams, campaigns, labels } = - params; + const { + languages, + countries, + agents, + inboxes, + teams, + campaigns, + labels, + priority, + } = params; switch (attribute_key) { case 'status': return getValuesForStatus(values); @@ -83,15 +96,14 @@ export const getValuesForFilter = (filter, params) => { return getValuesName(values, teams, 'id', 'name'); case 'campaign_id': return getValuesName(values, campaigns, 'id', 'title'); - case 'labels': { + case 'labels': return getValuesForLabels(values, labels); - } - case 'browser_language': { + case 'priority': + return getValuesForPriority(values, priority); + case 'browser_language': return getValuesForLanguages(values, languages); - } - case 'country_code': { + case 'country_code': return getValuesForCountries(values, countries); - } default: return { id: values[0], name: values[0] }; } @@ -100,9 +112,9 @@ export const getValuesForFilter = (filter, params) => { export const generateValuesForEditCustomViews = (filter, params) => { const { attribute_key, filter_operator, values } = filter; const { filterTypes, allCustomAttributes } = params; - const inboxType = getInputType(attribute_key, filter_operator, filterTypes); + const inputType = getInputType(attribute_key, filter_operator, filterTypes); - if (inboxType === undefined) { + if (inputType === undefined) { const filterInputTypes = getAttributeInputType( attribute_key, allCustomAttributes @@ -112,7 +124,7 @@ export const generateValuesForEditCustomViews = (filter, params) => { : { id: values[0], name: values[0] }; } - return inboxType === 'multi_select' || inboxType === 'search_select' + return inputType === 'multi_select' || inputType === 'search_select' ? getValuesForFilter(filter, params) : values[0].toString(); }; diff --git a/app/javascript/dashboard/i18n/locale/pt/teamsSettings.json b/app/javascript/dashboard/i18n/locale/pt/teamsSettings.json index b50283cd7..645a806f4 100644 --- a/app/javascript/dashboard/i18n/locale/pt/teamsSettings.json +++ b/app/javascript/dashboard/i18n/locale/pt/teamsSettings.json @@ -100,7 +100,7 @@ "NO": "cancelar" } }, - "SETTINGS": "Confirgurações", + "SETTINGS": "Configurações", "FORM": { "UPDATE": "Atualizar a equipa", "CREATE": "Criar uma equipa", diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/helpCenter.json b/app/javascript/dashboard/i18n/locale/pt_BR/helpCenter.json index 8042c5ebc..4559f74f9 100644 --- a/app/javascript/dashboard/i18n/locale/pt_BR/helpCenter.json +++ b/app/javascript/dashboard/i18n/locale/pt_BR/helpCenter.json @@ -9,7 +9,7 @@ "FILTER": "Filtrar por", "SORT": "Classificar por", "LOCALE": "Localidade", - "SETTINGS_BUTTON": "Confirgurações", + "SETTINGS_BUTTON": "Configurações", "NEW_BUTTON": "Novo artigo", "DROPDOWN_OPTIONS": { "PUBLISHED": "Publicado", @@ -121,7 +121,7 @@ "COUNT_LABEL": "artigos", "ADD": "Adicionar localidade", "VISIT": "Visitar site", - "SETTINGS": "Confirgurações", + "SETTINGS": "Configurações", "DELETE": "Excluir" }, "PORTAL_CONFIG": { diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json index f596d25dd..2a4f91be4 100644 --- a/app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json @@ -473,7 +473,7 @@ "WIDGET_BUILDER": "Construtor de Widget", "BOT_CONFIGURATION": "Configuração do Bot" }, - "SETTINGS": "Confirgurações", + "SETTINGS": "Configurações", "FEATURES": { "LABEL": "Funcionalidades", "DISPLAY_FILE_PICKER": "Exibir seletor de arquivos no widget", diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/settings.json b/app/javascript/dashboard/i18n/locale/pt_BR/settings.json index f684289d9..0048e8be2 100644 --- a/app/javascript/dashboard/i18n/locale/pt_BR/settings.json +++ b/app/javascript/dashboard/i18n/locale/pt_BR/settings.json @@ -333,7 +333,7 @@ "ARTICLES": "Artigos", "CATEGORIES": "Categorias", "LOCALES": "Localidades", - "SETTINGS": "Confirgurações" + "SETTINGS": "Configurações" }, "CHANNELS": "Canais", "SET_AUTO_OFFLINE": { diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/teamsSettings.json b/app/javascript/dashboard/i18n/locale/pt_BR/teamsSettings.json index 07890e7f9..b8a8e8a25 100644 --- a/app/javascript/dashboard/i18n/locale/pt_BR/teamsSettings.json +++ b/app/javascript/dashboard/i18n/locale/pt_BR/teamsSettings.json @@ -100,7 +100,7 @@ "NO": "Cancelar" } }, - "SETTINGS": "Confirgurações", + "SETTINGS": "Configurações", "FORM": { "UPDATE": "Atualizar equipe", "CREATE": "Criar nova equipe", diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/reports/Index.vue index 858ceb4ad..0cade8635 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/Index.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/reports/Index.vue @@ -1,11 +1,10 @@