Add telemetry for new quick start (#1285)

This commit is contained in:
victor-meng 2022-06-01 15:26:10 -07:00 committed by GitHub
parent 7e1343e84f
commit 7ab57c9ec4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 65 deletions

View File

@ -1193,6 +1193,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
subscriptionQuotaId: userContext.quotaId, subscriptionQuotaId: userContext.quotaId,
dataExplorerArea: Constants.Areas.ContextualPane, dataExplorerArea: Constants.Areas.ContextualPane,
useIndexingForSharedThroughput: this.state.enableIndexing, useIndexingForSharedThroughput: this.state.enableIndexing,
isQuickstart: !!this.props.isQuickstart,
}; };
const startKey: number = TelemetryProcessor.traceStart(Action.CreateCollection, telemetryData); const startKey: number = TelemetryProcessor.traceStart(Action.CreateCollection, telemetryData);
@ -1254,6 +1255,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
collection.expandCollection(); collection.expandCollection();
useDatabases.getState().updateDatabase(database); useDatabases.getState().updateDatabase(database);
useTeachingBubble.getState().setIsSampleDBExpanded(true); useTeachingBubble.getState().setIsSampleDBExpanded(true);
TelemetryProcessor.traceOpen(Action.LaunchUITour);
} }
} }
this.setState({ isExecuting: false }); this.setState({ isExecuting: false });

View File

