Skip to content

Commit 9954b37

Browse files
committed
[DASH-624] Add tracking in insight playground (#5737)
## Problem solved DASH-624 <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on enhancing the `CodeBlockContainer` and related components to support an `onCopy` callback, allowing for custom actions when code is copied. It also introduces tracking for user interactions within the `BlueprintPlayground` component. ### Detailed summary - Added `onCopy` prop to `CodeBlockContainer`, `RenderCode`, `PlainTextCodeBlock`, and `CodeClient`. - Updated button click handler in `CodeBlockContainer` to call `onCopy` and pass the copied code. - Integrated `useTrack` for tracking user events in `BlueprintPlayground`. - Added tracking for "run", "copy-url", and "copy-response" actions in relevant components. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 9b58a08 commit 9954b37

File tree

5 files changed

+41
-1
lines changed

5 files changed

+41
-1
lines changed

apps/dashboard/src/@/components/ui/code/CodeBlockContainer.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export function CodeBlockContainer(props: {
1414
scrollableContainerClassName?: string;
1515
copyButtonClassName?: string;
1616
shadowColor?: string;
17+
onCopy?: (code: string) => void;
1718
}) {
1819
const { hasCopied, onCopy } = useClipboard(props.codeToCopy);
1920

@@ -38,7 +39,10 @@ export function CodeBlockContainer(props: {
3839
<Button
3940
size="sm"
4041
variant="outline"
41-
onClick={onCopy}
42+
onClick={() => {
43+
onCopy();
44+
props.onCopy?.(props.codeToCopy);
45+
}}
4246
className={cn(
4347
"absolute top-3.5 right-3.5 h-auto bg-background p-2",
4448
props.copyButtonClassName,

apps/dashboard/src/@/components/ui/code/RenderCode.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export function RenderCode(props: {
88
copyButtonClassName?: string;
99
scrollableContainerClassName?: string;
1010
shadowColor?: string;
11+
onCopy?: (code: string) => void;
1112
}) {
1213
return (
1314
<CodeBlockContainer
@@ -17,6 +18,7 @@ export function RenderCode(props: {
1718
scrollableClassName={props.scrollableClassName}
1819
scrollableContainerClassName={props.scrollableContainerClassName}
1920
shadowColor={props.shadowColor}
21+
onCopy={props.onCopy}
2022
>
2123
<div
2224
// biome-ignore lint/security/noDangerouslySetInnerHtml: we know what we're doing here

apps/dashboard/src/@/components/ui/code/code.client.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type CodeProps = {
1515
scrollableContainerClassName?: string;
1616
shadowColor?: string;
1717
ignoreFormattingErrors?: boolean;
18+
onCopy?: (code: string) => void;
1819
};
1920

2021
export const CodeClient: React.FC<CodeProps> = ({
@@ -27,6 +28,7 @@ export const CodeClient: React.FC<CodeProps> = ({
2728
ignoreFormattingErrors,
2829
scrollableContainerClassName,
2930
shadowColor,
31+
onCopy,
3032
}) => {
3133
const codeQuery = useQuery({
3234
queryKey: ["html", code],
@@ -49,6 +51,7 @@ export const CodeClient: React.FC<CodeProps> = ({
4951
copyButtonClassName={copyButtonClassName}
5052
scrollableContainerClassName={scrollableContainerClassName}
5153
shadowColor={shadowColor}
54+
onCopy={onCopy}
5255
/>
5356
);
5457
}
@@ -62,6 +65,7 @@ export const CodeClient: React.FC<CodeProps> = ({
6265
copyButtonClassName={copyButtonClassName}
6366
scrollableContainerClassName={scrollableContainerClassName}
6467
shadowColor={shadowColor}
68+
onCopy={onCopy}
6569
/>
6670
);
6771
};

apps/dashboard/src/@/components/ui/code/plaintext-code.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export function PlainTextCodeBlock(props: {
99
codeClassName?: string;
1010
scrollableContainerClassName?: string;
1111
shadowColor?: string;
12+
onCopy?: (code: string) => void;
1213
}) {
1314
return (
1415
<CodeBlockContainer
@@ -18,6 +19,7 @@ export function PlainTextCodeBlock(props: {
1819
scrollableClassName={props.scrollableClassName}
1920
scrollableContainerClassName={props.scrollableContainerClassName}
2021
shadowColor={props.shadowColor}
22+
onCopy={props.onCopy}
2123
>
2224
<code className={cn("block whitespace-pre", props.codeClassName)}>
2325
{props.code}

apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ import Link from "next/link";
2828
import { useEffect, useMemo, useState } from "react";
2929
import { type UseFormReturn, useForm } from "react-hook-form";
3030
import { z } from "zod";
31+
import { useTrack } from "../../../../../../hooks/analytics/useTrack";
3132
import { getVercelEnv } from "../../../../../../lib/vercel-utils";
3233
import type { BlueprintParameter, BlueprintPathMetadata } from "../utils";
3334

35+
const trackingCategory = "insightBlueprint";
36+
3437
export function BlueprintPlayground(props: {
3538
metadata: BlueprintPathMetadata;
3639
backLink: string;
@@ -151,6 +154,7 @@ export function BlueprintPlaygroundUI(props: {
151154
projectSettingsLink: string;
152155
supportedChainIds: number[];
153156
}) {
157+
const trackEvent = useTrack();
154158
const parameters = useMemo(() => {
155159
return modifyParametersForPlayground(props.metadata.parameters);
156160
}, [props.metadata.parameters]);
@@ -182,6 +186,12 @@ export function BlueprintPlaygroundUI(props: {
182186
intent: "run",
183187
});
184188

189+
trackEvent({
190+
category: trackingCategory,
191+
action: "click",
192+
label: "run",
193+
url: url,
194+
});
185195
props.onRun(url);
186196
}
187197

@@ -306,6 +316,8 @@ function PlaygroundHeader(props: {
306316
domain: string;
307317
path: string;
308318
}) {
319+
const trackEvent = useTrack();
320+
309321
const [hasCopied, setHasCopied] = useState(false);
310322
return (
311323
<div className="border-b px-4 py-4 lg:flex lg:justify-center lg:py-3">
@@ -325,6 +337,14 @@ function PlaygroundHeader(props: {
325337
values: props.getFormValues(),
326338
intent: "copy",
327339
});
340+
341+
trackEvent({
342+
category: trackingCategory,
343+
action: "click",
344+
label: "copy-url",
345+
url: url,
346+
});
347+
328348
setTimeout(() => {
329349
setHasCopied(false);
330350
}, 500);
@@ -561,6 +581,7 @@ function ResponseSection(props: {
561581
| undefined;
562582
abortRequest: () => void;
563583
}) {
584+
const trackEvent = useTrack();
564585
const formattedData = useMemo(() => {
565586
if (!props.response?.data) return undefined;
566587
try {
@@ -628,6 +649,13 @@ function ResponseSection(props: {
628649
scrollableContainerClassName="h-full"
629650
scrollableClassName="h-full"
630651
shadowColor="hsl(var(--muted)/50%)"
652+
onCopy={() => {
653+
trackEvent({
654+
category: trackingCategory,
655+
action: "click",
656+
label: "copy-response",
657+
});
658+
}}
631659
/>
632660
)}
633661
</div>

0 commit comments

Comments
 (0)