import Vue from 'vue'; import types from '../../mutation-types'; import ConversationApi from '../../../api/inbox/conversation'; import MessageApi from '../../../api/inbox/message'; import { MESSAGE_STATUS, MESSAGE_TYPE } from 'shared/constants/messages'; import { createPendingMessage } from 'dashboard/helper/commons'; import { buildConversationList, isOnMentionsView, isOnUnattendedView, } from './helpers/actionHelpers'; import messageReadActions from './actions/messageReadActions'; import AnalyticsHelper, { ANALYTICS_EVENTS, } from '../../../helper/AnalyticsHelper'; // actions const actions = { getConversation: async ({ commit }, conversationId) => { try { const response = await ConversationApi.show(conversationId); commit(types.UPDATE_CONVERSATION, response.data); commit(`contacts/${types.SET_CONTACT_ITEM}`, response.data.meta.sender); } catch (error) { // Ignore error } }, fetchAllConversations: async ({ commit, dispatch }, params) => { commit(types.SET_LIST_LOADING_STATUS); try { const { data: { data }, } = await ConversationApi.get(params); buildConversationList( { commit, dispatch }, params, data, params.assigneeType ); } catch (error) { // Handle error } }, fetchFilteredConversations: async ({ commit, dispatch }, params) => { commit(types.SET_LIST_LOADING_STATUS); try { const { data } = await ConversationApi.filter(params); buildConversationList( { commit, dispatch }, params, data, 'appliedFilters' ); } catch (error) { // Handle error } }, emptyAllConversations({ commit }) { commit(types.EMPTY_ALL_CONVERSATION); }, clearSelectedState({ commit }) { commit(types.CLEAR_CURRENT_CHAT_WINDOW); }, fetchPreviousMessages: async ({ commit }, data) => { try { const { data: { meta, payload }, } = await MessageApi.getPreviousMessages(data); commit(`conversationMetadata/${types.SET_CONVERSATION_METADATA}`, { id: data.conversationId, data: meta, }); commit(types.SET_PREVIOUS_CONVERSATIONS, { id: data.conversationId, data: payload, }); if (payload.length < 20) { commit(types.SET_ALL_MESSAGES_LOADED); } } catch (error) { // Handle error } }, async setActiveChat({ commit, dispatch }, data) { commit(types.SET_CURRENT_CHAT_WINDOW, data); commit(types.CLEAR_ALL_MESSAGES_LOADED); if (data.dataFetched === undefined) { try { await dispatch('fetchPreviousMessages', { conversationId: data.id, before: data.messages[0].id, }); Vue.set(data, 'dataFetched', true); } catch (error) { // Ignore error } } }, assignAgent: async ({ dispatch }, { conversationId, agentId }) => { try { const response = await ConversationApi.assignAgent({ conversationId, agentId, }); dispatch('setCurrentChatAssignee', response.data); } catch (error) { // Handle error } }, setCurrentChatAssignee({ commit }, assignee) { commit(types.ASSIGN_AGENT, assignee); }, assignTeam: async ({ dispatch }, { conversationId, teamId }) => { try { const response = await ConversationApi.assignTeam({ conversationId, teamId, }); dispatch('setCurrentChatTeam', { team: response.data, conversationId }); } catch (error) { // Handle error } }, setCurrentChatTeam({ commit }, { team, conversationId }) { commit(types.ASSIGN_TEAM, { team, conversationId }); }, toggleStatus: async ( { commit }, { conversationId, status, snoozedUntil = null } ) => { try { const { data: { payload: { current_status: updatedStatus, snoozed_until: updatedSnoozedUntil, } = {}, } = {}, } = await ConversationApi.toggleStatus({ conversationId, status, snoozedUntil, }); commit(types.CHANGE_CONVERSATION_STATUS, { conversationId, status: updatedStatus, snoozedUntil: updatedSnoozedUntil, }); } catch (error) { // Handle error } }, createPendingMessageAndSend: async ({ dispatch }, data) => { const pendingMessage = createPendingMessage(data); dispatch('sendMessageWithData', pendingMessage); }, sendMessageWithData: async ({ commit }, pendingMessage) => { try { commit(types.ADD_MESSAGE, { ...pendingMessage, status: MESSAGE_STATUS.PROGRESS, }); const response = await MessageApi.create(pendingMessage); AnalyticsHelper.track( pendingMessage.private ? ANALYTICS_EVENTS.SENT_PRIVATE_NOTE : ANALYTICS_EVENTS.SENT_MESSAGE ); commit(types.ADD_MESSAGE, { ...response.data, status: MESSAGE_STATUS.SENT, }); } catch (error) { const errorMessage = error.response ? error.response.data.error : undefined; commit(types.ADD_MESSAGE, { ...pendingMessage, meta: { error: errorMessage, }, status: MESSAGE_STATUS.FAILED, }); throw error; } }, addMessage({ commit }, message) { commit(types.ADD_MESSAGE, message); if (message.message_type === MESSAGE_TYPE.INCOMING) { commit(types.SET_CONVERSATION_CAN_REPLY, { conversationId: message.conversation_id, canReply: true, }); } }, updateMessage({ commit }, message) { commit(types.ADD_MESSAGE, message); }, deleteMessage: async function deleteLabels( { commit }, { conversationId, messageId } ) { try { const response = await MessageApi.delete(conversationId, messageId); const { data } = response; // The delete message is actually deleting the content. commit(types.ADD_MESSAGE, data); } catch (error) { throw new Error(error); } }, addConversation({ commit, state, dispatch, rootState }, conversation) { const { currentInbox, appliedFilters } = state; const { inbox_id: inboxId, meta: { sender }, } = conversation; const hasAppliedFilters = !!appliedFilters.length; const isMatchingInboxFilter = !currentInbox || Number(currentInbox) === inboxId; if ( !hasAppliedFilters && !isOnMentionsView(rootState) && !isOnUnattendedView(rootState) && isMatchingInboxFilter ) { commit(types.ADD_CONVERSATION, conversation); dispatch('contacts/setContact', sender); } }, addMentions({ dispatch, rootState }, conversation) { if (isOnMentionsView(rootState)) { dispatch('updateConversation', conversation); } }, addUnattended({ dispatch, rootState }, conversation) { if (isOnUnattendedView(rootState)) { dispatch('updateConversation', conversation); } }, updateConversation({ commit, dispatch }, conversation) { const { meta: { sender }, } = conversation; commit(types.UPDATE_CONVERSATION, conversation); dispatch('conversationLabels/setConversationLabel', { id: conversation.id, data: conversation.labels, }); dispatch('contacts/setContact', sender); }, setChatFilter({ commit }, data) { commit(types.CHANGE_CHAT_STATUS_FILTER, data); }, updateAssignee({ commit }, data) { commit(types.UPDATE_ASSIGNEE, data); }, updateConversationContact({ commit }, data) { if (data.id) { commit(`contacts/${types.SET_CONTACT_ITEM}`, data); } commit(types.UPDATE_CONVERSATION_CONTACT, data); }, setActiveInbox({ commit }, inboxId) { commit(types.SET_ACTIVE_INBOX, inboxId); }, muteConversation: async ({ commit }, conversationId) => { try { await ConversationApi.mute(conversationId); commit(types.MUTE_CONVERSATION); } catch (error) { // } }, unmuteConversation: async ({ commit }, conversationId) => { try { await ConversationApi.unmute(conversationId); commit(types.UNMUTE_CONVERSATION); } catch (error) { // } }, sendEmailTranscript: async (_, { conversationId, email }) => { try { await ConversationApi.sendEmailTranscript({ conversationId, email }); } catch (error) { throw new Error(error); } }, updateCustomAttributes: async ( { commit }, { conversationId, customAttributes } ) => { try { const response = await ConversationApi.updateCustomAttributes({ conversationId, customAttributes, }); const { custom_attributes } = response.data; commit(types.UPDATE_CONVERSATION_CUSTOM_ATTRIBUTES, custom_attributes); } catch (error) { // Handle error } }, setConversationFilters({ commit }, data) { commit(types.SET_CONVERSATION_FILTERS, data); }, clearConversationFilters({ commit }) { commit(types.CLEAR_CONVERSATION_FILTERS); }, ...messageReadActions, }; export default actions;