Skip to content

feat(tracking): add vendor-neutral userInteraction tracking abstraction#2937

Open
manaswinidas wants to merge 1 commit into
kubeflow:mainfrom
manaswinidas:feat/user-interaction-tracking
Open

feat(tracking): add vendor-neutral userInteraction tracking abstraction#2937
manaswinidas wants to merge 1 commit into
kubeflow:mainfrom
manaswinidas:feat/user-interaction-tracking

Conversation

@manaswinidas

@manaswinidas manaswinidas commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Description

Add a concepts/userInteraction module that provides a non-opinionated tracking API via React context. This enables downstream integrations (e.g., ODH with Segment) to inject their own analytics implementation without introducing vendor-specific dependencies upstream.

What's included

File Purpose
trackingTypes.ts Event property types + TrackingOutcome enum
UserInteractionContext.ts React context with dev-mode console logger default
useUserInteraction.ts Consumer hook
UserInteractionProvider.tsx Provider for downstream to inject custom api
index.ts Barrel export

API

Method Purpose
trackFormEvent(name, props) Form submit/cancel (outcome, success, error)
trackLinkEvent(name, props) Navigation/link clicks (from, href, to, section)
trackSimpleEvent(name, props?) Simple named events
trackPageEvent() Page view tracking

How downstream uses it

import { useUserInteraction, TrackingOutcome } from '~/concepts/userInteraction';

const { trackFormEvent } = useUserInteraction();

// In a handler:
trackFormEvent('Model Registered', {
  outcome: TrackingOutcome.submit,
  success: true,
});

Downstream (e.g., ODH) injects a Segment-backed implementation via UserInteractionProvider:

<UserInteractionProvider api={segmentImpl}>
  <App />
</UserInteractionProvider>

Design decisions

  • No App.tsx change: The context default (dev-mode logger) works without a provider mounted. No dead wrapper needed.
  • Reuses existing DEV_MODE: Imports from ~/app/utilities/const rather than redefining.
  • Purely additive: 6 new files, zero modifications to existing code. No breaking changes.

Testing

  • Unit tests verify provider injection, event routing, and hot-swap behavior
  • Type check passes (npx tsc --noEmit)
  • Lint passes (npx eslint)
PASS src/concepts/userInteraction/__tests__/useUserInteraction.spec.tsx
  useUserInteraction
    ✓ calls the injected provider implementation instead of the default
    ✓ routes different event types to their respective handlers
    ✓ swaps implementation when provider is re-mounted with a different api

@google-oss-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from manaswinidas. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Add a concepts/userInteraction module that provides a non-opinionated
tracking API (trackFormEvent, trackLinkEvent, trackSimpleEvent,
trackPageEvent) via React context. The default implementation logs to
console in development and is a no-op in production.

Downstream integrations (e.g., ODH with Segment) can inject their own
implementation via the exported UserInteractionProvider component,
enabling analytics without introducing vendor-specific dependencies
upstream.

Signed-off-by: manaswinidas <dasmanaswini10@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@manaswinidas manaswinidas force-pushed the feat/user-interaction-tracking branch from ab900ed to 3ad4221 Compare July 10, 2026 11:13
};

export type LinkTrackingEventProperties = {
from?: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracking tools should already capture the current URL for all events. It seems redundant to have the caller supply this.

Comment on lines +25 to +26
href?: string;
to?: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the different between href and to?

Comment on lines +27 to +29
type?: string;
section?: string;
name?: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These need documentation. It's not clear to me how these should differ from the event name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants