fix: Update the relevant agent presence only (#5220)
This commit is contained in:
parent
cbcee6414c
commit
657bd44418
11 changed files with 100 additions and 62 deletions
|
@ -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',
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -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',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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 },
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue