diff --git a/web/satellite/vuetify-poc/src/components/ProjectCard.vue b/web/satellite/vuetify-poc/src/components/ProjectCard.vue index 8a039a209..7195bce4c 100644 --- a/web/satellite/vuetify-poc/src/components/ProjectCard.vue +++ b/web/satellite/vuetify-poc/src/components/ProjectCard.vue @@ -98,6 +98,8 @@ import { ProjectItemModel, PROJECT_ROLE_COLORS } from '@poc/types/projects'; import { ProjectInvitationResponse } from '@/types/projects'; import { ProjectRole } from '@/types/projectMembers'; import { useProjectsStore } from '@/store/modules/projectsStore'; +import { useAnalyticsStore } from '@/store/modules/analyticsStore'; +import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; import IconProject from '@poc/components/icons/IconProject.vue'; import IconSettings from '@poc/components/icons/IconSettings.vue'; @@ -111,6 +113,7 @@ const emit = defineEmits<{ (event: 'joinClick'): void; }>(); +const analyticsStore = useAnalyticsStore(); const projectsStore = useProjectsStore(); const router = useRouter(); @@ -123,6 +126,7 @@ function openProject(): void { if (!props.item) return; projectsStore.selectProject(props.item.id); router.push(`/projects/${props.item.id}/dashboard`); + analyticsStore.pageVisit('/projects/dashboard'); } /** @@ -132,7 +136,11 @@ async function declineInvitation(): Promise { if (!props.item || isDeclining.value) return; isDeclining.value = true; - await projectsStore.respondToInvitation(props.item.id, ProjectInvitationResponse.Decline).catch(_ => {}); + try { + await projectsStore.respondToInvitation(props.item.id, ProjectInvitationResponse.Decline); + analyticsStore.eventTriggered(AnalyticsEvent.PROJECT_INVITATION_DECLINED); + } catch { /* empty */ } + await projectsStore.getUserInvitations().catch(_ => {}); await projectsStore.getProjects().catch(_ => {}); diff --git a/web/satellite/vuetify-poc/src/components/ProjectsTableComponent.vue b/web/satellite/vuetify-poc/src/components/ProjectsTableComponent.vue index a436a0203..2a0789d25 100644 --- a/web/satellite/vuetify-poc/src/components/ProjectsTableComponent.vue +++ b/web/satellite/vuetify-poc/src/components/ProjectsTableComponent.vue @@ -130,6 +130,8 @@ import { ProjectInvitationResponse } from '@/types/projects'; import { ProjectRole } from '@/types/projectMembers'; import { SHORT_MONTHS_NAMES } from '@/utils/constants/date'; import { useProjectsStore } from '@/store/modules/projectsStore'; +import { useAnalyticsStore } from '@/store/modules/analyticsStore'; +import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; import IconSettings from '@poc/components/icons/IconSettings.vue'; import IconTeam from '@poc/components/icons/IconTeam.vue'; @@ -145,6 +147,7 @@ const emit = defineEmits<{ const search = ref(''); const decliningIds = ref(new Set()); +const analyticsStore = useAnalyticsStore(); const projectsStore = useProjectsStore(); const router = useRouter(); @@ -170,6 +173,7 @@ function getFormattedDate(date: Date): string { function openProject(item: ProjectItemModel): void { projectsStore.selectProject(item.id); router.push(`/projects/${item.id}/dashboard`); + analyticsStore.pageVisit('/projects/dashboard'); } /** @@ -179,7 +183,11 @@ async function declineInvitation(item: ProjectItemModel): Promise { if (decliningIds.value.has(item.id)) return; decliningIds.value.add(item.id); - await projectsStore.respondToInvitation(item.id, ProjectInvitationResponse.Decline).catch(_ => {}); + try { + await projectsStore.respondToInvitation(item.id, ProjectInvitationResponse.Decline); + analyticsStore.eventTriggered(AnalyticsEvent.PROJECT_INVITATION_DECLINED); + } catch { /* empty */ } + await projectsStore.getUserInvitations().catch(_ => {}); await projectsStore.getProjects().catch(_ => {}); diff --git a/web/satellite/vuetify-poc/src/components/dialogs/ChangeNameDialog.vue b/web/satellite/vuetify-poc/src/components/dialogs/ChangeNameDialog.vue index fde3cb0a9..cd25f07fc 100644 --- a/web/satellite/vuetify-poc/src/components/dialogs/ChangeNameDialog.vue +++ b/web/satellite/vuetify-poc/src/components/dialogs/ChangeNameDialog.vue @@ -93,11 +93,14 @@ import { import { useLoading } from '@/composables/useLoading'; import { useUsersStore } from '@/store/modules/usersStore'; import { UpdatedUser } from '@/types/users'; +import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; +import { useAnalyticsStore } from '@/store/modules/analyticsStore'; const rules = [ (value: string) => (!!value || 'Can\'t be empty'), ]; +const analyticsStore = useAnalyticsStore(); const userStore = useUsersStore(); const { isLoading, withLoading } = useLoading(); @@ -125,6 +128,8 @@ async function onChangeName(): Promise { await withLoading(async () => { try { await userStore.updateUser(new UpdatedUser(name.value, name.value)); + + analyticsStore.eventTriggered(AnalyticsEvent.PROFILE_UPDATED); } catch (error) { return; } diff --git a/web/satellite/vuetify-poc/src/components/dialogs/ChangePasswordDialog.vue b/web/satellite/vuetify-poc/src/components/dialogs/ChangePasswordDialog.vue index 6c4755ae6..5cbc85813 100644 --- a/web/satellite/vuetify-poc/src/components/dialogs/ChangePasswordDialog.vue +++ b/web/satellite/vuetify-poc/src/components/dialogs/ChangePasswordDialog.vue @@ -119,6 +119,8 @@ import { useLoading } from '@/composables/useLoading'; import { useConfigStore } from '@/store/modules/configStore'; import { AuthHttpApi } from '@/api/auth'; import { RouteConfig } from '@/types/router'; +import { useAnalyticsStore } from '@/store/modules/analyticsStore'; +import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; const DELAY_BEFORE_REDIRECT = 2000; // 2 sec const auth: AuthHttpApi = new AuthHttpApi(); @@ -134,6 +136,7 @@ const repeatRules = [ (value: string) => (value && value === newPassword.value || 'Passwords are not the same.'), ]; +const analyticsStore = useAnalyticsStore(); const { config } = useConfigStore().state; const { isLoading, withLoading } = useLoading(); const router = useRouter(); @@ -163,6 +166,8 @@ async function onChangePassword(): Promise { await withLoading(async () => { try { await auth.changePassword(oldPassword.value, newPassword.value); + + analyticsStore.eventTriggered(AnalyticsEvent.PASSWORD_CHANGED); } catch (error) { return; } diff --git a/web/satellite/vuetify-poc/src/components/dialogs/EnableMFADialog.vue b/web/satellite/vuetify-poc/src/components/dialogs/EnableMFADialog.vue index cf53f9515..f762ab124 100644 --- a/web/satellite/vuetify-poc/src/components/dialogs/EnableMFADialog.vue +++ b/web/satellite/vuetify-poc/src/components/dialogs/EnableMFADialog.vue @@ -162,6 +162,8 @@ import QRCode from 'qrcode'; import { useLoading } from '@/composables/useLoading'; import { useConfigStore } from '@/store/modules/configStore'; import { useUsersStore } from '@/store/modules/usersStore'; +import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; +import { useAnalyticsStore } from '@/store/modules/analyticsStore'; const rules = [ (value: string) => (!!value || 'Can\'t be empty'), @@ -170,6 +172,7 @@ const rules = [ (value: string) => (value.length === 6 || 'Can only be 6 numbers long'), ]; +const analyticsStore = useAnalyticsStore(); const { config } = useConfigStore().state; const usersStore = useUsersStore(); const { isLoading, withLoading } = useLoading(); @@ -234,6 +237,8 @@ function enable(): void { await usersStore.enableUserMFA(confirmPasscode.value); await usersStore.getUser(); await showCodes(); + + analyticsStore.eventTriggered(AnalyticsEvent.MFA_ENABLED); } catch (error) { isError.value = true; } diff --git a/web/satellite/vuetify-poc/src/components/dialogs/JoinProjectDialog.vue b/web/satellite/vuetify-poc/src/components/dialogs/JoinProjectDialog.vue index ad883a93e..97c15de3f 100644 --- a/web/satellite/vuetify-poc/src/components/dialogs/JoinProjectDialog.vue +++ b/web/satellite/vuetify-poc/src/components/dialogs/JoinProjectDialog.vue @@ -77,6 +77,9 @@ import { import { ProjectInvitationResponse } from '@/types/projects'; import { useProjectsStore } from '@/store/modules/projectsStore'; +import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; +import { useAnalyticsStore } from '@/store/modules/analyticsStore'; +import { RouteConfig } from '@/types/router'; const props = defineProps<{ modelValue: boolean, @@ -93,6 +96,7 @@ const emit = defineEmits<{ (event: 'update:modelValue', value: boolean): void, }>(); +const analyticsStore = useAnalyticsStore(); const projectsStore = useProjectsStore(); const router = useRouter(); @@ -105,6 +109,7 @@ const isDeclining = ref(false); function openProject(): void { projectsStore.selectProject(props.id); router.push(`/projects/${props.id}/dashboard`); + analyticsStore.pageVisit('/projects/dashboard'); } /** @@ -117,7 +122,16 @@ async function respondToInvitation(response: ProjectInvitationResponse): Promise isLoading.value = true; let success = false; - await projectsStore.respondToInvitation(props.id, response).then(() => { success = true; }).catch(_ => {}); + try { + await projectsStore.respondToInvitation(props.id, response); + success = true; + analyticsStore.eventTriggered( + response === ProjectInvitationResponse.Accept ? + AnalyticsEvent.PROJECT_INVITATION_ACCEPTED : + AnalyticsEvent.PROJECT_INVITATION_DECLINED, + ); + } catch { /* empty */ } + await projectsStore.getUserInvitations().catch(_ => {}); await projectsStore.getProjects().catch(_ => { success = false; }); diff --git a/web/satellite/vuetify-poc/src/layouts/default/AccountNav.vue b/web/satellite/vuetify-poc/src/layouts/default/AccountNav.vue index f99a3aca7..898459cf4 100644 --- a/web/satellite/vuetify-poc/src/layouts/default/AccountNav.vue +++ b/web/satellite/vuetify-poc/src/layouts/default/AccountNav.vue @@ -6,7 +6,7 @@