Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/compass-generative-ai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@mongodb-js/compass-connections": "^1.57.0",
"@mongodb-js/compass-intercom": "^0.23.0",
"@mongodb-js/compass-logging": "^1.6.10",
"@mongodb-js/compass-telemetry": "^1.7.1",
"@mongodb-js/compass-utils": "^0.8.9",
"bson": "^6.10.3",
"compass-preferences-model": "^2.39.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useCallback } from 'react';
import {
css,
cx,
Expand All @@ -8,6 +8,10 @@ import {
useDarkMode,
WorkspaceContainer,
} from '@mongodb-js/compass-components';
import {
type TrackFunction,
useTelemetry,
} from '@mongodb-js/compass-telemetry/provider';

import {
AIEntrySVG,
Expand Down Expand Up @@ -95,14 +99,20 @@ function AIExperienceEntry({
onClick: () => void;
}) {
const darkMode = useDarkMode();
const track = useTelemetry();

const handleClick = useCallback(() => {
track('AI Generate Query Clicked', { type });
onClick();
}, [track, onClick, type]);

return (
<button
className={cx(
aiEntryStyles,
darkMode ? aiEntryDarkModeStyles : aiEntryLightModeStyles
)}
onClick={onClick}
onClick={handleClick}
data-testid={dataTestId}
type="button"
title={`Generate ${type}`}
Expand All @@ -119,10 +129,12 @@ function createAIPlaceholderHTMLPlaceholder({
onClickAI,
darkMode,
placeholderText,
track,
}: {
onClickAI: () => void;
darkMode?: boolean;
placeholderText: string;
track: TrackFunction;
}): HTMLElement {
const containerEl = document.createElement('div');

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useCallback } from 'react';
import { connect } from 'react-redux';
import {
Banner,
Expand All @@ -15,6 +15,7 @@ import { AiImageBanner } from './ai-image-banner';
import { closeOptInModal, optIn } from '../store/atlas-optin-reducer';
import type { RootState } from '../store/atlas-ai-store';
import { usePreference } from 'compass-preferences-model/provider';
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';

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

Expand Down Expand Up @@ -79,16 +80,29 @@ export const AIOptInModal: React.FunctionComponent<OptInModalProps> = ({
projectId,
}) => {
const isProjectAIEnabled = usePreference('enableGenAIFeaturesAtlasProject');
const track = useTelemetry();
const PROJECT_SETTINGS_LINK = projectId
? window.location.origin + '/v2/' + projectId + '#/settings/groupSettings'
: null;

useEffect(() => {
if (isOptInModalVisible) {
track('AI Opt In Modal Shown', {});
}
}, [isOptInModalVisible, track]);

const onConfirmClick = () => {
if (isOptInInProgress) {
return;
}
onOptInClick();
};

const handleModalClose = useCallback(() => {
track('AI Opt In Modal Dismissed' as const, {});
onOptInModalClose();
}, [track, onOptInModalClose]);

return (
<ConfirmationModal
open={isOptInModalVisible}
Expand All @@ -99,7 +113,7 @@ export const AIOptInModal: React.FunctionComponent<OptInModalProps> = ({
onClick: onConfirmClick,
}}
cancelButtonProps={{
onClick: onOptInModalClose,
onClick: handleModalClose,
}}
>
<Body className={bodyStyles}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useCallback } from 'react';
import { connect } from 'react-redux';
import {
Body,
Expand All @@ -13,6 +13,7 @@ import {
import { AiImageBanner } from './ai-image-banner';
import { closeSignInModal, signIn } from '../store/atlas-signin-reducer';
import type { RootState } from '../store/atlas-ai-store';
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';

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

Expand Down Expand Up @@ -41,6 +42,18 @@ const AISignInModal: React.FunctionComponent<SignInModalProps> = ({
onSignInClick,
}) => {
const darkMode = useDarkMode();
const track = useTelemetry();

useEffect(() => {
if (isSignInModalVisible) {
track('AI Sign In Modal Shown', {});
}
}, [isSignInModalVisible, track]);

const handleModalClose = useCallback(() => {
track('AI Sign In Modal Dismissed', {});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Anemy is this triggered only on dismiss or also when the user logs in?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only triggered on dismiss, not on log in.

onSignInModalClose?.();
}, [track, onSignInModalClose]);

return (
<MarketingModal
Expand All @@ -62,7 +75,7 @@ const AISignInModal: React.FunctionComponent<SignInModalProps> = ({
</div>
}
open={isSignInModalVisible}
onClose={onSignInModalClose}
onClose={handleModalClose}
// @ts-expect-error leafygreen only allows strings, but we need to pass
// icons
buttonText={
Expand All @@ -88,7 +101,7 @@ const AISignInModal: React.FunctionComponent<SignInModalProps> = ({
onSignInClick?.();
}}
linkText="Not now"
onLinkClick={onSignInModalClose}
onLinkClick={handleModalClose}
>
<Body>
Atlas users can now quickly create queries and aggregations with
Expand Down
4 changes: 4 additions & 0 deletions packages/compass-query-bar/src/components/query-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '@mongodb-js/compass-generative-ai';
import { connect } from '../stores/context';
import { useIsAIFeatureEnabled } from 'compass-preferences-model/provider';
import { useTelemetry } from '@mongodb-js/compass-telemetry/provider';

import {
OPTION_DEFINITION,
Expand Down Expand Up @@ -158,6 +159,7 @@ export const QueryBar: React.FunctionComponent<QueryBarProps> = ({
}) => {
const darkMode = useDarkMode();
const isAIFeatureEnabled = useIsAIFeatureEnabled();
const track = useTelemetry();

const onFormSubmit = useCallback(
(evt: React.FormEvent) => {
Expand All @@ -177,6 +179,7 @@ export const QueryBar: React.FunctionComponent<QueryBarProps> = ({
},
darkMode,
placeholderText: OPTION_DEFINITION.filter.placeholder,
track,
})
: placeholders?.filter;
}, [
Expand All @@ -185,6 +188,7 @@ export const QueryBar: React.FunctionComponent<QueryBarProps> = ({
darkMode,
placeholders?.filter,
onShowAIInputClick,
track,
]);

const showAIEntryButton = useMemo(() => {
Expand Down
60 changes: 60 additions & 0 deletions packages/compass-telemetry/src/telemetry-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,61 @@ type AiResponseGeneratedEvent = ConnectionScopedEvent<{
};
}>;

/**
* This event is fired when the AI Opt-In Modal is shown to the user.
*
* @category Gen AI
*/
type AiOptInModalShownEvent = CommonEvent<{
name: 'AI Opt In Modal Shown';
payload: Record<string, never>;
}>;

/**
* This event is fired when the AI Opt-In Modal is dismissed by the user.
*
* @category Gen AI
*/
type AiOptInModalDismissedEvent = CommonEvent<{
name: 'AI Opt In Modal Dismissed';
payload: Record<string, never>;
}>;

/**
* This event is fired when the AI Sign-In Modal is shown to the user.
*
* @category Gen AI
*/
type AiSignInModalShownEvent = CommonEvent<{
name: 'AI Sign In Modal Shown';
payload: Record<string, never>;
}>;

/**
* This event is fired when the AI Sign-In Modal is dismissed by the user.
*
* @category Gen AI
*/
type AiSignInModalDismissedEvent = CommonEvent<{
name: 'AI Sign In Modal Dismissed';
payload: Record<string, never>;
}>;

/**
* This event is fired when a user clicks the Generate Query / Aggregation entry point.
*
* @category Gen AI
*/
type AiGenerateQueryClickedEvent = CommonEvent<{
name: 'AI Generate Query Clicked';
payload: {
/**
* The type of query being generated.
*/
type: 'aggregation' | 'query';
};
}>;

/**
* This event is fired when a user submits feedback for a pipeline generation.
*
Expand Down Expand Up @@ -2710,6 +2765,11 @@ export type TelemetryEvent =
| AggregationTimedOutEvent
| AggregationUseCaseAddedEvent
| AggregationUseCaseSavedEvent
| AiOptInModalShownEvent
| AiOptInModalDismissedEvent
| AiSignInModalShownEvent
| AiSignInModalDismissedEvent
| AiGenerateQueryClickedEvent
| AiPromptSubmittedEvent
| AiQueryFeedbackEvent
| AiResponseFailedEvent
Expand Down
Loading