diff --git a/frontend/src/pages/modelServing/screens/global/InferenceServiceTable.tsx b/frontend/src/pages/modelServing/screens/global/InferenceServiceTable.tsx index b4d9c4e3b7..3a55974ee4 100644 --- a/frontend/src/pages/modelServing/screens/global/InferenceServiceTable.tsx +++ b/frontend/src/pages/modelServing/screens/global/InferenceServiceTable.tsx @@ -7,6 +7,8 @@ import DashboardEmptyTableView from '~/concepts/dashboard/DashboardEmptyTableVie import { isModelMesh } from '~/pages/modelServing/utils'; import ManageKServeModal from '~/pages/modelServing/screens/projects/kServeModal/ManageKServeModal'; import ResourceTr from '~/components/ResourceTr'; +import { fireFormTrackingEvent } from '~/concepts/analyticsTracking/segmentIOUtils'; +import { TrackingOutcome } from '~/concepts/analyticsTracking/trackingProperties'; import InferenceServiceTableRow from './InferenceServiceTableRow'; import { getGlobalInferenceServiceColumns, getProjectInferenceServiceColumns } from './data'; import DeleteInferenceServiceModal from './DeleteInferenceServiceModal'; @@ -91,6 +93,10 @@ const InferenceServiceTable: React.FC = ({ : undefined } onClose={(deleted) => { + fireFormTrackingEvent('Model Deleted', { + outcome: deleted ? TrackingOutcome.submit : TrackingOutcome.cancel, + type: 'multi', + }); if (deleted) { refresh?.(); } @@ -101,6 +107,10 @@ const InferenceServiceTable: React.FC = ({ isOpen={!!editInferenceService && isModelMesh(editInferenceService)} editInfo={editInferenceService} onClose={(edited) => { + fireFormTrackingEvent('Model Updated', { + outcome: edited ? TrackingOutcome.submit : TrackingOutcome.cancel, + type: 'multi', + }); if (edited) { refresh?.(); } diff --git a/frontend/src/pages/modelServing/screens/projects/KServeSection/KServeInferenceServiceTable.tsx b/frontend/src/pages/modelServing/screens/projects/KServeSection/KServeInferenceServiceTable.tsx index 3d8d50c4f0..d5ea868d91 100644 --- a/frontend/src/pages/modelServing/screens/projects/KServeSection/KServeInferenceServiceTable.tsx +++ b/frontend/src/pages/modelServing/screens/projects/KServeSection/KServeInferenceServiceTable.tsx @@ -6,6 +6,8 @@ import KServeInferenceServiceTableRow from '~/pages/modelServing/screens/project import { ProjectDetailsContext } from '~/pages/projects/ProjectDetailsContext'; import ManageKServeModal from '~/pages/modelServing/screens/projects/kServeModal/ManageKServeModal'; import DeleteInferenceServiceModal from '~/pages/modelServing/screens/global/DeleteInferenceServiceModal'; +import { fireFormTrackingEvent } from '~/concepts/analyticsTracking/segmentIOUtils'; +import { TrackingOutcome } from '~/concepts/analyticsTracking/trackingProperties'; const KServeInferenceServiceTable: React.FC = () => { const [editKserveResources, setEditKServeResources] = React.useState< @@ -56,6 +58,10 @@ const KServeInferenceServiceTable: React.FC = () => { inferenceService={deleteKserveResources?.inferenceService} servingRuntime={deleteKserveResources?.servingRuntime} onClose={(deleted) => { + fireFormTrackingEvent('Model Deleted', { + outcome: deleted ? TrackingOutcome.submit : TrackingOutcome.cancel, + type: 'single', + }); if (deleted) { refreshServingRuntime(); refreshInferenceServices(); diff --git a/frontend/src/pages/modelServing/screens/projects/ModelMeshSection/ServingRuntimeTable.tsx b/frontend/src/pages/modelServing/screens/projects/ModelMeshSection/ServingRuntimeTable.tsx index 6d399bf66c..3a14873e9d 100644 --- a/frontend/src/pages/modelServing/screens/projects/ModelMeshSection/ServingRuntimeTable.tsx +++ b/frontend/src/pages/modelServing/screens/projects/ModelMeshSection/ServingRuntimeTable.tsx @@ -8,6 +8,8 @@ import ServingRuntimeTableRow from '~/pages/modelServing/screens/projects/ModelM import DeleteServingRuntimeModal from '~/pages/modelServing/screens/projects/ServingRuntimeModal/DeleteServingRuntimeModal'; import ManageServingRuntimeModal from '~/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal'; import ManageInferenceServiceModal from '~/pages/modelServing/screens/projects/InferenceServiceModal/ManageInferenceServiceModal'; +import { fireFormTrackingEvent } from '~/concepts/analyticsTracking/segmentIOUtils'; +import { TrackingOutcome } from '~/concepts/analyticsTracking/trackingProperties'; const accessReviewResource: AccessReviewResourceAttributes = { group: 'rbac.authorization.k8s.io', @@ -62,6 +64,9 @@ const ServingRuntimeTable: React.FC = () => { servingRuntime={deleteServingRuntime} inferenceServices={inferenceServices} onClose={(deleted) => { + fireFormTrackingEvent('Model Server Deleted', { + outcome: deleted ? TrackingOutcome.submit : TrackingOutcome.cancel, + }); if (deleted) { refreshServingRuntime(); } @@ -95,6 +100,10 @@ const ServingRuntimeTable: React.FC = () => { refreshDataConnections(); setExpandedServingRuntimeName(deployServingRuntime.metadata.name); } + fireFormTrackingEvent('Model Deployed', { + outcome: submit ? TrackingOutcome.submit : TrackingOutcome.cancel, + type: 'multi', + }); }} projectContext={{ currentProject, diff --git a/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal.tsx b/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal.tsx index b031249ef0..89576adf8c 100644 --- a/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal.tsx +++ b/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal.tsx @@ -20,6 +20,11 @@ import { ServingRuntimeEditInfo } from '~/pages/modelServing/screens/types'; import { useAccessReview } from '~/api'; import { AcceleratorProfileSelectFieldState } from '~/pages/notebookController/screens/server/AcceleratorProfileSelectField'; import useGenericObjectState from '~/utilities/useGenericObjectState'; +import { fireFormTrackingEvent } from '~/concepts/analyticsTracking/segmentIOUtils'; +import { + FormTrackingEventProperties, + TrackingOutcome, +} from '~/concepts/analyticsTracking/trackingProperties'; import ServingRuntimeReplicaSection from './ServingRuntimeReplicaSection'; import ServingRuntimeSizeSection from './ServingRuntimeSizeSection'; import ServingRuntimeTemplateSection from './ServingRuntimeTemplateSection'; @@ -43,6 +48,8 @@ const accessReviewResource: AccessReviewResourceAttributes = { verb: 'create', }; +const modelServerAddedName = 'Model Server Added'; +const modelServerEditName = 'Model Server Modified'; const ManageServingRuntimeModal: React.FC = ({ isOpen, onClose, @@ -101,6 +108,12 @@ const ManageServingRuntimeModal: React.FC = ({ ); const onBeforeClose = (submitted: boolean) => { + if (!submitted) { + fireFormTrackingEvent(editInfo ? modelServerEditName : modelServerAddedName, { + outcome: TrackingOutcome.cancel, + }); + } + onClose(submitted); setError(undefined); setActionInProgress(false); @@ -120,6 +133,12 @@ const ManageServingRuntimeModal: React.FC = ({ setError(undefined); setActionInProgress(true); + const props: FormTrackingEventProperties = { + outcome: TrackingOutcome.submit, + type: createData.servingRuntimeTemplateName, + size: createData.modelSize.name, + }; + submitServingRuntimeResourcesWithDryRun( servingRuntimeSelected, createData, @@ -134,8 +153,15 @@ const ManageServingRuntimeModal: React.FC = ({ undefined, true, ) - .then(() => onSuccess()) + .then(() => { + props.success = true; + fireFormTrackingEvent(editInfo ? modelServerEditName : modelServerAddedName, props); + onSuccess(); + }) .catch((e) => { + props.success = false; + props.errorMessage = e; + fireFormTrackingEvent(editInfo ? modelServerEditName : modelServerAddedName, props); setErrorModal(e); }); }; diff --git a/frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx b/frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx index f1799cf66a..0993ff250a 100644 --- a/frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx +++ b/frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx @@ -50,6 +50,11 @@ import { RegisteredModelDeployInfo } from '~/pages/modelRegistry/screens/Registe import usePrefillDeployModalFromModelRegistry from '~/pages/modelRegistry/screens/RegisteredModels/usePrefillDeployModalFromModelRegistry'; import { AcceleratorProfileSelectFieldState } from '~/pages/notebookController/screens/server/AcceleratorProfileSelectField'; import useGenericObjectState from '~/utilities/useGenericObjectState'; +import { fireFormTrackingEvent } from '~/concepts/analyticsTracking/segmentIOUtils'; +import { + FormTrackingEventProperties, + TrackingOutcome, +} from '~/concepts/analyticsTracking/trackingProperties'; import KServeAutoscalerReplicaSection from './KServeAutoscalerReplicaSection'; const accessReviewResource: AccessReviewResourceAttributes = { @@ -193,6 +198,9 @@ const ManageKServeModal: React.FC = ({ ); const onBeforeClose = (submitted: boolean) => { + fireFormTrackingEvent(editInfo ? 'Model Updated' : 'Model Deployed', { + outcome: TrackingOutcome.cancel, + }); onClose(submitted); setError(undefined); setActionInProgress(false); @@ -207,9 +215,10 @@ const ManageKServeModal: React.FC = ({ setActionInProgress(false); }; - const onSuccess = () => { + const onSuccess = (tProps: FormTrackingEventProperties) => { setActionInProgress(false); onBeforeClose(true); + fireFormTrackingEvent(editInfo ? 'Model Updated' : 'Model Deployed', tProps); }; const submit = () => { @@ -249,6 +258,15 @@ const ManageKServeModal: React.FC = ({ editInfo?.secrets, ); + const props: FormTrackingEventProperties = { + outcome: TrackingOutcome.submit, + type: 'single', + runtime: servingRuntimeName, + isCustomRuntime: customServingRuntimesEnabled, + servingRuntimeName: createDataServingRuntime.servingRuntimeTemplateName, + servingRuntimeFormat: createDataInferenceService.format.name, + numReplicas: createDataServingRuntime.servingRuntimeTemplateName, + }; Promise.all([ submitServingRuntimeResources({ dryRun: true }), submitInferenceServiceResource({ dryRun: true }), @@ -259,9 +277,16 @@ const ManageKServeModal: React.FC = ({ submitInferenceServiceResource({ dryRun: false }), ]), ) - .then(onSuccess) + .then(() => { + props.success = true; + fireFormTrackingEvent(editInfo ? 'Model Updated' : 'Model Deployed', props); + onSuccess(props); + }) .catch((e) => { + props.success = false; + props.errorMessage = e; setErrorModal(e); + fireFormTrackingEvent(editInfo ? 'Model Updated' : 'Model Deployed', props); }); };