feat(editor): Track AI credit balance clicks (no-changelog) (#36194)

This commit is contained in:
Romeo Balta 2026-08-13 11:56:37 +00:00 committed by GitHub
parent 598c1f3357
commit fd44d5911b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 1 deletions

View File

@ -3,6 +3,12 @@ import { z } from 'zod/v4';
import { defineTelemetryEvents } from '../define';
export const INSTANCE_AI_TELEMETRY = defineTelemetryEvents({
USER_CLICKED_AI_CREDIT_BALANCE: {
name: 'User clicked AI credit balance',
description:
'The user clicked the AI Assistant credit balance button to open or close the balance dropdown.',
properties: z.object({}),
},
BUILDER_SPECCED_TEMPLATED_CRED: {
name: 'Builder specced templated cred',
description:

View File

@ -1,7 +1,14 @@
import { describe, it, expect, vi } from 'vitest';
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { mount } from '@vue/test-utils';
import { TELEMETRY_EVENT } from '@n8n/telemetry';
import CreditsSettingsDropdown from './CreditsSettingsDropdown.vue';
const { telemetryTrack } = vi.hoisted(() => ({ telemetryTrack: vi.fn() }));
vi.mock('@n8n/composables/useTelemetry', () => ({
useTelemetry: () => ({ track: telemetryTrack }),
}));
vi.mock('@n8n/i18n', () => {
const baseText = (key: string, options?: { interpolate?: Record<string, string> }) => {
if (options?.interpolate) {
@ -28,6 +35,29 @@ function mountOpen(props: {
}
describe('CreditsSettingsDropdown', () => {
beforeEach(() => {
telemetryTrack.mockClear();
});
it('tracks every credit balance button click', async () => {
const wrapper = mount(CreditsSettingsDropdown, {
props: {
creditsRemaining: 50,
creditsQuota: 100,
isLowCredits: false,
},
});
const button = wrapper.get('[data-test-id="credits-dropdown-button"]');
await button.trigger('click');
await button.trigger('click');
expect(telemetryTrack.mock.calls).toEqual([
[TELEMETRY_EVENT.INSTANCE_AI.USER_CLICKED_AI_CREDIT_BALANCE, {}],
[TELEMETRY_EVENT.INSTANCE_AI.USER_CLICKED_AI_CREDIT_BALANCE, {}],
]);
});
it('rounds creditsRemaining to two decimal places', async () => {
const wrapper = mountOpen({
creditsRemaining: 97.357,

View File

@ -1,7 +1,9 @@
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { onClickOutside } from '@vueuse/core';
import { useTelemetry } from '@n8n/composables/useTelemetry';
import { useI18n } from '@n8n/i18n';
import { TELEMETRY_EVENT } from '@n8n/telemetry';
import { N8nButton, N8nIcon, N8nTooltip } from '@n8n/design-system';
import type { ButtonSize } from '@n8n/design-system';
import { round2 } from './creditFormatting';
@ -25,6 +27,7 @@ const emit = defineEmits<{
}>();
const i18n = useI18n();
const telemetry = useTelemetry();
const isOpen = ref(false);
const dropdownRef = ref<HTMLElement>();
@ -90,6 +93,7 @@ const tooltipContent = computed(() => {
});
function toggleDropdown() {
telemetry.track(TELEMETRY_EVENT.INSTANCE_AI.USER_CLICKED_AI_CREDIT_BALANCE, {});
isOpen.value = !isOpen.value;
}