Skip to content

Commit 44f1ba1

Browse files
authored
chore(telemetry): add tracking for AI modals and query generation funnel (#6965)
* chore(telemetry): add tracking for AI modals and query generation funnel * fix depcheck
1 parent 0d83a6c commit 44f1ba1

File tree

7 files changed

+114
-7
lines changed

7 files changed

+114
-7
lines changed

package-lock.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/compass-generative-ai/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"@mongodb-js/compass-connections": "^1.57.0",
5858
"@mongodb-js/compass-intercom": "^0.23.0",
5959
"@mongodb-js/compass-logging": "^1.6.10",
60+
"@mongodb-js/compass-telemetry": "^1.7.1",
6061
"@mongodb-js/compass-utils": "^0.8.9",
6162
"bson": "^6.10.3",
6263
"compass-preferences-model": "^2.39.0",

packages/compass-generative-ai/src/components/ai-experience-entry.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useCallback } from 'react';
22
import {
33
css,
44
cx,
@@ -8,6 +8,10 @@ import {
88
useDarkMode,
99
WorkspaceContainer,
1010
} from '@mongodb-js/compass-components';
11+
import {
12+
type TrackFunction,
13+
useTelemetry,
14+
} from '@mongodb-js/compass-telemetry/provider';
1115

1216
import {
1317
AIEntrySVG,
@@ -95,14 +99,20 @@ function AIExperienceEntry({
9599
onClick: () => void;
96100
}) {
97101
const darkMode = useDarkMode();
102+
const track = useTelemetry();
103+
104+
const handleClick = useCallback(() => {
105+
track('AI Generate Query Clicked', { type });
106+
onClick();
107+
}, [track, onClick, type]);
98108

99109
return (
100110
<button
101111
className={cx(
102112
aiEntryStyles,
103113
darkMode ? aiEntryDarkModeStyles : aiEntryLightModeStyles
104114
)}
105-
onClick={onClick}
115+
onClick={handleClick}
106116
data-testid={dataTestId}
107117
type="button"
108118
title={`Generate ${type}`}
@@ -119,10 +129,12 @@ function createAIPlaceholderHTMLPlaceholder({
119129
onClickAI,
120130
darkMode,
121131
placeholderText,
132+
track,
122133
}: {
123134
onClickAI: () => void;
124135
darkMode?: boolean;
125136
placeholderText: string;
137+
track: TrackFunction;
126138
}): HTMLElement {
127139
const containerEl = document.createElement('div');
128140

@@ -144,6 +156,7 @@ function createAIPlaceholderHTMLPlaceholder({
144156
aiButtonEl.addEventListener('click', (e) => {
145157
e.preventDefault();
146158
e.stopPropagation();
159+
track('AI Generate Query Clicked' as const, { type: 'query' });
147160
onClickAI();
148161
});
149162

packages/compass-generative-ai/src/components/ai-optin-modal.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useEffect, useCallback } from 'react';
22
import { connect } from 'react-redux';
33
import {
44
Banner,
@@ -15,6 +15,7 @@ import { AiImageBanner } from './ai-image-banner';
1515
import { closeOptInModal, optIn } from '../store/atlas-optin-reducer';
1616
import type { RootState } from '../store/atlas-ai-store';
1717
import { usePreference } from 'compass-preferences-model/provider';
18+
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
1819

1920
const GEN_AI_FAQ_LINK = 'https://www.mongodb.com/docs/generative-ai-faq/';
2021

@@ -79,16 +80,29 @@ export const AIOptInModal: React.FunctionComponent<OptInModalProps> = ({
7980
projectId,
8081
}) => {
8182
const isProjectAIEnabled = usePreference('enableGenAIFeaturesAtlasProject');
83+
const track = useTelemetry();
8284
const PROJECT_SETTINGS_LINK = projectId
8385
? window.location.origin + '/v2/' + projectId + '#/settings/groupSettings'
8486
: null;
8587

88+
useEffect(() => {
89+
if (isOptInModalVisible) {
90+
track('AI Opt In Modal Shown', {});
91+
}
92+
}, [isOptInModalVisible, track]);
93+
8694
const onConfirmClick = () => {
8795
if (isOptInInProgress) {
8896
return;
8997
}
9098
onOptInClick();
9199
};
100+
101+
const handleModalClose = useCallback(() => {
102+
track('AI Opt In Modal Dismissed' as const, {});
103+
onOptInModalClose();
104+
}, [track, onOptInModalClose]);
105+
92106
return (
93107
<ConfirmationModal
94108
open={isOptInModalVisible}
@@ -99,7 +113,7 @@ export const AIOptInModal: React.FunctionComponent<OptInModalProps> = ({
99113
onClick: onConfirmClick,
100114
}}
101115
cancelButtonProps={{
102-
onClick: onOptInModalClose,
116+
onClick: handleModalClose,
103117
}}
104118
>
105119
<Body className={bodyStyles}>

packages/compass-generative-ai/src/components/ai-signin-modal.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useEffect, useCallback } from 'react';
22
import { connect } from 'react-redux';
33
import {
44
Body,
@@ -13,6 +13,7 @@ import {
1313
import { AiImageBanner } from './ai-image-banner';
1414
import { closeSignInModal, signIn } from '../store/atlas-signin-reducer';
1515
import type { RootState } from '../store/atlas-ai-store';
16+
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
1617

1718
const GEN_AI_FAQ_LINK = 'https://www.mongodb.com/docs/generative-ai-faq/';
1819

@@ -41,6 +42,18 @@ const AISignInModal: React.FunctionComponent<SignInModalProps> = ({
4142
onSignInClick,
4243
}) => {
4344
const darkMode = useDarkMode();
45+
const track = useTelemetry();
46+
47+
useEffect(() => {
48+
if (isSignInModalVisible) {
49+
track('AI Sign In Modal Shown', {});
50+
}
51+
}, [isSignInModalVisible, track]);
52+
53+
const handleModalClose = useCallback(() => {
54+
track('AI Sign In Modal Dismissed', {});
55+
onSignInModalClose?.();
56+
}, [track, onSignInModalClose]);
4457

4558
return (
4659
<MarketingModal
@@ -62,7 +75,7 @@ const AISignInModal: React.FunctionComponent<SignInModalProps> = ({
6275
</div>
6376
}
6477
open={isSignInModalVisible}
65-
onClose={onSignInModalClose}
78+
onClose={handleModalClose}
6679
// @ts-expect-error leafygreen only allows strings, but we need to pass
6780
// icons
6881
buttonText={
@@ -88,7 +101,7 @@ const AISignInModal: React.FunctionComponent<SignInModalProps> = ({
88101
onSignInClick?.();
89102
}}
90103
linkText="Not now"
91-
onLinkClick={onSignInModalClose}
104+
onLinkClick={handleModalClose}
92105
>
93106
<Body>
94107
Atlas users can now quickly create queries and aggregations with

packages/compass-query-bar/src/components/query-bar.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from '@mongodb-js/compass-generative-ai';
1616
import { connect } from '../stores/context';
1717
import { useIsAIFeatureEnabled } from 'compass-preferences-model/provider';
18+
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';
1819

1920
import {
2021
OPTION_DEFINITION,
@@ -158,6 +159,7 @@ export const QueryBar: React.FunctionComponent<QueryBarProps> = ({
158159
}) => {
159160
const darkMode = useDarkMode();
160161
const isAIFeatureEnabled = useIsAIFeatureEnabled();
162+
const track = useTelemetry();
161163

162164
const onFormSubmit = useCallback(
163165
(evt: React.FormEvent) => {
@@ -177,6 +179,7 @@ export const QueryBar: React.FunctionComponent<QueryBarProps> = ({
177179
},
178180
darkMode,
179181
placeholderText: OPTION_DEFINITION.filter.placeholder,
182+
track,
180183
})
181184
: placeholders?.filter;
182185
}, [
@@ -185,6 +188,7 @@ export const QueryBar: React.FunctionComponent<QueryBarProps> = ({
185188
darkMode,
186189
placeholders?.filter,
187190
onShowAIInputClick,
191+
track,
188192
]);
189193

190194
const showAIEntryButton = useMemo(() => {

packages/compass-telemetry/src/telemetry-events.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,61 @@ type AiResponseGeneratedEvent = ConnectionScopedEvent<{
15241524
};
15251525
}>;
15261526

1527+
/**
1528+
* This event is fired when the AI Opt-In Modal is shown to the user.
1529+
*
1530+
* @category Gen AI
1531+
*/
1532+
type AiOptInModalShownEvent = CommonEvent<{
1533+
name: 'AI Opt In Modal Shown';
1534+
payload: Record<string, never>;
1535+
}>;
1536+
1537+
/**
1538+
* This event is fired when the AI Opt-In Modal is dismissed by the user.
1539+
*
1540+
* @category Gen AI
1541+
*/
1542+
type AiOptInModalDismissedEvent = CommonEvent<{
1543+
name: 'AI Opt In Modal Dismissed';
1544+
payload: Record<string, never>;
1545+
}>;
1546+
1547+
/**
1548+
* This event is fired when the AI Sign-In Modal is shown to the user.
1549+
*
1550+
* @category Gen AI
1551+
*/
1552+
type AiSignInModalShownEvent = CommonEvent<{
1553+
name: 'AI Sign In Modal Shown';
1554+
payload: Record<string, never>;
1555+
}>;
1556+
1557+
/**
1558+
* This event is fired when the AI Sign-In Modal is dismissed by the user.
1559+
*
1560+
* @category Gen AI
1561+
*/
1562+
type AiSignInModalDismissedEvent = CommonEvent<{
1563+
name: 'AI Sign In Modal Dismissed';
1564+
payload: Record<string, never>;
1565+
}>;
1566+
1567+
/**
1568+
* This event is fired when a user clicks the Generate Query / Aggregation entry point.
1569+
*
1570+
* @category Gen AI
1571+
*/
1572+
type AiGenerateQueryClickedEvent = CommonEvent<{
1573+
name: 'AI Generate Query Clicked';
1574+
payload: {
1575+
/**
1576+
* The type of query being generated.
1577+
*/
1578+
type: 'aggregation' | 'query';
1579+
};
1580+
}>;
1581+
15271582
/**
15281583
* This event is fired when a user submits feedback for a pipeline generation.
15291584
*
@@ -2732,6 +2787,11 @@ export type TelemetryEvent =
27322787
| AggregationTimedOutEvent
27332788
| AggregationUseCaseAddedEvent
27342789
| AggregationUseCaseSavedEvent
2790+
| AiOptInModalShownEvent
2791+
| AiOptInModalDismissedEvent
2792+
| AiSignInModalShownEvent
2793+
| AiSignInModalDismissedEvent
2794+
| AiGenerateQueryClickedEvent
27352795
| AiPromptSubmittedEvent
27362796
| AiQueryFeedbackEvent
27372797
| AiResponseFailedEvent

0 commit comments

Comments
 (0)