feat: more events tracking for SaaS (#6234)

This commit is contained in:
Shivam Mishra
2023-01-18 11:23:40 +05:30
committed by GitHub
parent 1df1b1f8e4
commit 37b9816827
40 changed files with 539 additions and 50 deletions

View File

@@ -70,6 +70,7 @@ import { mapGetters } from 'vuex';
import { filterAttributeGroups } from '../contactFilterItems';
import filterMixin from 'shared/mixins/filterMixin';
import * as OPERATORS from 'dashboard/components/widgets/FilterInput/FilterOperatorTypes.js';
import { CONTACTS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
export default {
components: {
FilterInputBox,
@@ -251,6 +252,12 @@ export default {
JSON.parse(JSON.stringify(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) {
this.appliedFilters[index].filter_operator = this.filterTypes.find(

View File

@@ -86,6 +86,7 @@ import contactFilterItems from '../contactFilterItems';
import filterQueryGenerator from '../../../../helper/filterQueryGenerator';
import AddCustomViews from 'dashboard/routes/dashboard/customviews/AddCustomViews';
import DeleteCustomViews from 'dashboard/routes/dashboard/customviews/DeleteCustomViews';
import { CONTACTS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
const DEFAULT_PAGE = 1;
const FILTER_TYPE_CONTACT = 1;
@@ -334,6 +335,14 @@ export default {
onSortChange(params) {
this.sortConfig = params;
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() {
this.showFiltersModal = !this.showFiltersModal;

View File

@@ -45,6 +45,7 @@
import Modal from '../../../../components/Modal';
import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
import { CONTACTS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
export default {
components: {
@@ -71,6 +72,9 @@ export default {
return '/downloads/import-contacts-sample.csv';
},
},
mounted() {
this.$track(CONTACTS_EVENTS.IMPORT_MODAL_OPEN);
},
methods: {
async uploadFile() {
try {
@@ -78,10 +82,12 @@ export default {
await this.$store.dispatch('contacts/import', this.file);
this.onClose();
this.showAlert(this.$t('IMPORT_CONTACTS.SUCCESS_MESSAGE'));
this.$track(CONTACTS_EVENTS.IMPORT_SUCCESS);
} catch (error) {
this.showAlert(
error.message || this.$t('IMPORT_CONTACTS.ERROR_MESSAGE')
);
this.$track(CONTACTS_EVENTS.IMPORT_FAILURE);
}
},
handleFileUpload() {

View File

@@ -35,9 +35,8 @@
import alertMixin from 'shared/mixins/alertMixin';
import { mixin as clickaway } from 'vue-clickaway';
import MacroPreview from './MacroPreview';
import AnalyticsHelper, {
ANALYTICS_EVENTS,
} from '../../../../helper/AnalyticsHelper';
import { CONVERSATION_EVENTS } from '../../../../helper/AnalyticsHelper/events';
export default {
components: {
MacroPreview,
@@ -67,7 +66,7 @@ export default {
macroId: macro.id,
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'));
} catch (error) {
this.showAlert(this.$t('MACROS.ERROR'));

View File

@@ -31,6 +31,7 @@
<script>
import { required, minLength } from 'vuelidate/lib/validators';
import alertMixin from 'shared/mixins/alertMixin';
import { CONTACTS_EVENTS } from '../../../helper/AnalyticsHelper/events';
export default {
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_SEGMENTS.SUCCESS_MESSAGE');
this.onClose();
this.$track(CONTACTS_EVENTS.SAVE_FILTER, {
type: this.filterType === 0 ? 'folder' : 'segment',
});
} catch (error) {
const errorMessage = error?.message;
this.alertMessage =

View File

@@ -16,6 +16,7 @@
<script>
import alertMixin from 'shared/mixins/alertMixin';
import { CONTACTS_EVENTS } from '../../../helper/AnalyticsHelper/events';
export default {
mixins: [alertMixin],
props: {
@@ -82,6 +83,9 @@ export default {
? this.$t('FILTER.CUSTOM_VIEWS.DELETE.API_FOLDERS.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) {
const errorMessage =
error?.response?.message || this.activeFilterType === 0

View File

@@ -42,6 +42,7 @@ import Modal from 'dashboard/components/Modal';
import alertMixin from 'shared/mixins/alertMixin';
import { required } from 'vuelidate/lib/validators';
import allLocales from 'shared/constants/locales.js';
import { PORTALS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
export default {
components: {
Modal,
@@ -108,6 +109,11 @@ export default {
'HELP_CENTER.PORTAL.ADD_LOCALE.API.SUCCESS_MESSAGE'
);
this.onClose();
this.$track(PORTALS_EVENTS.CREATE_LOCALE, {
localeAdded: this.selectedLocale,
totalLocales: updatedLocales.length,
from: this.$route.name,
});
} catch (error) {
this.alertMessage =
error?.message ||

View File

@@ -107,6 +107,7 @@
import alertMixin from 'shared/mixins/alertMixin';
import { mixin as clickaway } from 'vue-clickaway';
import wootConstants from 'dashboard/constants.js';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
const { ARTICLE_STATUS_TYPES } = wootConstants;
@@ -186,6 +187,11 @@ export default {
});
this.statusUpdateSuccessMessage(status);
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) {
this.alertMessage =
error?.message || this.statusUpdateErrorMessage(status);

View File

@@ -190,6 +190,7 @@ import thumbnail from 'dashboard/components/widgets/Thumbnail';
import LocaleItemTable from './PortalListItemTable';
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
import alertMixin from 'shared/mixins/alertMixin';
import { PORTALS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
export default {
components: {
@@ -309,6 +310,10 @@ export default {
'HELP_CENTER.PORTAL.CHANGE_DEFAULT_LOCALE.API.ERROR_MESSAGE'
),
});
this.$track(PORTALS_EVENTS.SET_DEFAULT_LOCALE, {
newLocale: localeCode,
from: this.$route.name,
});
},
deletePortalLocale({ localeCode }) {
const updatedLocales = this.allowedLocales.filter(
@@ -325,6 +330,10 @@ export default {
'HELP_CENTER.PORTAL.DELETE_LOCALE.API.ERROR_MESSAGE'
),
});
this.$track(PORTALS_EVENTS.DELETE_LOCALE, {
deletedLocale: localeCode,
from: this.$route.name,
});
},
async updatePortalLocales({
allowedLocales,

View File

@@ -53,6 +53,7 @@ import portalMixin from '../../mixins/portalMixin';
import alertMixin from 'shared/mixins/alertMixin';
import wootConstants from 'dashboard/constants';
import { buildPortalArticleURL } from 'dashboard/helper/portalHelper';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
const { ARTICLE_STATUS_TYPES } = wootConstants;
export default {
@@ -118,6 +119,9 @@ export default {
confirmDeletion() {
this.closeDeletePopup();
this.deleteArticle();
this.$track(PORTALS_EVENTS.DELETE_ARTICLE, {
status: this.article?.status,
});
},
async saveArticle({ ...values }) {
this.isUpdating = true;
@@ -171,6 +175,7 @@ export default {
status: ARTICLE_STATUS_TYPES.ARCHIVE,
});
this.alertMessage = this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.SUCCESS');
this.$track(PORTALS_EVENTS.ARCHIVE_ARTICLE, { uiFrom: 'sidebar' });
} catch (error) {
this.alertMessage =
error?.message || this.$t('HELP_CENTER.ARCHIVE_ARTICLE.API.ERROR');
@@ -186,6 +191,9 @@ export default {
},
showArticleInPortal() {
window.open(this.portalLink, '_blank');
this.$track(PORTALS_EVENTS.PREVIEW_ARTICLE, {
status: this.article?.status,
});
},
},
};

View File

@@ -29,6 +29,7 @@ import ArticleEditor from '../../components/ArticleEditor.vue';
import portalMixin from '../../mixins/portalMixin';
import alertMixin from 'shared/mixins/alertMixin.js';
import ArticleSettings from './ArticleSettings.vue';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
export default {
components: {
EditArticleHeader,
@@ -91,6 +92,9 @@ export default {
recentlyCreated: true,
},
});
this.$track(PORTALS_EVENTS.CREATE_ARTICLE, {
locale: this.locale,
});
} catch (error) {
this.alertMessage =
error?.message ||

View File

@@ -70,6 +70,7 @@
import alertMixin from 'shared/mixins/alertMixin';
import { required, minLength } from 'vuelidate/lib/validators';
import { convertToCategorySlug } from 'dashboard/helper/commons.js';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
export default {
mixins: [alertMixin],
@@ -158,6 +159,9 @@ export default {
'HELP_CENTER.CATEGORY.ADD.API.SUCCESS_MESSAGE'
);
this.onClose();
this.$track(PORTALS_EVENTS.CREATE_CATEGORY, {
hasDescription: Boolean(description),
});
} catch (error) {
const errorMessage = error?.message;
this.alertMessage =

View File

@@ -58,7 +58,7 @@
variant="smooth"
icon="delete"
color-scheme="alert"
@click="deleteCategory(category.id)"
@click="deleteCategory(category)"
/>
</td>
</tr>
@@ -83,8 +83,8 @@ export default {
editCategory(category) {
this.$emit('edit', category);
},
deleteCategory(categoryId) {
this.$emit('delete', categoryId);
deleteCategory(category) {
this.$emit('delete', category);
},
},
};

View File

@@ -70,6 +70,7 @@
import alertMixin from 'shared/mixins/alertMixin';
import { required, minLength } from 'vuelidate/lib/validators';
import { convertToCategorySlug } from 'dashboard/helper/commons.js';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
export default {
mixins: [alertMixin],
@@ -166,6 +167,7 @@ export default {
this.alertMessage = this.$t(
'HELP_CENTER.CATEGORY.EDIT.API.SUCCESS_MESSAGE'
);
this.$track(PORTALS_EVENTS.EDIT_CATEGORY);
this.onClose();
} catch (error) {
const errorMessage = error?.message;

View File

@@ -64,6 +64,7 @@ import portalMixin from '../../mixins/portalMixin';
import CategoryListItem from './CategoryListItem';
import AddCategory from './AddCategory';
import EditCategory from './EditCategory';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
export default {
components: {
@@ -137,15 +138,18 @@ export default {
locale: localeCode,
});
},
async deleteCategory(categoryId) {
async deleteCategory(category) {
try {
await this.$store.dispatch('categories/delete', {
portalSlug: this.currentPortalSlug,
categoryId: categoryId,
categoryId: category.id,
});
this.alertMessage = this.$t(
'HELP_CENTER.CATEGORY.DELETE.API.SUCCESS_MESSAGE'
);
this.$track(PORTALS_EVENTS.DELETE_CATEGORY, {
hasArticles: category?.meta?.articles_count !== 0,
});
} catch (error) {
const errorMessage = error?.message;
this.alertMessage =

View File

@@ -36,6 +36,7 @@ import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
import LocaleItemTable from 'dashboard/routes/dashboard/helpcenter/components/PortalListItemTable.vue';
import AddLocale from 'dashboard/routes/dashboard/helpcenter/components/AddLocale';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
export default {
components: {
LocaleItemTable,
@@ -85,6 +86,10 @@ export default {
'HELP_CENTER.PORTAL.CHANGE_DEFAULT_LOCALE.API.ERROR_MESSAGE'
),
});
this.$track(PORTALS_EVENTS.SET_DEFAULT_LOCALE, {
newLocale: localeCode,
from: this.$route.name,
});
},
deletePortalLocale({ localeCode }) {
const updatedLocales = this.allowedLocales.filter(
@@ -101,6 +106,10 @@ export default {
'HELP_CENTER.PORTAL.DELETE_LOCALE.API.ERROR_MESSAGE'
),
});
this.$track(PORTALS_EVENTS.DELETE_LOCALE, {
deletedLocale: localeCode,
from: this.$route.name,
});
},
async updatePortalLocales({
allowedLocales,

View File

@@ -17,6 +17,7 @@ import PortalSettingsCustomizationForm from 'dashboard/routes/dashboard/helpcent
import { mapGetters } from 'vuex';
import { getRandomColor } from 'dashboard/helper/labelColor';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
export default {
components: {
@@ -52,7 +53,6 @@ export default {
},
async updatePortalSettings(portalObj) {
const portalSlug = this.$route.params.portalSlug;
try {
await this.$store.dispatch('portals/update', {
portalSlug,
@@ -61,6 +61,12 @@ export default {
this.alertMessage = this.$t(
'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) {
this.alertMessage =
error?.message ||

View File

@@ -15,6 +15,7 @@ import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
import PortalSettingsBasicForm from 'dashboard/routes/dashboard/helpcenter/components/PortalSettingsBasicForm';
import { PORTALS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
export default {
components: {
@@ -49,6 +50,11 @@ export default {
name: 'portal_customization',
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) {
this.alertMessage =
error?.message ||

View File

@@ -177,6 +177,7 @@ import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
import campaignMixin from 'shared/mixins/campaignMixin';
import WootDateTimePicker from 'dashboard/components/ui/DateTimePicker.vue';
import { URLPattern } from 'urlpattern-polyfill';
import { CAMPAIGNS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
export default {
components: {
@@ -275,6 +276,11 @@ export default {
];
},
},
mounted() {
this.$track(CAMPAIGNS_EVENTS.OPEN_NEW_CAMPAIGN_MODAL, {
type: this.campaignType,
});
},
methods: {
onClose() {
this.$emit('on-close');
@@ -339,6 +345,12 @@ export default {
try {
const campaignDetails = this.getCampaignDetails();
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.onClose();
} catch (error) {

View File

@@ -25,6 +25,7 @@ import CsatTable from './components/CsatTable';
import ReportFilterSelector from './components/FilterSelector';
import { mapGetters } from 'vuex';
import { generateFileName } from '../../../../helper/downloadHelper';
import { REPORTS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
export default {
name: 'CsatResponses',
@@ -66,6 +67,13 @@ export default {
this.getResponses();
},
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.to = to;
this.getAllData();
@@ -73,6 +81,10 @@ export default {
onAgentsFilterChange(agents) {
this.userIds = agents.map(el => el.id);
this.getAllData();
this.$track(REPORTS_EVENTS.FILTER_REPORT, {
filterType: 'agent',
reportType: 'csat',
});
},
downloadReports() {
const type = 'csat';

View File

@@ -58,6 +58,7 @@ import ReportFilterSelector from './components/FilterSelector';
import { GROUP_BY_FILTER, METRIC_CHART } from './constants';
import reportMixin from '../../../../mixins/reportMixin';
import { formatTime } from '@chatwoot/utils';
import { REPORTS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
const REPORTS_KEYS = {
CONVERSATIONS: 'conversations_count',
@@ -222,6 +223,13 @@ export default {
this.fetchChartData();
},
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.to = to;
this.filterItemsList = this.fetchFilterItems(groupBy);
@@ -239,6 +247,12 @@ export default {
onFilterChange(payload) {
this.groupBy = GROUP_BY_FILTER[payload.id];
this.fetchAllData();
this.$track(REPORTS_EVENTS.FILTER_REPORT, {
filterType: 'groupBy',
filterValue: this.groupBy?.period,
reportType: 'conversations',
});
},
fetchFilterItems(group_by) {
switch (group_by) {
@@ -255,6 +269,12 @@ export default {
onBusinessHoursToggle(value) {
this.businessHours = value;
this.fetchAllData();
this.$track(REPORTS_EVENTS.FILTER_REPORT, {
filterType: 'businessHours',
filterValue: value,
reportType: 'conversations',
});
},
},
};

View File

@@ -62,6 +62,7 @@ import { GROUP_BY_FILTER, METRIC_CHART } from '../constants';
import reportMixin from '../../../../../mixins/reportMixin';
import { formatTime } from '@chatwoot/utils';
import { generateFileName } from '../../../../../helper/downloadHelper';
import { REPORTS_EVENTS } from '../../../../../helper/AnalyticsHelper/events';
const REPORTS_KEYS = {
CONVERSATIONS: 'conversations_count',
@@ -269,6 +270,14 @@ export default {
this.fetchChartData();
},
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.to = to;
this.groupByfilterItemsList = this.fetchFilterItems(groupBy);
@@ -292,6 +301,12 @@ export default {
onGroupByFilterChange(payload) {
this.groupBy = GROUP_BY_FILTER[payload.id];
this.fetchAllData();
this.$track(REPORTS_EVENTS.FILTER_REPORT, {
filterType: 'groupBy',
filterValue: this.groupBy?.period,
reportType: this.type,
});
},
fetchFilterItems(group_by) {
switch (group_by) {
@@ -308,6 +323,12 @@ export default {
onBusinessHoursToggle(value) {
this.businessHours = value;
this.fetchAllData();
this.$track(REPORTS_EVENTS.FILTER_REPORT, {
filterType: 'businessHours',
filterValue: value,
reportType: this.type,
});
},
},
};