From ef16c0ae69027880e2d42bacaf2fd8ec393365d4 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna <46787868+vamsikrishnamathala@users.noreply.github.com> Date: Mon, 11 Aug 2025 19:18:02 +0530 Subject: [PATCH] [WEB-4405]chore: added event tracker for work item types (#3623) * chore: added event tracker for custom properties * chore: added event trackers for custom properties * chore: handled conditional event names * chore: revert search item changes --------- Co-authored-by: Prateek Shourya --- .../settings/properties/custom-properties.tsx | 14 ++++ .../epics/settings/epics-properties.tsx | 13 ++++ .../issue-types/create-update/modal.tsx | 25 ++++++- .../ee/components/issue-types/empty-state.tsx | 24 ++++++- .../issue-types/issue-type-list-item.tsx | 17 ++++- .../properties/property-create-list-item.tsx | 9 ++- .../properties/property-list-item.tsx | 68 ++++++++++++++++++- .../issue-types/properties/property-list.tsx | 9 +++ .../issue-types/properties/quick-actions.tsx | 23 ++++++- .../components/issue-types/quick-actions.tsx | 16 ++++- apps/web/ee/components/issue-types/root.tsx | 9 ++- .../constants/src/event-tracker/extended.ts | 38 +++++++++++ 12 files changed, 250 insertions(+), 15 deletions(-) diff --git a/apps/web/ee/components/customers/settings/properties/custom-properties.tsx b/apps/web/ee/components/customers/settings/properties/custom-properties.tsx index e7fc8b553a..74c16e3540 100644 --- a/apps/web/ee/components/customers/settings/properties/custom-properties.tsx +++ b/apps/web/ee/components/customers/settings/properties/custom-properties.tsx @@ -4,6 +4,7 @@ import { v4 } from "uuid"; import { ChevronRight, Plus } from "lucide-react"; // plane constants // plane i18n +import { CUSTOMER_PROPERTY_TRACKER_ELEMENTS, CUSTOMER_PROPERTY_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // plane types import { EIssuePropertyType, TCreationListModes, TIssueProperty, TIssuePropertyPayload } from "@plane/types"; @@ -121,6 +122,18 @@ export const CustomerCustomPropertiesRoot: FC = observer(() => { lastElementRef={lastElementRef} properties={properties} isUpdateAllowed={false} + trackers={{ + create: { + button: CUSTOMER_PROPERTY_TRACKER_ELEMENTS.CREATE_PROPERTY_BUTTON, + eventName: CUSTOMER_PROPERTY_TRACKER_EVENTS.CREATE, + }, + update: { + eventName: CUSTOMER_PROPERTY_TRACKER_EVENTS.UPDATE, + }, + delete: { + eventName: CUSTOMER_PROPERTY_TRACKER_EVENTS.DELETE, + }, + }} />
diff --git a/apps/web/ee/components/issue-types/create-update/modal.tsx b/apps/web/ee/components/issue-types/create-update/modal.tsx index 3ff8b75c4d..7e3ef73a0d 100644 --- a/apps/web/ee/components/issue-types/create-update/modal.tsx +++ b/apps/web/ee/components/issue-types/create-update/modal.tsx @@ -1,16 +1,17 @@ import { FC, useEffect, useState } from "react"; import { observer } from "mobx-react"; // ui +import { WORK_ITEM_TYPE_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { TIssueType } from "@plane/types"; import { EModalPosition, EModalWidth, getRandomIconName, ModalCore, setToast, TOAST_TYPE } from "@plane/ui"; // helpers import { getRandomBackgroundColor } from "@plane/utils"; // plane web components +import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { CreateOrUpdateIssueTypeForm } from "@/plane-web/components/issue-types/"; // plane web import { useIssueType, useIssueTypes } from "@/plane-web/hooks/store"; -// plane imports type Props = { issueTypeId: string | null; @@ -69,13 +70,19 @@ export const CreateOrUpdateIssueTypeModal: FC = observer((props) => { if (!issueTypeFormData) return; setIsSubmitting(true); await createType(issueTypeFormData) - .then(() => { + .then((res) => { handleModalClearAndClose(); setToast({ type: TOAST_TYPE.SUCCESS, title: t("work_item_types.create.toast.success.title"), message: t("work_item_types.create.toast.success.message"), }); + captureSuccess({ + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.CREATE, + payload: { + work_item_type_id: res?.id, + }, + }); }) .catch((error) => { if (error.code === "ISSUE_TYPE_ALREADY_EXIST") { @@ -91,6 +98,10 @@ export const CreateOrUpdateIssueTypeModal: FC = observer((props) => { message: t("work_item_types.create.toast.error.message.default"), }); } + captureError({ + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.CREATE, + error: error as Error, + }); }) .finally(() => { setIsSubmitting(false); @@ -110,6 +121,12 @@ export const CreateOrUpdateIssueTypeModal: FC = observer((props) => { title: t("work_item_types.update.toast.success.title"), message: t("work_item_types.update.toast.success.message", { name: issueTypeFormData?.name }), }); + captureSuccess({ + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.UPDATE, + payload: { + work_item_type_id: issueTypeFormData?.id, + }, + }); }) .catch((error) => { if (error.code === "ISSUE_TYPE_ALREADY_EXIST") { @@ -125,6 +142,10 @@ export const CreateOrUpdateIssueTypeModal: FC = observer((props) => { message: t("work_item_types.update.toast.error.message.default"), }); } + captureError({ + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.UPDATE, + error: error as Error, + }); }) .finally(() => { setIsSubmitting(false); diff --git a/apps/web/ee/components/issue-types/empty-state.tsx b/apps/web/ee/components/issue-types/empty-state.tsx index 6b9a389361..a33c5c24e2 100644 --- a/apps/web/ee/components/issue-types/empty-state.tsx +++ b/apps/web/ee/components/issue-types/empty-state.tsx @@ -1,12 +1,14 @@ import { FC, useState } from "react"; import { observer } from "mobx-react"; // plane imports +import { WORK_ITEM_TYPE_TRACKER_ELEMENTS, WORK_ITEM_TYPE_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { EProductSubscriptionEnum } from "@plane/types"; import { AlertModalCore, setToast, TOAST_TYPE } from "@plane/ui"; // helpers import { DetailedEmptyState } from "@/components/empty-state"; // hooks +import { captureClick, captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path"; // plane web imports import { useFlag, useIssueTypes, useWorkspaceSubscription } from "@/plane-web/hooks/store"; @@ -43,13 +45,26 @@ export const IssueTypeEmptyState: FC = observer((props) => title: "Success!", message: "Work item types and custom properties are now enabled for this project", }); + captureSuccess({ + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.TYPES_ENABLED, + payload: { + project_id: projectId, + }, + }); }) - .catch(() => { + .catch((error) => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "Failed to enable work item types", }); + captureError({ + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.TYPES_ENABLED, + payload: { + project_id: projectId, + }, + error: error as Error, + }); }) .finally(() => { setIsLoading(false); @@ -66,7 +81,12 @@ export const IssueTypeEmptyState: FC = observer((props) => assetPath={resolvedPath} primaryButton={{ text: t("work_item_types.empty_state.enable.primary_button.text"), - onClick: () => setEnableIssueTypeConfirmation(true), + onClick: () => { + captureClick({ + elementName: WORK_ITEM_TYPE_TRACKER_ELEMENTS.HEADER_ENABLE_WORK_ITEM_TYPES_BUTTON, + }); + setEnableIssueTypeConfirmation(true); + }, }} size="md" /> diff --git a/apps/web/ee/components/issue-types/issue-type-list-item.tsx b/apps/web/ee/components/issue-types/issue-type-list-item.tsx index b1cfc2097c..8b0a46d384 100644 --- a/apps/web/ee/components/issue-types/issue-type-list-item.tsx +++ b/apps/web/ee/components/issue-types/issue-type-list-item.tsx @@ -1,10 +1,11 @@ -import { useState } from "react"; + import { observer } from "mobx-react"; import { ChevronRight } from "lucide-react"; // plane imports +import { WORK_ITEM_TYPE_TRACKER_ELEMENTS, WORK_ITEM_TYPE_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { TLoader, IIssueType } from "@plane/types"; -import { Collapsible, setToast, TOAST_TYPE, setPromiseToast } from "@plane/ui"; +import { Collapsible } from "@plane/ui"; // helpers import { cn } from "@plane/utils"; // plane web components @@ -125,6 +126,18 @@ export const IssueTypeListItem = observer((props: TIssueTypeListItem) => { issueTypeId={issueTypeId} propertiesLoader={propertiesLoader} getWorkItemTypeById={getWorkItemTypeById} + trackers={{ + create: { + button: WORK_ITEM_TYPE_TRACKER_ELEMENTS.CREATE_PROPERTY_BUTTON, + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.CREATE_PROPERTY, + }, + update: { + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.UPDATE, + }, + delete: { + eventName: WORK_ITEM_TYPE_TRACKER_EVENTS.DELETE, + }, + }} /> diff --git a/apps/web/ee/components/issue-types/properties/property-create-list-item.tsx b/apps/web/ee/components/issue-types/properties/property-create-list-item.tsx index 63b36c6de0..5389c65602 100644 --- a/apps/web/ee/components/issue-types/properties/property-create-list-item.tsx +++ b/apps/web/ee/components/issue-types/properties/property-create-list-item.tsx @@ -11,6 +11,12 @@ export type TIssuePropertyCreateListItem = { issuePropertyCreateListData?: TIssuePropertyCreateList; customPropertyOperations: TCustomPropertyOperations; isUpdateAllowed: boolean; + trackers?: { + [key in "create" | "update" | "delete" | "quickActions"]?: { + button?: string; + eventName?: string; + }; + }; }; export const IssuePropertyCreateListItem = observer( @@ -18,7 +24,7 @@ export const IssuePropertyCreateListItem = observer( props: TIssuePropertyCreateListItem, ref: React.Ref ) { - const { issuePropertyCreateListData, customPropertyOperations, isUpdateAllowed } = props; + const { issuePropertyCreateListData, customPropertyOperations, isUpdateAllowed, trackers } = props; return (
@@ -27,6 +33,7 @@ export const IssuePropertyCreateListItem = observer( operationMode="create" customPropertyOperations={customPropertyOperations} isUpdateAllowed={isUpdateAllowed} + trackers={trackers} />
); diff --git a/apps/web/ee/components/issue-types/properties/property-list-item.tsx b/apps/web/ee/components/issue-types/properties/property-list-item.tsx index 9f6559fbdc..709e0b6b54 100644 --- a/apps/web/ee/components/issue-types/properties/property-list-item.tsx +++ b/apps/web/ee/components/issue-types/properties/property-list-item.tsx @@ -19,6 +19,7 @@ import { import { Button, InfoIcon, TOAST_TYPE, Tooltip, setPromiseToast, setToast } from "@plane/ui"; import { getIssuePropertyAttributeDisplayNameKey, cn } from "@plane/utils"; // plane web components +import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { AttributePill, IssuePropertyLogo, @@ -48,6 +49,12 @@ type TIssuePropertyListItem = { operationMode?: TOperationMode; customPropertyOperations: TCustomPropertyOperations; isUpdateAllowed: boolean; + trackers?: { + [key in "create" | "update" | "delete" | "quickActions"]?: { + button?: string; + eventName?: string; + }; + }; }; export type TIssuePropertyFormError = { @@ -62,8 +69,14 @@ const defaultIssuePropertyError: TIssuePropertyFormError = { }; export const IssuePropertyListItem = observer((props: TIssuePropertyListItem) => { - const { customPropertyId, issuePropertyCreateListData, operationMode, customPropertyOperations, isUpdateAllowed } = - props; + const { + customPropertyId, + issuePropertyCreateListData, + operationMode, + customPropertyOperations, + isUpdateAllowed, + trackers, + } = props; const { getPropertyDetail, getSortedActivePropertyOptions, @@ -178,6 +191,14 @@ export const IssuePropertyListItem = observer((props: TIssuePropertyListItem) => options: optionsPayload, }) .then(async (response) => { + if (trackers?.create?.eventName) { + captureSuccess({ + eventName: trackers.create.eventName, + payload: { + name: issuePropertyData?.display_name, + }, + }); + } setToast({ type: TOAST_TYPE.SUCCESS, title: t("work_item_types.settings.properties.toast.create.success.title"), @@ -188,6 +209,15 @@ export const IssuePropertyListItem = observer((props: TIssuePropertyListItem) => return response; }) .catch((error) => { + if (trackers?.create?.eventName) { + captureError({ + eventName: trackers.create.eventName, + payload: { + name: issuePropertyData?.display_name, + }, + error: error, + }); + } setToast({ type: TOAST_TYPE.ERROR, title: t("work_item_types.settings.properties.toast.create.error.title"), @@ -238,6 +268,14 @@ export const IssuePropertyListItem = observer((props: TIssuePropertyListItem) => options: optionsPayload, }) .then(() => { + if (trackers?.update?.eventName) { + captureSuccess({ + eventName: trackers.update.eventName, + payload: { + name: issuePropertyData?.display_name, + }, + }); + } if (showToast) setToast({ type: TOAST_TYPE.SUCCESS, @@ -248,6 +286,15 @@ export const IssuePropertyListItem = observer((props: TIssuePropertyListItem) => }); }) .catch((error) => { + if (trackers?.update?.eventName) { + captureError({ + eventName: trackers.update.eventName, + payload: { + name: issuePropertyData?.display_name, + }, + error: error, + }); + } if (showToast) setToast({ type: TOAST_TYPE.ERROR, @@ -282,6 +329,14 @@ export const IssuePropertyListItem = observer((props: TIssuePropertyListItem) => setIsSubmitting(true); await deleteProperty(propertyId) .then(() => { + if (trackers?.delete?.eventName) { + captureSuccess({ + eventName: trackers.delete.eventName, + payload: { + name: issuePropertyData?.display_name, + }, + }); + } setToast({ type: TOAST_TYPE.SUCCESS, title: t("work_item_types.settings.properties.toast.delete.success.title"), @@ -291,6 +346,14 @@ export const IssuePropertyListItem = observer((props: TIssuePropertyListItem) => }); }) .catch(() => { + if (trackers?.delete?.eventName) { + captureError({ + eventName: trackers.delete.eventName, + payload: { + name: issuePropertyData?.display_name, + }, + }); + } setToast({ type: TOAST_TYPE.ERROR, title: t("work_item_types.settings.properties.toast.delete.error.title"), @@ -457,6 +520,7 @@ export const IssuePropertyListItem = observer((props: TIssuePropertyListItem) => onDisable={async () => handlePropertyDataChange("is_active", false, true)} onDelete={handleDelete} onIssuePropertyOperationMode={(mode) => setIssuePropertyOperationMode(mode)} + trackers={trackers} /> diff --git a/apps/web/ee/components/issue-types/properties/property-list.tsx b/apps/web/ee/components/issue-types/properties/property-list.tsx index 535d7df088..fd9a702cd5 100644 --- a/apps/web/ee/components/issue-types/properties/property-list.tsx +++ b/apps/web/ee/components/issue-types/properties/property-list.tsx @@ -19,6 +19,12 @@ type TIssuePropertyList = { containerRef: React.RefObject; lastElementRef: React.RefObject; isUpdateAllowed: boolean; + trackers?: { + [key in "create" | "update" | "delete" | "quickActions"]?: { + button?: string; + eventName?: string; + }; + }; }; export const IssuePropertyList: FC = observer((props) => { @@ -29,6 +35,7 @@ export const IssuePropertyList: FC = observer((props) => { containerRef, lastElementRef, isUpdateAllowed, + trackers, } = props; return ( @@ -45,6 +52,7 @@ export const IssuePropertyList: FC = observer((props) => { customPropertyId={property.id} customPropertyOperations={customPropertyOperations} isUpdateAllowed={isUpdateAllowed} + trackers={trackers} /> ))} @@ -60,6 +68,7 @@ export const IssuePropertyList: FC = observer((props) => { issuePropertyCreateListData={issueProperty} customPropertyOperations={customPropertyOperations} isUpdateAllowed + trackers={trackers} /> ))} diff --git a/apps/web/ee/components/issue-types/properties/quick-actions.tsx b/apps/web/ee/components/issue-types/properties/quick-actions.tsx index 3a53f7ace1..121db6ea59 100644 --- a/apps/web/ee/components/issue-types/properties/quick-actions.tsx +++ b/apps/web/ee/components/issue-types/properties/quick-actions.tsx @@ -7,6 +7,7 @@ import { TOperationMode } from "@plane/types"; import { CustomMenu, TContextMenuItem } from "@plane/ui"; import { cn } from "@plane/utils"; // plane web components +import { captureClick } from "@/helpers/event-tracker.helper"; import { DeleteConfirmationModal } from "@/plane-web/components/issue-types"; type TIssuePropertyQuickActions = { @@ -14,10 +15,16 @@ type TIssuePropertyQuickActions = { onDisable: () => Promise; onDelete: () => Promise; onIssuePropertyOperationMode: (mode: TOperationMode) => void; + trackers?: { + [key in "create" | "update" | "delete" | "quickActions"]?: { + button?: string; + eventName?: string; + }; + }; }; export const IssuePropertyQuickActions = observer((props: TIssuePropertyQuickActions) => { - const { isPropertyDisabled, onDisable, onDelete, onIssuePropertyOperationMode } = props; + const { isPropertyDisabled, onDisable, onDelete, onIssuePropertyOperationMode, trackers } = props; // plane hooks const { t } = useTranslation(); // states @@ -26,13 +33,23 @@ export const IssuePropertyQuickActions = observer((props: TIssuePropertyQuickAct const MENU_ITEMS: TContextMenuItem[] = [ { key: "edit", - action: () => onIssuePropertyOperationMode("update"), + action: () => { + captureClick({ + elementName: trackers?.quickActions?.button || "", + }); + onIssuePropertyOperationMode("update"); + }, title: t("common.actions.edit"), icon: Pencil, }, { key: "delete", - action: () => setIsDeleteModalOpen(true), + action: () => { + captureClick({ + elementName: trackers?.quickActions?.button || "", + }); + setIsDeleteModalOpen(true); + }, title: t("common.actions.delete"), icon: Trash2, }, diff --git a/apps/web/ee/components/issue-types/quick-actions.tsx b/apps/web/ee/components/issue-types/quick-actions.tsx index a37246a81d..ba1154da19 100644 --- a/apps/web/ee/components/issue-types/quick-actions.tsx +++ b/apps/web/ee/components/issue-types/quick-actions.tsx @@ -4,10 +4,12 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { Pencil, Trash2 } from "lucide-react"; // plane imports +import { WORK_ITEM_TYPE_TRACKER_ELEMENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { IIssueType } from "@plane/types"; import { CustomMenu, setPromiseToast, TContextMenuItem, ToggleSwitch, Tooltip } from "@plane/ui"; import { cn } from "@plane/utils"; +import { captureClick } from "@/helpers/event-tracker.helper"; type Props = { issueTypeId: string; @@ -38,13 +40,23 @@ export const IssueTypeQuickActions: React.FC = observer((props) => { const MENU_ITEMS: (TContextMenuItem & { tooltipContent?: string })[] = [ { key: "edit", - action: () => onEditIssueTypeIdChange(issueTypeId), + action: () => { + captureClick({ + elementName: WORK_ITEM_TYPE_TRACKER_ELEMENTS.PROPERTY_QUICK_ACTIONS, + }); + onEditIssueTypeIdChange(issueTypeId); + }, title: t("common.actions.edit"), icon: Pencil, }, { key: "delete", - action: () => onDeleteIssueTypeIdChange(issueTypeId), + action: () => { + captureClick({ + elementName: WORK_ITEM_TYPE_TRACKER_ELEMENTS.PROPERTY_QUICK_ACTIONS, + }); + onDeleteIssueTypeIdChange(issueTypeId); + }, title: t("common.actions.delete"), tooltipContent: issueTypeDetail?.is_default ? t("work_item_types.settings.cant_delete_default_message") diff --git a/apps/web/ee/components/issue-types/root.tsx b/apps/web/ee/components/issue-types/root.tsx index bbcb0c21eb..3618446011 100644 --- a/apps/web/ee/components/issue-types/root.tsx +++ b/apps/web/ee/components/issue-types/root.tsx @@ -3,9 +3,11 @@ import { useCallback, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // plane imports +import { WORK_ITEM_TYPE_TRACKER_ELEMENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // plane web components import { SettingsHeading } from "@/components/settings"; +import { captureClick } from "@/helpers/event-tracker.helper"; import { IssueTypeEmptyState, IssueTypesList, CreateOrUpdateIssueTypeModal } from "@/plane-web/components/issue-types"; // plane web hooks import { useIssueTypes } from "@/plane-web/hooks/store"; @@ -62,7 +64,12 @@ export const IssueTypesRoot = observer(() => { showButton={isWorkItemTypeEnabled} button={{ label: t("work_item_types.create.button"), - onClick: () => setIsModalOpen(true), + onClick: () => { + captureClick({ + elementName: WORK_ITEM_TYPE_TRACKER_ELEMENTS.HEADER_CREATE_WORK_ITEM_TYPE_BUTTON, + }); + setIsModalOpen(true); + }, }} />
diff --git a/packages/constants/src/event-tracker/extended.ts b/packages/constants/src/event-tracker/extended.ts index 0161cac1c7..85fbc063ce 100644 --- a/packages/constants/src/event-tracker/extended.ts +++ b/packages/constants/src/event-tracker/extended.ts @@ -198,6 +198,44 @@ export const TEAMSPACE_VIEW_TRACKER_ELEMENTS = { CONTEXT_MENU: "teamspace_view_context_menu", }; +export const WORK_ITEM_TYPE_TRACKER_EVENTS = { + TYPES_ENABLED: "work_item_types_enabled", + CREATE: "work_item_type_created", + UPDATE: "work_item_type_updated", + DELETE: "work_item_type_deleted", + ENABLE: "work_item_type_enabled", + DISABLE: "work_item_type_disabled", + CREATE_PROPERTY: "work_item_type_create_property", +}; + +export const WORK_ITEM_TYPE_TRACKER_ELEMENTS = { + HEADER_CREATE_WORK_ITEM_TYPE_BUTTON: "work_item_type_header_create_button", + HEADER_ENABLE_WORK_ITEM_TYPES_BUTTON: "work_item_type_header_enable_work_item_types_button", + HEADER_ENABLE_DISABLE_WORK_ITEM_TYPE_BUTTON: "work_item_type_header_enable_disable_button", + CREATE_PROPERTY_BUTTON: "work_item_type_create_property_button", + PROPERTY_QUICK_ACTIONS: "work_item_type_property_quick_actions", +}; + +export const EPIC_CUSTOM_PROPERTY_TRACKER_EVENTS = { + CREATE: "epic_custom_property_created", + UPDATE: "epic_custom_property_updated", + DELETE: "epic_custom_property_deleted", +}; +export const EPIC_CUSTOM_PROPERTY_TRACKER_ELEMENTS = { + CREATE_PROPERTY_BUTTON: "epic_custom_property_create_property_button", + PROPERTY_QUICK_ACTIONS: "epic_custom_property_property_quick_actions", +}; + +export const CUSTOMER_PROPERTY_TRACKER_EVENTS = { + CREATE: "customer_custom_property_created", + UPDATE: "customer_custom_property_updated", + DELETE: "customer_custom_property_deleted", +}; +export const CUSTOMER_PROPERTY_TRACKER_ELEMENTS = { + CREATE_PROPERTY_BUTTON: "customer_custom_property_create_property_button", + PROPERTY_QUICK_ACTIONS: "customer_custom_property_property_quick_actions", +}; +// Project Template Tracker Start export const INTEGRATION_TRACKER_ELEMENTS = { INTEGRATIONS_MAPPING_ENTITY_ITEM_BUTTON: "integrations_mapping_entity_item_button", };