@ -5,6 +5,8 @@ import { Coachmark, DirectionalHint, Image, Link, Stack, TeachingBubbleContent,
import { useCarousel } from "hooks/useCarousel"; import { useCarousel } from "hooks/useCarousel";
import { useTabs } from "hooks/useTabs"; import { useTabs } from "hooks/useTabs";
import * as React from "react"; import * as React from "react";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
import AddDatabaseIcon from "../../../images/AddDatabase.svg"; import AddDatabaseIcon from "../../../images/AddDatabase.svg";
import NewQueryIcon from "../../../images/AddSqlQuery_16x16.svg"; import NewQueryIcon from "../../../images/AddSqlQuery_16x16.svg";
import NewStoredProcedureIcon from "../../../images/AddStoredProcedure.svg"; import NewStoredProcedureIcon from "../../../images/AddStoredProcedure.svg";
@ -201,10 +203,12 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
title: "Launch quick start", title: "Launch quick start",
description: "Launch a quick start tutorial to get started with sample data", description: "Launch a quick start tutorial to get started with sample data",
showLinkIcon: userContext.apiType === "Mongo", showLinkIcon: userContext.apiType === "Mongo",
onClick: () => onClick: () => {
userContext.apiType === "Mongo" userContext.apiType === "Mongo"
? window.open("http://aka.ms/mongodbquickstart", "_blank") ? window.open("http://aka.ms/mongodbquickstart", "_blank")
: this.container.onNewCollectionClicked({ isQuickstart: true }), : this.container.onNewCollectionClicked({ isQuickstart: true });
traceOpen(Action.LaunchQuickstart, { apiType: userContext.apiType });
},
}; };
heroes.push(launchQuickstartBtn); heroes.push(launchQuickstartBtn);
} else if (useNotebook.getState().isPhoenixNotebooks) { } else if (useNotebook.getState().isPhoenixNotebooks) {
@ -221,7 +225,10 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
iconSrc: ContainersIcon, iconSrc: ContainersIcon,
title: `New ${getCollectionName()}`, title: `New ${getCollectionName()}`,
description: "Create a new container for storage and throughput", description: "Create a new container for storage and throughput",
onClick: () => this.container.onNewCollectionClicked(), onClick: () => {
this.container.onNewCollectionClicked();
traceOpen(Action.NewContainerHomepage, { apiType: userContext.apiType });
},
}; };
heroes.push(newContainerBtn); heroes.push(newContainerBtn);
@ -397,29 +404,6 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
} }
} }
private getCommonTasksItems(): JSX.Element {
const commonTaskItems = this.createCommonTaskItems();
return (
<ul>
{commonTaskItems.map((item) => (
<li
className="focusable"
key={`${item.title}${item.description}`}
onClick={item.onClick}
onKeyPress={(event: React.KeyboardEvent) => this.onSplashScreenItemKeyPress(event, item.onClick)}
tabIndex={0}
role="button"
>
<img src={item.iconSrc} alt="" />
<span className="oneLineContent" title={item.info}>
{item.title}
</span>
</li>
))}
</ul>
);
}
private top3Items(): JSX.Element { private top3Items(): JSX.Element {
let items: { link: string; title: string; description: string }[]; let items: { link: string; title: string; description: string }[];
switch (userContext.apiType) { switch (userContext.apiType) {
@ -524,7 +508,12 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
{items.map((item, i) => ( {items.map((item, i) => (
<Stack key={`top${i}`} style={{ marginBottom: 26 }}> <Stack key={`top${i}`} style={{ marginBottom: 26 }}>
<Stack horizontal verticalAlign="center" style={{ fontSize: 14 }}> <Stack horizontal verticalAlign="center" style={{ fontSize: 14 }}>
<Link href={item.link} target="_blank" style={{ marginRight: 5 }}> <Link
onClick={() => traceOpen(Action.Top3ItemsClicked, { item: i + 1, apiType: userContext.apiType })}
href={item.link}
target="_blank"
style={{ marginRight: 5 }}
>
{item.title} {item.title}
</Link> </Link>
<Image src={LinkIcon} /> <Image src={LinkIcon} />
@ -665,7 +654,14 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
{items.map((item, i) => ( {items.map((item, i) => (
<Stack key={`learningResource${i}`} style={{ marginBottom: 26 }}> <Stack key={`learningResource${i}`} style={{ marginBottom: 26 }}>
<Stack horizontal verticalAlign="center" style={{ fontSize: 14 }}> <Stack horizontal verticalAlign="center" style={{ fontSize: 14 }}>
<Link href={item.link} target="_blank" style={{ marginRight: 5 }}> <Link
onClick={() =>
traceOpen(Action.LearningResourcesClicked, { item: i + 1, apiType: userContext.apiType })
}
href={item.link}
target="_blank"
style={{ marginRight: 5 }}
>
{item.title} {item.title}
</Link> </Link>
<Image src={LinkIcon} /> <Image src={LinkIcon} />
@ -676,33 +672,4 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
</Stack> </Stack>
); );
} }
private getTipItems(): JSX.Element {
const tipsItems = this.createTipsItems();
return (
<ul>
{tipsItems.map((item) => (
<li
className="tipContainer focusable"
key={`${item.title}${item.description}`}
onClick={item.onClick}
onKeyPress={(event: React.KeyboardEvent) => this.onSplashScreenItemKeyPress(event, item.onClick)}
tabIndex={0}
role="link"
>
<div className="title" title={item.info}>
{item.title}
</div>
<div className="description">{item.description}</div>
</li>
))}
<li>
<a role="link" href={SplashScreen.seeMoreItemUrl} rel="noreferrer" target="_blank" tabIndex={0}>
{SplashScreen.seeMoreItemTitle}
</a>
</li>
</ul>
);
}
} }

View File

@ -2,6 +2,8 @@ import { DefaultButton, IconButton, Image, Modal, PrimaryButton, Stack, Text } f
import { useCarousel } from "hooks/useCarousel"; import { useCarousel } from "hooks/useCarousel";
import React, { useState } from "react"; import React, { useState } from "react";
import Youtube from "react-youtube"; import Youtube from "react-youtube";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import { traceSuccess } from "Shared/Telemetry/TelemetryProcessor";
import { userContext } from "UserContext"; import { userContext } from "UserContext";
import Image1 from "../../../images/CarouselImage1.svg"; import Image1 from "../../../images/CarouselImage1.svg";
import Image2 from "../../../images/CarouselImage2.svg"; import Image2 from "../../../images/CarouselImage2.svg";
@ -49,6 +51,10 @@ export const QuickstartCarousel: React.FC<QuickstartCarouselProps> = ({
} }
setPage(page + 1); setPage(page + 1);
} }
if (page === 3) {
traceSuccess(Action.CompleteCarousel);
}
}} }}
/> />
</Stack> </Stack>
@ -73,7 +79,7 @@ const getHeaderText = (page: number): string => {
const getContent = (page: number): JSX.Element => { const getContent = (page: number): JSX.Element => {
switch (page) { switch (page) {
case 1: case 1:
return <Youtube videoId="Jvgh64rvdXU" />; return <Youtube videoId="Jvgh64rvdXU" onPlay={() => traceSuccess(Action.PlayCarouselVideo)} />;
case 2: case 2:
return <Image style={{ width: 640 }} src={Image1} />; return <Image style={{ width: 640 }} src={Image1} />;
case 3: case 3:

View File

@ -2,10 +2,17 @@ import { Link, Stack, TeachingBubble, Text } from "@fluentui/react";
import { useTabs } from "hooks/useTabs"; import { useTabs } from "hooks/useTabs";
import { useTeachingBubble } from "hooks/useTeachingBubble"; import { useTeachingBubble } from "hooks/useTeachingBubble";
import React from "react"; import React from "react";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import { traceCancel } from "Shared/Telemetry/TelemetryProcessor";
export const QuickstartTutorial: React.FC = (): JSX.Element => { export const QuickstartTutorial: React.FC = (): JSX.Element => {
const { step, isSampleDBExpanded, isDocumentsTabOpened, sampleCollection, setStep } = useTeachingBubble(); const { step, isSampleDBExpanded, isDocumentsTabOpened, sampleCollection, setStep } = useTeachingBubble();
const onDimissTeachingBubble = (): void => {
setStep(0);
traceCancel(Action.CancelUITour, { step });
};
switch (step) { switch (step) {
case 1: case 1:
return isSampleDBExpanded ? ( return isSampleDBExpanded ? (
@ -20,7 +27,7 @@ export const QuickstartTutorial: React.FC = (): JSX.Element => {
setStep(2); setStep(2);
}, },
}} }}
onDismiss={() => setStep(0)} onDismiss={() => onDimissTeachingBubble()}
footerContent="Step 1 of 7" footerContent="Step 1 of 7"
> >
Start viewing and working with your data by opening Items under Data Start viewing and working with your data by opening Items under Data
@ -42,7 +49,7 @@ export const QuickstartTutorial: React.FC = (): JSX.Element => {
text: "Previous", text: "Previous",
onClick: () => setStep(1), onClick: () => setStep(1),
}} }}
onDismiss={() => setStep(0)} onDismiss={() => onDimissTeachingBubble()}
footerContent="Step 2 of 7" footerContent="Step 2 of 7"
> >
View item here using the items window. Additionally you can also filter items to be reviewed with the filter View item here using the items window. Additionally you can also filter items to be reviewed with the filter
@ -65,7 +72,7 @@ export const QuickstartTutorial: React.FC = (): JSX.Element => {
text: "Previous", text: "Previous",
onClick: () => setStep(2), onClick: () => setStep(2),
}} }}
onDismiss={() => setStep(0)} onDismiss={() => onDimissTeachingBubble()}
footerContent="Step 3 of 7" footerContent="Step 3 of 7"
> >
Add new item by copy / pasting JSON; or uploading a JSON Add new item by copy / pasting JSON; or uploading a JSON
@ -85,7 +92,7 @@ export const QuickstartTutorial: React.FC = (): JSX.Element => {
text: "Previous", text: "Previous",
onClick: () => setStep(3), onClick: () => setStep(3),
}} }}
onDismiss={() => setStep(0)} onDismiss={() => onDimissTeachingBubble()}
footerContent="Step 4 of 7" footerContent="Step 4 of 7"
> >
Query your data using either the filter function or new query. Query your data using either the filter function or new query.
@ -105,7 +112,7 @@ export const QuickstartTutorial: React.FC = (): JSX.Element => {
text: "Previous", text: "Previous",
onClick: () => setStep(4), onClick: () => setStep(4),
}} }}
onDismiss={() => setStep(0)} onDismiss={() => onDimissTeachingBubble()}
footerContent="Step 5 of 7" footerContent="Step 5 of 7"
> >
Change throughput provisioned to your container according to your needs Change throughput provisioned to your container according to your needs
@ -125,7 +132,7 @@ export const QuickstartTutorial: React.FC = (): JSX.Element => {
text: "Previous", text: "Previous",
onClick: () => setStep(5), onClick: () => setStep(5),
}} }}
onDismiss={() => setStep(0)} onDismiss={() => onDimissTeachingBubble()}
footerContent="Step 6 of 7" footerContent="Step 6 of 7"
> >
Visualize your data, store queries in an interactive document Visualize your data, store queries in an interactive document
@ -145,7 +152,7 @@ export const QuickstartTutorial: React.FC = (): JSX.Element => {
text: "Previous", text: "Previous",
onClick: () => setStep(6), onClick: () => setStep(6),
}} }}
onDismiss={() => setStep(0)} onDismiss={() => onDimissTeachingBubble()}
footerContent="Step 7 of 7" footerContent="Step 7 of 7"
> >
<Stack> <Stack>

