diff --git a/app/javascript/dashboard/composables/spec/useMacros.spec.js b/app/javascript/dashboard/composables/spec/useMacros.spec.js new file mode 100644 index 000000000..d268547a5 --- /dev/null +++ b/app/javascript/dashboard/composables/spec/useMacros.spec.js @@ -0,0 +1,175 @@ +import { describe, it, expect, vi } from 'vitest'; +import { useMacros } from '../useMacros'; +import { useStoreGetters } from 'dashboard/composables/store'; +import { PRIORITY_CONDITION_VALUES } from 'dashboard/helper/automationHelper.js'; + +vi.mock('dashboard/composables/store'); +vi.mock('dashboard/helper/automationHelper.js'); + +describe('useMacros', () => { + const mockLabels = [ + { + id: 6, + title: 'sales', + description: 'sales team', + color: '#8EA20F', + show_on_sidebar: true, + }, + { + id: 2, + title: 'billing', + description: 'billing', + color: '#4077DA', + show_on_sidebar: true, + }, + { + id: 1, + title: 'snoozed', + description: 'Items marked for later', + color: '#D12F42', + show_on_sidebar: true, + }, + { + id: 5, + title: 'mobile-app', + description: 'tech team', + color: '#2DB1CC', + show_on_sidebar: true, + }, + { + id: 14, + title: 'human-resources-department-with-long-title', + description: 'Test', + color: '#FF6E09', + show_on_sidebar: true, + }, + { + id: 22, + title: 'priority', + description: 'For important sales leads', + color: '#7E7CED', + show_on_sidebar: true, + }, + ]; + const mockTeams = [ + { + id: 1, + name: '⚙️ sales team', + description: 'This is our internal sales team', + allow_auto_assign: true, + account_id: 1, + is_member: true, + }, + { + id: 2, + name: '🤷♂️ fayaz', + description: 'Test', + allow_auto_assign: true, + account_id: 1, + is_member: true, + }, + { + id: 3, + name: '🇮🇳 apac sales', + description: 'Sales team for France Territory', + allow_auto_assign: true, + account_id: 1, + is_member: true, + }, + ]; + const mockAgents = [ + { + id: 1, + account_id: 1, + availability_status: 'offline', + auto_offline: true, + confirmed: true, + email: 'john@doe.com', + available_name: 'John Doe', + name: 'John Doe', + role: 'agent', + thumbnail: 'https://example.com/image.png', + }, + { + id: 9, + account_id: 1, + availability_status: 'offline', + auto_offline: true, + confirmed: true, + email: 'clark@kent.com', + available_name: 'Clark Kent', + name: 'Clark Kent', + role: 'agent', + thumbnail: '', + }, + ]; + + beforeEach(() => { + useStoreGetters.mockReturnValue({ + 'labels/getLabels': { value: mockLabels }, + 'teams/getTeams': { value: mockTeams }, + 'agents/getAgents': { value: mockAgents }, + }); + }); + + it('initializes computed properties correctly', () => { + const { getMacroDropdownValues } = useMacros(); + expect(getMacroDropdownValues('add_label')).toHaveLength(mockLabels.length); + expect(getMacroDropdownValues('assign_team')).toHaveLength( + mockTeams.length + ); + expect(getMacroDropdownValues('assign_agent')).toHaveLength( + mockAgents.length + 1 + ); // +1 for "Self" + }); + + it('returns teams for assign_team and send_email_to_team types', () => { + const { getMacroDropdownValues } = useMacros(); + expect(getMacroDropdownValues('assign_team')).toEqual(mockTeams); + expect(getMacroDropdownValues('send_email_to_team')).toEqual(mockTeams); + }); + + it('returns agents with "Self" option for assign_agent type', () => { + const { getMacroDropdownValues } = useMacros(); + const result = getMacroDropdownValues('assign_agent'); + expect(result[0]).toEqual({ id: 'self', name: 'Self' }); + expect(result.slice(1)).toEqual(mockAgents); + }); + + it('returns formatted labels for add_label and remove_label types', () => { + const { getMacroDropdownValues } = useMacros(); + const expectedLabels = mockLabels.map(i => ({ + id: i.title, + name: i.title, + })); + expect(getMacroDropdownValues('add_label')).toEqual(expectedLabels); + expect(getMacroDropdownValues('remove_label')).toEqual(expectedLabels); + }); + + it('returns PRIORITY_CONDITION_VALUES for change_priority type', () => { + const { getMacroDropdownValues } = useMacros(); + expect(getMacroDropdownValues('change_priority')).toEqual( + PRIORITY_CONDITION_VALUES + ); + }); + + it('returns an empty array for unknown types', () => { + const { getMacroDropdownValues } = useMacros(); + expect(getMacroDropdownValues('unknown_type')).toEqual([]); + }); + + it('handles empty data correctly', () => { + useStoreGetters.mockReturnValue({ + 'labels/getLabels': { value: [] }, + 'teams/getTeams': { value: [] }, + 'agents/getAgents': { value: [] }, + }); + + const { getMacroDropdownValues } = useMacros(); + expect(getMacroDropdownValues('add_label')).toEqual([]); + expect(getMacroDropdownValues('assign_team')).toEqual([]); + expect(getMacroDropdownValues('assign_agent')).toEqual([ + { id: 'self', name: 'Self' }, + ]); + }); +}); diff --git a/app/javascript/dashboard/composables/useMacros.js b/app/javascript/dashboard/composables/useMacros.js new file mode 100644 index 000000000..6967331ea --- /dev/null +++ b/app/javascript/dashboard/composables/useMacros.js @@ -0,0 +1,44 @@ +import { computed } from 'vue'; +import { useStoreGetters } from 'dashboard/composables/store'; +import { PRIORITY_CONDITION_VALUES } from 'dashboard/helper/automationHelper.js'; + +/** + * Composable for handling macro-related functionality + * @returns {Object} An object containing the getMacroDropdownValues function + */ +export const useMacros = () => { + const getters = useStoreGetters(); + + const labels = computed(() => getters['labels/getLabels'].value); + const teams = computed(() => getters['teams/getTeams'].value); + const agents = computed(() => getters['agents/getAgents'].value); + + /** + * Get dropdown values based on the specified type + * @param {string} type - The type of dropdown values to retrieve + * @returns {Array} An array of dropdown values + */ + const getMacroDropdownValues = type => { + switch (type) { + case 'assign_team': + case 'send_email_to_team': + return teams.value; + case 'assign_agent': + return [{ id: 'self', name: 'Self' }, ...agents.value]; + case 'add_label': + case 'remove_label': + return labels.value.map(i => ({ + id: i.title, + name: i.title, + })); + case 'change_priority': + return PRIORITY_CONDITION_VALUES; + default: + return []; + } + }; + + return { + getMacroDropdownValues, + }; +}; diff --git a/app/javascript/dashboard/mixins/macrosMixin.js b/app/javascript/dashboard/mixins/macrosMixin.js deleted file mode 100644 index 4aea89227..000000000 --- a/app/javascript/dashboard/mixins/macrosMixin.js +++ /dev/null @@ -1,34 +0,0 @@ -import { mapGetters } from 'vuex'; -import { PRIORITY_CONDITION_VALUES } from 'dashboard/helper/automationHelper.js'; -export default { - computed: { - ...mapGetters({ - labels: 'labels/getLabels', - teams: 'teams/getTeams', - agents: 'agents/getAgents', - }), - }, - methods: { - getDropdownValues(type) { - switch (type) { - case 'assign_team': - case 'send_email_to_team': - return this.teams; - case 'assign_agent': - return [{ id: 'self', name: 'Self' }, ...this.agents]; - case 'add_label': - case 'remove_label': - return this.labels.map(i => { - return { - id: i.title, - name: i.title, - }; - }); - case 'change_priority': - return PRIORITY_CONDITION_VALUES; - default: - return []; - } - }, - }, -}; diff --git a/app/javascript/dashboard/mixins/specs/macros.spec.js b/app/javascript/dashboard/mixins/specs/macros.spec.js deleted file mode 100644 index a8b3ee2b1..000000000 --- a/app/javascript/dashboard/mixins/specs/macros.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import { createWrapper } from '@vue/test-utils'; -import macrosMixin from '../macrosMixin'; -import Vue from 'vue'; -import { teams, labels, agents } from '../../helper/specs/macrosFixtures'; -import { PRIORITY_CONDITION_VALUES } from 'dashboard/helper/automationHelper.js'; -describe('webhookMixin', () => { - describe('#getEventLabel', () => { - it('returns correct i18n translation:', () => { - const Component = { - render() {}, - title: 'MyComponent', - mixins: [macrosMixin], - data: () => { - return { - teams, - labels, - agents, - }; - }, - methods: { - $t(text) { - return text; - }, - }, - }; - - const resolvedLabels = labels.map(i => { - return { - id: i.title, - name: i.title, - }; - }); - - const Constructor = Vue.extend(Component); - const vm = new Constructor().$mount(); - const wrapper = createWrapper(vm); - expect(wrapper.vm.getDropdownValues('assign_team')).toEqual(teams); - expect(wrapper.vm.getDropdownValues('send_email_to_team')).toEqual(teams); - expect(wrapper.vm.getDropdownValues('add_label')).toEqual(resolvedLabels); - expect(wrapper.vm.getDropdownValues('assign_agent')).toEqual([ - { id: 'self', name: 'Self' }, - ...agents, - ]); - expect(wrapper.vm.getDropdownValues('change_priority')).toEqual( - PRIORITY_CONDITION_VALUES - ); - expect(wrapper.vm.getDropdownValues()).toEqual([]); - }); - }); -}); diff --git a/app/javascript/dashboard/routes/dashboard/settings/macros/MacroEditor.vue b/app/javascript/dashboard/routes/dashboard/settings/macros/MacroEditor.vue index 1b02ba2e5..f29d822ff 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/macros/MacroEditor.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/macros/MacroEditor.vue @@ -1,126 +1,123 @@ - @@ -128,11 +125,12 @@ export default {