web/satellite: add tracking event for segment.io (#3641)
This commit is contained in:
parent
6ce22be744
commit
0253eff2ec
3
web/satellite/package-lock.json
generated
3
web/satellite/package-lock.json
generated
@ -1073,7 +1073,8 @@
|
|||||||
"@types/segment-analytics": {
|
"@types/segment-analytics": {
|
||||||
"version": "0.0.32",
|
"version": "0.0.32",
|
||||||
"resolved": "https://registry.npmjs.org/@types/segment-analytics/-/segment-analytics-0.0.32.tgz",
|
"resolved": "https://registry.npmjs.org/@types/segment-analytics/-/segment-analytics-0.0.32.tgz",
|
||||||
"integrity": "sha512-p0SHnfHfZwemTeaISvu8WUXtw81A4AOU4GEr7B9S9jLx2iu/z/4aLT0flRJtHVusVAlMeJSdobn0uD/oR1sFEw=="
|
"integrity": "sha512-p0SHnfHfZwemTeaISvu8WUXtw81A4AOU4GEr7B9S9jLx2iu/z/4aLT0flRJtHVusVAlMeJSdobn0uD/oR1sFEw==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/sinon": {
|
"@types/sinon": {
|
||||||
"version": "7.0.13",
|
"version": "7.0.13",
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
"dev": "vue-cli-service build --mode development"
|
"dev": "vue-cli-service build --mode development"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/segment-analytics": "0.0.32",
|
|
||||||
"apollo-cache-inmemory": "1.6.3",
|
"apollo-cache-inmemory": "1.6.3",
|
||||||
"apollo-client": "2.6.4",
|
"apollo-client": "2.6.4",
|
||||||
"apollo-link": "1.2.12",
|
"apollo-link": "1.2.12",
|
||||||
@ -37,6 +36,7 @@
|
|||||||
"@vue/cli-plugin-typescript": "3.11.0",
|
"@vue/cli-plugin-typescript": "3.11.0",
|
||||||
"@vue/cli-plugin-unit-jest": "3.11.0",
|
"@vue/cli-plugin-unit-jest": "3.11.0",
|
||||||
"@vue/cli-service": "3.11.0",
|
"@vue/cli-service": "3.11.0",
|
||||||
|
"@types/segment-analytics": "0.0.32",
|
||||||
"@vue/test-utils": "1.0.0-beta.29",
|
"@vue/test-utils": "1.0.0-beta.29",
|
||||||
"babel-core": "7.0.0-bridge.0",
|
"babel-core": "7.0.0-bridge.0",
|
||||||
"compression-webpack-plugin": "3.0.0",
|
"compression-webpack-plugin": "3.0.0",
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class='delete-account__form-container'>
|
<div class='delete-account__form-container'>
|
||||||
<p class='delete-account__form-container__confirmation-text'>Are you sure you want to delete your account? If you do so, all your information, projects and API Keys will be deleted forever (drop from the satellite).</p>
|
<p class='delete-account__form-container__confirmation-text'>Are you sure you want to delete your account? If you do so, all your information, projects and API Keys will be deleted forever (drop from the satellite).</p>
|
||||||
<HeaderedInput
|
<HeaderedInput
|
||||||
label='Enter your password'
|
label='Enter your password'
|
||||||
placeholder='Your Password'
|
placeholder='Your Password'
|
||||||
class='full-input'
|
class='full-input'
|
||||||
width='100%'
|
width='100%'
|
||||||
@ -55,7 +55,9 @@ import { AuthHttpApi } from '@/api/auth';
|
|||||||
import { RouteConfig } from '@/router';
|
import { RouteConfig } from '@/router';
|
||||||
import { AuthToken } from '@/utils/authToken';
|
import { AuthToken } from '@/utils/authToken';
|
||||||
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { validatePassword } from '@/utils/validation';
|
import { validatePassword } from '@/utils/validation';
|
||||||
|
import { LocalData } from '../../utils/localData';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
@ -94,6 +96,9 @@ export default class DeleteAccountPopup extends Vue {
|
|||||||
try {
|
try {
|
||||||
await this.auth.delete(this.password);
|
await this.auth.delete(this.password);
|
||||||
await this.$notify.success('Account was successfully deleted');
|
await this.$notify.success('Account was successfully deleted');
|
||||||
|
this.$segment.track(SegmentEvent.USER_DELETED, {
|
||||||
|
email: this.$store.getters.user.email,
|
||||||
|
});
|
||||||
|
|
||||||
AuthToken.remove();
|
AuthToken.remove();
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ import VPagination from '@/components/common/VPagination.vue';
|
|||||||
|
|
||||||
import { RouteConfig } from '@/router';
|
import { RouteConfig } from '@/router';
|
||||||
import { BillingHistoryItem } from '@/types/payments';
|
import { BillingHistoryItem } from '@/types/payments';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
@ -46,6 +47,13 @@ import { BillingHistoryItem } from '@/types/payments';
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class BillingHistory extends Vue {
|
export default class BillingHistory extends Vue {
|
||||||
|
public mounted(): void {
|
||||||
|
this.$segment.track(SegmentEvent.BILLING_HISTORY_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
invoice_count: this.$store.state.paymentsModule.billingHistory.length,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public get billingHistoryItems(): BillingHistoryItem[] {
|
public get billingHistoryItems(): BillingHistoryItem[] {
|
||||||
return this.$store.state.paymentsModule.billingHistory;
|
return this.$store.state.paymentsModule.billingHistory;
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ import VButton from '@/components/common/VButton.vue';
|
|||||||
import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
|
import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
|
||||||
import { CreditCard } from '@/types/payments';
|
import { CreditCard } from '@/types/payments';
|
||||||
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
|
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { PaymentMethodsBlockState } from '@/utils/constants/billingEnums';
|
import { PaymentMethodsBlockState } from '@/utils/constants/billingEnums';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -109,6 +110,9 @@ export default class PaymentMethods extends Vue {
|
|||||||
|
|
||||||
public mounted() {
|
public mounted() {
|
||||||
try {
|
try {
|
||||||
|
this.$segment.track(SegmentEvent.PAYMENT_METHODS_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
});
|
||||||
this.$store.dispatch(GET_CREDIT_CARDS);
|
this.$store.dispatch(GET_CREDIT_CARDS);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
|
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, error.message);
|
||||||
@ -178,6 +182,10 @@ export default class PaymentMethods extends Vue {
|
|||||||
await this.$notify.error(error.message);
|
await this.$notify.error(error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.$segment.track(SegmentEvent.PAYMENT_METHOD_ADDED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
});
|
||||||
|
|
||||||
this.tokenDepositValue = this.DEFAULT_TOKEN_DEPOSIT_VALUE;
|
this.tokenDepositValue = this.DEFAULT_TOKEN_DEPOSIT_VALUE;
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch(GET_BILLING_HISTORY);
|
await this.$store.dispatch(GET_BILLING_HISTORY);
|
||||||
@ -190,6 +198,9 @@ export default class PaymentMethods extends Vue {
|
|||||||
|
|
||||||
public async onConfirmAddStripe(): Promise<void> {
|
public async onConfirmAddStripe(): Promise<void> {
|
||||||
await this.$refs.stripeCardInput.onSubmit();
|
await this.$refs.stripeCardInput.onSubmit();
|
||||||
|
this.$segment.track(SegmentEvent.PAYMENT_METHOD_ADDED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async addCard(token: string) {
|
public async addCard(token: string) {
|
||||||
@ -210,6 +221,9 @@ export default class PaymentMethods extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Card successfully added');
|
await this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Card successfully added');
|
||||||
|
this.$segment.track(SegmentEvent.PAYMENT_METHOD_ADDED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch(GET_CREDIT_CARDS);
|
await this.$store.dispatch(GET_CREDIT_CARDS);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -123,6 +123,7 @@ import EmptySearchResultIcon from '@/../static/images/common/emptySearchResult.s
|
|||||||
import { ApiKey, ApiKeyOrderBy } from '@/types/apiKeys';
|
import { ApiKey, ApiKeyOrderBy } from '@/types/apiKeys';
|
||||||
import { SortDirection } from '@/types/common';
|
import { SortDirection } from '@/types/common';
|
||||||
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
|
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { EMPTY_STATE_IMAGES } from '@/utils/constants/emptyStatesImages';
|
import { EMPTY_STATE_IMAGES } from '@/utils/constants/emptyStatesImages';
|
||||||
|
|
||||||
import ApiKeysCopyPopup from './ApiKeysCopyPopup.vue';
|
import ApiKeysCopyPopup from './ApiKeysCopyPopup.vue';
|
||||||
@ -179,6 +180,10 @@ export default class ApiKeysArea extends Vue {
|
|||||||
|
|
||||||
public async mounted(): Promise<void> {
|
public async mounted(): Promise<void> {
|
||||||
await this.$store.dispatch(FETCH, 1);
|
await this.$store.dispatch(FETCH, 1);
|
||||||
|
this.$segment.track(SegmentEvent.API_KEYS_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
api_keys_count: this.selectedAPIKeysCount,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async beforeDestroy(): Promise<void> {
|
public async beforeDestroy(): Promise<void> {
|
||||||
@ -220,6 +225,9 @@ export default class ApiKeysArea extends Vue {
|
|||||||
try {
|
try {
|
||||||
await this.$store.dispatch(DELETE);
|
await this.$store.dispatch(DELETE);
|
||||||
await this.$notify.success(`API keys deleted successfully`);
|
await this.$notify.success(`API keys deleted successfully`);
|
||||||
|
this.$segment.track(SegmentEvent.API_KEY_DELETED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await this.$notify.error(error.message);
|
await this.$notify.error(error.message);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
|
|||||||
|
|
||||||
import { ApiKey } from '@/types/apiKeys';
|
import { ApiKey } from '@/types/apiKeys';
|
||||||
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
|
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
|
|
||||||
const CREATE = API_KEYS_ACTIONS.CREATE;
|
const CREATE = API_KEYS_ACTIONS.CREATE;
|
||||||
|
|
||||||
@ -95,6 +96,10 @@ export default class ApiKeysCreationPopup extends Vue {
|
|||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.name = '';
|
this.name = '';
|
||||||
|
|
||||||
|
this.$segment.track(SegmentEvent.API_KEY_CREATED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch(API_KEYS_ACTIONS.FETCH, this.FIRST_PAGE);
|
await this.$store.dispatch(API_KEYS_ACTIONS.FETCH, this.FIRST_PAGE);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
class="delete-project-input"
|
class="delete-project-input"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Enter Project Name"
|
placeholder="Enter Project Name"
|
||||||
v-model="projectName"
|
v-model="projectName"
|
||||||
@keyup="resetError"
|
@keyup="resetError"
|
||||||
@ -34,8 +34,8 @@
|
|||||||
/>
|
/>
|
||||||
<VButton
|
<VButton
|
||||||
label="Delete"
|
label="Delete"
|
||||||
width="205px"
|
width="205px"
|
||||||
height="48px"
|
height="48px"
|
||||||
class="red"
|
class="red"
|
||||||
:on-press="onDeleteProjectClick"
|
:on-press="onDeleteProjectClick"
|
||||||
:is-disabled="isDeleteButtonDisabled"
|
:is-disabled="isDeleteButtonDisabled"
|
||||||
@ -66,6 +66,7 @@ import {
|
|||||||
APP_STATE_ACTIONS,
|
APP_STATE_ACTIONS,
|
||||||
PM_ACTIONS,
|
PM_ACTIONS,
|
||||||
} from '@/utils/constants/actionNames';
|
} from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
@ -97,7 +98,9 @@ export default class DeleteProjectPopup extends Vue {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch(PROJECTS_ACTIONS.DELETE, this.$store.getters.selectedProject.id);
|
await this.$store.dispatch(PROJECTS_ACTIONS.DELETE, this.$store.getters.selectedProject.id);
|
||||||
|
this.$segment.track(SegmentEvent.PROJECT_DELETED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
});
|
||||||
await this.$notify.success('Project was successfully deleted');
|
await this.$notify.success('Project was successfully deleted');
|
||||||
|
|
||||||
await this.selectProject();
|
await this.selectProject();
|
||||||
|
@ -70,6 +70,7 @@ import {
|
|||||||
APP_STATE_ACTIONS,
|
APP_STATE_ACTIONS,
|
||||||
PM_ACTIONS,
|
PM_ACTIONS,
|
||||||
} from '@/utils/constants/actionNames';
|
} from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
@ -115,6 +116,9 @@ export default class NewProjectPopup extends Vue {
|
|||||||
try {
|
try {
|
||||||
const project = await this.createProject();
|
const project = await this.createProject();
|
||||||
this.createdProjectId = project.id;
|
this.createdProjectId = project.id;
|
||||||
|
this.$segment.track(SegmentEvent.PROJECT_CREATED, {
|
||||||
|
project_id: this.createdProjectId,
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
await this.$notify.error(e.message);
|
await this.$notify.error(e.message);
|
||||||
|
@ -67,6 +67,7 @@ import { RouteConfig } from '@/router';
|
|||||||
import { PROJECTS_ACTIONS } from '@/store/modules/projects';
|
import { PROJECTS_ACTIONS } from '@/store/modules/projects';
|
||||||
import { UpdateProjectModel } from '@/types/projects';
|
import { UpdateProjectModel } from '@/types/projects';
|
||||||
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { LocalData } from '@/utils/localData';
|
import { LocalData } from '@/utils/localData';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -85,6 +86,9 @@ export default class ProjectDetailsArea extends Vue {
|
|||||||
public async mounted(): Promise<void> {
|
public async mounted(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
|
await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
|
||||||
|
this.$segment.track(SegmentEvent.PROJECT_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await this.$notify.error(error.message);
|
await this.$notify.error(error.message);
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ import DownloadReportIcon from '@/../static/images/project/downloadReport.svg';
|
|||||||
import { RouteConfig } from '@/router';
|
import { RouteConfig } from '@/router';
|
||||||
import { PROJECT_USAGE_ACTIONS } from '@/store/modules/usage';
|
import { PROJECT_USAGE_ACTIONS } from '@/store/modules/usage';
|
||||||
import { DateRange } from '@/types/usage';
|
import { DateRange } from '@/types/usage';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { DateFormat } from '@/utils/datepicker';
|
import { DateFormat } from '@/utils/datepicker';
|
||||||
import { toUnixTimestamp } from '@/utils/time';
|
import { toUnixTimestamp } from '@/utils/time';
|
||||||
|
|
||||||
@ -126,6 +127,11 @@ export default class UsageReport extends Vue {
|
|||||||
|
|
||||||
public async mounted(): Promise<void> {
|
public async mounted(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
this.$segment.track(SegmentEvent.REPORT_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
start_date: this.dateRange.startDate,
|
||||||
|
end_date: this.dateRange.endDate,
|
||||||
|
});
|
||||||
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
|
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
|
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
|
||||||
@ -156,6 +162,11 @@ export default class UsageReport extends Vue {
|
|||||||
this.onButtonClickAction(event);
|
this.onButtonClickAction(event);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
this.$segment.track(SegmentEvent.REPORT_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
start_date: this.dateRange.startDate,
|
||||||
|
end_date: this.dateRange.endDate,
|
||||||
|
});
|
||||||
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
|
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
|
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
|
||||||
@ -166,6 +177,11 @@ export default class UsageReport extends Vue {
|
|||||||
this.onButtonClickAction(event);
|
this.onButtonClickAction(event);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
this.$segment.track(SegmentEvent.REPORT_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
start_date: this.dateRange.startDate,
|
||||||
|
end_date: this.dateRange.endDate,
|
||||||
|
});
|
||||||
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_PREVIOUS_ROLLUP);
|
await this.$store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_PREVIOUS_ROLLUP);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
|
await this.$notify.error(`Unable to fetch project usage. ${error.message}`);
|
||||||
@ -175,6 +191,11 @@ export default class UsageReport extends Vue {
|
|||||||
public onCustomDateClick(event: any): void {
|
public onCustomDateClick(event: any): void {
|
||||||
(this as any).$refs.datePicker.showCheck();
|
(this as any).$refs.datePicker.showCheck();
|
||||||
this.onButtonClickAction(event);
|
this.onButtonClickAction(event);
|
||||||
|
this.$segment.track(SegmentEvent.REPORT_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
start_date: this.dateRange.startDate,
|
||||||
|
end_date: this.dateRange.endDate,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public onReportClick(): void {
|
public onReportClick(): void {
|
||||||
@ -189,6 +210,12 @@ export default class UsageReport extends Vue {
|
|||||||
url.searchParams.append('since', toUnixTimestamp(startDate).toString());
|
url.searchParams.append('since', toUnixTimestamp(startDate).toString());
|
||||||
url.searchParams.append('before', toUnixTimestamp(endDate).toString());
|
url.searchParams.append('before', toUnixTimestamp(endDate).toString());
|
||||||
|
|
||||||
|
this.$segment.track(SegmentEvent.REPORT_DOWNLOADED, {
|
||||||
|
start_date: startDate,
|
||||||
|
end_date: endDate,
|
||||||
|
project_id: projectID,
|
||||||
|
});
|
||||||
|
|
||||||
window.open(url.href, '_blank');
|
window.open(url.href, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ import DeleteFieldIcon from '@/../static/images/team/deleteField.svg';
|
|||||||
import { RouteConfig } from '@/router';
|
import { RouteConfig } from '@/router';
|
||||||
import { EmailInput } from '@/types/EmailInput';
|
import { EmailInput } from '@/types/EmailInput';
|
||||||
import { APP_STATE_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames';
|
import { APP_STATE_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { validateEmail } from '@/utils/validation';
|
import { validateEmail } from '@/utils/validation';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -173,6 +174,11 @@ export default class AddUserPopup extends Vue {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.$segment.track(SegmentEvent.TEAM_MEMBER_INVITED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
invited_emails: emailArray,
|
||||||
|
});
|
||||||
|
|
||||||
await this.$notify.success('Members successfully added to project!');
|
await this.$notify.success('Members successfully added to project!');
|
||||||
this.$store.dispatch(PM_ACTIONS.SET_SEARCH_QUERY, '');
|
this.$store.dispatch(PM_ACTIONS.SET_SEARCH_QUERY, '');
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ import EmptySearchResultIcon from '@/../static/images/common/emptySearchResult.s
|
|||||||
import { SortDirection } from '@/types/common';
|
import { SortDirection } from '@/types/common';
|
||||||
import { ProjectMember, ProjectMemberHeaderState, ProjectMemberOrderBy } from '@/types/projectMembers';
|
import { ProjectMember, ProjectMemberHeaderState, ProjectMemberOrderBy } from '@/types/projectMembers';
|
||||||
import { PM_ACTIONS } from '@/utils/constants/actionNames';
|
import { PM_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
FETCH,
|
FETCH,
|
||||||
@ -82,6 +83,10 @@ export default class ProjectMembersArea extends Vue {
|
|||||||
|
|
||||||
public async mounted(): Promise<void> {
|
public async mounted(): Promise<void> {
|
||||||
await this.$store.dispatch(FETCH, 1);
|
await this.$store.dispatch(FETCH, 1);
|
||||||
|
this.$segment.track(SegmentEvent.TEAM_VIEWED, {
|
||||||
|
project_id: this.$store.getters.selectedProject.id,
|
||||||
|
team_member_count: this.projectMembersTotalCount,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public onMemberClick(member: ProjectMember): void {
|
public onMemberClick(member: ProjectMember): void {
|
||||||
|
@ -2,7 +2,20 @@
|
|||||||
// See LICENSE for copying information.
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
export enum SegmentEvent {
|
export enum SegmentEvent {
|
||||||
CLICKED_LOGO = 'clicked-on-logo',
|
PROJECT_CREATED= 'Project Created',
|
||||||
CLICKED_LOGIN = 'clicked-on-login',
|
PROJECT_DELETED= 'Project Deleted',
|
||||||
CLICKED_BACK_TO_LOGIN = 'clicked-on-back-to-login',
|
PROJECT_VIEWED= 'Project Viewed',
|
||||||
|
USER_DELETED= 'User Deleted',
|
||||||
|
USER_LOGGED_IN= 'User Logged In',
|
||||||
|
EMAIL_VERIFIED= 'Email Verified',
|
||||||
|
API_KEY_CREATED= 'API Key Created',
|
||||||
|
API_KEY_DELETED= 'API Key Deleted',
|
||||||
|
API_KEYS_VIEWED= 'API Key Viewed',
|
||||||
|
PAYMENT_METHODS_VIEWED= 'Payment Methods Viewed',
|
||||||
|
PAYMENT_METHOD_ADDED= 'Payment Method Added',
|
||||||
|
REPORT_DOWNLOADED= 'Report Downloaded',
|
||||||
|
REPORT_VIEWED= 'Report Viewed',
|
||||||
|
BILLING_HISTORY_VIEWED= 'Billing History Viewed',
|
||||||
|
TEAM_MEMBER_INVITED= 'Team Member Invited',
|
||||||
|
TEAM_VIEWED= 'Team Viewed',
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
|||||||
* Segmentio is a wrapper around segment.io analytics package
|
* Segmentio is a wrapper around segment.io analytics package
|
||||||
*/
|
*/
|
||||||
export class Segmentio {
|
export class Segmentio {
|
||||||
analytics: SegmentAnalytics.AnalyticsJS;
|
private analytics: SegmentAnalytics.AnalyticsJS;
|
||||||
public init(key: string) {
|
public init(key: string) {
|
||||||
if (this.analytics || key.length === 0 || key.includes('SegmentIOPublicKey')) {
|
if (this.analytics || key.length === 0 || key.includes('SegmentIOPublicKey')) {
|
||||||
return;
|
return;
|
||||||
@ -34,12 +34,12 @@ export class Segmentio {
|
|||||||
this.analytics.page();
|
this.analytics.page();
|
||||||
}
|
}
|
||||||
|
|
||||||
public identify() {
|
public identify(userId: string, traits?: Object, options?: SegmentAnalytics.SegmentOpts, callback?: () => void) {
|
||||||
if (!this.analytics) {
|
if (!this.analytics) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.analytics.identify();
|
this.analytics.identify(userId, traits, options, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public track(event: SegmentEvent, properties?: Object, options?: SegmentAnalytics.SegmentOpts, callback?: () => void) {
|
public track(event: SegmentEvent, properties?: Object, options?: SegmentAnalytics.SegmentOpts, callback?: () => void) {
|
||||||
|
@ -13,6 +13,7 @@ import LogoIcon from '@/../static/images/Logo.svg';
|
|||||||
|
|
||||||
import { AuthHttpApi } from '@/api/auth';
|
import { AuthHttpApi } from '@/api/auth';
|
||||||
import { RouteConfig } from '@/router';
|
import { RouteConfig } from '@/router';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
|
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
|
||||||
import { validateEmail } from '@/utils/validation';
|
import { validateEmail } from '@/utils/validation';
|
||||||
|
|
||||||
@ -51,11 +52,11 @@ export default class ForgotPassword extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onBackToLoginClick(): void {
|
public onBackToLoginClick(): void {
|
||||||
this.$router.push(RouteConfig.Login.path);
|
this.$router.push(RouteConfig.Login.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLogoClick(): void {
|
public onLogoClick(): void {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
private validateFields(): boolean {
|
private validateFields(): boolean {
|
||||||
|
@ -16,6 +16,7 @@ import { AuthHttpApi } from '@/api/auth';
|
|||||||
import { RouteConfig } from '@/router';
|
import { RouteConfig } from '@/router';
|
||||||
import { AuthToken } from '@/utils/authToken';
|
import { AuthToken } from '@/utils/authToken';
|
||||||
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { AppState } from '@/utils/constants/appStateEnum';
|
import { AppState } from '@/utils/constants/appStateEnum';
|
||||||
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
|
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
|
||||||
import { validateEmail, validatePassword } from '@/utils/validation';
|
import { validateEmail, validatePassword } from '@/utils/validation';
|
||||||
@ -78,6 +79,9 @@ export default class Login extends Vue {
|
|||||||
try {
|
try {
|
||||||
this.authToken = await this.auth.token(this.email, this.password);
|
this.authToken = await this.auth.token(this.email, this.password);
|
||||||
AuthToken.set(this.authToken);
|
AuthToken.set(this.authToken);
|
||||||
|
this.$segment.track(SegmentEvent.USER_LOGGED_IN, {
|
||||||
|
email: this.email,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await this.$notify.error(error.message);
|
await this.$notify.error(error.message);
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
@ -17,6 +17,7 @@ import { AuthHttpApi } from '@/api/auth';
|
|||||||
import { RouteConfig } from '@/router';
|
import { RouteConfig } from '@/router';
|
||||||
import { User } from '@/types/users';
|
import { User } from '@/types/users';
|
||||||
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
|
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
|
||||||
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
|
import { LOADING_CLASSES } from '@/utils/constants/classConstants';
|
||||||
import { LocalData } from '@/utils/localData';
|
import { LocalData } from '@/utils/localData';
|
||||||
import { validateEmail, validatePassword } from '@/utils/validation';
|
import { validateEmail, validatePassword } from '@/utils/validation';
|
||||||
@ -176,6 +177,11 @@ export default class RegisterArea extends Vue {
|
|||||||
|
|
||||||
LocalData.setUserId(this.userId);
|
LocalData.setUserId(this.userId);
|
||||||
|
|
||||||
|
this.$segment.identify(this.userId, {
|
||||||
|
email: this.$store.getters.user.email,
|
||||||
|
referralToken: this.referralToken,
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: improve it
|
// TODO: improve it
|
||||||
this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_SUCCESSFUL_REGISTRATION_POPUP);
|
this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_SUCCESSFUL_REGISTRATION_POPUP);
|
||||||
const registrationSuccessPopupRef = this.$refs['register_success_popup'];
|
const registrationSuccessPopupRef = this.$refs['register_success_popup'];
|
||||||
|
@ -10,13 +10,16 @@ import { makeNotificationsModule } from '@/store/modules/notifications';
|
|||||||
import { makeProjectsModule } from '@/store/modules/projects';
|
import { makeProjectsModule } from '@/store/modules/projects';
|
||||||
import { ApiKey, ApiKeysPage } from '@/types/apiKeys';
|
import { ApiKey, ApiKeysPage } from '@/types/apiKeys';
|
||||||
import { Project } from '@/types/projects';
|
import { Project } from '@/types/projects';
|
||||||
|
import { SegmentioPlugin } from '@/utils/plugins/segment';
|
||||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||||
|
|
||||||
import { ApiKeysMock } from '../mock/api/apiKeys';
|
import { ApiKeysMock } from '../mock/api/apiKeys';
|
||||||
import { ProjectsApiMock } from '../mock/api/projects';
|
import { ProjectsApiMock } from '../mock/api/projects';
|
||||||
|
|
||||||
const localVue = createLocalVue();
|
const localVue = createLocalVue();
|
||||||
|
const segmentioPlugin = new SegmentioPlugin();
|
||||||
localVue.use(Vuex);
|
localVue.use(Vuex);
|
||||||
|
localVue.use(segmentioPlugin);
|
||||||
|
|
||||||
const apiKeysApi = new ApiKeysMock();
|
const apiKeysApi = new ApiKeysMock();
|
||||||
const apiKeysModule = makeApiKeysModule(apiKeysApi);
|
const apiKeysModule = makeApiKeysModule(apiKeysApi);
|
||||||
|
@ -14,12 +14,15 @@ import { ApiKey } from '@/types/apiKeys';
|
|||||||
import { Project } from '@/types/projects';
|
import { Project } from '@/types/projects';
|
||||||
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
|
import { API_KEYS_ACTIONS } from '@/utils/constants/actionNames';
|
||||||
import { NotificatorPlugin } from '@/utils/plugins/notificator';
|
import { NotificatorPlugin } from '@/utils/plugins/notificator';
|
||||||
|
import { SegmentioPlugin } from '@/utils/plugins/segment';
|
||||||
import { createLocalVue, mount } from '@vue/test-utils';
|
import { createLocalVue, mount } from '@vue/test-utils';
|
||||||
|
|
||||||
const localVue = createLocalVue();
|
const localVue = createLocalVue();
|
||||||
localVue.use(Vuex);
|
localVue.use(Vuex);
|
||||||
const notificationPlugin = new NotificatorPlugin();
|
const notificationPlugin = new NotificatorPlugin();
|
||||||
|
const segmentioPlugin = new SegmentioPlugin();
|
||||||
localVue.use(notificationPlugin);
|
localVue.use(notificationPlugin);
|
||||||
|
localVue.use(segmentioPlugin);
|
||||||
const apiKeysApi = new ApiKeysApiGql();
|
const apiKeysApi = new ApiKeysApiGql();
|
||||||
const apiKeysModule = makeApiKeysModule(apiKeysApi);
|
const apiKeysModule = makeApiKeysModule(apiKeysApi);
|
||||||
const projectsApi = new ProjectsApiGql();
|
const projectsApi = new ProjectsApiGql();
|
||||||
|
@ -10,13 +10,16 @@ import { makeProjectMembersModule, PROJECT_MEMBER_MUTATIONS } from '@/store/modu
|
|||||||
import { makeProjectsModule } from '@/store/modules/projects';
|
import { makeProjectsModule } from '@/store/modules/projects';
|
||||||
import { ProjectMember, ProjectMembersPage } from '@/types/projectMembers';
|
import { ProjectMember, ProjectMembersPage } from '@/types/projectMembers';
|
||||||
import { Project } from '@/types/projects';
|
import { Project } from '@/types/projects';
|
||||||
|
import { SegmentioPlugin } from '@/utils/plugins/segment';
|
||||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||||
|
|
||||||
import { ProjectMembersApiMock } from '../mock/api/projectMembers';
|
import { ProjectMembersApiMock } from '../mock/api/projectMembers';
|
||||||
import { ProjectsApiMock } from '../mock/api/projects';
|
import { ProjectsApiMock } from '../mock/api/projects';
|
||||||
|
|
||||||
const localVue = createLocalVue();
|
const localVue = createLocalVue();
|
||||||
|
const segmentioPlugin = new SegmentioPlugin();
|
||||||
localVue.use(Vuex);
|
localVue.use(Vuex);
|
||||||
|
localVue.use(segmentioPlugin);
|
||||||
|
|
||||||
const pmApi = new ProjectMembersApiMock();
|
const pmApi = new ProjectMembersApiMock();
|
||||||
const projectMembersModule = makeProjectMembersModule(pmApi);
|
const projectMembersModule = makeProjectMembersModule(pmApi);
|
||||||
|
Loading…
Reference in New Issue
Block a user