View File

@ -121,6 +121,15 @@ export enum Action {
ExpandAddCollectionPaneAdvancedSection, ExpandAddCollectionPaneAdvancedSection,
SchemaAnalyzerClickAnalyze, SchemaAnalyzerClickAnalyze,
SelfServeComponent, SelfServeComponent,
LaunchQuickstart,
NewContainerHomepage,
Top3ItemsClicked,
LearningResourcesClicked,
PlayCarouselVideo,
OpenCarousel,
CompleteCarousel,
LaunchUITour,
CancelUITour,
} }
export const ActionModifiers = { export const ActionModifiers = {

View File

@ -1,4 +1,6 @@
import { useCarousel } from "hooks/useCarousel"; import { useCarousel } from "hooks/useCarousel";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
import { AuthType } from "./AuthType"; import { AuthType } from "./AuthType";
import { DatabaseAccount } from "./Contracts/DataModels"; import { DatabaseAccount } from "./Contracts/DataModels";
import { SubscriptionType } from "./Contracts/SubscriptionType"; import { SubscriptionType } from "./Contracts/SubscriptionType";
@ -99,6 +101,7 @@ function updateUserContext(newContext: Partial<UserContext>): void {
) { ) {
useCarousel.getState().setShouldOpen(true); useCarousel.getState().setShouldOpen(true);
localStorage.setItem(newContext.databaseAccount.id, "true"); localStorage.setItem(newContext.databaseAccount.id, "true");
traceOpen(Action.OpenCarousel);
} }
} }
Object.assign(userContext, newContext); Object.assign(userContext, newContext);