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:
parent
5ec9af9325
commit
5cb88237f5
16 changed files with 139 additions and 98 deletions
|
@ -6,20 +6,6 @@ class FBChannel extends ApiClient {
|
|||
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) {
|
||||
return axios.post(
|
||||
`${this.url.replace(this.resource, '')}callbacks/register_facebook_page`,
|
||||
|
|
|
@ -9,7 +9,5 @@ describe('#FBChannel', () => {
|
|||
expect(fbChannel).toHaveProperty('create');
|
||||
expect(fbChannel).toHaveProperty('update');
|
||||
expect(fbChannel).toHaveProperty('delete');
|
||||
expect(fbChannel).toHaveProperty('markSeen');
|
||||
expect(fbChannel).toHaveProperty('toggleTyping');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import agents from '../contacts';
|
||||
import contacts from '../contacts';
|
||||
import ApiClient from '../ApiClient';
|
||||
|
||||
describe('#ContactsAPI', () => {
|
||||
it('creates correct instance', () => {
|
||||
expect(agents).toBeInstanceOf(ApiClient);
|
||||
expect(agents).toHaveProperty('get');
|
||||
expect(agents).toHaveProperty('show');
|
||||
expect(agents).toHaveProperty('create');
|
||||
expect(agents).toHaveProperty('update');
|
||||
expect(agents).toHaveProperty('delete');
|
||||
expect(agents).toHaveProperty('getConversations');
|
||||
expect(contacts).toBeInstanceOf(ApiClient);
|
||||
expect(contacts).toHaveProperty('get');
|
||||
expect(contacts).toHaveProperty('show');
|
||||
expect(contacts).toHaveProperty('create');
|
||||
expect(contacts).toHaveProperty('update');
|
||||
expect(contacts).toHaveProperty('delete');
|
||||
expect(contacts).toHaveProperty('getConversations');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -88,14 +88,17 @@ export default {
|
|||
chatListLoading: 'getChatListLoadingStatus',
|
||||
currentUserID: 'getCurrentUserID',
|
||||
activeInbox: 'getSelectedInbox',
|
||||
convStats: 'getConvTabStats',
|
||||
conversationStats: 'conversationStats/getStats',
|
||||
}),
|
||||
assigneeTabItems() {
|
||||
return this.$t('CHAT_LIST.ASSIGNEE_TYPE_TABS').map(item => ({
|
||||
key: item.KEY,
|
||||
name: item.NAME,
|
||||
count: this.convStats[item.COUNT_KEY] || 0,
|
||||
}));
|
||||
return this.$t('CHAT_LIST.ASSIGNEE_TYPE_TABS').map(item => {
|
||||
const count = this.conversationStats[item.COUNT_KEY] || 0;
|
||||
return {
|
||||
key: item.KEY,
|
||||
name: item.NAME,
|
||||
count,
|
||||
};
|
||||
});
|
||||
},
|
||||
inbox() {
|
||||
return this.$store.getters['inboxes/getInbox'](this.activeInbox);
|
||||
|
@ -130,7 +133,7 @@ export default {
|
|||
this.$store.dispatch('agents/get');
|
||||
|
||||
bus.$on('fetch_conversation_stats', () => {
|
||||
this.$store.dispatch('getConversationStats', this.conversationFilters);
|
||||
this.$store.dispatch('conversationStats/get', this.conversationFilters);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -22,11 +22,6 @@ export default {
|
|||
default: wootConstants.ASSIGNEE_TYPE.ME,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabsIndex: wootConstants.ASSIGNEE_TYPE.ME,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
activeTabIndex() {
|
||||
return this.items.findIndex(item => item.key === this.activeTab);
|
||||
|
|
|
@ -269,7 +269,7 @@ export default {
|
|||
toggleTyping(status) {
|
||||
if (this.channelType === 'Channel::WebWidget' && !this.isPrivate) {
|
||||
const conversationId = this.currentChat.id;
|
||||
this.$store.dispatch('toggleTyping', {
|
||||
this.$store.dispatch('conversationTypingStatus/toggleTyping', {
|
||||
status,
|
||||
conversationId,
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ import conversationLabels from './modules/conversationLabels';
|
|||
import conversationMetadata from './modules/conversationMetadata';
|
||||
import conversationPage from './modules/conversationPage';
|
||||
import conversations from './modules/conversations';
|
||||
import conversationStats from './modules/conversationStats';
|
||||
import conversationTypingStatus from './modules/conversationTypingStatus';
|
||||
import globalConfig from 'shared/store/globalConfig';
|
||||
import inboxes from './modules/inboxes';
|
||||
|
@ -33,6 +34,7 @@ export default new Vuex.Store({
|
|||
conversationLabels,
|
||||
conversationMetadata,
|
||||
conversationPage,
|
||||
conversationStats,
|
||||
conversations,
|
||||
conversationTypingStatus,
|
||||
globalConfig,
|
||||
|
|
53
app/javascript/dashboard/store/modules/conversationStats.js
Normal file
53
app/javascript/dashboard/store/modules/conversationStats.js
Normal 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,
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import * as types from '../mutation-types';
|
||||
|
||||
import ConversationAPI from '../../api/inbox/conversation';
|
||||
const state = {
|
||||
records: {},
|
||||
};
|
||||
|
@ -12,6 +12,13 @@ export const getters = {
|
|||
};
|
||||
|
||||
export const actions = {
|
||||
toggleTyping: async (_, { status, conversationId }) => {
|
||||
try {
|
||||
await ConversationAPI.toggleTyping({ status, conversationId });
|
||||
} catch (error) {
|
||||
// Handle error
|
||||
}
|
||||
},
|
||||
create: ({ commit }, { conversationId, user }) => {
|
||||
commit(types.default.ADD_USER_TYPING_TO_CONVERSATION, {
|
||||
conversationId,
|
||||
|
|
|
@ -2,7 +2,6 @@ import Vue from 'vue';
|
|||
import * as types from '../../mutation-types';
|
||||
import ConversationApi from '../../../api/inbox/conversation';
|
||||
import MessageApi from '../../../api/inbox/message';
|
||||
import FBChannel from '../../../api/channel/fbChannel';
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
|
@ -26,7 +25,7 @@ const actions = {
|
|||
const { data } = response.data;
|
||||
const { payload: chatList, meta: metaData } = data;
|
||||
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(
|
||||
`contacts/${types.default.SET_CONTACTS}`,
|
||||
|
@ -171,24 +170,6 @@ const actions = {
|
|||
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) => {
|
||||
setTimeout(() => {
|
||||
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;
|
||||
|
|
|
@ -52,7 +52,6 @@ const getters = {
|
|||
},
|
||||
getChatStatusFilter: ({ chatStatusFilter }) => chatStatusFilter,
|
||||
getSelectedInbox: ({ currentInbox }) => currentInbox,
|
||||
getConvTabStats: ({ convTabStats }) => convTabStats,
|
||||
getNextChatConversation: _state => {
|
||||
const { selectedChat } = _state;
|
||||
const conversations = getters.getAllStatusChats(_state);
|
||||
|
|
|
@ -12,16 +12,10 @@ const initialSelectedChat = {
|
|||
status: null,
|
||||
muted: false,
|
||||
seen: false,
|
||||
agentTyping: 'off',
|
||||
dataFetched: false,
|
||||
};
|
||||
const state = {
|
||||
allConversations: [],
|
||||
convTabStats: {
|
||||
mineCount: 0,
|
||||
unAssignedCount: 0,
|
||||
allCount: 0,
|
||||
},
|
||||
selectedChat: { ...initialSelectedChat },
|
||||
listLoadingStatus: true,
|
||||
chatStatusFilter: wootConstants.STATUS_TYPE.OPEN,
|
||||
|
@ -57,7 +51,6 @@ const mutations = {
|
|||
},
|
||||
[types.default.CLEAR_CURRENT_CHAT_WINDOW](_state) {
|
||||
_state.selectedChat.id = null;
|
||||
_state.selectedChat.agentTyping = 'off';
|
||||
},
|
||||
|
||||
[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) {
|
||||
if (activeChat) {
|
||||
Object.assign(_state.selectedChat, activeChat);
|
||||
|
@ -176,10 +156,6 @@ const mutations = {
|
|||
_state.selectedChat.seen = true;
|
||||
},
|
||||
|
||||
[types.default.SET_AGENT_TYPING](_state, { status }) {
|
||||
_state.selectedChat.agentTyping = status;
|
||||
},
|
||||
|
||||
[types.default.SET_LIST_LOADING_STATUS](_state) {
|
||||
_state.listLoadingStatus = true;
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import axios from 'axios';
|
||||
import actions from '../actions';
|
||||
import { actions } from '../../conversationStats';
|
||||
import * as types from '../../../mutation-types';
|
||||
|
||||
const commit = jest.fn();
|
||||
|
@ -7,10 +7,10 @@ global.axios = axios;
|
|||
jest.mock('axios');
|
||||
|
||||
describe('#actions', () => {
|
||||
describe('#getConversationStats', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
describe('#get', () => {
|
||||
it('sends correct mutations if API is success', async () => {
|
||||
axios.get.mockResolvedValue({ data: { meta: { mine_count: 1 } } });
|
||||
await actions.getConversationStats(
|
||||
await actions.get(
|
||||
{ commit },
|
||||
{ inboxId: 1, assigneeTpe: 'me', status: 'open' }
|
||||
);
|
||||
|
@ -20,11 +20,26 @@ describe('#actions', () => {
|
|||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.get.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await actions.getConversationStats(
|
||||
await actions.get(
|
||||
{ commit },
|
||||
{ inboxId: 1, assigneeTpe: 'me', status: 'open' }
|
||||
);
|
||||
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 },
|
||||
],
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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,
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -32,7 +32,6 @@ export default {
|
|||
ADD_MESSAGE: 'ADD_MESSAGE',
|
||||
MARK_SEEN: 'MARK_SEEN',
|
||||
MARK_MESSAGE_READ: 'MARK_MESSAGE_READ',
|
||||
SET_AGENT_TYPING: 'SET_AGENT_TYPING',
|
||||
SET_PREVIOUS_CONVERSATIONS: 'SET_PREVIOUS_CONVERSATIONS',
|
||||
SET_ACTIVE_INBOX: 'SET_ACTIVE_INBOX',
|
||||
|
||||
|
|
Loading…
Reference in a new issue