[WEB-4423] refactor: event trackers (#7289)

* feat: event tracker helper

* feat: track click events for `data-ph-element`

* fix: handled click events

* fix: handled name

* chore: tracker element updates

* chore: remove export

* chore: tracker element type

* chore: track element and event helper.

* chore: minor improvements

* chore: minor refactors

* fix: workspace events

* fix: added slug

* fix: changes nomenclature

* fix: nomenclature

* chore: update event tracker helper types

* fix: data id

* refactor: cycle events (#7290)

* chore: update event tracker helper types

* refactor: cycle events

* refactor: cycle events

* refactor: cycle event tracker

* chore: update tracker elements

* chore: check for closest element with data-ph-element attribute

---------

Co-authored-by: Prateek Shourya <prateekshourya@Prateeks-MacBook-Pro.local>

* Refactor module events (#7291)

* chore: update event tracker helper types

* refactor: cycle events

* refactor: cycle events

* refactor: cycle event tracker

* refactor: module tracker event and element

* chore: update tracker element

* chore: revert unnecessary changes

---------

Co-authored-by: Prateek Shourya <prateekshourya@Prateeks-MacBook-Pro.local>

* refactor: global views, product tour, notifications, onboarding, users and sidebar related events

* chore: member tracker events (#7302)

* chore: member-tracker-events

* fix: constants

* refactor: update event tracker constants

* refactor: auth related event trackers (#7306)

* Chore: state events (#7307)

* chore: state events

* fix: refactor

* chore: project events (#7305)

* chore: project-events

* fix: refactor

* fix: removed hardcoded values

* fix: github redirection event

* chore: project page tracker events (#7304)

* added events for most page events

* refactor: simplify lock button event handling in PageLockControl

---------

Co-authored-by: Palanikannan M <akashmalinimurugu@gmail.com>
Co-authored-by: M. Palanikannan <73993394+Palanikannan1437@users.noreply.github.com>

* chore: minor cleanup and import fixes

* refactor: added tracker elements for buttons (#7308)

Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>

* fix: event type

* refactor: posthog group event

* chore: removed instances of event tracker (#7309)

* refactor: remove event tracker stores and hooks

* refactor: remove event tracker store

* fix: build errors

* clean up event tracker payloads

* fix: coderabbit suggestions

---------

Co-authored-by: Prateek Shourya <prateekshourya@Prateeks-MacBook-Pro.local>
Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: Palanikannan M <akashmalinimurugu@gmail.com>
Co-authored-by: M. Palanikannan <73993394+Palanikannan1437@users.noreply.github.com>
Co-authored-by: Vamsi Krishna <46787868+vamsikrishnamathala@users.noreply.github.com>
This commit is contained in:
Akshita Goyal 2025-07-02 15:23:18 +05:30 committed by GitHub
parent fa9c63716c
commit cfe169c6d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
139 changed files with 2095 additions and 1888 deletions

View file

@ -4,7 +4,7 @@ import { useMemo } from "react";
import { observer } from "mobx-react";
import { useRouter } from "next/navigation";
// plane package imports
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { type TabItem, Tabs } from "@plane/ui";
// components
@ -12,7 +12,8 @@ import AnalyticsFilterActions from "@/components/analytics/analytics-filter-acti
import { PageHead } from "@/components/core";
import { ComicBoxButton, DetailedEmptyState } from "@/components/empty-state";
// hooks
import { useCommandPalette, useEventTracker, useProject, useUserPermissions, useWorkspace } from "@/hooks/store";
import { captureClick } from "@/helpers/event-tracker.helper";
import { useCommandPalette, useProject, useUserPermissions, useWorkspace } from "@/hooks/store";
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
import { getAnalyticsTabs } from "@/plane-web/components/analytics/tabs";
@ -36,7 +37,6 @@ const AnalyticsPage = observer((props: Props) => {
// store hooks
const { toggleCreateProjectModal } = useCommandPalette();
const { setTrackElement } = useEventTracker();
const { workspaceProjectIds, loader } = useProject();
const { currentWorkspace } = useWorkspace();
const { allowPermissions } = useUserPermissions();
@ -101,8 +101,8 @@ const AnalyticsPage = observer((props: Props) => {
title={t("workspace_analytics.empty_state.general.primary_button.comic.title")}
description={t("workspace_analytics.empty_state.general.primary_button.comic.description")}
onClick={() => {
setTrackElement("Analytics empty state");
toggleCreateProjectModal(true);
captureClick({ elementName: PROJECT_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_PROJECT_BUTTON });
}}
disabled={!canPerformEmptyStateActions}
/>

View file

@ -5,7 +5,7 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { Plus, Search } from "lucide-react";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { setToast, TOAST_TYPE, Tooltip } from "@plane/ui";
import { cn, copyUrlToClipboard, orderJoinedProjects } from "@plane/utils";
@ -122,6 +122,7 @@ export const ExtendedProjectSidebar = observer(() => {
<Tooltip tooltipHeading={t("create_project")} tooltipContent="">
<button
type="button"
data-ph-element={PROJECT_TRACKER_ELEMENTS.EXTENDED_SIDEBAR_ADD_BUTTON}
className="p-0.5 rounded hover:bg-custom-sidebar-background-80 flex-shrink-0"
onClick={() => {
setIsProjectModalOpen(true);

View file

@ -7,18 +7,17 @@ import { Home } from "lucide-react";
import githubBlackImage from "/public/logos/github-black.png";
import githubWhiteImage from "/public/logos/github-white.png";
// ui
import { GITHUB_REDIRECTED_TRACKER_EVENT } from "@plane/constants";
import { GITHUB_REDIRECTED_TRACKER_EVENT, HEADER_GITHUB_ICON } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Breadcrumbs, Header } from "@plane/ui";
// components
import { BreadcrumbLink } from "@/components/common";
// constants
// hooks
import { useEventTracker } from "@/hooks/store";
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
export const WorkspaceDashboardHeader = () => {
// hooks
const { captureEvent } = useEventTracker();
const { resolvedTheme } = useTheme();
const { t } = useTranslation();
@ -39,8 +38,14 @@ export const WorkspaceDashboardHeader = () => {
<Header.RightItem>
<a
onClick={() =>
captureEvent(GITHUB_REDIRECTED_TRACKER_EVENT, {
element: "navbar",
captureElementAndEvent({
element: {
elementName: HEADER_GITHUB_ICON,
},
event: {
eventName: GITHUB_REDIRECTED_TRACKER_EVENT,
state: "SUCCESS",
},
})
}
className="flex flex-shrink-0 items-center gap-1.5 rounded bg-custom-background-80 px-3 py-1.5"

View file

@ -13,6 +13,7 @@ import {
EUserPermissionsLevel,
EProjectFeatureKey,
ISSUE_DISPLAY_FILTERS_BY_PAGE,
WORK_ITEM_TRACKER_ELEMENTS,
} from "@plane/constants";
import { usePlatformOS } from "@plane/hooks";
import { useTranslation } from "@plane/i18n";
@ -34,7 +35,6 @@ import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelect
import {
useCommandPalette,
useCycle,
useEventTracker,
useIssues,
useLabel,
useMember,
@ -68,7 +68,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
} = useIssues(EIssuesStoreType.CYCLE);
const { currentProjectCycleIds, getCycleById } = useCycle();
const { toggleCreateIssueModal } = useCommandPalette();
const { setTrackElement } = useEventTracker();
const { currentProjectDetails, loader } = useProject();
const { projectStates } = useProjectState();
const { projectLabels } = useLabel();
@ -263,9 +262,9 @@ export const CycleIssuesHeader: React.FC = observer(() => {
<Button
className="h-full self-start"
onClick={() => {
setTrackElement("Cycle work items page");
toggleCreateIssueModal(true, EIssuesStoreType.CYCLE);
}}
data-ph-element={WORK_ITEM_TRACKER_ELEMENTS.HEADER_ADD_BUTTON.CYCLE}
size="sm"
>
{t("issue.add.label")}

View file

@ -4,13 +4,13 @@ import { FC } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// ui
import { EProjectFeatureKey, EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { EProjectFeatureKey, EUserPermissions, EUserPermissionsLevel, CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Breadcrumbs, Button, Header } from "@plane/ui";
// components
import { CyclesViewHeader } from "@/components/cycles";
// hooks
import { useCommandPalette, useEventTracker, useProject, useUserPermissions } from "@/hooks/store";
import { useCommandPalette, useProject, useUserPermissions } from "@/hooks/store";
import { useAppRouter } from "@/hooks/use-app-router";
// plane web
import { CommonProjectBreadcrumbs } from "@/plane-web/components/breadcrumbs/common";
@ -23,7 +23,6 @@ export const CyclesListHeader: FC = observer(() => {
// store hooks
const { toggleCreateCycleModal } = useCommandPalette();
const { setTrackElement } = useEventTracker();
const { allowPermissions } = useUserPermissions();
const { currentProjectDetails, loader } = useProject();
const { t } = useTranslation();
@ -51,8 +50,8 @@ export const CyclesListHeader: FC = observer(() => {
<Button
variant="primary"
size="sm"
data-ph-element={CYCLE_TRACKER_ELEMENTS.RIGHT_HEADER_ADD_BUTTON}
onClick={() => {
setTrackElement("Cycles page");
toggleCreateCycleModal(true);
}}
>

View file

@ -4,7 +4,7 @@ import { useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { EUserPermissionsLevel } from "@plane/constants";
import { EUserPermissionsLevel, CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EUserProjectRoles, TCycleFilters } from "@plane/types";
// components
@ -16,7 +16,7 @@ import { ComicBoxButton, DetailedEmptyState } from "@/components/empty-state";
import { CycleModuleListLayout } from "@/components/ui";
// helpers
// hooks
import { useEventTracker, useCycle, useProject, useCycleFilter, useUserPermissions } from "@/hooks/store";
import { useCycle, useProject, useCycleFilter, useUserPermissions } from "@/hooks/store";
import { useAppRouter } from "@/hooks/use-app-router";
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
@ -24,7 +24,6 @@ const ProjectCyclesPage = observer(() => {
// states
const [createModal, setCreateModal] = useState(false);
// store hooks
const { setTrackElement } = useEventTracker();
const { currentProjectCycleIds, loader } = useCycle();
const { getProjectById, currentProjectDetails } = useProject();
// router
@ -100,8 +99,8 @@ const ProjectCyclesPage = observer(() => {
label={t("project_cycles.empty_state.general.primary_button.text")}
title={t("project_cycles.empty_state.general.primary_button.comic.title")}
description={t("project_cycles.empty_state.general.primary_button.comic.description")}
data-ph-element={CYCLE_TRACKER_ELEMENTS.EMPTY_STATE_ADD_BUTTON}
onClick={() => {
setTrackElement("Cycle empty state");
setCreateModal(true);
}}
disabled={!hasMemberLevelPermission}

View file

@ -13,6 +13,7 @@ import {
EUserPermissions,
EUserPermissionsLevel,
EProjectFeatureKey,
WORK_ITEM_TRACKER_ELEMENTS,
} from "@plane/constants";
import {
EIssuesStoreType,
@ -31,7 +32,6 @@ import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelect
import { ModuleQuickActions } from "@/components/modules";
// hooks
import {
useEventTracker,
useLabel,
useMember,
useModule,
@ -66,7 +66,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
const { updateFilters } = useIssuesActions(EIssuesStoreType.MODULE);
const { projectModuleIds, getModuleById } = useModule();
const { toggleCreateIssueModal } = useCommandPalette();
const { setTrackElement } = useEventTracker();
const { allowPermissions } = useUserPermissions();
const { currentProjectDetails, loader } = useProject();
const { projectLabels } = useLabel();
@ -259,9 +258,9 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
<Button
className="hidden sm:flex"
onClick={() => {
setTrackElement("Module work items page");
toggleCreateIssueModal(true, EIssuesStoreType.MODULE);
}}
data-ph-element={WORK_ITEM_TRACKER_ELEMENTS.HEADER_ADD_BUTTON.MODULE}
size="sm"
>
Add work item

View file

@ -3,14 +3,14 @@
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { EProjectFeatureKey, EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { EProjectFeatureKey, EUserPermissions, EUserPermissionsLevel, MODULE_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// ui
import { Breadcrumbs, Button, Header } from "@plane/ui";
// components
import { ModuleViewHeader } from "@/components/modules";
// hooks
import { useCommandPalette, useEventTracker, useProject, useUserPermissions } from "@/hooks/store";
import { useCommandPalette, useProject, useUserPermissions } from "@/hooks/store";
import { useAppRouter } from "@/hooks/use-app-router";
// plane web
import { CommonProjectBreadcrumbs } from "@/plane-web/components/breadcrumbs";
@ -22,7 +22,6 @@ export const ModulesListHeader: React.FC = observer(() => {
const { workspaceSlug, projectId } = useParams() as { workspaceSlug: string; projectId: string };
// store hooks
const { toggleCreateModuleModal } = useCommandPalette();
const { setTrackElement } = useEventTracker();
const { allowPermissions } = useUserPermissions();
const { loader } = useProject();
@ -55,8 +54,8 @@ export const ModulesListHeader: React.FC = observer(() => {
<Button
variant="primary"
size="sm"
data-ph-element={MODULE_TRACKER_ELEMENTS.RIGHT_HEADER_ADD_BUTTON}
onClick={() => {
setTrackElement("Modules page");
toggleCreateModuleModal(true);
}}
>

View file

@ -4,13 +4,13 @@ import { useState } from "react";
import { observer } from "mobx-react";
import { useParams, useRouter, useSearchParams } from "next/navigation";
// constants
import { EPageAccess, EProjectFeatureKey } from "@plane/constants";
import { EPageAccess, EProjectFeatureKey, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
// plane types
import { TPage } from "@plane/types";
// plane ui
import { Breadcrumbs, Button, Header, setToast, TOAST_TYPE } from "@plane/ui";
// hooks
import { useEventTracker, useProject } from "@/hooks/store";
import { useProject } from "@/hooks/store";
// plane web
import { CommonProjectBreadcrumbs } from "@/plane-web/components/breadcrumbs";
// plane web hooks
@ -27,11 +27,9 @@ export const PagesListHeader = observer(() => {
// store hooks
const { currentProjectDetails, loader } = useProject();
const { canCurrentUserCreatePage, createPage } = usePageStore(EPageStoreType.PROJECT);
const { setTrackElement } = useEventTracker();
// handle page create
const handleCreatePage = async () => {
setIsCreatingPage(true);
setTrackElement("Project pages page");
const payload: Partial<TPage> = {
access: pageType === "private" ? EPageAccess.PRIVATE : EPageAccess.PUBLIC,
@ -66,7 +64,13 @@ export const PagesListHeader = observer(() => {
</Header.LeftItem>
{canCurrentUserCreatePage ? (
<Header.RightItem>
<Button variant="primary" size="sm" onClick={handleCreatePage} loading={isCreatingPage}>
<Button
variant="primary"
size="sm"
onClick={handleCreatePage}
loading={isCreatingPage}
data-ph-element={PROJECT_TRACKER_ELEMENTS.CREATE_HEADER_BUTTON}
>
{isCreatingPage ? "Adding" : "Add page"}
</Button>
</Header.RightItem>

View file

@ -12,6 +12,7 @@ import {
EUserPermissions,
EUserPermissionsLevel,
EProjectFeatureKey,
WORK_ITEM_TRACKER_ELEMENTS,
} from "@plane/constants";
// types
import {
@ -30,11 +31,9 @@ import { SwitcherIcon, SwitcherLabel } from "@/components/common";
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues";
// constants
import { ViewQuickActions } from "@/components/views";
// helpers
// hooks
import {
useCommandPalette,
useEventTracker,
useIssues,
useLabel,
useMember,
@ -57,7 +56,6 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
const {
issuesFilter: { issueFilters, updateFilters },
} = useIssues(EIssuesStoreType.PROJECT_VIEW);
const { setTrackElement } = useEventTracker();
const { toggleCreateIssueModal } = useCommandPalette();
const { allowPermissions } = useUserPermissions();
@ -258,9 +256,9 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
{canUserCreateIssue ? (
<Button
onClick={() => {
setTrackElement("PROJECT_VIEW_PAGE_HEADER");
toggleCreateIssueModal(true, EIssuesStoreType.PROJECT_VIEW);
}}
data-ph-element={WORK_ITEM_TRACKER_ELEMENTS.HEADER_ADD_BUTTON.PROJECT_VIEW}
size="sm"
>
Add work item

View file

@ -8,8 +8,9 @@ import { Layers } from "lucide-react";
import {
EIssueFilterType,
ISSUE_DISPLAY_FILTERS_BY_PAGE,
DEFAULT_GLOBAL_VIEWS_LIST,
EIssueLayoutTypes,
GLOBAL_VIEW_TRACKER_ELEMENTS,
DEFAULT_GLOBAL_VIEWS_LIST,
} from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import {
@ -225,7 +226,12 @@ export const GlobalIssuesHeader = observer(() => {
<></>
)}
<Button variant="primary" size="sm" onClick={() => setCreateViewModal(true)}>
<Button
variant="primary"
size="sm"
data-ph-element={GLOBAL_VIEW_TRACKER_ELEMENTS.RIGHT_HEADER_ADD_BUTTON}
onClick={() => setCreateViewModal(true)}
>
{t("workspace_views.add_view")}
</Button>
<div className="hidden md:block">