Chore: Move conversationStats to a seperate module (#962)

* Chore: Move conversationStats to a seperate module

* Move toggleTyping to conversationTypingStatus

* Remove unused agentTyping flag

* Fix review comments
This commit is contained in:
Pranav Raj S 2020-06-14 14:07:52 +05:30 committed by GitHub
parent 5ec9af9325
commit 5cb88237f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 139 additions and 98 deletions

View file

@ -6,20 +6,6 @@ class FBChannel extends ApiClient {
super('facebook_indicators', { accountScoped: true }); super('facebook_indicators', { accountScoped: true });
} }
markSeen({ inboxId, contactId }) {
return axios.post(`${this.url}/mark_seen`, {
inbox_id: inboxId,
contact_id: contactId,
});
}
toggleTyping({ status, inboxId, contactId }) {
return axios.post(`${this.url}/typing_${status}`, {
inbox_id: inboxId,
contact_id: contactId,
});
}
create(params) { create(params) {
return axios.post( return axios.post(
`${this.url.replace(this.resource, '')}callbacks/register_facebook_page`, `${this.url.replace(this.resource, '')}callbacks/register_facebook_page`,

View file

@ -9,7 +9,5 @@ describe('#FBChannel', () => {
expect(fbChannel).toHaveProperty('create'); expect(fbChannel).toHaveProperty('create');
expect(fbChannel).toHaveProperty('update'); expect(fbChannel).toHaveProperty('update');
expect(fbChannel).toHaveProperty('delete'); expect(fbChannel).toHaveProperty('delete');
expect(fbChannel).toHaveProperty('markSeen');
expect(fbChannel).toHaveProperty('toggleTyping');
}); });
}); });

View file

@ -1,14 +1,14 @@
import agents from '../contacts'; import contacts from '../contacts';
import ApiClient from '../ApiClient'; import ApiClient from '../ApiClient';
describe('#ContactsAPI', () => { describe('#ContactsAPI', () => {
it('creates correct instance', () => { it('creates correct instance', () => {
expect(agents).toBeInstanceOf(ApiClient); expect(contacts).toBeInstanceOf(ApiClient);
expect(agents).toHaveProperty('get'); expect(contacts).toHaveProperty('get');
expect(agents).toHaveProperty('show'); expect(contacts).toHaveProperty('show');
expect(agents).toHaveProperty('create'); expect(contacts).toHaveProperty('create');
expect(agents).toHaveProperty('update'); expect(contacts).toHaveProperty('update');
expect(agents).toHaveProperty('delete'); expect(contacts).toHaveProperty('delete');
expect(agents).toHaveProperty('getConversations'); expect(contacts).toHaveProperty('getConversations');
}); });
}); });

View file

