Skip to content

Commit e9b43ea

Browse files
ENG-1448 - Add PostHog capture events for broader Roam feature usage telemetry (#798)
* add more posthog.capture * revert Export.tsx * add more * Apply suggestion from @devin-ai-integration[bot] Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix devin suggestion * format * coderabbit * Add posthog event capture for suggestion adoption in SuggestionsBody component --------- Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 0a896f4 commit e9b43ea

25 files changed

Lines changed: 235 additions & 8 deletions

apps/roam/src/components/CreateRelationDialog.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import type { Result } from "~/utils/types";
2424
import internalError from "~/utils/internalError";
2525
import getDiscourseNodes from "~/utils/getDiscourseNodes";
2626
import { USE_REIFIED_RELATIONS } from "~/data/userSettings";
27+
import posthog from "posthog-js";
2728

2829
export type CreateRelationDialogProps = {
2930
onClose: () => void;
@@ -162,6 +163,10 @@ const CreateRelationDialog = ({
162163
};
163164

164165
const onCreateSync = (): void => {
166+
posthog.capture("Create Relation Dialog: Create Triggered", {
167+
relationName: selectedRelationName,
168+
hasTarget: !!selectedTarget.uid,
169+
});
165170
onCreate()
166171
.then((result: boolean) => {
167172
if (result) {

apps/roam/src/components/DiscourseFloatingMenu.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from "@blueprintjs/core";
1313
import { FeedbackWidget } from "./BirdEatsBugs";
1414
import { render as renderSettings } from "~/components/settings/Settings";
15+
import posthog from "posthog-js";
1516

1617
type DiscourseFloatingMenuProps = {
1718
// CSS placement class
@@ -36,6 +37,7 @@ export const DiscourseFloatingMenu = (props: DiscourseFloatingMenuProps) => (
3637
text="Send feedback"
3738
icon="send-message"
3839
onClick={() => {
40+
posthog.capture("Floating Menu: Feedback Clicked");
3941
try {
4042
(window.birdeatsbug as FeedbackWidget | undefined)?.trigger?.();
4143
} catch (error) {
@@ -46,26 +48,34 @@ export const DiscourseFloatingMenu = (props: DiscourseFloatingMenuProps) => (
4648
<MenuItem
4749
text="Docs"
4850
icon="book"
51+
onClick={() => posthog.capture("Floating Menu: Docs Clicked")}
4952
href="https://discoursegraphs.com/docs/roam"
5053
rel="noopener noreferrer"
5154
target="_blank"
5255
/>
5356
<MenuItem
5457
text="Community"
5558
icon="social-media"
59+
onClick={() => posthog.capture("Floating Menu: Community Clicked")}
5660
href="https://join.slack.com/t/discoursegraphs/shared_invite/zt-37xklatti-cpEjgPQC0YyKYQWPNgAkEg"
5761
rel="noopener noreferrer"
5862
target="_blank"
5963
/>
6064
<MenuItem
6165
text="Settings"
6266
icon="cog"
63-
onClick={() => renderSettings({ onloadArgs: props.onloadArgs! })}
67+
onClick={() => {
68+
posthog.capture("Floating Menu: Settings Clicked");
69+
renderSettings({ onloadArgs: props.onloadArgs! });
70+
}}
6471
rel="noopener noreferrer"
6572
target="_blank"
6673
/>
6774
</Menu>
6875
}
76+
onOpened={() => {
77+
posthog.capture("Floating Menu: Opened");
78+
}}
6979
onClosed={() => {
7080
document.getElementById("dg-floating-menu-button")?.blur();
7181
}}

apps/roam/src/components/DiscourseSuggestionsPanel.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
Collapse,
88
} from "@blueprintjs/core";
99
import React, { useState, useCallback, useEffect } from "react";
10+
import posthog from "posthog-js";
1011
import SuggestionsBody from "./SuggestionsBody";
1112

1213
export const DiscourseSuggestionsPanel = ({
@@ -31,6 +32,9 @@ export const DiscourseSuggestionsPanel = ({
3132
const handleToggle = useCallback(() => {
3233
setIsOpen((prev) => {
3334
const next = !prev;
35+
posthog.capture("Suggestive Mode Panel: Toggled", {
36+
isOpen: next,
37+
});
3438
onToggle(next);
3539
return next;
3640
});

apps/roam/src/components/Export.tsx

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ import getDiscourseRelations, {
8383
DiscourseRelation,
8484
} from "~/utils/getDiscourseRelations";
8585
import { AddReferencedNodeType } from "./canvas/DiscourseRelationShape/DiscourseRelationTool";
86+
import posthog from "posthog-js";
8687

8788
const ExportProgress = ({ id }: { id: string }) => {
8889
const [progress, setProgress] = useState(0);
@@ -154,6 +155,9 @@ const ExportDialog: ExportDialogComponent = ({
154155
useEffect(() => {
155156
setDialogOpen(isOpen);
156157
}, [isOpen]);
158+
159+
// TODO: maybe add posthog capture here for isOpen
160+
157161
const [dialogOpen, setDialogOpen] = useState(isOpen);
158162
const exportTypes = useMemo(
159163
() => getExportTypes({ results, exportId, isExportDiscourseGraph }),
@@ -651,6 +655,8 @@ const ExportDialog: ExportDialogComponent = ({
651655
let toastContent: React.ReactNode;
652656
let uid = selectedPageUid;
653657
const title = selectedPageTitle;
658+
const isCanvasDestination = !isSendToGraph && isCanvasPage;
659+
const shouldCreatePage = !isSendToGraph && !isLiveBlock(uid);
654660

655661
if (isSendToGraph) {
656662
addToGraphOverView();
@@ -687,6 +693,13 @@ const ExportDialog: ExportDialogComponent = ({
687693
);
688694
}
689695

696+
posthog.capture("Results View: Send To Destination", {
697+
destination: isSendToGraph ? "graph" : "page",
698+
isCanvasDestination,
699+
createdPage: shouldCreatePage,
700+
resultCount: results.length,
701+
});
702+
690703
renderToast({
691704
content: toastContent,
692705
intent: "success",
@@ -735,10 +748,20 @@ const ExportDialog: ExportDialogComponent = ({
735748
if (download) {
736749
const blob = new Blob([download], { type: "application/zip" });
737750
saveAs(blob, `${filename}.zip`);
751+
posthog.capture("Export Dialog: Export Completed", {
752+
exportType: "PDF",
753+
destination: activeExportDestination,
754+
fileCount: files.length,
755+
});
738756
}
739757
onClose();
740758
} catch (e) {
741759
setError("Failed to export files.");
760+
posthog.capture("Export Dialog: Export Failed", {
761+
exportType: "PDF",
762+
destination: activeExportDestination,
763+
error: (e as Error).message ?? "unknown error",
764+
});
742765
}
743766
};
744767
const ExportPanel = (
@@ -838,6 +861,13 @@ const ExportDialog: ExportDialogComponent = ({
838861
setLoading(true);
839862
updateExportProgress({ progress: 0, id: exportId });
840863
setError("");
864+
posthog.capture("Export Dialog: Export Started", {
865+
exportType: activeExportType,
866+
destination: activeExportDestination,
867+
includeDiscourseContext,
868+
resultCount: results.length,
869+
isExportDiscourseGraph,
870+
});
841871
// eslint-disable-next-line @typescript-eslint/no-misused-promises
842872
setTimeout(async () => {
843873
try {
@@ -879,6 +909,11 @@ const ExportDialog: ExportDialogComponent = ({
879909
content: "Upload Success",
880910
intent: "success",
881911
});
912+
posthog.capture("Export Dialog: Export Completed", {
913+
exportType: activeExportType,
914+
destination: activeExportDestination,
915+
fileCount: files.length,
916+
});
882917
onClose();
883918
}
884919
} catch (error) {
@@ -894,6 +929,11 @@ const ExportDialog: ExportDialogComponent = ({
894929
type: "text/plain;charset=utf-8",
895930
});
896931
saveAs(blob, title);
932+
posthog.capture("Export Dialog: Export Completed", {
933+
exportType: activeExportType,
934+
destination: activeExportDestination,
935+
fileCount: files.length,
936+
});
897937
onClose();
898938
return;
899939
}
@@ -906,12 +946,22 @@ const ExportDialog: ExportDialogComponent = ({
906946
);
907947
void zip.generateAsync({ type: "blob" }).then((content) => {
908948
saveAs(content, `${filename}.zip`);
949+
posthog.capture("Export Dialog: Export Completed", {
950+
exportType: activeExportType,
951+
destination: activeExportDestination,
952+
fileCount: files.length,
953+
});
909954
onClose();
910955
});
911956
} else {
912957
setError(`Unsupported export type: ${exportType}`);
913958
}
914959
} catch (e) {
960+
posthog.capture("Export Dialog: Export Failed", {
961+
exportType: activeExportType,
962+
destination: activeExportDestination,
963+
error: (e as Error).message ?? "unknown error",
964+
});
915965
internalError({
916966
error: e as Error,
917967
type: "Export Dialog Failed",
@@ -1007,7 +1057,12 @@ const ExportDialog: ExportDialogComponent = ({
10071057
id="export-tabs"
10081058
large={true}
10091059
selectedTabId={selectedTabId}
1010-
onChange={(newTabId: string) => setSelectedTabId(newTabId)}
1060+
onChange={(newTabId: string) => {
1061+
setSelectedTabId(newTabId);
1062+
posthog.capture("Export Dialog: Tab Opened", {
1063+
tabId: newTabId,
1064+
});
1065+
}}
10111066
>
10121067
<Tab id="sendto" title="Send To" panel={SendToPanel} />
10131068
<Tab id="export" title="Export" panel={ExportPanel} />

apps/roam/src/components/ImportDialog.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import React, { useMemo, useState } from "react";
1111
import createBlock from "roamjs-components/writes/createBlock";
1212
import getChildrenLengthByPageUid from "roamjs-components/queries/getChildrenLengthByPageUid";
1313
import createOverlayRender from "roamjs-components/util/createOverlayRender";
14+
import posthog from "posthog-js";
1415
import importDiscourseGraph from "~/utils/importDiscourseGraph";
1516

1617
const ImportDialog = ({ onClose }: { onClose: () => void }) => {
@@ -49,6 +50,10 @@ const ImportDialog = ({ onClose }: { onClose: () => void }) => {
4950
disabled={loading}
5051
onClick={() => {
5152
setLoading(true);
53+
posthog.capture("Import Dialog: Import Started", {
54+
hasFile: !!file,
55+
title,
56+
});
5257
setTimeout(() => {
5358
const reader = new FileReader();
5459
reader.onload = (event) => {

apps/roam/src/components/LeftSidebarView.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByPar
4242
import { DISCOURSE_CONFIG_PAGE_TITLE } from "~/utils/renderNodeConfigPage";
4343
import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid";
4444
import { migrateLeftSidebarSettings } from "~/utils/migrateLeftSidebarSettings";
45+
import posthog from "posthog-js";
4546

4647
const parseReference = (text: string) => {
4748
const extracted = extractRef(text);
@@ -61,6 +62,10 @@ const openTarget = async (e: React.MouseEvent, targetUid: string) => {
6162
e.preventDefault();
6263
e.stopPropagation();
6364
const target = parseReference(targetUid);
65+
posthog.capture("Left Sidebar: Target Opened", {
66+
targetType: target.type,
67+
openInSidebar: e.shiftKey,
68+
});
6469
if (target.type === "block") {
6570
if (e.shiftKey) {
6671
await openBlockInSidebar(target.uid);

apps/roam/src/components/ModifyNodeDialog.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { render as renderToast } from "roamjs-components/components/Toast";
3535
import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle";
3636
import resolveQueryBuilderRef from "~/utils/resolveQueryBuilderRef";
3737
import runQuery from "~/utils/runQuery";
38+
import posthog from "posthog-js";
3839

3940
export type ModifyNodeDialogMode = "create" | "edit";
4041
export type ModifyNodeDialogProps = {
@@ -301,6 +302,10 @@ const ModifyNodeDialog = ({
301302

302303
const onSubmit = async () => {
303304
if (!content.text.trim()) return;
305+
posthog.capture("Modify Node Dialog: Submit Triggered", {
306+
mode,
307+
nodeType: selectedNodeType.type,
308+
});
304309
try {
305310
if (mode === "create") {
306311
// If content is locked (user selected existing node), just insert it

apps/roam/src/components/QueryDrawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ const QueryDrawer = ({
380380
);
381381

382382
export const openQueryDrawer = (onloadArgs: OnloadArgs) => {
383-
posthog.capture("Query Drawer: Opened", {});
383+
posthog.capture("Query Drawer: Opened");
384384
return Promise.resolve(
385385
getPageUidByPageTitle("roam/js/query-builder/drawer") ||
386386
createPage({

apps/roam/src/components/SuggestionsBody.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { render as renderToast } from "roamjs-components/components/Toast";
2929
import { getSetting } from "~/utils/extensionSettings";
3030
import { USE_REIFIED_RELATIONS } from "~/data/userSettings";
3131
import { createReifiedRelation } from "~/utils/createReifiedBlock";
32+
import posthog from "posthog-js";
3233

3334
export type DiscourseData = {
3435
results: Awaited<ReturnType<typeof getDiscourseContextResults>>;
@@ -369,6 +370,12 @@ const SuggestionsBody = ({
369370
node: { text: `[[${node.text}]]` },
370371
});
371372
}
373+
posthog.capture("Suggestive Mode: Suggestion Adopted", {
374+
tag,
375+
nodeType: node.type,
376+
nodeText: node.text,
377+
useReifiedRelations: getSetting<boolean>(USE_REIFIED_RELATIONS, false),
378+
});
372379
setHydeFilteredNodes((prev) => prev.filter((n) => n.uid !== node.uid));
373380
};
374381

apps/roam/src/components/VectorDuplicateMatches.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTit
88
import { DiscourseNode } from "~/utils/getDiscourseNodes";
99
import extractContentFromTitle from "~/utils/extractContentFromTitle";
1010
import { handleTitleAdditions } from "~/utils/handleTitleAdditions";
11+
import posthog from "posthog-js";
1112

1213
export const VectorDuplicateMatches = ({
1314
pageTitle,
@@ -109,6 +110,7 @@ export const VectorDuplicateMatches = ({
109110
className="flex cursor-pointer items-center justify-between p-2"
110111
onClick={() => {
111112
setIsOpen(!isOpen);
113+
posthog.capture("Possible Duplicates: Toggled");
112114
}}
113115
>
114116
<div className="flex items-center gap-2">

0 commit comments

Comments
 (0)