Skip to content

Commit 2ee740c

Browse files
committed
feat: add new track in ui
1 parent 747f874 commit 2ee740c

File tree

11 files changed

+1062
-34
lines changed

11 files changed

+1062
-34
lines changed

app/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@radix-ui/react-tabs": "^1.0.4",
2929
"@radix-ui/react-toggle": "^1.0.3",
3030
"@radix-ui/react-toggle-group": "^1.0.4",
31+
"@segment/analytics-next": "^1.69.0",
3132
"autoprefixer": "^10.3.5",
3233
"buffer": "^6.0.3",
3334
"class-variance-authority": "^0.7.0",

app/src/components/codeExportModal/index.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import commonStore from "@/store/common";
1212
import { darkModeContext } from "@/store/context";
1313
import { Button } from "@/components/ui/button";
1414
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
15+
import { tracker } from "@/utils/tracker";
1516

1617
import { usePythonCode } from "./usePythonCode";
1718

@@ -108,6 +109,7 @@ const CodeExport: React.FC<ICodeExport> = observer((props) => {
108109
<Button
109110
onClick={() => {
110111
copyToCliboard(JSON.stringify(visSpec, null, 2));
112+
tracker.track("click", {"entity": "copy_code_button"});
111113
}}
112114
>
113115
Copy to Clipboard

app/src/components/uploadChartModal/index.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { observer } from "mobx-react-lite";
33
import type { IGWHandler } from "@kanaries/graphic-walker/interfaces";
44
import type { VizSpecStore } from '@kanaries/graphic-walker/store/visualSpecStore'
55
import { chartToWorkflow } from "@kanaries/graphic-walker"
6+
import { tracker } from "@/utils/tracker";
67

78
import communicationStore from "../../store/communication";
89
import commonStore from "../../store/common";
@@ -86,6 +87,7 @@ const UploadChartModal: React.FC<IUploadChartModal> = observer((props) => {
8687
const onClick = async () => {
8788
if (uploading) return;
8889
setUploading(true);
90+
tracker.track("click", {"entity": "upload_chart_button"});
8991

9092
const visSpec = props.storeRef.current?.exportCode()!;
9193
try {

app/src/components/uploadSpecModal/index.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react";
22
import { observer } from "mobx-react-lite";
33
import type { VizSpecStore } from '@kanaries/graphic-walker/store/visualSpecStore'
44
import { chartToWorkflow } from "@kanaries/graphic-walker/utils/workflow";
5+
import { tracker } from "@/utils/tracker";
56

67
import communicationStore from "../../store/communication";
78
import commonStore from "../../store/common";
@@ -43,6 +44,7 @@ const UploadSpecModal: React.FC<IUploadSpecModal> = observer((props) => {
4344

4445
const onClick = async () => {
4546
if (uploading) return;
47+
tracker.track("click", {"entity": "upload_spec_to_cloud_button"});
4648
setUploading(true);
4749

4850
try {
@@ -66,6 +68,7 @@ const UploadSpecModal: React.FC<IUploadSpecModal> = observer((props) => {
6668
}
6769

6870
const saveSpecToLocal = () => {
71+
tracker.track("click", {"entity": "save_spec_to_local_file_button"});
6972
const visSpec = props.storeRef.current?.exportCode();
7073
const configObj = {
7174
config: visSpec,
@@ -96,7 +99,10 @@ const UploadSpecModal: React.FC<IUploadSpecModal> = observer((props) => {
9699
<div className="grid h-full grid-rows-2 gap-6 lg:grid-cols-2 lg:grid-rows-1">
97100
<button
98101
className={"flex flex-col items-start gap-2 rounded-lg border p-3 text-left text-sm transition-all hover:bg-accent"}
99-
onClick={() => {setContentType("upload")}}
102+
onClick={() => {
103+
setContentType("upload");
104+
tracker.track("click", {"entity": "select_upload_spec_to_cloud_button"});
105+
}}
100106
>
101107
<div className="flex items-center justify-center h-[160px] w-full">
102108
<span className="font-semibold">upload as cloud file</span>

app/src/index.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { loadDataSource, postDataService, finishDataService, getDatasFromKernelB
1515
import commonStore from "./store/common";
1616
import { initJupyterCommunication, initHttpCommunication } from "./utils/communication";
1717
import communicationStore from "./store/communication"
18-
import { setConfig, checkUploadPrivacy } from './utils/userConfig';
18+
import { setConfig } from './utils/userConfig';
1919
import CodeExportModal from './components/codeExportModal';
2020
import type { IPreviewProps, IChartPreviewProps } from './components/preview';
2121
import { Preview, ChartPreview } from './components/preview';
@@ -26,6 +26,7 @@ import { getSaveTool, hidePreview } from './tools/saveTool';
2626
import { getExportTool } from './tools/exportTool';
2727
import { getExportDataframeTool } from './tools/exportDataframe';
2828
import { formatExportedChartDatas } from "./utils/save";
29+
import { tracker } from "@/utils/tracker";
2930
import Notification from "./notify"
3031
import initDslParser from "@kanaries/gw-dsl-parser";
3132
import {
@@ -165,7 +166,11 @@ const ExploreApp: React.FC<IAppProps & {initChartFlag: boolean}> = (props) => {
165166

166167
useEffect(() => {
167168
commonStore.setShowCloudTool(props.showCloudTool);
168-
if (userConfig) setConfig(userConfig);
169+
tracker.setUserId(props.hashcode ?? "");
170+
if (userConfig) {
171+
setConfig(userConfig);
172+
tracker.setOpen(userConfig.privacy === "events");
173+
};
169174
}, []);
170175

171176
useEffect(() => {

app/src/tools/exportDataframe.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useState } from 'react';
22
import communicationStore from "../store/communication"
33
import commonStore from '../store/common';
4+
import { tracker } from "@/utils/tracker";
45

56
import { DocumentArrowDownIcon } from '@heroicons/react/24/outline';
67
import { Loader2 } from "lucide-react"
@@ -37,6 +38,8 @@ export function getExportDataframeTool(
3738
const onClick = async () => {
3839
if (exporting) return;
3940
setExporting(true);
41+
tracker.track("click", {"entity": "export_dataframe_icon"});
42+
4043
try {
4144
if (props.parseDslType === "server") {
4245
await communicationStore.comm?.sendMsg("export_dataframe_by_payload", {

app/src/tools/exportTool.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22

3+
import { tracker } from "@/utils/tracker";
34
import { CodeBracketSquareIcon } from '@heroicons/react/24/outline';
45

56
import type { ToolbarButtonItem } from "@kanaries/graphic-walker/components/toolbar/toolbar-button"
@@ -8,10 +9,14 @@ import type { ToolbarButtonItem } from "@kanaries/graphic-walker/components/tool
89
export function getExportTool(
910
setExportOpen: React.Dispatch<React.SetStateAction<boolean>>
1011
) : ToolbarButtonItem {
12+
const onClick = () => {
13+
setExportOpen(true);
14+
tracker.track("click", {"entity": "export_code_icon"});
15+
}
1116
return {
1217
key: "export_pygwalker_code",
1318
label: "export_code",
1419
icon: (iconProps?: any) => <CodeBracketSquareIcon {...iconProps} />,
15-
onClick: () => { setExportOpen(true); }
20+
onClick
1621
}
1722
}

app/src/tools/loginTool.tsx

-23
This file was deleted.

app/src/tools/saveTool.tsx

+12-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import communicationStore from "../store/communication"
33
import commonStore from '../store/common';
44
import { formatExportedChartDatas } from "../utils/save"
55
import { checkUploadPrivacy } from '../utils/userConfig';
6+
import { tracker } from "@/utils/tracker";
67

78
import { chartToWorkflow } from "@kanaries/graphic-walker"
89
import { DocumentTextIcon } from '@heroicons/react/24/outline';
@@ -60,9 +61,10 @@ export function getSaveTool(
6061
}, 500);
6162
}
6263

63-
const onClick = async () => {
64+
const onClick = async (where: string) => {
6465
if (saving) return;
6566
setSaving(true);
67+
tracker.track("click", {"entity": `save_${where}`, "spec_type": props.specType})
6668

6769
// if exportChart is undefined, it means that the chart is not reload, so we think dont need to save.
6870
if (gwRef.current?.exportChart === undefined) {
@@ -109,14 +111,19 @@ export function getSaveTool(
109111
}
110112
}
111113

114+
const onClickUpload = () => {
115+
commonStore.setUploadChartModalOpen(true);
116+
tracker.track("click", {"entity": "save_icon_form_upload", "spec_type": props.specType});
117+
}
118+
112119
useEffect(() => {
113120
let locker = false;
114121
document.addEventListener("keydown", (event) => {
115122
if ((event.metaKey || event.ctrlKey) && event.key === 's') {
116123
event.preventDefault();
117124
if (locker) return;
118125
locker = true;
119-
onClick().then(() => {
126+
onClick("from_keyboard").then(() => {
120127
locker = false;
121128
});
122129
}
@@ -132,16 +139,16 @@ export function getSaveTool(
132139
},
133140
form: (
134141
<div className='flex flex-col'>
135-
<Button variant="ghost" aria-label="save spec" onClick={onClick}>
142+
<Button variant="ghost" aria-label="save spec" onClick={() => onClick("icon_form_save")}>
136143
save spec
137144
</Button>
138145
{showUploadButton && (
139-
<Button variant="ghost" aria-label="upload chart" onClick={() => {commonStore.setUploadChartModalOpen(true)}}>
146+
<Button variant="ghost" aria-label="upload chart" onClick={onClickUpload}>
140147
upload chart
141148
</Button>
142149
)}
143150
</div>
144151
),
145-
onClick: onClick,
152+
onClick: () => onClick("icon"),
146153
}
147154
}

app/src/utils/tracker.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { AnalyticsBrowser } from '@segment/analytics-next'
2+
3+
4+
const initTracker = () => {
5+
var userId = "";
6+
var open = false;
7+
var analytics;
8+
9+
const setUserId = (id: string) => {
10+
userId = id;
11+
};
12+
13+
const setOpen = (value: boolean) => {
14+
if (value) {
15+
analytics = AnalyticsBrowser.load({ writeKey: '9gxTNvl6Pl4WaZ5aymeHEBqNN8K4Op0U' })
16+
}
17+
open = value;
18+
}
19+
20+
const track = (eventName: string, data: any) => {
21+
if (open) {
22+
analytics.track(eventName, {...data, userId})
23+
}
24+
};
25+
26+
return {
27+
setUserId,
28+
setOpen,
29+
track
30+
}
31+
}
32+
33+
export const tracker = initTracker();

0 commit comments

Comments
 (0)