@ -88,14 +88,17 @@ export default {
chatListLoading: 'getChatListLoadingStatus', chatListLoading: 'getChatListLoadingStatus',
currentUserID: 'getCurrentUserID', currentUserID: 'getCurrentUserID',
activeInbox: 'getSelectedInbox', activeInbox: 'getSelectedInbox',
convStats: 'getConvTabStats', conversationStats: 'conversationStats/getStats',
}), }),
assigneeTabItems() { assigneeTabItems() {
return this.$t('CHAT_LIST.ASSIGNEE_TYPE_TABS').map(item => ({ return this.$t('CHAT_LIST.ASSIGNEE_TYPE_TABS').map(item => {
key: item.KEY, const count = this.conversationStats[item.COUNT_KEY] || 0;
name: item.NAME, return {
count: this.convStats[item.COUNT_KEY] || 0, key: item.KEY,
})); name: item.NAME,
count,
};
});
}, },
inbox() { inbox() {
return this.$store.getters['inboxes/getInbox'](this.activeInbox); return this.$store.getters['inboxes/getInbox'](this.activeInbox);
@ -130,7 +133,7 @@ export default {
this.$store.dispatch('agents/get'); this.$store.dispatch('agents/get');
bus.$on('fetch_conversation_stats', () => { bus.$on('fetch_conversation_stats', () => {
this.$store.dispatch('getConversationStats', this.conversationFilters); this.$store.dispatch('conversationStats/get', this.conversationFilters);
}); });
}, },
methods: { methods: {

View file

@ -22,11 +22,6 @@ export default {
default: wootConstants.ASSIGNEE_TYPE.ME, default: wootConstants.ASSIGNEE_TYPE.ME,
}, },
}, },
data() {
return {
tabsIndex: wootConstants.ASSIGNEE_TYPE.ME,
};
},
computed: { computed: {
activeTabIndex() { activeTabIndex() {
return this.items.findIndex(item => item.key === this.activeTab); return this.items.findIndex(item => item.key === this.activeTab);

View file

@ -269,7 +269,7 @@ export default {
toggleTyping(status) { toggleTyping(status) {
if (this.channelType === 'Channel::WebWidget' && !this.isPrivate) { if (this.channelType === 'Channel::WebWidget' && !this.isPrivate) {
const conversationId = this.currentChat.id; const conversationId = this.currentChat.id;
this.$store.dispatch('toggleTyping', { this.$store.dispatch('conversationTypingStatus/toggleTyping', {
status, status,
conversationId, conversationId,
}); });

View file

@ -12,6 +12,7 @@ import conversationLabels from './modules/conversationLabels';
import conversationMetadata from './modules/conversationMetadata'; import conversationMetadata from './modules/conversationMetadata';
import conversationPage from './modules/conversationPage'; import conversationPage from './modules/conversationPage';
import conversations from './modules/conversations'; import conversations from './modules/conversations';
import conversationStats from './modules/conversationStats';
import conversationTypingStatus from './modules/conversationTypingStatus'; import conversationTypingStatus from './modules/conversationTypingStatus';
import globalConfig from 'shared/store/globalConfig'; import globalConfig from 'shared/store/globalConfig';
import inboxes from './modules/inboxes'; import inboxes from './modules/inboxes';
@ -33,6 +34,7 @@ export default new Vuex.Store({
conversationLabels, conversationLabels,
conversationMetadata, conversationMetadata,
conversationPage, conversationPage,
conversationStats,
conversations, conversations,
conversationTypingStatus, conversationTypingStatus,
globalConfig, globalConfig,

View file

@ -0,0 +1,53 @@
import Vue from 'vue';
import types from '../mutation-types';
import ConversationApi from '../../api/inbox/conversation';
const state = {
mineCount: 0,
unAssignedCount: 0,
allCount: 0,
};
export const getters = {
getStats: $state => $state,
};
export const actions = {
get: async ({ commit }, params) => {
try {
const response = await ConversationApi.meta(params);
const {
data: { meta },
} = response;
commit(types.SET_CONV_TAB_META, meta);
} catch (error) {
// Ignore error
}
},
set({ commit }, meta) {
commit(types.SET_CONV_TAB_META, meta);
},
};
export const mutations = {
[types.SET_CONV_TAB_META](
$state,
{
mine_count: mineCount,
unassigned_count: unAssignedCount,
all_count: allCount,
} = {}
) {
Vue.set($state, 'mineCount', mineCount);
Vue.set($state, 'allCount', allCount);
Vue.set($state, 'unAssignedCount', unAssignedCount);
},
};
export default {
namespaced: true,
state,
getters,
actions,
mutations,
};

View file

@ -1,6 +1,6 @@
import Vue from 'vue'; import Vue from 'vue';
import * as types from '../mutation-types'; import * as types from '../mutation-types';
import ConversationAPI from '../../api/inbox/conversation';
const state = { const state = {
records: {}, records: {},
}; };
@ -12,6 +12,13 @@ export const getters = {
}; };
export const actions = { export const actions = {
toggleTyping: async (_, { status, conversationId }) => {
try {
await ConversationAPI.toggleTyping({ status, conversationId });
} catch (error) {
// Handle error
}
},
create: ({ commit }, { conversationId, user }) => { create: ({ commit }, { conversationId, user }) => {
commit(types.default.ADD_USER_TYPING_TO_CONVERSATION, { commit(types.default.ADD_USER_TYPING_TO_CONVERSATION, {
conversationId, conversationId,

View file

@ -2,7 +2,6 @@ import Vue from 'vue';
import * as types from '../../mutation-types'; import * as types from '../../mutation-types';
import ConversationApi from '../../../api/inbox/conversation'; import ConversationApi from '../../../api/inbox/conversation';
import MessageApi from '../../../api/inbox/message'; import MessageApi from '../../../api/inbox/message';
import FBChannel from '../../../api/channel/fbChannel';
// actions // actions
const actions = { const actions = {
@ -26,7 +25,7 @@ const actions = {
const { data } = response.data; const { data } = response.data;
const { payload: chatList, meta: metaData } = data; const { payload: chatList, meta: metaData } = data;
commit(types.default.SET_ALL_CONVERSATION, chatList); commit(types.default.SET_ALL_CONVERSATION, chatList);
commit(types.default.SET_CONV_TAB_META, metaData); dispatch('conversationStats/set', metaData);
commit(types.default.CLEAR_LIST_LOADING_STATUS); commit(types.default.CLEAR_LIST_LOADING_STATUS);
commit( commit(
`contacts/${types.default.SET_CONTACTS}`, `contacts/${types.default.SET_CONTACTS}`,
@ -171,24 +170,6 @@ const actions = {
commit(types.default.UPDATE_CONVERSATION, conversation); commit(types.default.UPDATE_CONVERSATION, conversation);
}, },
toggleTyping: async ({ commit }, { status, conversationId }) => {
try {
commit(types.default.SET_AGENT_TYPING, { status });
await ConversationApi.toggleTyping({ status, conversationId });
} catch (error) {
// Handle error
}
},
markSeen: async ({ commit }, data) => {
try {
await FBChannel.markSeen(data);
commit(types.default.MARK_SEEN);
} catch (error) {
// Handle error
}
},
markMessagesRead: async ({ commit }, data) => { markMessagesRead: async ({ commit }, data) => {
setTimeout(() => { setTimeout(() => {
commit(types.default.MARK_MESSAGE_READ, data); commit(types.default.MARK_MESSAGE_READ, data);
@ -236,15 +217,6 @@ const actions = {
// //
} }
}, },
getConversationStats: async ({ commit }, params) => {
try {
const response = await ConversationApi.meta(params);
commit(types.default.SET_CONV_TAB_META, response.data.meta);
} catch (error) {
// Ignore error
}
},
}; };
export default actions; export default actions;

View file

@ -52,7 +52,6 @@ const getters = {
}, },
getChatStatusFilter: ({ chatStatusFilter }) => chatStatusFilter, getChatStatusFilter: ({ chatStatusFilter }) => chatStatusFilter,
getSelectedInbox: ({ currentInbox }) => currentInbox, getSelectedInbox: ({ currentInbox }) => currentInbox,
getConvTabStats: ({ convTabStats }) => convTabStats,
getNextChatConversation: _state => { getNextChatConversation: _state => {
const { selectedChat } = _state; const { selectedChat } = _state;
const conversations = getters.getAllStatusChats(_state); const conversations = getters.getAllStatusChats(_state);

View file

@ -12,16 +12,10 @@ const initialSelectedChat = {
status: null, status: null,
muted: false, muted: false,
seen: false, seen: false,
agentTyping: 'off',
dataFetched: false, dataFetched: false,
}; };
const state = { const state = {
allConversations: [], allConversations: [],
convTabStats: {
mineCount: 0,
unAssignedCount: 0,
allCount: 0,
},
selectedChat: { ...initialSelectedChat }, selectedChat: { ...initialSelectedChat },
listLoadingStatus: true, listLoadingStatus: true,
chatStatusFilter: wootConstants.STATUS_TYPE.OPEN, chatStatusFilter: wootConstants.STATUS_TYPE.OPEN,
@ -57,7 +51,6 @@ const mutations = {
}, },
[types.default.CLEAR_CURRENT_CHAT_WINDOW](_state) { [types.default.CLEAR_CURRENT_CHAT_WINDOW](_state) {
_state.selectedChat.id = null; _state.selectedChat.id = null;
_state.selectedChat.agentTyping = 'off';
}, },
[types.default.SET_PREVIOUS_CONVERSATIONS](_state, { id, data }) { [types.default.SET_PREVIOUS_CONVERSATIONS](_state, { id, data }) {
@ -67,19 +60,6 @@ const mutations = {
} }
}, },
[types.default.SET_CONV_TAB_META](
_state,
{
mine_count: mineCount,
unassigned_count: unAssignedCount,
all_count: allCount,
} = {}
) {
Vue.set(_state.convTabStats, 'mineCount', mineCount);
Vue.set(_state.convTabStats, 'allCount', allCount);
Vue.set(_state.convTabStats, 'unAssignedCount', unAssignedCount);
},
[types.default.CURRENT_CHAT_WINDOW](_state, activeChat) { [types.default.CURRENT_CHAT_WINDOW](_state, activeChat) {
if (activeChat) { if (activeChat) {
Object.assign(_state.selectedChat, activeChat); Object.assign(_state.selectedChat, activeChat);
@ -176,10 +156,6 @@ const mutations = {
_state.selectedChat.seen = true; _state.selectedChat.seen = true;
}, },
[types.default.SET_AGENT_TYPING](_state, { status }) {
_state.selectedChat.agentTyping = status;
},
[types.default.SET_LIST_LOADING_STATUS](_state) { [types.default.SET_LIST_LOADING_STATUS](_state) {
_state.listLoadingStatus = true; _state.listLoadingStatus = true;
}, },

View file

@ -1,5 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import actions from '../actions'; import { actions } from '../../conversationStats';
import * as types from '../../../mutation-types'; import * as types from '../../../mutation-types';
const commit = jest.fn(); const commit = jest.fn();
@ -7,10 +7,10 @@ global.axios = axios;
jest.mock('axios'); jest.mock('axios');
describe('#actions', () => { describe('#actions', () => {
describe('#getConversationStats', () => { describe('#get', () => {
it('sends correct actions if API is success', async () => { it('sends correct mutations if API is success', async () => {
axios.get.mockResolvedValue({ data: { meta: { mine_count: 1 } } }); axios.get.mockResolvedValue({ data: { meta: { mine_count: 1 } } });
await actions.getConversationStats( await actions.get(
{ commit }, { commit },
{ inboxId: 1, assigneeTpe: 'me', status: 'open' } { inboxId: 1, assigneeTpe: 'me', status: 'open' }
); );
@ -20,11 +20,26 @@ describe('#actions', () => {
}); });
it('sends correct actions if API is error', async () => { it('sends correct actions if API is error', async () => {
axios.get.mockRejectedValue({ message: 'Incorrect header' }); axios.get.mockRejectedValue({ message: 'Incorrect header' });
await actions.getConversationStats( await actions.get(
{ commit }, { commit },
{ inboxId: 1, assigneeTpe: 'me', status: 'open' } { inboxId: 1, assigneeTpe: 'me', status: 'open' }
); );
expect(commit.mock.calls).toEqual([]); expect(commit.mock.calls).toEqual([]);
}); });
}); });
describe('#set', () => {
it('sends correct mutations', async () => {
actions.set(
{ commit },
{ mine_count: 1, unassigned_count: 1, all_count: 2 }
);
expect(commit.mock.calls).toEqual([
[
types.default.SET_CONV_TAB_META,
{ mine_count: 1, unassigned_count: 1, all_count: 2 },
],
]);
});
});
}); });

View file

@ -0,0 +1,16 @@
import { getters } from '../../conversationStats';
describe('#getters', () => {
it('getCurrentPage', () => {
const state = {
mineCount: 1,
unAssignedCount: 1,
allCount: 2,
};
expect(getters.getStats(state)).toEqual({
mineCount: 1,
unAssignedCount: 1,
allCount: 2,
});
});
});

View file

@ -0,0 +1,20 @@
import types from '../../../mutation-types';
import { mutations } from '../../conversationStats';
describe('#mutations', () => {
describe('#SET_CONV_TAB_META', () => {
it('set conversation stats correctly', () => {
const state = {};
mutations[types.SET_CONV_TAB_META](state, {
mine_count: 1,
unassigned_count: 1,
all_count: 2,
});
expect(state).toEqual({
mineCount: 1,
unAssignedCount: 1,
allCount: 2,
});
});
});
});

View file

@ -32,7 +32,6 @@ export default {
ADD_MESSAGE: 'ADD_MESSAGE', ADD_MESSAGE: 'ADD_MESSAGE',
MARK_SEEN: 'MARK_SEEN', MARK_SEEN: 'MARK_SEEN',
MARK_MESSAGE_READ: 'MARK_MESSAGE_READ', MARK_MESSAGE_READ: 'MARK_MESSAGE_READ',
SET_AGENT_TYPING: 'SET_AGENT_TYPING',
SET_PREVIOUS_CONVERSATIONS: 'SET_PREVIOUS_CONVERSATIONS', SET_PREVIOUS_CONVERSATIONS: 'SET_PREVIOUS_CONVERSATIONS',
SET_ACTIVE_INBOX: 'SET_ACTIVE_INBOX', SET_ACTIVE_INBOX: 'SET_ACTIVE_INBOX',