diff --git a/app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue b/app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue index d6d5bbd85..bb700a86c 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ConversationBox.vue @@ -19,6 +19,7 @@ @@ -59,6 +60,13 @@ export default { return this.isContactPanelOpen && this.currentChat.id; }, }, + watch: { + 'currentChat.inbox_id'(inboxId) { + if (inboxId) { + this.$store.dispatch('inboxMembers/fetch', { inboxId }); + } + }, + }, methods: { onToggleContactPanel() { this.$emit('contact-panel-toggle'); diff --git a/app/javascript/dashboard/components/widgets/conversation/ConversationHeader.vue b/app/javascript/dashboard/components/widgets/conversation/ConversationHeader.vue index 228030a45..4d62e8dd9 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ConversationHeader.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ConversationHeader.vue @@ -34,6 +34,7 @@ {}, @@ -135,8 +139,9 @@ export default { computed: { ...mapGetters({ currentChat: 'getSelectedChat', - agents: 'agents/getVerifiedAgents', teams: 'teams/getTeams', + getAgents: 'inboxMembers/getMembersByInbox', + uiFlags: 'inboxMembers/getUIFlags', }), currentConversationMetaData() { return this.$store.getters[ @@ -201,7 +206,7 @@ export default { return this.$store.getters['contacts/getContact'](this.contactId); }, agentsList() { - return [{ id: 0, name: 'None' }, ...this.agents]; + return [{ id: 0, name: 'None' }, ...this.getAgents(this.inboxId)]; }, teamsList() { return [{ id: 0, name: 'None' }, ...this.teams]; diff --git a/app/javascript/dashboard/store/modules/inboxMembers.js b/app/javascript/dashboard/store/modules/inboxMembers.js index 4661e0f78..071def998 100644 --- a/app/javascript/dashboard/store/modules/inboxMembers.js +++ b/app/javascript/dashboard/store/modules/inboxMembers.js @@ -1,10 +1,44 @@ +import Vue from 'vue'; + import InboxMembersAPI from '../../api/inboxMembers'; -const state = {}; +const state = { + records: {}, + uiFlags: { + isFetching: false, + }, +}; -const getters = {}; +export const types = { + SET_INBOX_MEMBERS_UI_FLAG: 'SET_INBOX_MEMBERS_UI_FLAG', + SET_INBOX_MEMBERS: 'SET_INBOX_MEMBERS', +}; -const actions = { +export const getters = { + getMembersByInbox: $state => inboxId => { + const allAgents = $state.records[inboxId] || []; + const verifiedAgents = allAgents.filter(record => record.confirmed); + return verifiedAgents; + }, + getUIFlags($state) { + return $state.uiFlags; + }, +}; + +export const actions = { + async fetch({ commit }, { inboxId }) { + commit(types.SET_INBOX_MEMBERS_UI_FLAG, { isFetching: true }); + try { + const { + data: { payload }, + } = await InboxMembersAPI.show(inboxId); + commit(types.SET_INBOX_MEMBERS, { inboxId, members: payload }); + } catch (error) { + throw new Error(error); + } finally { + commit(types.SET_INBOX_MEMBERS_UI_FLAG, { isFetching: false }); + } + }, get(_, { inboxId }) { return InboxMembersAPI.show(inboxId); }, @@ -13,7 +47,17 @@ const actions = { }, }; -const mutations = {}; +export const mutations = { + [types.SET_INBOX_MEMBERS_UI_FLAG]($state, data) { + $state.uiFlags = { + ...$state.uiFlags, + ...data, + }; + }, + [types.SET_INBOX_MEMBERS]: ($state, { inboxId, members }) => { + Vue.set($state.records, inboxId, members); + }, +}; export default { namespaced: true, diff --git a/app/javascript/dashboard/store/modules/specs/inboxMembers/actions.spec.js b/app/javascript/dashboard/store/modules/specs/inboxMembers/actions.spec.js new file mode 100644 index 000000000..af2b63cd2 --- /dev/null +++ b/app/javascript/dashboard/store/modules/specs/inboxMembers/actions.spec.js @@ -0,0 +1,31 @@ +import axios from 'axios'; +import { actions, types } from '../../inboxMembers'; +import inboxMembers from './fixtures'; + +const commit = jest.fn(); +global.axios = axios; +jest.mock('axios'); + +describe('#actions', () => { + describe('#fetch', () => { + it('sends correct actions if API is success', async () => { + axios.get.mockResolvedValue({ data: { payload: inboxMembers } }); + await actions.fetch({ commit }, { inboxId: 1 }); + expect(commit.mock.calls).toEqual([ + [types.SET_INBOX_MEMBERS_UI_FLAG, { isFetching: true }], + [types.SET_INBOX_MEMBERS, { inboxId: 1, members: inboxMembers }], + [types.SET_INBOX_MEMBERS_UI_FLAG, { isFetching: false }], + ]); + }); + it('sends correct actions if API is error', async () => { + axios.get.mockRejectedValue({ message: 'Incorrect header' }); + await expect(actions.fetch({ commit }, { inboxId: 1 })).rejects.toThrow( + Error + ); + expect(commit.mock.calls).toEqual([ + [types.SET_INBOX_MEMBERS_UI_FLAG, { isFetching: true }], + [types.SET_INBOX_MEMBERS_UI_FLAG, { isFetching: false }], + ]); + }); + }); +}); diff --git a/app/javascript/dashboard/store/modules/specs/inboxMembers/fixtures.js b/app/javascript/dashboard/store/modules/specs/inboxMembers/fixtures.js new file mode 100644 index 000000000..c7b968e33 --- /dev/null +++ b/app/javascript/dashboard/store/modules/specs/inboxMembers/fixtures.js @@ -0,0 +1,28 @@ +export default [ + { + id: 1, + provider: 'email', + uid: 'agent1@chatwoot.com', + name: 'Agent1', + email: 'agent1@chatwoot.com', + account_id: 1, + created_at: '2019-11-18T02:21:06.225Z', + updated_at: '2019-12-20T07:43:35.794Z', + pubsub_token: 'random-1', + role: 'agent', + confirmed: true, + }, + { + id: 2, + provider: 'email', + uid: 'agent2@chatwoot.com', + name: 'Agent2', + email: 'agent2@chatwoot.com', + account_id: 1, + created_at: '2019-11-18T02:21:06.225Z', + updated_at: '2019-12-20T07:43:35.794Z', + pubsub_token: 'random-2', + role: 'agent', + confirmed: true, + }, +]; diff --git a/app/javascript/dashboard/store/modules/specs/inboxMembers/getters.spec.js b/app/javascript/dashboard/store/modules/specs/inboxMembers/getters.spec.js new file mode 100644 index 000000000..9b83c548e --- /dev/null +++ b/app/javascript/dashboard/store/modules/specs/inboxMembers/getters.spec.js @@ -0,0 +1,24 @@ +import { getters } from '../../teamMembers'; +import teamMembers from './fixtures'; + +describe('#getters', () => { + it('getMembersByInbox', () => { + const state = { + records: { + 1: [teamMembers[0]], + }, + }; + expect(getters.getTeamMembers(state)(1)).toEqual([teamMembers[0]]); + }); + + it('getUIFlags', () => { + const state = { + uiFlags: { + isFetching: false, + }, + }; + expect(getters.getUIFlags(state)).toEqual({ + isFetching: false, + }); + }); +}); diff --git a/app/javascript/dashboard/store/modules/specs/inboxMembers/mutations.spec.js b/app/javascript/dashboard/store/modules/specs/inboxMembers/mutations.spec.js new file mode 100644 index 000000000..11d59ef93 --- /dev/null +++ b/app/javascript/dashboard/store/modules/specs/inboxMembers/mutations.spec.js @@ -0,0 +1,16 @@ +import { mutations, types } from '../../inboxMembers'; +import inboxMembers from './fixtures'; + +describe('#mutations', () => { + describe('#SET_INBOX_MEMBERS', () => { + it('Adds inbox members to records', () => { + const state = { records: {} }; + mutations[types.SET_INBOX_MEMBERS](state, { + members: [...inboxMembers], + inboxId: 1, + }); + + expect(state.records).toEqual({ 1: inboxMembers }); + }); + }); +});