fix: Update the relevant agent presence only (#5220)

This commit is contained in:
Pranav Raj S 2022-08-09 12:32:09 +05:30 committed by GitHub
parent cbcee6414c
commit 657bd44418
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 100 additions and 62 deletions

View file

@ -41,7 +41,7 @@
:header="this.$t('OVERVIEW_REPORTS.AGENT_CONVERSATIONS.HEADER')" :header="this.$t('OVERVIEW_REPORTS.AGENT_CONVERSATIONS.HEADER')"
> >
<agent-table <agent-table
:total-agents="agentsCount" :agents="agents"
:agent-metrics="agentConversationMetric" :agent-metrics="agentConversationMetric"
:page-index="pageIndex" :page-index="pageIndex"
:is-loading="uiFlags.isFetchingAgentConversationMetric" :is-loading="uiFlags.isFetchingAgentConversationMetric"
@ -70,7 +70,7 @@ export default {
computed: { computed: {
...mapGetters({ ...mapGetters({
agentStatus: 'agents/getAgentStatus', agentStatus: 'agents/getAgentStatus',
agentsCount: 'agents/getAgentsCount', agents: 'agents/getAgents',
accountConversationMetric: 'getAccountConversationMetric', accountConversationMetric: 'getAccountConversationMetric',
agentConversationMetric: 'getAgentConversationMetric', agentConversationMetric: 'getAgentConversationMetric',
uiFlags: 'getOverviewUIFlags', uiFlags: 'getOverviewUIFlags',

View file

@ -18,7 +18,7 @@
/> />
<div v-if="agentMetrics.length > 0" class="table-pagination"> <div v-if="agentMetrics.length > 0" class="table-pagination">
<ve-pagination <ve-pagination
:total="totalAgents" :total="agents.length"
:page-index="pageIndex" :page-index="pageIndex"
:page-size="25" :page-size="25"
:page-size-option="[25]" :page-size-option="[25]"
@ -43,9 +43,9 @@ export default {
VePagination, VePagination,
}, },
props: { props: {
totalAgents: { agents: {
type: Number, type: Array,
default: 0, default: () => [],
}, },
agentMetrics: { agentMetrics: {
type: Array, type: Array,
@ -60,19 +60,17 @@ export default {
default: 1, default: 1,
}, },
}, },
data() {
return {};
},
computed: { computed: {
tableData() { tableData() {
return this.agentMetrics.map(agent => { return this.agentMetrics.map(agent => {
const agentInformation = this.getAgentInformation(agent.id);
return { return {
agent: agent.name, agent: agentInformation.name,
email: agent.email, email: agentInformation.email,
thumbnail: agent.thumbnail, thumbnail: agentInformation.thumbnail,
open: agent.metric.open || 0, open: agent.metric.open || 0,
unattended: agent.metric.unattended || 0, unattended: agent.metric.unattended || 0,
status: agent.availability, status: agentInformation.availability_status,
}; };
}); });
}, },
@ -123,11 +121,13 @@ export default {
]; ];
}, },
}, },
mounted() {},
methods: { methods: {
onPageNumberChange(pageIndex) { onPageNumberChange(pageIndex) {
this.$emit('page-change', pageIndex); this.$emit('page-change', pageIndex);
}, },
getAgentInformation(id) {
return this.agents.find(agent => agent.id === Number(id));
},
}, },
}; };
</script> </script>

View file

@ -35,9 +35,6 @@ export const getters = {
}; };
return status; return status;
}, },
getAgentsCount($state) {
return $state.records.length;
},
}; };
export const actions = { export const actions = {
@ -73,14 +70,15 @@ export const actions = {
throw new Error(error); throw new Error(error);
} }
}, },
updateSingleAgentPresence: ({ commit }, { id, availabilityStatus }) => {
updatePresence: async ({ commit, dispatch }, data) => { commit(types.default.UPDATE_SINGLE_AGENT_PRESENCE, {
commit(types.default.SET_AGENT_UPDATING_STATUS, true); id,
commit(types.default.UPDATE_AGENTS_PRESENCE, data); availabilityStatus,
dispatch('updateReportAgentStatus', data, { root: true }); });
commit(types.default.SET_AGENT_UPDATING_STATUS, false); },
updatePresence: async ({ commit }, data) => {
commit(types.default.UPDATE_AGENTS_PRESENCE, data);
}, },
delete: async ({ commit }, agentId) => { delete: async ({ commit }, agentId) => {
commit(types.default.SET_AGENT_DELETING_STATUS, true); commit(types.default.SET_AGENT_DELETING_STATUS, true);
try { try {
@ -113,6 +111,14 @@ export const mutations = {
[types.default.EDIT_AGENT]: MutationHelpers.update, [types.default.EDIT_AGENT]: MutationHelpers.update,
[types.default.DELETE_AGENT]: MutationHelpers.destroy, [types.default.DELETE_AGENT]: MutationHelpers.destroy,
[types.default.UPDATE_AGENTS_PRESENCE]: MutationHelpers.updatePresence, [types.default.UPDATE_AGENTS_PRESENCE]: MutationHelpers.updatePresence,
[types.default.UPDATE_SINGLE_AGENT_PRESENCE]: (
$state,
{ id, availabilityStatus }
) =>
MutationHelpers.updateSingleRecordPresence($state.records, {
id,
availabilityStatus,
}),
}; };
export default { export default {

View file

@ -159,7 +159,10 @@ export const actions = {
const userData = response.data; const userData = response.data;
const { id } = userData; const { id } = userData;
commit(types.SET_CURRENT_USER, response.data); commit(types.SET_CURRENT_USER, response.data);
dispatch('agents/updatePresence', { [id]: params.availability }); dispatch('agents/updateSingleAgentPresence', {
id,
availabilityStatus: params.availability,
});
} catch (error) { } catch (error) {
// Ignore error // Ignore error
} }

View file

@ -1,10 +1,6 @@
/* eslint no-console: 0 */ /* eslint no-console: 0 */
/* eslint no-param-reassign: 0 */
/* eslint no-shadow: 0 */
import * as types from '../mutation-types'; import * as types from '../mutation-types';
import Report from '../../api/reports'; import Report from '../../api/reports';
import Vue from 'vue';
import { downloadCsvFile } from '../../helper/downloadHelper'; import { downloadCsvFile } from '../../helper/downloadHelper';
const state = { const state = {
@ -116,9 +112,6 @@ export const actions = {
commit(types.default.TOGGLE_AGENT_CONVERSATION_METRIC_LOADING, false); commit(types.default.TOGGLE_AGENT_CONVERSATION_METRIC_LOADING, false);
}); });
}, },
updateReportAgentStatus({ commit }, data) {
commit(types.default.UPDATE_REPORT_AGENTS_STATUS, data);
},
downloadAgentReports(_, reportObj) { downloadAgentReports(_, reportObj) {
return Report.getAgentReports(reportObj) return Report.getAgentReports(reportObj)
.then(response => { .then(response => {
@ -179,16 +172,6 @@ const mutations = {
[types.default.TOGGLE_AGENT_CONVERSATION_METRIC_LOADING](_state, flag) { [types.default.TOGGLE_AGENT_CONVERSATION_METRIC_LOADING](_state, flag) {
_state.overview.uiFlags.isFetchingAgentConversationMetric = flag; _state.overview.uiFlags.isFetchingAgentConversationMetric = flag;
}, },
[types.default.UPDATE_REPORT_AGENTS_STATUS](_state, data) {
_state.overview.agentConversationMetric.forEach((element, index) => {
const availabilityStatus = data[element.id];
Vue.set(
_state.overview.agentConversationMetric[index],
'availability',
availabilityStatus || 'offline'
);
});
},
}; };
export default { export default {

View file

@ -96,13 +96,21 @@ describe('#actions', () => {
}); });
describe('#updatePresence', () => { describe('#updatePresence', () => {
it('sends correct actions if API is success', async () => { it('sends correct actions', async () => {
const data = { users: { 1: 'online' }, contacts: { 2: 'online' } }; const data = { users: { 1: 'online' }, contacts: { 2: 'online' } };
actions.updatePresence({ commit, dispatch }, data); actions.updatePresence({ commit, dispatch }, data);
expect(commit.mock.calls).toEqual([ expect(commit.mock.calls).toEqual([
[types.default.SET_AGENT_UPDATING_STATUS, true],
[types.default.UPDATE_AGENTS_PRESENCE, data], [types.default.UPDATE_AGENTS_PRESENCE, data],
[types.default.SET_AGENT_UPDATING_STATUS, false], ]);
});
});
describe('#updateSingleAgentPresence', () => {
it('sends correct actions', async () => {
const data = { id: 1, availabilityStatus: 'online' };
actions.updateSingleAgentPresence({ commit, dispatch }, data);
expect(commit.mock.calls).toEqual([
[types.default.UPDATE_SINGLE_AGENT_PRESENCE, data],
]); ]);
}); });
}); });

View file

@ -129,19 +129,4 @@ describe('#getters', () => {
offline: 1, offline: 1,
}); });
}); });
it('getAgentStatus', () => {
const state = {
records: [
{
id: 1,
name: 'Agent 1',
email: 'agent1@chatwoot.com',
confirmed: true,
availability_status: 'online',
},
],
};
expect(getters.getAgentsCount(state)).toEqual(1);
});
}); });

