From 932f382b5866fdf0575cc72dda49cbfa2487d219 Mon Sep 17 00:00:00 2001 From: Abram Date: Mon, 11 Dec 2023 18:09:03 +0100 Subject: [PATCH 1/8] Update - added event to track --- agenta-web/src/pages/_app.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/agenta-web/src/pages/_app.tsx b/agenta-web/src/pages/_app.tsx index 13079b6888..f58e6b70ce 100644 --- a/agenta-web/src/pages/_app.tsx +++ b/agenta-web/src/pages/_app.tsx @@ -1,7 +1,11 @@ -import "@/styles/globals.css" -import posthog from "posthog-js" +import { useEffect } from 'react' import type {AppProps} from "next/app" +import { useRouter } from 'next/router' + +import posthog from "posthog-js" import {PostHogProvider} from "posthog-js/react" + +import "@/styles/globals.css" import Layout from "@/components/Layout/Layout" import ThemeContextProvider from "@/components/Layout/ThemeContextProvider" import AppContextProvider from "@/contexts/app.context" @@ -16,10 +20,21 @@ if (typeof window !== "undefined") { if (process.env.NODE_ENV === "development") posthog.debug() }, capture_pageview: false, + persistence: "localStorage+cookie" }) } export default function App({Component, pageProps}: AppProps) { + const router = useRouter() + + useEffect(() => { + const handleRouteChange = () => posthog.capture('$pageview', { $current_url: window.location.href }) + router.events.on('routeChangeComplete', handleRouteChange) + + return () => { + router.events.off('routeChangeComplete', handleRouteChange) + } + }, []) return ( From db18dbf2f33f5b257c3baf39472318ad4d5c158d Mon Sep 17 00:00:00 2001 From: Abram Date: Mon, 11 Dec 2023 18:10:06 +0100 Subject: [PATCH 2/8] Update - sync oss (ui) tracking with cli --- .../components/AppSelector/AppSelector.tsx | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/agenta-web/src/components/AppSelector/AppSelector.tsx b/agenta-web/src/components/AppSelector/AppSelector.tsx index e006780947..b5c274509c 100644 --- a/agenta-web/src/components/AppSelector/AppSelector.tsx +++ b/agenta-web/src/components/AppSelector/AppSelector.tsx @@ -204,7 +204,7 @@ const AppSelector: React.FC = () => { orgId: selectedOrg?.id!, providerKey: isDemo() ? "" : (providerKeys as string), timeout, - onStatusChange: (status, details, appId) => { + onStatusChange: async (status, details, appId) => { setStatusData((prev) => ({status, details, appId: appId || prev.appId})) if (["error", "bad_request", "timeout", "success"].includes(status)) setFetchingTemplate(false) @@ -212,17 +212,14 @@ const AppSelector: React.FC = () => { mutate() if (trackingEnabled) { - // Get user profile - getProfile().then((res) => { - // Update distinct_id and track successfully app variant deployment - posthog?.identify(res?.data?.id) - posthog?.capture("app_deployment", { - properties: { - app_id: appId, - environment: "UI", - deployed_by: res?.data?.id, - }, - }) + const profileRes = await getProfile() + posthog.identify(profileRes?.data?.id) + posthog.capture("app_deployment", { + properties: { + app_id: appId, + environment: "UI", + deployed_by: profileRes?.data?.id, + }, }) } } From 61e98f6a057e55a828c9d3aa14394978d6004e95 Mon Sep 17 00:00:00 2001 From: Abram Date: Mon, 11 Dec 2023 18:10:40 +0100 Subject: [PATCH 3/8] Update - capture event when variant is saved on the UI --- agenta-web/src/components/Playground/Views/ParametersView.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/agenta-web/src/components/Playground/Views/ParametersView.tsx b/agenta-web/src/components/Playground/Views/ParametersView.tsx index 43740f3257..4d869cfe41 100644 --- a/agenta-web/src/components/Playground/Views/ParametersView.tsx +++ b/agenta-web/src/components/Playground/Views/ParametersView.tsx @@ -1,5 +1,6 @@ import {Environment, Parameter, Variant} from "@/lib/Types" import type {CollapseProps} from "antd" +import {usePostHog} from "posthog-js/react" import {Button, Col, Collapse, Row, Space, Tooltip, message} from "antd" import React, {useEffect, useState} from "react" import {createUseStyles} from "react-jss" @@ -70,6 +71,7 @@ const ParametersView: React.FC = ({ tabID, }) => { const classes = useStyles() + const posthog = usePostHog() const [messageApi, contextHolder] = message.useMessage() const [isPublishModalOpen, setPublishModalOpen] = useState(false) const isVariantExisting = !!variant.variantId @@ -106,6 +108,7 @@ const ParametersView: React.FC = ({ onStateChange(false) res(true) }) + posthog.capture('variant_saved', { variant_id: variant.variantId }) }) } From 0a14b7486de9bfc3130bb0b7ff85716341b42391 Mon Sep 17 00:00:00 2001 From: Abram Date: Mon, 11 Dec 2023 18:10:51 +0100 Subject: [PATCH 4/8] Update - capture event when app is saved on the UI --- .../src/components/Playground/Views/PublishVariantModal.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx b/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx index 3c729ce0c2..160259c6fe 100644 --- a/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx +++ b/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx @@ -3,6 +3,7 @@ import {fetchEnvironments, publishVariant} from "@/lib/services/api" import {Button, Checkbox, Modal, Space, Typography, message} from "antd" import type {CheckboxChangeEvent} from "antd/es/checkbox" import {useRouter} from "next/router" +import {usePostHog} from "posthog-js/react" import React, {useEffect, useState} from "react" import {createUseStyles} from "react-jss" @@ -35,6 +36,7 @@ const PublishVariantModal: React.FC = ({ setSelectedEnvs([]) } const router = useRouter() + const posthog = usePostHog() const appId = router.query.app_id as string const [selectedEnvs, setSelectedEnvs] = useState([]) @@ -55,6 +57,7 @@ const PublishVariantModal: React.FC = ({ closeModal() await loadEnvironments() message.success(`Published ${variant.variantName} to ${envName}`) + posthog.capture('app_deployed', { app_id: appId, environment: envName }) }) } From 0267787ee3922bc60b90287f172cdcf030c6ed92 Mon Sep 17 00:00:00 2001 From: Abram Date: Mon, 11 Dec 2023 18:11:55 +0100 Subject: [PATCH 5/8] :art: Format - ran prettier --write . --- .../components/Playground/Views/ParametersView.tsx | 2 +- .../Playground/Views/PublishVariantModal.tsx | 2 +- agenta-web/src/pages/_app.tsx | 13 +++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/agenta-web/src/components/Playground/Views/ParametersView.tsx b/agenta-web/src/components/Playground/Views/ParametersView.tsx index 4d869cfe41..02b6d699df 100644 --- a/agenta-web/src/components/Playground/Views/ParametersView.tsx +++ b/agenta-web/src/components/Playground/Views/ParametersView.tsx @@ -108,7 +108,7 @@ const ParametersView: React.FC = ({ onStateChange(false) res(true) }) - posthog.capture('variant_saved', { variant_id: variant.variantId }) + posthog.capture("variant_saved", {variant_id: variant.variantId}) }) } diff --git a/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx b/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx index 160259c6fe..0b3000c819 100644 --- a/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx +++ b/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx @@ -57,7 +57,7 @@ const PublishVariantModal: React.FC = ({ closeModal() await loadEnvironments() message.success(`Published ${variant.variantName} to ${envName}`) - posthog.capture('app_deployed', { app_id: appId, environment: envName }) + posthog.capture("app_deployed", {app_id: appId, environment: envName}) }) } diff --git a/agenta-web/src/pages/_app.tsx b/agenta-web/src/pages/_app.tsx index f58e6b70ce..4e3f89b94c 100644 --- a/agenta-web/src/pages/_app.tsx +++ b/agenta-web/src/pages/_app.tsx @@ -1,6 +1,6 @@ -import { useEffect } from 'react' +import {useEffect} from "react" import type {AppProps} from "next/app" -import { useRouter } from 'next/router' +import {useRouter} from "next/router" import posthog from "posthog-js" import {PostHogProvider} from "posthog-js/react" @@ -20,7 +20,7 @@ if (typeof window !== "undefined") { if (process.env.NODE_ENV === "development") posthog.debug() }, capture_pageview: false, - persistence: "localStorage+cookie" + persistence: "localStorage+cookie", }) } @@ -28,11 +28,12 @@ export default function App({Component, pageProps}: AppProps) { const router = useRouter() useEffect(() => { - const handleRouteChange = () => posthog.capture('$pageview', { $current_url: window.location.href }) - router.events.on('routeChangeComplete', handleRouteChange) + const handleRouteChange = () => + posthog.capture("$pageview", {$current_url: window.location.href}) + router.events.on("routeChangeComplete", handleRouteChange) return () => { - router.events.off('routeChangeComplete', handleRouteChange) + router.events.off("routeChangeComplete", handleRouteChange) } }, []) return ( From ea804478a366ee8ee6133c915fc327d5a0b43d4d Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Tue, 12 Dec 2023 10:51:23 +0100 Subject: [PATCH 6/8] modifies posthog logic --- agenta-web/src/components/AppSelector/AppSelector.tsx | 6 ++---- agenta-web/src/contexts/profile.context.tsx | 3 +++ agenta-web/src/hooks/useSession.ts | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/agenta-web/src/components/AppSelector/AppSelector.tsx b/agenta-web/src/components/AppSelector/AppSelector.tsx index b5c274509c..37228bed09 100644 --- a/agenta-web/src/components/AppSelector/AppSelector.tsx +++ b/agenta-web/src/components/AppSelector/AppSelector.tsx @@ -105,7 +105,7 @@ const AppSelector: React.FC = () => { const [isWriteAppModalOpen, setIsWriteAppModalOpen] = useState(false) const [isMaxAppModalOpen, setIsMaxAppModalOpen] = useState(false) const [templates, setTemplates] = useState([]) - + const {user} = useProfileData() const [templateMessage, setTemplateMessage] = useState("") const [templateId, setTemplateId] = useState(undefined) const [isInputTemplateModalOpen, setIsInputTemplateModalOpen] = useState(false) @@ -212,13 +212,11 @@ const AppSelector: React.FC = () => { mutate() if (trackingEnabled) { - const profileRes = await getProfile() - posthog.identify(profileRes?.data?.id) posthog.capture("app_deployment", { properties: { app_id: appId, environment: "UI", - deployed_by: profileRes?.data?.id, + deployed_by: user?.id, }, }) } diff --git a/agenta-web/src/contexts/profile.context.tsx b/agenta-web/src/contexts/profile.context.tsx index a7afb91a65..e15215a0bf 100644 --- a/agenta-web/src/contexts/profile.context.tsx +++ b/agenta-web/src/contexts/profile.context.tsx @@ -4,6 +4,7 @@ import {isDemo} from "@/lib/helpers/utils" import {getOrgsList, getProfile} from "@/lib/services/api" import {Org, User} from "@/lib/Types" import {useRouter} from "next/router" +import { usePostHog } from "posthog-js/react" import { PropsWithChildren, createContext, @@ -54,6 +55,7 @@ const profileContextValues = {...initialValues} export const getProfileValues = () => profileContextValues const ProfileContextProvider: React.FC = ({children}) => { + const posthog = usePostHog() const router = useRouter() const [user, setUser] = useState(null) const [orgs, setOrgs] = useState([]) @@ -65,6 +67,7 @@ const ProfileContextProvider: React.FC = ({children}) => { setLoading(true) Promise.all([getProfile(), getOrgsList()]) .then(([profile, orgs]) => { + posthog.identify(isDemo() ? profile.data.email : profile.data.id) setUser(profile.data) setOrgs(orgs.data) setSelectedOrg( diff --git a/agenta-web/src/hooks/useSession.ts b/agenta-web/src/hooks/useSession.ts index acea322698..196288e246 100644 --- a/agenta-web/src/hooks/useSession.ts +++ b/agenta-web/src/hooks/useSession.ts @@ -1,6 +1,7 @@ import {useProfileData} from "@/contexts/profile.context" import {isDemo} from "@/lib/helpers/utils" import {useRouter} from "next/router" +import posthog from "posthog-js" import {useSessionContext} from "supertokens-auth-react/recipe/session" import {signOut} from "supertokens-auth-react/recipe/thirdpartypasswordless" @@ -17,6 +18,7 @@ export const useSession: () => {loading: boolean; doesSessionExist: boolean; log logout: () => { signOut() .then(() => { + posthog.reset() reset() router.push("/auth") }) From 84a9f3572a10fa8c7c1bbc596775c76cfd4eff23 Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Tue, 12 Dec 2023 10:51:58 +0100 Subject: [PATCH 7/8] format fix --- agenta-web/src/contexts/profile.context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agenta-web/src/contexts/profile.context.tsx b/agenta-web/src/contexts/profile.context.tsx index e15215a0bf..455b713bab 100644 --- a/agenta-web/src/contexts/profile.context.tsx +++ b/agenta-web/src/contexts/profile.context.tsx @@ -4,7 +4,7 @@ import {isDemo} from "@/lib/helpers/utils" import {getOrgsList, getProfile} from "@/lib/services/api" import {Org, User} from "@/lib/Types" import {useRouter} from "next/router" -import { usePostHog } from "posthog-js/react" +import {usePostHog} from "posthog-js/react" import { PropsWithChildren, createContext, From 8aa1925ec327100d388b4cf72ea641a023b15aca Mon Sep 17 00:00:00 2001 From: MohammedMaaz Date: Tue, 12 Dec 2023 15:49:59 +0500 Subject: [PATCH 8/8] added usePostHogAg hook --- .../components/AppSelector/AppSelector.tsx | 23 +++++-------- .../Playground/Views/ParametersView.tsx | 4 +-- .../Playground/Views/PublishVariantModal.tsx | 4 +-- agenta-web/src/contexts/profile.context.tsx | 6 ++-- agenta-web/src/hooks/usePostHogAg.ts | 34 +++++++++++++++++++ 5 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 agenta-web/src/hooks/usePostHogAg.ts diff --git a/agenta-web/src/components/AppSelector/AppSelector.tsx b/agenta-web/src/components/AppSelector/AppSelector.tsx index 37228bed09..e32e2b1b69 100644 --- a/agenta-web/src/components/AppSelector/AppSelector.tsx +++ b/agenta-web/src/components/AppSelector/AppSelector.tsx @@ -1,6 +1,5 @@ import {useState, useEffect, useMemo} from "react" import {useRouter} from "next/router" -import {usePostHog} from "posthog-js/react" import {PlusOutlined} from "@ant-design/icons" import {Input, Modal, ConfigProvider, theme, Spin, Card, Button, notification, Divider} from "antd" import AppCard from "./AppCard" @@ -12,7 +11,6 @@ import Welcome from "./Welcome" import {getApikeys, isAppNameInputValid, isDemo} from "@/lib/helpers/utils" import { createAndStartTemplate, - getProfile, getTemplates, removeApp, waitForAppToStart, @@ -25,6 +23,7 @@ import {createUseStyles} from "react-jss" import {useAppsData} from "@/contexts/app.context" import {useProfileData} from "@/contexts/profile.context" import CreateAppStatusModal from "./modals/CreateAppStatusModal" +import {usePostHogAg} from "@/hooks/usePostHogAg" type StyleProps = { themeMode: "dark" | "light" @@ -97,7 +96,7 @@ const timeout = isDemo() ? 60000 : 30000 const AppSelector: React.FC = () => { const router = useRouter() - const posthog = usePostHog() + const posthog = usePostHogAg() const {appTheme} = useAppTheme() const classes = useStyles({themeMode: appTheme} as StyleProps) const [isCreateAppModalOpen, setIsCreateAppModalOpen] = useState(false) @@ -120,7 +119,6 @@ const AppSelector: React.FC = () => { appId: undefined, }) - const trackingEnabled = process.env.NEXT_PUBLIC_TELEMETRY_TRACKING_ENABLED === "true" const showCreateAppModal = async () => { setIsCreateAppModalOpen(true) } @@ -210,16 +208,13 @@ const AppSelector: React.FC = () => { setFetchingTemplate(false) if (status === "success") { mutate() - - if (trackingEnabled) { - posthog.capture("app_deployment", { - properties: { - app_id: appId, - environment: "UI", - deployed_by: user?.id, - }, - }) - } + posthog.capture("app_deployment", { + properties: { + app_id: appId, + environment: "UI", + deployed_by: user?.id, + }, + }) } }, }) diff --git a/agenta-web/src/components/Playground/Views/ParametersView.tsx b/agenta-web/src/components/Playground/Views/ParametersView.tsx index 02b6d699df..1866f438cf 100644 --- a/agenta-web/src/components/Playground/Views/ParametersView.tsx +++ b/agenta-web/src/components/Playground/Views/ParametersView.tsx @@ -1,6 +1,5 @@ import {Environment, Parameter, Variant} from "@/lib/Types" import type {CollapseProps} from "antd" -import {usePostHog} from "posthog-js/react" import {Button, Col, Collapse, Row, Space, Tooltip, message} from "antd" import React, {useEffect, useState} from "react" import {createUseStyles} from "react-jss" @@ -8,6 +7,7 @@ import {ModelParameters, ObjectParameters, StringParameters} from "./ParametersC import PublishVariantModal from "./PublishVariantModal" import {removeVariant} from "@/lib/services/api" import {CloudUploadOutlined, DeleteOutlined, SaveOutlined} from "@ant-design/icons" +import {usePostHogAg} from "@/hooks/usePostHogAg" interface Props { variant: Variant @@ -71,7 +71,7 @@ const ParametersView: React.FC = ({ tabID, }) => { const classes = useStyles() - const posthog = usePostHog() + const posthog = usePostHogAg() const [messageApi, contextHolder] = message.useMessage() const [isPublishModalOpen, setPublishModalOpen] = useState(false) const isVariantExisting = !!variant.variantId diff --git a/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx b/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx index 0b3000c819..8ff5508518 100644 --- a/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx +++ b/agenta-web/src/components/Playground/Views/PublishVariantModal.tsx @@ -1,9 +1,9 @@ +import {usePostHogAg} from "@/hooks/usePostHogAg" import {Environment, Variant} from "@/lib/Types" import {fetchEnvironments, publishVariant} from "@/lib/services/api" import {Button, Checkbox, Modal, Space, Typography, message} from "antd" import type {CheckboxChangeEvent} from "antd/es/checkbox" import {useRouter} from "next/router" -import {usePostHog} from "posthog-js/react" import React, {useEffect, useState} from "react" import {createUseStyles} from "react-jss" @@ -36,7 +36,7 @@ const PublishVariantModal: React.FC = ({ setSelectedEnvs([]) } const router = useRouter() - const posthog = usePostHog() + const posthog = usePostHogAg() const appId = router.query.app_id as string const [selectedEnvs, setSelectedEnvs] = useState([]) diff --git a/agenta-web/src/contexts/profile.context.tsx b/agenta-web/src/contexts/profile.context.tsx index 455b713bab..0e6ca730b7 100644 --- a/agenta-web/src/contexts/profile.context.tsx +++ b/agenta-web/src/contexts/profile.context.tsx @@ -1,10 +1,10 @@ +import {usePostHogAg} from "@/hooks/usePostHogAg" import {useSession} from "@/hooks/useSession" import useStateCallback from "@/hooks/useStateCallback" import {isDemo} from "@/lib/helpers/utils" import {getOrgsList, getProfile} from "@/lib/services/api" import {Org, User} from "@/lib/Types" import {useRouter} from "next/router" -import {usePostHog} from "posthog-js/react" import { PropsWithChildren, createContext, @@ -55,7 +55,7 @@ const profileContextValues = {...initialValues} export const getProfileValues = () => profileContextValues const ProfileContextProvider: React.FC = ({children}) => { - const posthog = usePostHog() + const posthog = usePostHogAg() const router = useRouter() const [user, setUser] = useState(null) const [orgs, setOrgs] = useState([]) @@ -67,7 +67,7 @@ const ProfileContextProvider: React.FC = ({children}) => { setLoading(true) Promise.all([getProfile(), getOrgsList()]) .then(([profile, orgs]) => { - posthog.identify(isDemo() ? profile.data.email : profile.data.id) + posthog.identify() setUser(profile.data) setOrgs(orgs.data) setSelectedOrg( diff --git a/agenta-web/src/hooks/usePostHogAg.ts b/agenta-web/src/hooks/usePostHogAg.ts new file mode 100644 index 0000000000..5a3f069dff --- /dev/null +++ b/agenta-web/src/hooks/usePostHogAg.ts @@ -0,0 +1,34 @@ +import {useProfileData} from "@/contexts/profile.context" +import {isDemo} from "@/lib/helpers/utils" +import {usePostHog} from "posthog-js/react" +import {useLayoutEffect} from "react" + +export const usePostHogAg = () => { + const trackingEnabled = process.env.NEXT_PUBLIC_TELEMETRY_TRACKING_ENABLED === "true" + const {user} = useProfileData() + const posthog = usePostHog() + + const _id = isDemo() ? user?.email : user?.id + + const capture: typeof posthog.capture = (...args) => { + if (trackingEnabled && user?.id) { + posthog.capture(...args) + } + } + + const identify: typeof posthog.identify = (id, ...args) => { + if (trackingEnabled && user?.id) { + posthog.identify(_id || id, ...args) + } + } + + useLayoutEffect(() => { + if (!trackingEnabled) posthog.opt_out_capturing() + }, [trackingEnabled]) + + useLayoutEffect(() => { + if (posthog.get_distinct_id() !== _id) identify() + }, [user?.id]) + + return {...posthog, identify, capture} +}