diff --git a/src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx
index 7e3096408a0f..8175cc62c470 100644
--- a/src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx
+++ b/src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx
@@ -1,16 +1,16 @@
import useHandleNodeClass from "@/CustomNodes/hooks/use-handle-node-class";
-import { ParameterRenderComponent } from "@/components/parameterRenderComponent";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
-import { ReactNode, useEffect, useRef, useState } from "react";
+import {
+ CustomParameterComponent,
+ getCustomParameterTitle,
+} from "@/customization/components/custom-parameter";
+import { useEffect, useRef } from "react";
import { default as IconComponent } from "../../../../components/genericIconComponent";
import ShadTooltip from "../../../../components/shadTooltipComponent";
import { LANGFLOW_SUPPORTED_TYPES } from "../../../../constants/constants";
import useFlowStore from "../../../../stores/flowStore";
import { useTypesStore } from "../../../../stores/typesStore";
-import {
- NodeInputFieldComponentType,
- ParameterComponentType,
-} from "../../../../types/components";
+import { NodeInputFieldComponentType } from "../../../../types/components";
import { scapedJSONStringfy } from "../../../../utils/reactflowUtils";
import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount";
import useHandleOnNewValue from "../../../hooks/use-handle-new-value";
@@ -105,11 +105,21 @@ export default function NodeInputField({
{proxy ? (
{proxy.id}}>
- {{title}}
+ {
+
+ {getCustomParameterTitle({ title, nodeId: data.id })}
+
+ }
) : (
- {{title}}
+
+ {
+
+ {getCustomParameterTitle({ title, nodeId: data.id })}
+
+ }
+
)}
@@ -133,7 +143,7 @@ export default function NodeInputField({
{displayHandle && Handle}
{data.node?.template[name] !== undefined && (
-
{
e.preventDefault();
e.stopPropagation();
+ track("Playground Button Clicked", { flowId: data.id });
setLoadingPlayground(true);
const flow = getFlowById(data.id);
if (flow) {
diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx
index 817d1b2f77f7..951e8b6c2f14 100644
--- a/src/frontend/src/components/chatComponent/index.tsx
+++ b/src/frontend/src/components/chatComponent/index.tsx
@@ -1,6 +1,7 @@
import { ENABLE_API } from "@/customization/feature-flags";
+import { track } from "@/customization/utils/analytics";
import { Transition } from "@headlessui/react";
-import { useMemo, useState } from "react";
+import { useEffect, useMemo, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import IOModal from "../../modals/IOModal";
import ApiModal from "../../modals/apiModal";
@@ -48,6 +49,12 @@ export default function FlowToolbar(): JSX.Element {
const hasApiKey = useStoreStore((state) => state.hasApiKey);
const currentFlow = useFlowStore((state) => state.currentFlow);
+ useEffect(() => {
+ if (open) {
+ track("Playground Button Clicked");
+ }
+ }, [open]);
+
const ModalMemo = useMemo(
() => (
= (
const mutation: UseMutationResult, any, UserInputType> = mutate(
["useAddUser"],
- async (payload: UserInputType) => {
- const res = await addUserFunction(payload);
- return res;
- },
+ addUserFunction,
options,
);
diff --git a/src/frontend/src/customization/components/custom-parameter.tsx b/src/frontend/src/customization/components/custom-parameter.tsx
new file mode 100644
index 000000000000..d2358e5edf39
--- /dev/null
+++ b/src/frontend/src/customization/components/custom-parameter.tsx
@@ -0,0 +1,49 @@
+import { ParameterRenderComponent } from "@/components/parameterRenderComponent";
+import { handleOnNewValueType } from "@/CustomNodes/hooks/use-handle-new-value";
+import { APIClassType, InputFieldType } from "@/types/api";
+
+export function CustomParameterComponent({
+ handleOnNewValue,
+ name,
+ nodeId,
+ templateData,
+ templateValue,
+ editNode,
+ handleNodeClass,
+ nodeClass,
+ disabled,
+}: {
+ handleOnNewValue: handleOnNewValueType;
+ name: string;
+ nodeId: string;
+ templateData: Partial;
+ templateValue: any;
+ editNode: boolean;
+ handleNodeClass: (value: any, code?: string, type?: string) => void;
+ nodeClass: APIClassType;
+ disabled: boolean;
+}) {
+ return (
+
+ );
+}
+
+export function getCustomParameterTitle({
+ title,
+ nodeId,
+}: {
+ title: string;
+ nodeId: string;
+}) {
+ return title;
+}
diff --git a/src/frontend/src/customization/utils/analytics.ts b/src/frontend/src/customization/utils/analytics.ts
new file mode 100644
index 000000000000..03a7c92765b4
--- /dev/null
+++ b/src/frontend/src/customization/utils/analytics.ts
@@ -0,0 +1,7 @@
+export const track = async (
+ name: string,
+ properties: Record = {},
+ id: string = "",
+): Promise => {
+ return;
+};
diff --git a/src/frontend/src/modals/baseModal/index.tsx b/src/frontend/src/modals/baseModal/index.tsx
index 947b70d4d451..6502b090b3ed 100644
--- a/src/frontend/src/modals/baseModal/index.tsx
+++ b/src/frontend/src/modals/baseModal/index.tsx
@@ -89,9 +89,16 @@ const Footer: React.FC<{
onClick?: () => void;
};
close?: boolean;
-}> = ({ children, submit, close }) => {
+ centered?: boolean;
+}> = ({ children, submit, close, centered }) => {
return (
-
+
{submit ? (
{children ??
}
diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
index 0e18a67abee6..dab20de6645e 100644
--- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
@@ -1,5 +1,6 @@
import LoadingComponent from "@/components/loadingComponent";
import { useGetBuildsQuery } from "@/controllers/API/queries/_builds";
+import { track } from "@/customization/utils/analytics";
import useAutoSaveFlow from "@/hooks/flows/use-autosave-flow";
import useUploadFlow from "@/hooks/flows/use-upload-flow";
import _, { cloneDeep } from "lodash";
@@ -334,6 +335,8 @@ export default function Page({ view }: { view?: boolean }): JSX.Element {
event.dataTransfer.getData("nodedata"),
);
+ track(`Component Added: ${data.node?.display_name}`);
+
const newId = getNodeId(data.type);
const newNode: NodeType = {
diff --git a/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx b/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx
index a351fa171c10..e6b80704a594 100644
--- a/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx
+++ b/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx
@@ -1,6 +1,7 @@
import FolderSidebarNav from "@/components/folderSidebarComponent";
import { useDeleteFolders } from "@/controllers/API/queries/folders";
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
+import { track } from "@/customization/utils/analytics";
import useAlertStore from "@/stores/alertStore";
import { useState } from "react";
import { Outlet, useLocation } from "react-router-dom";
@@ -65,7 +66,10 @@ export default function HomePage(): JSX.Element {
setOpenModal(true)}
+ onFirstBtnClick={() => {
+ setOpenModal(true);
+ track("New Project Button Clicked");
+ }}
options={dropdownOptions}
plusButton={true}
dropdownOptions={false}
diff --git a/src/frontend/src/pages/Playground/index.tsx b/src/frontend/src/pages/Playground/index.tsx
index 7671e58c6f48..211a32f41391 100644
--- a/src/frontend/src/pages/Playground/index.tsx
+++ b/src/frontend/src/pages/Playground/index.tsx
@@ -1,6 +1,7 @@
import { useGetRefreshFlows } from "@/controllers/API/queries/flows/use-get-refresh-flows";
import { useGetGlobalVariables } from "@/controllers/API/queries/variables";
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
+import { track } from "@/customization/utils/analytics";
import { useStoreStore } from "@/stores/storeStore";
import { useTypesStore } from "@/stores/typesStore";
import { useEffect } from "react";
@@ -57,6 +58,10 @@ export default function PlaygroundPage() {
awaitgetTypes();
}, [id, flows, validApiKey]);
+ useEffect(() => {
+ if (id) track("Playground Page Loaded", { flowId: id });
+ }, []);
+
return (
{currentSavedFlow && (
diff --git a/src/frontend/src/pages/SignUpPage/index.tsx b/src/frontend/src/pages/SignUpPage/index.tsx
index f50e51fad04e..adef82adefb3 100644
--- a/src/frontend/src/pages/SignUpPage/index.tsx
+++ b/src/frontend/src/pages/SignUpPage/index.tsx
@@ -1,6 +1,7 @@
import { useAddUser } from "@/controllers/API/queries/auth";
import { CustomLink } from "@/customization/components/custom-link";
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
+import { track } from "@/customization/utils/analytics";
import * as Form from "@radix-ui/react-form";
import { FormEvent, useEffect, useState } from "react";
import InputComponent from "../../components/inputComponent";
@@ -52,7 +53,8 @@ export default function SignUp(): JSX.Element {
};
mutateAddUser(newUser, {
- onSuccess: () => {
+ onSuccess: (user) => {
+ track("User Signed Up", user);
setSuccessData({
title: SIGN_UP_SUCCESS,
});