View file

@ -97,4 +97,44 @@ describe('#mutations', () => {
]); ]);
}); });
}); });
describe('#UPDATE_SINGLE_AGENT_PRESENCE', () => {
it('updates single agent presence', () => {
const state = {
records: [
{
id: 1,
name: 'Agent1',
email: 'agent1@chatwoot.com',
availability_status: 'offline',
},
{
id: 2,
name: 'Agent1',
email: 'agent1@chatwoot.com',
availability_status: 'online',
},
],
};
mutations[types.default.UPDATE_SINGLE_AGENT_PRESENCE](state, {
id: 1,
availabilityStatus: 'busy',
});
expect(state.records).toEqual([
{
id: 1,
name: 'Agent1',
email: 'agent1@chatwoot.com',
availability_status: 'busy',
},
{
id: 2,
name: 'Agent1',
email: 'agent1@chatwoot.com',
availability_status: 'online',
},
]);
});
});
}); });

View file

@ -80,7 +80,10 @@ describe('#actions', () => {
], ],
]); ]);
expect(dispatch.mock.calls).toEqual([ expect(dispatch.mock.calls).toEqual([
['agents/updatePresence', { 1: 'offline' }], [
'agents/updateSingleAgentPresence',
{ availabilityStatus: 'offline', id: 1 },
],
]); ]);
}); });
}); });

