fix(editor): Add telemetry to Insights (#14511)

This commit is contained in:
Csaba Tuncsik
2025-04-10 12:46:49 +02:00
committed by GitHub
parent 313cfec74d
commit 2fb970aaa1
4 changed files with 56 additions and 7 deletions

View File

@@ -276,6 +276,8 @@ const handleSelect = (key: string) => {
trackHelpItemClick(key); trackHelpItemClick(key);
break; break;
} }
case 'insights':
telemetry.track('User clicked insights link from side menu');
default: default:
break; break;
} }

View File

@@ -371,6 +371,9 @@ const saveSettings = async () => {
void externalHooks.run('workflowSettings.saveSettings', { oldSettings }); void externalHooks.run('workflowSettings.saveSettings', { oldSettings });
telemetry.track('User updated workflow settings', { telemetry.track('User updated workflow settings', {
workflow_id: workflowsStore.workflowId, workflow_id: workflowsStore.workflowId,
// null and undefined values are removed from the object, but we need the keys to be there
time_saved: workflowSettings.value.timeSavedPerExecution ?? '',
error_workflow: workflowSettings.value.errorWorkflow ?? '',
}); });
}; };

View File

@@ -10,6 +10,7 @@ import type { InsightsSummary } from '@n8n/api-types';
import { smartDecimal } from '@n8n/utils/number/smartDecimal'; import { smartDecimal } from '@n8n/utils/number/smartDecimal';
import { computed, ref, useCssModule } from 'vue'; import { computed, ref, useCssModule } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useTelemetry } from '@/composables/useTelemetry';
const props = defineProps<{ const props = defineProps<{
summary: InsightsSummaryDisplay; summary: InsightsSummaryDisplay;
@@ -19,6 +20,7 @@ const props = defineProps<{
const i18n = useI18n(); const i18n = useI18n();
const route = useRoute(); const route = useRoute();
const $style = useCssModule(); const $style = useCssModule();
const telemetry = useTelemetry();
const lastNDays = ref(7); const lastNDays = ref(7);
@@ -50,6 +52,12 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
} }
return $style.neutral; return $style.neutral;
}; };
const trackTabClick = (insightType: keyof InsightsSummary) => {
telemetry.track(`User clicked ${summaryTitles.value[insightType]}`, {
referrer: route.name === VIEWS.INSIGHTS ? 'Dashboard' : 'Overview',
});
};
</script> </script>
<template> <template>
@@ -61,7 +69,7 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
:key="id" :key="id"
:data-test-id="`insights-summary-tab-${id}`" :data-test-id="`insights-summary-tab-${id}`"
> >
<router-link :to="to" :exact-active-class="$style.activeTab"> <router-link :to="to" :exact-active-class="$style.activeTab" @click="trackTabClick(id)">
<strong> <strong>
<N8nTooltip placement="bottom" :disabled="id !== 'timeSaved'"> <N8nTooltip placement="bottom" :disabled="id !== 'timeSaved'">
<template #content> <template #content>

View File

@@ -12,7 +12,10 @@ import N8nDataTableServer, {
type TableHeader, type TableHeader,
} from '@n8n/design-system/components/N8nDataTableServer/N8nDataTableServer.vue'; } from '@n8n/design-system/components/N8nDataTableServer/N8nDataTableServer.vue';
import { smartDecimal } from '@n8n/utils/number/smartDecimal'; import { smartDecimal } from '@n8n/utils/number/smartDecimal';
import { computed, ref } from 'vue'; import { useTelemetry } from '@/composables/useTelemetry';
import { VIEWS } from '@/constants';
import { computed, ref, watch } from 'vue';
import { type RouteLocationRaw } from 'vue-router';
const props = defineProps<{ const props = defineProps<{
data: InsightsByWorkflow; data: InsightsByWorkflow;
@@ -20,6 +23,7 @@ const props = defineProps<{
}>(); }>();
const i18n = useI18n(); const i18n = useI18n();
const telemetry = useTelemetry();
type Item = InsightsByWorkflow['data'][number]; type Item = InsightsByWorkflow['data'][number];
@@ -96,6 +100,28 @@ const emit = defineEmits<{
}, },
]; ];
}>(); }>();
const getWorkflowLink = (item: Item): RouteLocationRaw => ({
name: VIEWS.WORKFLOW,
params: {
name: item.workflowId,
},
});
const trackWorkflowClick = (item: Item) => {
telemetry.track('User clicked on workflow from insights table', {
workflow_id: item.workflowId,
});
};
watch(sortBy, (newValue) => {
telemetry.track('User sorted insights table', {
sorted_by: (newValue ?? []).map((item) => ({
...item,
label: headers.value.find((header) => header.key === item.id)?.title,
})),
});
});
</script> </script>
<template> <template>
@@ -112,11 +138,13 @@ const emit = defineEmits<{
@update:options="emit('update:options', $event)" @update:options="emit('update:options', $event)"
> >
<template #[`item.workflowName`]="{ item }"> <template #[`item.workflowName`]="{ item }">
<router-link :to="getWorkflowLink(item)" class="link" @click="trackWorkflowClick(item)">
<N8nTooltip :content="item.workflowName" placement="top"> <N8nTooltip :content="item.workflowName" placement="top">
<div class="ellipsis"> <div class="ellipsis">
{{ item.workflowName }} {{ item.workflowName }}
</div> </div>
</N8nTooltip> </N8nTooltip>
</router-link>
</template> </template>
<template #[`item.projectName`]="{ item }"> <template #[`item.projectName`]="{ item }">
<N8nTooltip v-if="item.projectName" :content="item.projectName" placement="top"> <N8nTooltip v-if="item.projectName" :content="item.projectName" placement="top">
@@ -137,4 +165,12 @@ const emit = defineEmits<{
text-overflow: ellipsis; text-overflow: ellipsis;
line-height: 1.2; line-height: 1.2;
} }
.link {
display: flex;
height: 100%;
align-items: center;
text-decoration: none;
color: var(--color-text-base);
}
</style> </style>