mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-30 18:47:51 +00:00 
			
		
		
		
	feat: more events tracking for SaaS (#6234)
This commit is contained in:
		| @@ -43,9 +43,7 @@ import { | |||||||
| import eventListenerMixins from 'shared/mixins/eventListenerMixins'; | import eventListenerMixins from 'shared/mixins/eventListenerMixins'; | ||||||
| import uiSettingsMixin from 'dashboard/mixins/uiSettings'; | import uiSettingsMixin from 'dashboard/mixins/uiSettings'; | ||||||
| import { isEditorHotKeyEnabled } from 'dashboard/mixins/uiSettings'; | import { isEditorHotKeyEnabled } from 'dashboard/mixins/uiSettings'; | ||||||
| import AnalyticsHelper, { | import { CONVERSATION_EVENTS } from '../../../helper/AnalyticsHelper/events'; | ||||||
|   ANALYTICS_EVENTS, |  | ||||||
| } from '../../../helper/AnalyticsHelper'; |  | ||||||
|  |  | ||||||
| const createState = (content, placeholder, plugins = []) => { | const createState = (content, placeholder, plugins = []) => { | ||||||
|   return EditorState.create({ |   return EditorState.create({ | ||||||
| @@ -265,7 +263,7 @@ export default { | |||||||
|       ); |       ); | ||||||
|       this.state = this.editorView.state.apply(tr); |       this.state = this.editorView.state.apply(tr); | ||||||
|       this.emitOnChange(); |       this.emitOnChange(); | ||||||
|       AnalyticsHelper.track(ANALYTICS_EVENTS.USED_MENTIONS); |       this.$track(CONVERSATION_EVENTS.USED_MENTIONS); | ||||||
|  |  | ||||||
|       return false; |       return false; | ||||||
|     }, |     }, | ||||||
| @@ -295,7 +293,7 @@ export default { | |||||||
|       this.emitOnChange(); |       this.emitOnChange(); | ||||||
|  |  | ||||||
|       tr.scrollIntoView(); |       tr.scrollIntoView(); | ||||||
|       AnalyticsHelper.track(ANALYTICS_EVENTS.INSERTED_A_CANNED_RESPONSE); |       this.$track(CONVERSATION_EVENTS.INSERTED_A_CANNED_RESPONSE); | ||||||
|       return false; |       return false; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -164,9 +164,7 @@ import { LocalStorage, LOCAL_STORAGE_KEYS } from '../../../helper/localStorage'; | |||||||
| import { trimContent, debounce } from '@chatwoot/utils'; | import { trimContent, debounce } from '@chatwoot/utils'; | ||||||
| import wootConstants from 'dashboard/constants'; | import wootConstants from 'dashboard/constants'; | ||||||
| import { isEditorHotKeyEnabled } from 'dashboard/mixins/uiSettings'; | import { isEditorHotKeyEnabled } from 'dashboard/mixins/uiSettings'; | ||||||
| import AnalyticsHelper, { | import { CONVERSATION_EVENTS } from '../../../helper/AnalyticsHelper/events'; | ||||||
|   ANALYTICS_EVENTS, |  | ||||||
| } from '../../../helper/AnalyticsHelper'; |  | ||||||
|  |  | ||||||
| const EmojiInput = () => import('shared/components/emoji/EmojiInput'); | const EmojiInput = () => import('shared/components/emoji/EmojiInput'); | ||||||
|  |  | ||||||
| @@ -710,7 +708,7 @@ export default { | |||||||
|     }, |     }, | ||||||
|     replaceText(message) { |     replaceText(message) { | ||||||
|       setTimeout(() => { |       setTimeout(() => { | ||||||
|         AnalyticsHelper.track(ANALYTICS_EVENTS.INSERTED_A_CANNED_RESPONSE); |         this.$track(CONVERSATION_EVENTS.INSERTED_A_CANNED_RESPONSE); | ||||||
|         this.message = message; |         this.message = message; | ||||||
|       }, 100); |       }, 100); | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -1,9 +1,73 @@ | |||||||
| export const EXECUTED_A_MACRO = 'Executed a macro'; | export const CONVERSATION_EVENTS = Object.freeze({ | ||||||
| export const SENT_MESSAGE = 'Sent a message'; |   EXECUTED_A_MACRO: 'Executed a macro', | ||||||
| export const SENT_PRIVATE_NOTE = 'Sent a private note'; |   SENT_MESSAGE: 'Sent a message', | ||||||
| export const INSERTED_A_CANNED_RESPONSE = 'Inserted a canned response'; |   SENT_PRIVATE_NOTE: 'Sent a private note', | ||||||
| export const USED_MENTIONS = 'Used mentions'; |   INSERTED_A_CANNED_RESPONSE: 'Inserted a canned response', | ||||||
| export const MERGED_CONTACTS = 'Used merge contact option'; |   USED_MENTIONS: 'Used mentions', | ||||||
| export const ADDED_TO_CANNED_RESPONSE = 'Used added to canned response option'; | }); | ||||||
| export const ADDED_A_CUSTOM_ATTRIBUTE = 'Added a custom attribute'; |  | ||||||
| export const ADDED_AN_INBOX = 'Added an inbox'; | export const ACCOUNT_EVENTS = Object.freeze({ | ||||||
|  |   ADDED_TO_CANNED_RESPONSE: 'Used added to canned response option', | ||||||
|  |   ADDED_A_CUSTOM_ATTRIBUTE: 'Added a custom attribute', | ||||||
|  |   ADDED_AN_INBOX: 'Added an inbox', | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | export const LABEL_EVENTS = Object.freeze({ | ||||||
|  |   CREATE: 'Created a label', | ||||||
|  |   UPDATE: 'Updated a label', | ||||||
|  |   DELETED: 'Deleted a label', | ||||||
|  |   APPLY_LABEL: 'Applied a label', | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // REPORTS EVENTS | ||||||
|  | export const REPORTS_EVENTS = Object.freeze({ | ||||||
|  |   DOWNLOAD_REPORT: 'Downloaded a report', | ||||||
|  |   FILTER_REPORT: 'Used filters in the reports', | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // CONTACTS PAGE EVENTS | ||||||
|  | export const CONTACTS_EVENTS = Object.freeze({ | ||||||
|  |   APPLY_FILTER: 'Applied filters in the contacts list', | ||||||
|  |   SAVE_FILTER: 'Saved a filter in the contacts list', | ||||||
|  |   DELETE_FILTER: 'Deleted a filter in the contacts list', | ||||||
|  |  | ||||||
|  |   APPLY_SORT: 'Sorted contacts list', | ||||||
|  |   SEARCH: 'Searched contacts list', | ||||||
|  |   CREATE_CONTACT: 'Created a contact', | ||||||
|  |   MERGED_CONTACTS: 'Used merge contact option', | ||||||
|  |   IMPORT_MODAL_OPEN: 'Opened import contacts modal', | ||||||
|  |   IMPORT_FAILURE: 'Import contacts failed', | ||||||
|  |   IMPORT_SUCCESS: 'Imported contacts successfully', | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // CAMPAIGN EVENTS | ||||||
|  | export const CAMPAIGNS_EVENTS = Object.freeze({ | ||||||
|  |   OPEN_NEW_CAMPAIGN_MODAL: 'Opened new campaign modal', | ||||||
|  |   CREATE_CAMPAIGN: 'Created a new campaign', | ||||||
|  |   UPDATE_CAMPAIGN: 'Updated a campaign', | ||||||
|  |   DELETE_CAMPAIGN: 'Deleted a campaign', | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // PORTAL EVENTS | ||||||
|  | export const PORTALS_EVENTS = Object.freeze({ | ||||||
|  |   ONBOARD_BASIC_INFORMATION: 'New Portal: Completed basic information', | ||||||
|  |   ONBOARD_CUSTOMIZATION: 'New portal: Completed customization', | ||||||
|  |   CREATE_PORTAL: 'Created a portal', | ||||||
|  |   DELETE_PORTAL: 'Deleted a portal', | ||||||
|  |   UPDATE_PORTAL: 'Updated a portal', | ||||||
|  |  | ||||||
|  |   CREATE_LOCALE: 'Created a portal locale', | ||||||
|  |   SET_DEFAULT_LOCALE: 'Set default portal locale', | ||||||
|  |   DELETE_LOCALE: 'Deleted a portal locale', | ||||||
|  |   SWITCH_LOCALE: 'Switched portal locale', | ||||||
|  |  | ||||||
|  |   CREATE_CATEGORY: 'Created a portal category', | ||||||
|  |   DELETE_CATEGORY: 'Deleted a portal category', | ||||||
|  |   EDIT_CATEGORY: 'Edited a portal category', | ||||||
|  |  | ||||||
|  |   CREATE_ARTICLE: 'Created an article', | ||||||
|  |   PUBLISH_ARTICLE: 'Published an article', | ||||||
|  |   ARCHIVE_ARTICLE: 'Archived an article', | ||||||
|  |   DELETE_ARTICLE: 'Deleted an article', | ||||||
|  |   PREVIEW_ARTICLE: 'Previewed article', | ||||||
|  | }); | ||||||
|   | |||||||
| @@ -1,12 +1,26 @@ | |||||||
| import { AnalyticsBrowser } from '@june-so/analytics-next'; | import { AnalyticsBrowser } from '@june-so/analytics-next'; | ||||||
|  |  | ||||||
| class AnalyticsHelper { | /** | ||||||
|  |  * AnalyticsHelper class to initialize and track user analytics | ||||||
|  |  * @class AnalyticsHelper | ||||||
|  |  */ | ||||||
|  | export class AnalyticsHelper { | ||||||
|  |   /** | ||||||
|  |    * @constructor | ||||||
|  |    * @param {Object} [options={}] - options for analytics | ||||||
|  |    * @param {string} [options.token] - analytics token | ||||||
|  |    */ | ||||||
|   constructor({ token: analyticsToken } = {}) { |   constructor({ token: analyticsToken } = {}) { | ||||||
|     this.analyticsToken = analyticsToken; |     this.analyticsToken = analyticsToken; | ||||||
|     this.analytics = null; |     this.analytics = null; | ||||||
|     this.user = {}; |     this.user = {}; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Initialize analytics | ||||||
|  |    * @function | ||||||
|  |    * @async | ||||||
|  |    */ | ||||||
|   async init() { |   async init() { | ||||||
|     if (!this.analyticsToken) { |     if (!this.analyticsToken) { | ||||||
|       return; |       return; | ||||||
| @@ -18,6 +32,11 @@ class AnalyticsHelper { | |||||||
|     this.analytics = analytics; |     this.analytics = analytics; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Identify the user | ||||||
|  |    * @function | ||||||
|  |    * @param {Object} user - User object | ||||||
|  |    */ | ||||||
|   identify(user) { |   identify(user) { | ||||||
|     if (!this.analytics) { |     if (!this.analytics) { | ||||||
|       return; |       return; | ||||||
| @@ -41,6 +60,12 @@ class AnalyticsHelper { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Track any event | ||||||
|  |    * @function | ||||||
|  |    * @param {string} eventName - event name | ||||||
|  |    * @param {Object} [properties={}] - event properties | ||||||
|  |    */ | ||||||
|   track(eventName, properties = {}) { |   track(eventName, properties = {}) { | ||||||
|     if (!this.analytics) { |     if (!this.analytics) { | ||||||
|       return; |       return; | ||||||
| @@ -53,6 +78,11 @@ class AnalyticsHelper { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Track the page views | ||||||
|  |    * @function | ||||||
|  |    * @param {Object} params - Page view properties | ||||||
|  |    */ | ||||||
|   page(params) { |   page(params) { | ||||||
|     if (!this.analytics) { |     if (!this.analytics) { | ||||||
|       return; |       return; | ||||||
| @@ -62,6 +92,5 @@ class AnalyticsHelper { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| export * as ANALYTICS_EVENTS from './events'; | // This object is shared across, the init is called in app/javascript/packs/application.js | ||||||
|  |  | ||||||
| export default new AnalyticsHelper(window.analyticsConfig); | export default new AnalyticsHelper(window.analyticsConfig); | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								app/javascript/dashboard/helper/AnalyticsHelper/plugin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/javascript/dashboard/helper/AnalyticsHelper/plugin.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | import analyticsHelper from '.'; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   // This function is called when the Vue plugin is installed | ||||||
|  |   install(Vue) { | ||||||
|  |     analyticsHelper.init(); | ||||||
|  |     Vue.prototype.$analytics = analyticsHelper; | ||||||
|  |     // Add a shorthand function for the track method on the helper module | ||||||
|  |     Vue.prototype.$track = analyticsHelper.track.bind(analyticsHelper); | ||||||
|  |   }, | ||||||
|  | }; | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | import * as AnalyticsEvents from '../events'; | ||||||
|  |  | ||||||
|  | describe('Analytics Events', () => { | ||||||
|  |   it('should be frozen', () => { | ||||||
|  |     Object.entries(AnalyticsEvents).forEach(([, value]) => { | ||||||
|  |       expect(Object.isFrozen(value)).toBe(true); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('event names should be unique across the board', () => { | ||||||
|  |     const allValues = Object.values(AnalyticsEvents).reduce( | ||||||
|  |       (acc, curr) => acc.concat(Object.values(curr)), | ||||||
|  |       [] | ||||||
|  |     ); | ||||||
|  |     const uniqueValues = new Set(allValues); | ||||||
|  |     expect(allValues.length).toBe(uniqueValues.size); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should not allow properties to be modified', () => { | ||||||
|  |     Object.values(AnalyticsEvents).forEach(eventsObject => { | ||||||
|  |       expect(() => { | ||||||
|  |         eventsObject.NEW_PROPERTY = 'new value'; | ||||||
|  |       }).toThrow(); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @@ -0,0 +1,139 @@ | |||||||
|  | import helperObject, { AnalyticsHelper } from '../'; | ||||||
|  |  | ||||||
|  | jest.mock('@june-so/analytics-next', () => ({ | ||||||
|  |   AnalyticsBrowser: { | ||||||
|  |     load: () => [ | ||||||
|  |       { | ||||||
|  |         identify: jest.fn(), | ||||||
|  |         track: jest.fn(), | ||||||
|  |         page: jest.fn(), | ||||||
|  |         group: jest.fn(), | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  | })); | ||||||
|  |  | ||||||
|  | describe('helperObject', () => { | ||||||
|  |   it('should return an instance of AnalyticsHelper', () => { | ||||||
|  |     expect(helperObject).toBeInstanceOf(AnalyticsHelper); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | describe('AnalyticsHelper', () => { | ||||||
|  |   let analyticsHelper; | ||||||
|  |   beforeEach(() => { | ||||||
|  |     analyticsHelper = new AnalyticsHelper({ token: 'test_token' }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   describe('init', () => { | ||||||
|  |     it('should initialize the analytics browser with the correct token', async () => { | ||||||
|  |       await analyticsHelper.init(); | ||||||
|  |       expect(analyticsHelper.analytics).not.toBe(null); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should not initialize the analytics browser if token is not provided', async () => { | ||||||
|  |       analyticsHelper = new AnalyticsHelper(); | ||||||
|  |       await analyticsHelper.init(); | ||||||
|  |       expect(analyticsHelper.analytics).toBe(null); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   describe('identify', () => { | ||||||
|  |     beforeEach(() => { | ||||||
|  |       analyticsHelper.analytics = { identify: jest.fn(), group: jest.fn() }; | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should call identify on analytics browser with correct arguments', () => { | ||||||
|  |       analyticsHelper.identify({ | ||||||
|  |         id: '123', | ||||||
|  |         email: 'test@example.com', | ||||||
|  |         name: 'Test User', | ||||||
|  |         avatar_url: 'avatar_url', | ||||||
|  |         accounts: [{ id: '1', name: 'Account 1' }], | ||||||
|  |         account_id: '1', | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       expect(analyticsHelper.analytics.identify).toHaveBeenCalledWith( | ||||||
|  |         'test@example.com', | ||||||
|  |         { | ||||||
|  |           userId: '123', | ||||||
|  |           email: 'test@example.com', | ||||||
|  |           name: 'Test User', | ||||||
|  |           avatar: 'avatar_url', | ||||||
|  |         } | ||||||
|  |       ); | ||||||
|  |       expect(analyticsHelper.analytics.group).toHaveBeenCalled(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should call identify on analytics browser without group', () => { | ||||||
|  |       analyticsHelper.identify({ | ||||||
|  |         id: '123', | ||||||
|  |         email: 'test@example.com', | ||||||
|  |         name: 'Test User', | ||||||
|  |         avatar_url: 'avatar_url', | ||||||
|  |         accounts: [{ id: '1', name: 'Account 1' }], | ||||||
|  |         account_id: '5', | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       expect(analyticsHelper.analytics.group).not.toHaveBeenCalled(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should not call analytics.page if analytics is null', () => { | ||||||
|  |       analyticsHelper.analytics = null; | ||||||
|  |       analyticsHelper.identify({}); | ||||||
|  |       expect(analyticsHelper.analytics).toBe(null); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   describe('track', () => { | ||||||
|  |     beforeEach(() => { | ||||||
|  |       analyticsHelper.analytics = { track: jest.fn() }; | ||||||
|  |       analyticsHelper.user = { id: '123' }; | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should call track on analytics browser with correct arguments', () => { | ||||||
|  |       analyticsHelper.track('Test Event', { prop1: 'value1', prop2: 'value2' }); | ||||||
|  |       expect(analyticsHelper.analytics.track).toHaveBeenCalledWith({ | ||||||
|  |         userId: '123', | ||||||
|  |         event: 'Test Event', | ||||||
|  |         properties: { prop1: 'value1', prop2: 'value2' }, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should call track on analytics browser with default properties', () => { | ||||||
|  |       analyticsHelper.track('Test Event'); | ||||||
|  |       expect(analyticsHelper.analytics.track).toHaveBeenCalledWith({ | ||||||
|  |         userId: '123', | ||||||
|  |         event: 'Test Event', | ||||||
|  |         properties: {}, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should not call track on analytics browser if analytics is not initialized', () => { | ||||||
|  |       analyticsHelper.analytics = null; | ||||||
|  |       analyticsHelper.track('Test Event', { prop1: 'value1', prop2: 'value2' }); | ||||||
|  |       expect(analyticsHelper.analytics).toBe(null); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   describe('page', () => { | ||||||
|  |     beforeEach(() => { | ||||||
|  |       analyticsHelper.analytics = { page: jest.fn() }; | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should call the analytics.page method with the correct arguments', () => { | ||||||
|  |       const params = { | ||||||
|  |         name: 'Test page', | ||||||
|  |         url: '/test', | ||||||
|  |       }; | ||||||
|  |       analyticsHelper.page(params); | ||||||
|  |       expect(analyticsHelper.analytics.page).toHaveBeenCalledWith(params); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('should not call analytics.page if analytics is null', () => { | ||||||
|  |       analyticsHelper.analytics = null; | ||||||
|  |       analyticsHelper.page(); | ||||||
|  |       expect(analyticsHelper.analytics).toBe(null); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @@ -0,0 +1,35 @@ | |||||||
|  | import Vue from 'vue'; | ||||||
|  | import plugin from '../plugin'; | ||||||
|  | import analyticsHelper from '../index'; | ||||||
|  |  | ||||||
|  | describe('Vue Analytics Plugin', () => { | ||||||
|  |   beforeEach(() => { | ||||||
|  |     jest.spyOn(analyticsHelper, 'init'); | ||||||
|  |     jest.spyOn(analyticsHelper, 'track'); | ||||||
|  |     Vue.use(plugin); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   afterEach(() => { | ||||||
|  |     jest.resetModules(); | ||||||
|  |     jest.clearAllMocks(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should call the init method on the analyticsHelper', () => { | ||||||
|  |     expect(analyticsHelper.init).toHaveBeenCalled(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should add the analyticsHelper to the Vue prototype', () => { | ||||||
|  |     expect(Vue.prototype.$analytics).toBe(analyticsHelper); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should add the track method to the Vue prototype', () => { | ||||||
|  |     expect(typeof Vue.prototype.$track).toBe('function'); | ||||||
|  |     Vue.prototype.$track('eventName'); | ||||||
|  |     expect(analyticsHelper.track).toHaveBeenCalledWith('eventName'); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('should call the track method on the analyticsHelper when $track is called', () => { | ||||||
|  |     Vue.prototype.$track('eventName'); | ||||||
|  |     expect(analyticsHelper.track).toHaveBeenCalledWith('eventName'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @@ -24,9 +24,7 @@ import MergeContact from 'dashboard/modules/contact/components/MergeContact'; | |||||||
| import ContactAPI from 'dashboard/api/contacts'; | import ContactAPI from 'dashboard/api/contacts'; | ||||||
|  |  | ||||||
| import { mapGetters } from 'vuex'; | import { mapGetters } from 'vuex'; | ||||||
| import AnalyticsHelper, { | import { CONTACTS_EVENTS } from '../../helper/AnalyticsHelper/events'; | ||||||
|   ANALYTICS_EVENTS, |  | ||||||
| } from '../../helper/AnalyticsHelper'; |  | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { MergeContact }, |   components: { MergeContact }, | ||||||
| @@ -75,7 +73,7 @@ export default { | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     async onMergeContacts(childContactId) { |     async onMergeContacts(childContactId) { | ||||||
|       AnalyticsHelper.track(ANALYTICS_EVENTS.MERGED_CONTACTS); |       this.$track(CONTACTS_EVENTS.MERGED_CONTACTS); | ||||||
|       try { |       try { | ||||||
|         await this.$store.dispatch('contacts/merge', { |         await this.$store.dispatch('contacts/merge', { | ||||||
|           childId: childContactId, |           childId: childContactId, | ||||||
|   | |||||||
| @@ -72,9 +72,7 @@ import AddCannedModal from 'dashboard/routes/dashboard/settings/canned/AddCanned | |||||||
| import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem'; | import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem'; | ||||||
| import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu'; | import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu'; | ||||||
| import { copyTextToClipboard } from 'shared/helpers/clipboard'; | import { copyTextToClipboard } from 'shared/helpers/clipboard'; | ||||||
| import AnalyticsHelper, { | import { ACCOUNT_EVENTS } from '../../../helper/AnalyticsHelper/events'; | ||||||
|   ANALYTICS_EVENTS, |  | ||||||
| } from '../../../helper/AnalyticsHelper'; |  | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -130,7 +128,7 @@ export default { | |||||||
|       this.$emit('toggle', false); |       this.$emit('toggle', false); | ||||||
|     }, |     }, | ||||||
|     showCannedResponseModal() { |     showCannedResponseModal() { | ||||||
|       AnalyticsHelper.track(ANALYTICS_EVENTS.ADDED_TO_CANNED_RESPONSE); |       this.$track(ACCOUNT_EVENTS.ADDED_TO_CANNED_RESPONSE); | ||||||
|       this.isCannedResponseModalOpen = true; |       this.isCannedResponseModalOpen = true; | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -70,6 +70,7 @@ import { mapGetters } from 'vuex'; | |||||||
| import { filterAttributeGroups } from '../contactFilterItems'; | import { filterAttributeGroups } from '../contactFilterItems'; | ||||||
| import filterMixin from 'shared/mixins/filterMixin'; | import filterMixin from 'shared/mixins/filterMixin'; | ||||||
| import * as OPERATORS from 'dashboard/components/widgets/FilterInput/FilterOperatorTypes.js'; | import * as OPERATORS from 'dashboard/components/widgets/FilterInput/FilterOperatorTypes.js'; | ||||||
|  | import { CONTACTS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|     FilterInputBox, |     FilterInputBox, | ||||||
| @@ -251,6 +252,12 @@ export default { | |||||||
|         JSON.parse(JSON.stringify(this.appliedFilters)) |         JSON.parse(JSON.stringify(this.appliedFilters)) | ||||||
|       ); |       ); | ||||||
|       this.$emit('applyFilter', this.appliedFilters); |       this.$emit('applyFilter', this.appliedFilters); | ||||||
|  |       this.$track(CONTACTS_EVENTS.APPLY_FILTER, { | ||||||
|  |         applied_filters: this.appliedFilters.map(filter => ({ | ||||||
|  |           key: filter.attribute_key, | ||||||
|  |           operator: filter.filter_operator, | ||||||
|  |         })), | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     resetFilter(index, currentFilter) { |     resetFilter(index, currentFilter) { | ||||||
|       this.appliedFilters[index].filter_operator = this.filterTypes.find( |       this.appliedFilters[index].filter_operator = this.filterTypes.find( | ||||||
|   | |||||||
| @@ -86,6 +86,7 @@ import contactFilterItems from '../contactFilterItems'; | |||||||
| import filterQueryGenerator from '../../../../helper/filterQueryGenerator'; | import filterQueryGenerator from '../../../../helper/filterQueryGenerator'; | ||||||
| import AddCustomViews from 'dashboard/routes/dashboard/customviews/AddCustomViews'; | import AddCustomViews from 'dashboard/routes/dashboard/customviews/AddCustomViews'; | ||||||
| import DeleteCustomViews from 'dashboard/routes/dashboard/customviews/DeleteCustomViews'; | import DeleteCustomViews from 'dashboard/routes/dashboard/customviews/DeleteCustomViews'; | ||||||
|  | import { CONTACTS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| const DEFAULT_PAGE = 1; | const DEFAULT_PAGE = 1; | ||||||
| const FILTER_TYPE_CONTACT = 1; | const FILTER_TYPE_CONTACT = 1; | ||||||
| @@ -334,6 +335,14 @@ export default { | |||||||
|     onSortChange(params) { |     onSortChange(params) { | ||||||
|       this.sortConfig = params; |       this.sortConfig = params; | ||||||
|       this.fetchContacts(this.meta.currentPage); |       this.fetchContacts(this.meta.currentPage); | ||||||
|  |  | ||||||
|  |       const sortBy = | ||||||
|  |         Object.entries(params).find(pair => Boolean(pair[1])) || []; | ||||||
|  |  | ||||||
|  |       this.$track(CONTACTS_EVENTS.APPLY_SORT, { | ||||||
|  |         appliedOn: sortBy[0], | ||||||
|  |         order: sortBy[1], | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     onToggleFilters() { |     onToggleFilters() { | ||||||
|       this.showFiltersModal = !this.showFiltersModal; |       this.showFiltersModal = !this.showFiltersModal; | ||||||
|   | |||||||
| @@ -45,6 +45,7 @@ | |||||||
| import Modal from '../../../../components/Modal'; | import Modal from '../../../../components/Modal'; | ||||||
| import { mapGetters } from 'vuex'; | import { mapGetters } from 'vuex'; | ||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
|  | import { CONTACTS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -71,6 +72,9 @@ export default { | |||||||
|       return '/downloads/import-contacts-sample.csv'; |       return '/downloads/import-contacts-sample.csv'; | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   mounted() { | ||||||
|  |     this.$track(CONTACTS_EVENTS.IMPORT_MODAL_OPEN); | ||||||
|  |   }, | ||||||
|   methods: { |   methods: { | ||||||
|     async uploadFile() { |     async uploadFile() { | ||||||
|       try { |       try { | ||||||
| @@ -78,10 +82,12 @@ export default { | |||||||
|         await this.$store.dispatch('contacts/import', this.file); |         await this.$store.dispatch('contacts/import', this.file); | ||||||
|         this.onClose(); |         this.onClose(); | ||||||
|         this.showAlert(this.$t('IMPORT_CONTACTS.SUCCESS_MESSAGE')); |         this.showAlert(this.$t('IMPORT_CONTACTS.SUCCESS_MESSAGE')); | ||||||
|  |         this.$track(CONTACTS_EVENTS.IMPORT_SUCCESS); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         this.showAlert( |         this.showAlert( | ||||||
|           error.message || this.$t('IMPORT_CONTACTS.ERROR_MESSAGE') |           error.message || this.$t('IMPORT_CONTACTS.ERROR_MESSAGE') | ||||||
|         ); |         ); | ||||||
|  |         this.$track(CONTACTS_EVENTS.IMPORT_FAILURE); | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     handleFileUpload() { |     handleFileUpload() { | ||||||
|   | |||||||
| @@ -35,9 +35,8 @@ | |||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
| import { mixin as clickaway } from 'vue-clickaway'; | import { mixin as clickaway } from 'vue-clickaway'; | ||||||
| import MacroPreview from './MacroPreview'; | import MacroPreview from './MacroPreview'; | ||||||
| import AnalyticsHelper, { | import { CONVERSATION_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
|   ANALYTICS_EVENTS, |  | ||||||
| } from '../../../../helper/AnalyticsHelper'; |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|     MacroPreview, |     MacroPreview, | ||||||
| @@ -67,7 +66,7 @@ export default { | |||||||
|           macroId: macro.id, |           macroId: macro.id, | ||||||
|           conversationIds: [this.conversationId], |           conversationIds: [this.conversationId], | ||||||
|         }); |         }); | ||||||
|         AnalyticsHelper.track(ANALYTICS_EVENTS.EXECUTED_A_MACRO); |         this.$track(CONVERSATION_EVENTS.EXECUTED_A_MACRO); | ||||||
|         this.showAlert(this.$t('MACROS.EXECUTE.EXECUTED_SUCCESSFULLY')); |         this.showAlert(this.$t('MACROS.EXECUTE.EXECUTED_SUCCESSFULLY')); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         this.showAlert(this.$t('MACROS.ERROR')); |         this.showAlert(this.$t('MACROS.ERROR')); | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ | |||||||
| <script> | <script> | ||||||
| import { required, minLength } from 'vuelidate/lib/validators'; | import { required, minLength } from 'vuelidate/lib/validators'; | ||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
|  | import { CONTACTS_EVENTS } from '../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   mixins: [alertMixin], |   mixins: [alertMixin], | ||||||
| @@ -89,6 +90,10 @@ export default { | |||||||
|             ? this.$t('FILTER.CUSTOM_VIEWS.ADD.API_FOLDERS.SUCCESS_MESSAGE') |             ? this.$t('FILTER.CUSTOM_VIEWS.ADD.API_FOLDERS.SUCCESS_MESSAGE') | ||||||
|             : this.$t('FILTER.CUSTOM_VIEWS.ADD.API_SEGMENTS.SUCCESS_MESSAGE'); |             : this.$t('FILTER.CUSTOM_VIEWS.ADD.API_SEGMENTS.SUCCESS_MESSAGE'); | ||||||
|         this.onClose(); |         this.onClose(); | ||||||
|  |  | ||||||
|  |         this.$track(CONTACTS_EVENTS.SAVE_FILTER, { | ||||||
|  |           type: this.filterType === 0 ? 'folder' : 'segment', | ||||||
|  |         }); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         const errorMessage = error?.message; |         const errorMessage = error?.message; | ||||||
|         this.alertMessage = |         this.alertMessage = | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
|  | import { CONTACTS_EVENTS } from '../../../helper/AnalyticsHelper/events'; | ||||||
| export default { | export default { | ||||||
|   mixins: [alertMixin], |   mixins: [alertMixin], | ||||||
|   props: { |   props: { | ||||||
| @@ -82,6 +83,9 @@ export default { | |||||||
|             ? this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_FOLDERS.SUCCESS_MESSAGE') |             ? this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_FOLDERS.SUCCESS_MESSAGE') | ||||||
|             : this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_SEGMENTS.SUCCESS_MESSAGE') |             : this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_SEGMENTS.SUCCESS_MESSAGE') | ||||||
|         ); |         ); | ||||||
|  |         this.$track(CONTACTS_EVENTS.DELETE_FILTER, { | ||||||
|  |           type: this.filterType === 0 ? 'folder' : 'segment', | ||||||
|  |         }); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         const errorMessage = |         const errorMessage = | ||||||
|           error?.response?.message || this.activeFilterType === 0 |           error?.response?.message || this.activeFilterType === 0 | ||||||
|   | |||||||
| @@ -42,6 +42,7 @@ import Modal from 'dashboard/components/Modal'; | |||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
| import { required } from 'vuelidate/lib/validators'; | import { required } from 'vuelidate/lib/validators'; | ||||||
| import allLocales from 'shared/constants/locales.js'; | import allLocales from 'shared/constants/locales.js'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|     Modal, |     Modal, | ||||||
| @@ -108,6 +109,11 @@ export default { | |||||||
|           'HELP_CENTER.PORTAL.ADD_LOCALE.API.SUCCESS_MESSAGE' |           'HELP_CENTER.PORTAL.ADD_LOCALE.API.SUCCESS_MESSAGE' | ||||||
|         ); |         ); | ||||||
|         this.onClose(); |         this.onClose(); | ||||||
|  |         this.$track(PORTALS_EVENTS.CREATE_LOCALE, { | ||||||
|  |           localeAdded: this.selectedLocale, | ||||||
|  |           totalLocales: updatedLocales.length, | ||||||
|  |           from: this.$route.name, | ||||||
|  |         }); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         this.alertMessage = |         this.alertMessage = | ||||||
|           error?.message || |           error?.message || | ||||||
|   | |||||||
| @@ -107,6 +107,7 @@ | |||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
| import { mixin as clickaway } from 'vue-clickaway'; | import { mixin as clickaway } from 'vue-clickaway'; | ||||||
| import wootConstants from 'dashboard/constants.js'; | import wootConstants from 'dashboard/constants.js'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| const { ARTICLE_STATUS_TYPES } = wootConstants; | const { ARTICLE_STATUS_TYPES } = wootConstants; | ||||||
|  |  | ||||||
| @@ -186,6 +187,11 @@ export default { | |||||||
|         }); |         }); | ||||||
|         this.statusUpdateSuccessMessage(status); |         this.statusUpdateSuccessMessage(status); | ||||||
|         this.closeActionsDropdown(); |         this.closeActionsDropdown(); | ||||||
|  |         if (status === this.ARTICLE_STATUS_TYPES.ARCHIVE) { | ||||||
|  |           this.$track(PORTALS_EVENTS.ARCHIVE_ARTICLE, { uiFrom: 'header' }); | ||||||
|  |         } else if (status === this.ARTICLE_STATUS_TYPES.PUBLISH) { | ||||||
|  |           this.$track(PORTALS_EVENTS.PUBLISH_ARTICLE); | ||||||
|  |         } | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         this.alertMessage = |         this.alertMessage = | ||||||
|           error?.message || this.statusUpdateErrorMessage(status); |           error?.message || this.statusUpdateErrorMessage(status); | ||||||
|   | |||||||
| @@ -190,6 +190,7 @@ import thumbnail from 'dashboard/components/widgets/Thumbnail'; | |||||||
| import LocaleItemTable from './PortalListItemTable'; | import LocaleItemTable from './PortalListItemTable'; | ||||||
| import uiSettingsMixin from 'dashboard/mixins/uiSettings'; | import uiSettingsMixin from 'dashboard/mixins/uiSettings'; | ||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -309,6 +310,10 @@ export default { | |||||||
|           'HELP_CENTER.PORTAL.CHANGE_DEFAULT_LOCALE.API.ERROR_MESSAGE' |           'HELP_CENTER.PORTAL.CHANGE_DEFAULT_LOCALE.API.ERROR_MESSAGE' | ||||||
|         ), |         ), | ||||||
|       }); |       }); | ||||||
|  |       this.$track(PORTALS_EVENTS.SET_DEFAULT_LOCALE, { | ||||||
|  |         newLocale: localeCode, | ||||||
|  |         from: this.$route.name, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     deletePortalLocale({ localeCode }) { |     deletePortalLocale({ localeCode }) { | ||||||
|       const updatedLocales = this.allowedLocales.filter( |       const updatedLocales = this.allowedLocales.filter( | ||||||
| @@ -325,6 +330,10 @@ export default { | |||||||
|           'HELP_CENTER.PORTAL.DELETE_LOCALE.API.ERROR_MESSAGE' |           'HELP_CENTER.PORTAL.DELETE_LOCALE.API.ERROR_MESSAGE' | ||||||
|         ), |         ), | ||||||
|       }); |       }); | ||||||
|  |       this.$track(PORTALS_EVENTS.DELETE_LOCALE, { | ||||||
|  |         deletedLocale: localeCode, | ||||||
|  |         from: this.$route.name, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     async updatePortalLocales({ |     async updatePortalLocales({ | ||||||
|       allowedLocales, |       allowedLocales, | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ import portalMixin from '../../mixins/portalMixin'; | |||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
| import wootConstants from 'dashboard/constants'; | import wootConstants from 'dashboard/constants'; | ||||||
| import { buildPortalArticleURL } from 'dashboard/helper/portalHelper'; | import { buildPortalArticleURL } from 'dashboard/helper/portalHelper'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| const { ARTICLE_STATUS_TYPES } = wootConstants; | const { ARTICLE_STATUS_TYPES } = wootConstants; | ||||||
| export default { | export default { | ||||||
| @@ -118,6 +119,9 @@ export default { | |||||||
|     confirmDeletion() { |     confirmDeletion() { | ||||||
|       this.closeDeletePopup(); |       this.closeDeletePopup(); | ||||||
|       this.deleteArticle(); |       this.deleteArticle(); | ||||||
|  |       this.$track(PORTALS_EVENTS.DELETE_ARTICLE, { | ||||||
|  |         status: this.article?.status, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     async saveArticle({ ...values }) { |     async saveArticle({ ...values }) { | ||||||
|       this.isUpdating = true; |       this.isUpdating = true; | ||||||
| @@ -171,6 +175,7 @@ export default { | |||||||
|           status: ARTICLE_STATUS_TYPES.ARCHIVE, |           status: ARTICLE_STATUS_TYPES.ARCHIVE, | ||||||
|         }); |         }); | ||||||
|         this.alertMessage = this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.SUCCESS'); |         this.alertMessage = this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.SUCCESS'); | ||||||
|  |         this.$track(PORTALS_EVENTS.ARCHIVE_ARTICLE, { uiFrom: 'sidebar' }); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         this.alertMessage = |         this.alertMessage = | ||||||
|           error?.message || this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.ERROR'); |           error?.message || this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.ERROR'); | ||||||
| @@ -186,6 +191,9 @@ export default { | |||||||
|     }, |     }, | ||||||
|     showArticleInPortal() { |     showArticleInPortal() { | ||||||
|       window.open(this.portalLink, '_blank'); |       window.open(this.portalLink, '_blank'); | ||||||
|  |       this.$track(PORTALS_EVENTS.PREVIEW_ARTICLE, { | ||||||
|  |         status: this.article?.status, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ import ArticleEditor from '../../components/ArticleEditor.vue'; | |||||||
| import portalMixin from '../../mixins/portalMixin'; | import portalMixin from '../../mixins/portalMixin'; | ||||||
| import alertMixin from 'shared/mixins/alertMixin.js'; | import alertMixin from 'shared/mixins/alertMixin.js'; | ||||||
| import ArticleSettings from './ArticleSettings.vue'; | import ArticleSettings from './ArticleSettings.vue'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|     EditArticleHeader, |     EditArticleHeader, | ||||||
| @@ -91,6 +92,9 @@ export default { | |||||||
|               recentlyCreated: true, |               recentlyCreated: true, | ||||||
|             }, |             }, | ||||||
|           }); |           }); | ||||||
|  |           this.$track(PORTALS_EVENTS.CREATE_ARTICLE, { | ||||||
|  |             locale: this.locale, | ||||||
|  |           }); | ||||||
|         } catch (error) { |         } catch (error) { | ||||||
|           this.alertMessage = |           this.alertMessage = | ||||||
|             error?.message || |             error?.message || | ||||||
|   | |||||||
| @@ -70,6 +70,7 @@ | |||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
| import { required, minLength } from 'vuelidate/lib/validators'; | import { required, minLength } from 'vuelidate/lib/validators'; | ||||||
| import { convertToCategorySlug } from 'dashboard/helper/commons.js'; | import { convertToCategorySlug } from 'dashboard/helper/commons.js'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   mixins: [alertMixin], |   mixins: [alertMixin], | ||||||
| @@ -158,6 +159,9 @@ export default { | |||||||
|           'HELP_CENTER.CATEGORY.ADD.API.SUCCESS_MESSAGE' |           'HELP_CENTER.CATEGORY.ADD.API.SUCCESS_MESSAGE' | ||||||
|         ); |         ); | ||||||
|         this.onClose(); |         this.onClose(); | ||||||
|  |         this.$track(PORTALS_EVENTS.CREATE_CATEGORY, { | ||||||
|  |           hasDescription: Boolean(description), | ||||||
|  |         }); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         const errorMessage = error?.message; |         const errorMessage = error?.message; | ||||||
|         this.alertMessage = |         this.alertMessage = | ||||||
|   | |||||||
| @@ -58,7 +58,7 @@ | |||||||
|               variant="smooth" |               variant="smooth" | ||||||
|               icon="delete" |               icon="delete" | ||||||
|               color-scheme="alert" |               color-scheme="alert" | ||||||
|               @click="deleteCategory(category.id)" |               @click="deleteCategory(category)" | ||||||
|             /> |             /> | ||||||
|           </td> |           </td> | ||||||
|         </tr> |         </tr> | ||||||
| @@ -83,8 +83,8 @@ export default { | |||||||
|     editCategory(category) { |     editCategory(category) { | ||||||
|       this.$emit('edit', category); |       this.$emit('edit', category); | ||||||
|     }, |     }, | ||||||
|     deleteCategory(categoryId) { |     deleteCategory(category) { | ||||||
|       this.$emit('delete', categoryId); |       this.$emit('delete', category); | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -70,6 +70,7 @@ | |||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
| import { required, minLength } from 'vuelidate/lib/validators'; | import { required, minLength } from 'vuelidate/lib/validators'; | ||||||
| import { convertToCategorySlug } from 'dashboard/helper/commons.js'; | import { convertToCategorySlug } from 'dashboard/helper/commons.js'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   mixins: [alertMixin], |   mixins: [alertMixin], | ||||||
| @@ -166,6 +167,7 @@ export default { | |||||||
|         this.alertMessage = this.$t( |         this.alertMessage = this.$t( | ||||||
|           'HELP_CENTER.CATEGORY.EDIT.API.SUCCESS_MESSAGE' |           'HELP_CENTER.CATEGORY.EDIT.API.SUCCESS_MESSAGE' | ||||||
|         ); |         ); | ||||||
|  |         this.$track(PORTALS_EVENTS.EDIT_CATEGORY); | ||||||
|         this.onClose(); |         this.onClose(); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         const errorMessage = error?.message; |         const errorMessage = error?.message; | ||||||
|   | |||||||
| @@ -64,6 +64,7 @@ import portalMixin from '../../mixins/portalMixin'; | |||||||
| import CategoryListItem from './CategoryListItem'; | import CategoryListItem from './CategoryListItem'; | ||||||
| import AddCategory from './AddCategory'; | import AddCategory from './AddCategory'; | ||||||
| import EditCategory from './EditCategory'; | import EditCategory from './EditCategory'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -137,15 +138,18 @@ export default { | |||||||
|         locale: localeCode, |         locale: localeCode, | ||||||
|       }); |       }); | ||||||
|     }, |     }, | ||||||
|     async deleteCategory(categoryId) { |     async deleteCategory(category) { | ||||||
|       try { |       try { | ||||||
|         await this.$store.dispatch('categories/delete', { |         await this.$store.dispatch('categories/delete', { | ||||||
|           portalSlug: this.currentPortalSlug, |           portalSlug: this.currentPortalSlug, | ||||||
|           categoryId: categoryId, |           categoryId: category.id, | ||||||
|         }); |         }); | ||||||
|         this.alertMessage = this.$t( |         this.alertMessage = this.$t( | ||||||
|           'HELP_CENTER.CATEGORY.DELETE.API.SUCCESS_MESSAGE' |           'HELP_CENTER.CATEGORY.DELETE.API.SUCCESS_MESSAGE' | ||||||
|         ); |         ); | ||||||
|  |         this.$track(PORTALS_EVENTS.DELETE_CATEGORY, { | ||||||
|  |           hasArticles: category?.meta?.articles_count !== 0, | ||||||
|  |         }); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         const errorMessage = error?.message; |         const errorMessage = error?.message; | ||||||
|         this.alertMessage = |         this.alertMessage = | ||||||
|   | |||||||
| @@ -36,6 +36,7 @@ import { mapGetters } from 'vuex'; | |||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
| import LocaleItemTable from 'dashboard/routes/dashboard/helpcenter/components/PortalListItemTable.vue'; | import LocaleItemTable from 'dashboard/routes/dashboard/helpcenter/components/PortalListItemTable.vue'; | ||||||
| import AddLocale from 'dashboard/routes/dashboard/helpcenter/components/AddLocale'; | import AddLocale from 'dashboard/routes/dashboard/helpcenter/components/AddLocale'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|     LocaleItemTable, |     LocaleItemTable, | ||||||
| @@ -85,6 +86,10 @@ export default { | |||||||
|           'HELP_CENTER.PORTAL.CHANGE_DEFAULT_LOCALE.API.ERROR_MESSAGE' |           'HELP_CENTER.PORTAL.CHANGE_DEFAULT_LOCALE.API.ERROR_MESSAGE' | ||||||
|         ), |         ), | ||||||
|       }); |       }); | ||||||
|  |       this.$track(PORTALS_EVENTS.SET_DEFAULT_LOCALE, { | ||||||
|  |         newLocale: localeCode, | ||||||
|  |         from: this.$route.name, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     deletePortalLocale({ localeCode }) { |     deletePortalLocale({ localeCode }) { | ||||||
|       const updatedLocales = this.allowedLocales.filter( |       const updatedLocales = this.allowedLocales.filter( | ||||||
| @@ -101,6 +106,10 @@ export default { | |||||||
|           'HELP_CENTER.PORTAL.DELETE_LOCALE.API.ERROR_MESSAGE' |           'HELP_CENTER.PORTAL.DELETE_LOCALE.API.ERROR_MESSAGE' | ||||||
|         ), |         ), | ||||||
|       }); |       }); | ||||||
|  |       this.$track(PORTALS_EVENTS.DELETE_LOCALE, { | ||||||
|  |         deletedLocale: localeCode, | ||||||
|  |         from: this.$route.name, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     async updatePortalLocales({ |     async updatePortalLocales({ | ||||||
|       allowedLocales, |       allowedLocales, | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ import PortalSettingsCustomizationForm from 'dashboard/routes/dashboard/helpcent | |||||||
| import { mapGetters } from 'vuex'; | import { mapGetters } from 'vuex'; | ||||||
|  |  | ||||||
| import { getRandomColor } from 'dashboard/helper/labelColor'; | import { getRandomColor } from 'dashboard/helper/labelColor'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -52,7 +53,6 @@ export default { | |||||||
|     }, |     }, | ||||||
|     async updatePortalSettings(portalObj) { |     async updatePortalSettings(portalObj) { | ||||||
|       const portalSlug = this.$route.params.portalSlug; |       const portalSlug = this.$route.params.portalSlug; | ||||||
|  |  | ||||||
|       try { |       try { | ||||||
|         await this.$store.dispatch('portals/update', { |         await this.$store.dispatch('portals/update', { | ||||||
|           portalSlug, |           portalSlug, | ||||||
| @@ -61,6 +61,12 @@ export default { | |||||||
|         this.alertMessage = this.$t( |         this.alertMessage = this.$t( | ||||||
|           'HELP_CENTER.PORTAL.ADD.API.SUCCESS_MESSAGE_FOR_UPDATE' |           'HELP_CENTER.PORTAL.ADD.API.SUCCESS_MESSAGE_FOR_UPDATE' | ||||||
|         ); |         ); | ||||||
|  |  | ||||||
|  |         this.$track(PORTALS_EVENTS.ONBOARD_CUSTOMIZATION, { | ||||||
|  |           hasHomePageLink: Boolean(portalObj.homepage_link), | ||||||
|  |           hasPageTitle: Boolean(portalObj.page_title), | ||||||
|  |           hasHeaderText: Boolean(portalObj.headerText), | ||||||
|  |         }); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         this.alertMessage = |         this.alertMessage = | ||||||
|           error?.message || |           error?.message || | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import { mapGetters } from 'vuex'; | |||||||
| import alertMixin from 'shared/mixins/alertMixin'; | import alertMixin from 'shared/mixins/alertMixin'; | ||||||
|  |  | ||||||
| import PortalSettingsBasicForm from 'dashboard/routes/dashboard/helpcenter/components/PortalSettingsBasicForm'; | import PortalSettingsBasicForm from 'dashboard/routes/dashboard/helpcenter/components/PortalSettingsBasicForm'; | ||||||
|  | import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -49,6 +50,11 @@ export default { | |||||||
|           name: 'portal_customization', |           name: 'portal_customization', | ||||||
|           params: { portalSlug: portal.slug }, |           params: { portalSlug: portal.slug }, | ||||||
|         }); |         }); | ||||||
|  |         const analyticsPayload = { | ||||||
|  |           has_custom_domain: portal.domain !== '', | ||||||
|  |         }; | ||||||
|  |         this.$track(PORTALS_EVENTS.ONBOARD_BASIC_INFORMATION, analyticsPayload); | ||||||
|  |         this.$track(PORTALS_EVENTS.CREATE_PORTAL, analyticsPayload); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         this.alertMessage = |         this.alertMessage = | ||||||
|           error?.message || |           error?.message || | ||||||
|   | |||||||
| @@ -177,6 +177,7 @@ import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor'; | |||||||
| import campaignMixin from 'shared/mixins/campaignMixin'; | import campaignMixin from 'shared/mixins/campaignMixin'; | ||||||
| import WootDateTimePicker from 'dashboard/components/ui/DateTimePicker.vue'; | import WootDateTimePicker from 'dashboard/components/ui/DateTimePicker.vue'; | ||||||
| import { URLPattern } from 'urlpattern-polyfill'; | import { URLPattern } from 'urlpattern-polyfill'; | ||||||
|  | import { CAMPAIGNS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
| @@ -275,6 +276,11 @@ export default { | |||||||
|       ]; |       ]; | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   mounted() { | ||||||
|  |     this.$track(CAMPAIGNS_EVENTS.OPEN_NEW_CAMPAIGN_MODAL, { | ||||||
|  |       type: this.campaignType, | ||||||
|  |     }); | ||||||
|  |   }, | ||||||
|   methods: { |   methods: { | ||||||
|     onClose() { |     onClose() { | ||||||
|       this.$emit('on-close'); |       this.$emit('on-close'); | ||||||
| @@ -339,6 +345,12 @@ export default { | |||||||
|       try { |       try { | ||||||
|         const campaignDetails = this.getCampaignDetails(); |         const campaignDetails = this.getCampaignDetails(); | ||||||
|         await this.$store.dispatch('campaigns/create', campaignDetails); |         await this.$store.dispatch('campaigns/create', campaignDetails); | ||||||
|  |  | ||||||
|  |         // tracking this here instead of the store to track the type of campaign | ||||||
|  |         this.$track(CAMPAIGNS_EVENTS.CREATE_CAMPAIGN, { | ||||||
|  |           type: this.campaignType, | ||||||
|  |         }); | ||||||
|  |  | ||||||
|         this.showAlert(this.$t('CAMPAIGN.ADD.API.SUCCESS_MESSAGE')); |         this.showAlert(this.$t('CAMPAIGN.ADD.API.SUCCESS_MESSAGE')); | ||||||
|         this.onClose(); |         this.onClose(); | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import CsatTable from './components/CsatTable'; | |||||||
| import ReportFilterSelector from './components/FilterSelector'; | import ReportFilterSelector from './components/FilterSelector'; | ||||||
| import { mapGetters } from 'vuex'; | import { mapGetters } from 'vuex'; | ||||||
| import { generateFileName } from '../../../../helper/downloadHelper'; | import { generateFileName } from '../../../../helper/downloadHelper'; | ||||||
|  | import { REPORTS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   name: 'CsatResponses', |   name: 'CsatResponses', | ||||||
| @@ -66,6 +67,13 @@ export default { | |||||||
|       this.getResponses(); |       this.getResponses(); | ||||||
|     }, |     }, | ||||||
|     onDateRangeChange({ from, to }) { |     onDateRangeChange({ from, to }) { | ||||||
|  |       // do not track filter change on inital load | ||||||
|  |       if (this.from !== 0 && this.to !== 0) { | ||||||
|  |         this.$track(REPORTS_EVENTS.FILTER_REPORT, { | ||||||
|  |           filterType: 'date', | ||||||
|  |           reportType: 'csat', | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|       this.from = from; |       this.from = from; | ||||||
|       this.to = to; |       this.to = to; | ||||||
|       this.getAllData(); |       this.getAllData(); | ||||||
| @@ -73,6 +81,10 @@ export default { | |||||||
|     onAgentsFilterChange(agents) { |     onAgentsFilterChange(agents) { | ||||||
|       this.userIds = agents.map(el => el.id); |       this.userIds = agents.map(el => el.id); | ||||||
|       this.getAllData(); |       this.getAllData(); | ||||||
|  |       this.$track(REPORTS_EVENTS.FILTER_REPORT, { | ||||||
|  |         filterType: 'agent', | ||||||
|  |         reportType: 'csat', | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     downloadReports() { |     downloadReports() { | ||||||
|       const type = 'csat'; |       const type = 'csat'; | ||||||
|   | |||||||
| @@ -58,6 +58,7 @@ import ReportFilterSelector from './components/FilterSelector'; | |||||||
| import { GROUP_BY_FILTER, METRIC_CHART } from './constants'; | import { GROUP_BY_FILTER, METRIC_CHART } from './constants'; | ||||||
| import reportMixin from '../../../../mixins/reportMixin'; | import reportMixin from '../../../../mixins/reportMixin'; | ||||||
| import { formatTime } from '@chatwoot/utils'; | import { formatTime } from '@chatwoot/utils'; | ||||||
|  | import { REPORTS_EVENTS } from '../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| const REPORTS_KEYS = { | const REPORTS_KEYS = { | ||||||
|   CONVERSATIONS: 'conversations_count', |   CONVERSATIONS: 'conversations_count', | ||||||
| @@ -222,6 +223,13 @@ export default { | |||||||
|       this.fetchChartData(); |       this.fetchChartData(); | ||||||
|     }, |     }, | ||||||
|     onDateRangeChange({ from, to, groupBy }) { |     onDateRangeChange({ from, to, groupBy }) { | ||||||
|  |       // do not track filter change on inital load | ||||||
|  |       if (this.from !== 0 && this.to !== 0) { | ||||||
|  |         this.$track(REPORTS_EVENTS.FILTER_REPORT, { | ||||||
|  |           filterType: 'date', | ||||||
|  |           reportType: 'conversations', | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|       this.from = from; |       this.from = from; | ||||||
|       this.to = to; |       this.to = to; | ||||||
|       this.filterItemsList = this.fetchFilterItems(groupBy); |       this.filterItemsList = this.fetchFilterItems(groupBy); | ||||||
| @@ -239,6 +247,12 @@ export default { | |||||||
|     onFilterChange(payload) { |     onFilterChange(payload) { | ||||||
|       this.groupBy = GROUP_BY_FILTER[payload.id]; |       this.groupBy = GROUP_BY_FILTER[payload.id]; | ||||||
|       this.fetchAllData(); |       this.fetchAllData(); | ||||||
|  |  | ||||||
|  |       this.$track(REPORTS_EVENTS.FILTER_REPORT, { | ||||||
|  |         filterType: 'groupBy', | ||||||
|  |         filterValue: this.groupBy?.period, | ||||||
|  |         reportType: 'conversations', | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     fetchFilterItems(group_by) { |     fetchFilterItems(group_by) { | ||||||
|       switch (group_by) { |       switch (group_by) { | ||||||
| @@ -255,6 +269,12 @@ export default { | |||||||
|     onBusinessHoursToggle(value) { |     onBusinessHoursToggle(value) { | ||||||
|       this.businessHours = value; |       this.businessHours = value; | ||||||
|       this.fetchAllData(); |       this.fetchAllData(); | ||||||
|  |  | ||||||
|  |       this.$track(REPORTS_EVENTS.FILTER_REPORT, { | ||||||
|  |         filterType: 'businessHours', | ||||||
|  |         filterValue: value, | ||||||
|  |         reportType: 'conversations', | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -62,6 +62,7 @@ import { GROUP_BY_FILTER, METRIC_CHART } from '../constants'; | |||||||
| import reportMixin from '../../../../../mixins/reportMixin'; | import reportMixin from '../../../../../mixins/reportMixin'; | ||||||
| import { formatTime } from '@chatwoot/utils'; | import { formatTime } from '@chatwoot/utils'; | ||||||
| import { generateFileName } from '../../../../../helper/downloadHelper'; | import { generateFileName } from '../../../../../helper/downloadHelper'; | ||||||
|  | import { REPORTS_EVENTS } from '../../../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| const REPORTS_KEYS = { | const REPORTS_KEYS = { | ||||||
|   CONVERSATIONS: 'conversations_count', |   CONVERSATIONS: 'conversations_count', | ||||||
| @@ -269,6 +270,14 @@ export default { | |||||||
|       this.fetchChartData(); |       this.fetchChartData(); | ||||||
|     }, |     }, | ||||||
|     onDateRangeChange({ from, to, groupBy }) { |     onDateRangeChange({ from, to, groupBy }) { | ||||||
|  |       // do not track filter change on inital load | ||||||
|  |       if (this.from !== 0 && this.to !== 0) { | ||||||
|  |         this.$track(REPORTS_EVENTS.FILTER_REPORT, { | ||||||
|  |           filterType: 'date', | ||||||
|  |           reportType: this.type, | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |  | ||||||
|       this.from = from; |       this.from = from; | ||||||
|       this.to = to; |       this.to = to; | ||||||
|       this.groupByfilterItemsList = this.fetchFilterItems(groupBy); |       this.groupByfilterItemsList = this.fetchFilterItems(groupBy); | ||||||
| @@ -292,6 +301,12 @@ export default { | |||||||
|     onGroupByFilterChange(payload) { |     onGroupByFilterChange(payload) { | ||||||
|       this.groupBy = GROUP_BY_FILTER[payload.id]; |       this.groupBy = GROUP_BY_FILTER[payload.id]; | ||||||
|       this.fetchAllData(); |       this.fetchAllData(); | ||||||
|  |  | ||||||
|  |       this.$track(REPORTS_EVENTS.FILTER_REPORT, { | ||||||
|  |         filterType: 'groupBy', | ||||||
|  |         filterValue: this.groupBy?.period, | ||||||
|  |         reportType: this.type, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|     fetchFilterItems(group_by) { |     fetchFilterItems(group_by) { | ||||||
|       switch (group_by) { |       switch (group_by) { | ||||||
| @@ -308,6 +323,12 @@ export default { | |||||||
|     onBusinessHoursToggle(value) { |     onBusinessHoursToggle(value) { | ||||||
|       this.businessHours = value; |       this.businessHours = value; | ||||||
|       this.fetchAllData(); |       this.fetchAllData(); | ||||||
|  |  | ||||||
|  |       this.$track(REPORTS_EVENTS.FILTER_REPORT, { | ||||||
|  |         filterType: 'businessHours', | ||||||
|  |         filterValue: value, | ||||||
|  |         reportType: this.type, | ||||||
|  |       }); | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers'; | import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers'; | ||||||
| import types from '../mutation-types'; | import types from '../mutation-types'; | ||||||
| import CampaignsAPI from '../../api/campaigns'; | import CampaignsAPI from '../../api/campaigns'; | ||||||
|  | import AnalyticsHelper from '../../helper/AnalyticsHelper'; | ||||||
|  | import { CAMPAIGNS_EVENTS } from '../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export const state = { | export const state = { | ||||||
|   records: [], |   records: [], | ||||||
| @@ -51,6 +53,7 @@ export const actions = { | |||||||
|     commit(types.SET_CAMPAIGN_UI_FLAG, { isUpdating: true }); |     commit(types.SET_CAMPAIGN_UI_FLAG, { isUpdating: true }); | ||||||
|     try { |     try { | ||||||
|       const response = await CampaignsAPI.update(id, updateObj); |       const response = await CampaignsAPI.update(id, updateObj); | ||||||
|  |       AnalyticsHelper.track(CAMPAIGNS_EVENTS.UPDATE_CAMPAIGN); | ||||||
|       commit(types.EDIT_CAMPAIGN, response.data); |       commit(types.EDIT_CAMPAIGN, response.data); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       throw new Error(error); |       throw new Error(error); | ||||||
| @@ -62,6 +65,7 @@ export const actions = { | |||||||
|     commit(types.SET_CAMPAIGN_UI_FLAG, { isDeleting: true }); |     commit(types.SET_CAMPAIGN_UI_FLAG, { isDeleting: true }); | ||||||
|     try { |     try { | ||||||
|       await CampaignsAPI.delete(id); |       await CampaignsAPI.delete(id); | ||||||
|  |       AnalyticsHelper.track(CAMPAIGNS_EVENTS.DELETE_CAMPAIGN); | ||||||
|       commit(types.DELETE_CAMPAIGN, id); |       commit(types.DELETE_CAMPAIGN, id); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       throw new Error(error); |       throw new Error(error); | ||||||
|   | |||||||
| @@ -5,6 +5,8 @@ import { | |||||||
| import types from '../../mutation-types'; | import types from '../../mutation-types'; | ||||||
| import ContactAPI from '../../../api/contacts'; | import ContactAPI from '../../../api/contacts'; | ||||||
| import AccountActionsAPI from '../../../api/accountActions'; | import AccountActionsAPI from '../../../api/accountActions'; | ||||||
|  | import AnalyticsHelper from '../../../helper/AnalyticsHelper'; | ||||||
|  | import { CONTACTS_EVENTS } from '../../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| const buildContactFormData = contactParams => { | const buildContactFormData = contactParams => { | ||||||
|   const formData = new FormData(); |   const formData = new FormData(); | ||||||
| @@ -104,6 +106,8 @@ export const actions = { | |||||||
|       const response = await ContactAPI.create( |       const response = await ContactAPI.create( | ||||||
|         isFormData ? buildContactFormData(contactParams) : contactParams |         isFormData ? buildContactFormData(contactParams) : contactParams | ||||||
|       ); |       ); | ||||||
|  |  | ||||||
|  |       AnalyticsHelper.track(CONTACTS_EVENTS.CREATE_CONTACT); | ||||||
|       commit(types.SET_CONTACT_ITEM, response.data.payload.contact); |       commit(types.SET_CONTACT_ITEM, response.data.payload.contact); | ||||||
|       commit(types.SET_CONTACT_UI_FLAG, { isCreating: false }); |       commit(types.SET_CONTACT_UI_FLAG, { isCreating: false }); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|   | |||||||
| @@ -10,9 +10,8 @@ import { | |||||||
|   isOnUnattendedView, |   isOnUnattendedView, | ||||||
| } from './helpers/actionHelpers'; | } from './helpers/actionHelpers'; | ||||||
| import messageReadActions from './actions/messageReadActions'; | import messageReadActions from './actions/messageReadActions'; | ||||||
| import AnalyticsHelper, { | import AnalyticsHelper from '../../../helper/AnalyticsHelper'; | ||||||
|   ANALYTICS_EVENTS, | import { CONVERSATION_EVENTS } from '../../../helper/AnalyticsHelper/events'; | ||||||
| } from '../../../helper/AnalyticsHelper'; |  | ||||||
| // actions | // actions | ||||||
| const actions = { | const actions = { | ||||||
|   getConversation: async ({ commit }, conversationId) => { |   getConversation: async ({ commit }, conversationId) => { | ||||||
| @@ -176,8 +175,8 @@ const actions = { | |||||||
|       const response = await MessageApi.create(pendingMessage); |       const response = await MessageApi.create(pendingMessage); | ||||||
|       AnalyticsHelper.track( |       AnalyticsHelper.track( | ||||||
|         pendingMessage.private |         pendingMessage.private | ||||||
|           ? ANALYTICS_EVENTS.SENT_PRIVATE_NOTE |           ? CONVERSATION_EVENTS.CONVERSATION.SENT_PRIVATE_NOTE | ||||||
|           : ANALYTICS_EVENTS.SENT_MESSAGE |           : CONVERSATION_EVENTS.CONVERSATION.SENT_MESSAGE | ||||||
|       ); |       ); | ||||||
|       commit(types.ADD_MESSAGE, { |       commit(types.ADD_MESSAGE, { | ||||||
|         ...response.data, |         ...response.data, | ||||||
|   | |||||||
| @@ -2,6 +2,8 @@ import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers'; | |||||||
| import types from '../mutation-types'; | import types from '../mutation-types'; | ||||||
| import CSATReports from '../../api/csatReports'; | import CSATReports from '../../api/csatReports'; | ||||||
| import { downloadCsvFile } from '../../helper/downloadHelper'; | import { downloadCsvFile } from '../../helper/downloadHelper'; | ||||||
|  | import AnalyticsHelper from '../../helper/AnalyticsHelper'; | ||||||
|  | import { REPORTS_EVENTS } from '../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| const computeDistribution = (value, total) => | const computeDistribution = (value, total) => | ||||||
|   ((value * 100) / total).toFixed(2); |   ((value * 100) / total).toFixed(2); | ||||||
| @@ -111,6 +113,9 @@ export const actions = { | |||||||
|   downloadCSATReports(_, params) { |   downloadCSATReports(_, params) { | ||||||
|     return CSATReports.download(params).then(response => { |     return CSATReports.download(params).then(response => { | ||||||
|       downloadCsvFile(params.fileName, response.data); |       downloadCsvFile(params.fileName, response.data); | ||||||
|  |       AnalyticsHelper.track(REPORTS_EVENTS.DOWNLOAD_REPORT, { | ||||||
|  |         reportType: 'csat', | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -6,9 +6,8 @@ import WebChannel from '../../api/channel/webChannel'; | |||||||
| import FBChannel from '../../api/channel/fbChannel'; | import FBChannel from '../../api/channel/fbChannel'; | ||||||
| import TwilioChannel from '../../api/channel/twilioChannel'; | import TwilioChannel from '../../api/channel/twilioChannel'; | ||||||
| import { throwErrorMessage } from '../utils/api'; | import { throwErrorMessage } from '../utils/api'; | ||||||
| import AnalyticsHelper, { | import AnalyticsHelper from '../../helper/AnalyticsHelper'; | ||||||
|   ANALYTICS_EVENTS, | import { ACCOUNT_EVENTS } from '../../helper/AnalyticsHelper/events'; | ||||||
| } from '../../helper/AnalyticsHelper'; |  | ||||||
|  |  | ||||||
| const buildInboxData = inboxParams => { | const buildInboxData = inboxParams => { | ||||||
|   const formData = new FormData(); |   const formData = new FormData(); | ||||||
| @@ -121,7 +120,7 @@ export const getters = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| const sendAnalyticsEvent = channelType => { | const sendAnalyticsEvent = channelType => { | ||||||
|   AnalyticsHelper.track(ANALYTICS_EVENTS.ADDED_AN_INBOX, { |   AnalyticsHelper.track(ACCOUNT_EVENTS.ADDED_AN_INBOX, { | ||||||
|     channelType, |     channelType, | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers'; | import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers'; | ||||||
| import types from '../mutation-types'; | import types from '../mutation-types'; | ||||||
| import LabelsAPI from '../../api/labels'; | import LabelsAPI from '../../api/labels'; | ||||||
|  | import AnalyticsHelper from '../../helper/AnalyticsHelper'; | ||||||
|  | import { LABEL_EVENTS } from '../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| export const state = { | export const state = { | ||||||
|   records: [], |   records: [], | ||||||
| @@ -43,6 +45,7 @@ export const actions = { | |||||||
|     commit(types.SET_LABEL_UI_FLAG, { isCreating: true }); |     commit(types.SET_LABEL_UI_FLAG, { isCreating: true }); | ||||||
|     try { |     try { | ||||||
|       const response = await LabelsAPI.create(cannedObj); |       const response = await LabelsAPI.create(cannedObj); | ||||||
|  |       AnalyticsHelper.track(LABEL_EVENTS.CREATE); | ||||||
|       commit(types.ADD_LABEL, response.data); |       commit(types.ADD_LABEL, response.data); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       const errorMessage = error?.response?.data?.message; |       const errorMessage = error?.response?.data?.message; | ||||||
| @@ -56,6 +59,7 @@ export const actions = { | |||||||
|     commit(types.SET_LABEL_UI_FLAG, { isUpdating: true }); |     commit(types.SET_LABEL_UI_FLAG, { isUpdating: true }); | ||||||
|     try { |     try { | ||||||
|       const response = await LabelsAPI.update(id, updateObj); |       const response = await LabelsAPI.update(id, updateObj); | ||||||
|  |       AnalyticsHelper.track(LABEL_EVENTS.UPDATE); | ||||||
|       commit(types.EDIT_LABEL, response.data); |       commit(types.EDIT_LABEL, response.data); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       throw new Error(error); |       throw new Error(error); | ||||||
| @@ -68,6 +72,7 @@ export const actions = { | |||||||
|     commit(types.SET_LABEL_UI_FLAG, { isDeleting: true }); |     commit(types.SET_LABEL_UI_FLAG, { isDeleting: true }); | ||||||
|     try { |     try { | ||||||
|       await LabelsAPI.delete(id); |       await LabelsAPI.delete(id); | ||||||
|  |       AnalyticsHelper.track(LABEL_EVENTS.DELETED); | ||||||
|       commit(types.DELETE_LABEL, id); |       commit(types.DELETE_LABEL, id); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       throw new Error(error); |       throw new Error(error); | ||||||
|   | |||||||
| @@ -2,6 +2,8 @@ | |||||||
| import * as types from '../mutation-types'; | import * as types from '../mutation-types'; | ||||||
| import Report from '../../api/reports'; | import Report from '../../api/reports'; | ||||||
| import { downloadCsvFile } from '../../helper/downloadHelper'; | import { downloadCsvFile } from '../../helper/downloadHelper'; | ||||||
|  | import AnalyticsHelper from '../../helper/AnalyticsHelper'; | ||||||
|  | import { REPORTS_EVENTS } from '../../helper/AnalyticsHelper/events'; | ||||||
|  |  | ||||||
| const state = { | const state = { | ||||||
|   fetchingStatus: false, |   fetchingStatus: false, | ||||||
| @@ -116,6 +118,10 @@ export const actions = { | |||||||
|     return Report.getAgentReports(reportObj) |     return Report.getAgentReports(reportObj) | ||||||
|       .then(response => { |       .then(response => { | ||||||
|         downloadCsvFile(reportObj.fileName, response.data); |         downloadCsvFile(reportObj.fileName, response.data); | ||||||
|  |         AnalyticsHelper.track(REPORTS_EVENTS.DOWNLOAD_REPORT, { | ||||||
|  |           reportType: 'agent', | ||||||
|  |           businessHours: reportObj?.businessHours, | ||||||
|  |         }); | ||||||
|       }) |       }) | ||||||
|       .catch(error => { |       .catch(error => { | ||||||
|         console.error(error); |         console.error(error); | ||||||
| @@ -125,6 +131,10 @@ export const actions = { | |||||||
|     return Report.getLabelReports(reportObj) |     return Report.getLabelReports(reportObj) | ||||||
|       .then(response => { |       .then(response => { | ||||||
|         downloadCsvFile(reportObj.fileName, response.data); |         downloadCsvFile(reportObj.fileName, response.data); | ||||||
|  |         AnalyticsHelper.track(REPORTS_EVENTS.DOWNLOAD_REPORT, { | ||||||
|  |           reportType: 'label', | ||||||
|  |           businessHours: reportObj?.businessHours, | ||||||
|  |         }); | ||||||
|       }) |       }) | ||||||
|       .catch(error => { |       .catch(error => { | ||||||
|         console.error(error); |         console.error(error); | ||||||
| @@ -134,6 +144,10 @@ export const actions = { | |||||||
|     return Report.getInboxReports(reportObj) |     return Report.getInboxReports(reportObj) | ||||||
|       .then(response => { |       .then(response => { | ||||||
|         downloadCsvFile(reportObj.fileName, response.data); |         downloadCsvFile(reportObj.fileName, response.data); | ||||||
|  |         AnalyticsHelper.track(REPORTS_EVENTS.DOWNLOAD_REPORT, { | ||||||
|  |           reportType: 'inbox', | ||||||
|  |           businessHours: reportObj?.businessHours, | ||||||
|  |         }); | ||||||
|       }) |       }) | ||||||
|       .catch(error => { |       .catch(error => { | ||||||
|         console.error(error); |         console.error(error); | ||||||
| @@ -143,6 +157,10 @@ export const actions = { | |||||||
|     return Report.getTeamReports(reportObj) |     return Report.getTeamReports(reportObj) | ||||||
|       .then(response => { |       .then(response => { | ||||||
|         downloadCsvFile(reportObj.fileName, response.data); |         downloadCsvFile(reportObj.fileName, response.data); | ||||||
|  |         AnalyticsHelper.track(REPORTS_EVENTS.DOWNLOAD_REPORT, { | ||||||
|  |           reportType: 'team', | ||||||
|  |           businessHours: reportObj?.businessHours, | ||||||
|  |         }); | ||||||
|       }) |       }) | ||||||
|       .catch(error => { |       .catch(error => { | ||||||
|         console.error(error); |         console.error(error); | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ import { | |||||||
| import FluentIcon from 'shared/components/FluentIcon/DashboardIcon'; | import FluentIcon from 'shared/components/FluentIcon/DashboardIcon'; | ||||||
| import VueDOMPurifyHTML from 'vue-dompurify-html'; | import VueDOMPurifyHTML from 'vue-dompurify-html'; | ||||||
| import { domPurifyConfig } from '../shared/helpers/HTMLSanitizer'; | import { domPurifyConfig } from '../shared/helpers/HTMLSanitizer'; | ||||||
| import AnalyticsHelper from '../dashboard/helper/AnalyticsHelper'; | import AnalyticsPlugin from '../dashboard/helper/AnalyticsHelper/plugin'; | ||||||
|  |  | ||||||
| Vue.config.env = process.env; | Vue.config.env = process.env; | ||||||
|  |  | ||||||
| @@ -55,6 +55,7 @@ Vue.use(VTooltip, { | |||||||
|   defaultHtml: false, |   defaultHtml: false, | ||||||
| }); | }); | ||||||
| Vue.use(hljs.vuePlugin); | Vue.use(hljs.vuePlugin); | ||||||
|  | Vue.use(AnalyticsPlugin); | ||||||
|  |  | ||||||
| Vue.component('multiselect', Multiselect); | Vue.component('multiselect', Multiselect); | ||||||
| Vue.component('woot-switch', WootSwitch); | Vue.component('woot-switch', WootSwitch); | ||||||
| @@ -74,7 +75,6 @@ window.WootConstants = constants; | |||||||
| window.axios = createAxios(axios); | window.axios = createAxios(axios); | ||||||
| window.bus = new Vue(); | window.bus = new Vue(); | ||||||
| initializeChatwootEvents(); | initializeChatwootEvents(); | ||||||
| AnalyticsHelper.init(); |  | ||||||
| initializeAnalyticsEvents(); | initializeAnalyticsEvents(); | ||||||
| initalizeRouter(); | initalizeRouter(); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Shivam Mishra
					Shivam Mishra