View file

@ -70,6 +70,7 @@ export default {
EDIT_AGENT: 'EDIT_AGENT', EDIT_AGENT: 'EDIT_AGENT',
DELETE_AGENT: 'DELETE_AGENT', DELETE_AGENT: 'DELETE_AGENT',
UPDATE_AGENTS_PRESENCE: 'UPDATE_AGENTS_PRESENCE', UPDATE_AGENTS_PRESENCE: 'UPDATE_AGENTS_PRESENCE',
UPDATE_SINGLE_AGENT_PRESENCE: 'UPDATE_SINGLE_AGENT_PRESENCE',
// Canned Response // Canned Response
SET_CANNED_UI_FLAG: 'SET_CANNED_UI_FLAG', SET_CANNED_UI_FLAG: 'SET_CANNED_UI_FLAG',
@ -150,7 +151,6 @@ export default {
SET_AGENT_CONVERSATION_METRIC: 'SET_AGENT_CONVERSATION_METRIC', SET_AGENT_CONVERSATION_METRIC: 'SET_AGENT_CONVERSATION_METRIC',
TOGGLE_AGENT_CONVERSATION_METRIC_LOADING: TOGGLE_AGENT_CONVERSATION_METRIC_LOADING:
'TOGGLE_AGENT_CONVERSATION_METRIC_LOADING', 'TOGGLE_AGENT_CONVERSATION_METRIC_LOADING',
UPDATE_REPORT_AGENTS_STATUS: 'UPDATE_AGENTS_STATUS',
// Conversation Metadata // Conversation Metadata
SET_CONVERSATION_METADATA: 'SET_CONVERSATION_METADATA', SET_CONVERSATION_METADATA: 'SET_CONVERSATION_METADATA',

View file

@ -45,6 +45,16 @@ export const updatePresence = (state, data) => {
}); });
}; };
export const updateSingleRecordPresence = (
records,
{ id, availabilityStatus }
) => {
const [selectedRecord] = records.filter(record => record.id === Number(id));
if (selectedRecord) {
Vue.set(selectedRecord, 'availability_status', availabilityStatus);
}
};
export const destroy = (state, id) => { export const destroy = (state, id) => {
state.records = state.records.filter(record => record.id !== id); state.records = state.records.filter(record => record.id !== id);
}; };