diff --git a/static/app/views/performance/newTraceDetails/traceAnalytics.tsx b/static/app/views/performance/newTraceDetails/traceAnalytics.tsx index fc423cb5bf46d7..bd0a6390a93b9d 100644 --- a/static/app/views/performance/newTraceDetails/traceAnalytics.tsx +++ b/static/app/views/performance/newTraceDetails/traceAnalytics.tsx @@ -71,6 +71,10 @@ const trackViewContinuousProfile = (organization: Organization) => trackAnalytics('trace.trace_layout.view_continuous_profile', { organization, }); +const trackViewTransactionProfile = (organization: Organization) => + trackAnalytics('trace.trace_layout.view_transaction_profile', { + organization, + }); const trackTabPin = (organization: Organization) => trackAnalytics('trace.trace_layout.tab_pin', { @@ -209,6 +213,7 @@ const traceAnalytics = { trackShowInView, trackViewEventJSON, trackViewContinuousProfile, + trackViewTransactionProfile, // Layout actions trackLayoutChange, trackDrawerMinimize, diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx index 5761397441829b..429f8914fdd7f7 100644 --- a/static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx +++ b/static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx @@ -52,7 +52,10 @@ import {useParams} from 'sentry/utils/useParams'; import {traceAnalytics} from '../../traceAnalytics'; import {useTransaction} from '../../traceApi/useTransaction'; import {useDrawerContainerRef} from '../../traceDrawer/details/drawerContainerRefContext'; -import {makeTraceContinuousProfilingLink} from '../../traceDrawer/traceProfilingLink'; +import { + makeTraceContinuousProfilingLink, + makeTransactionProfilingLink, +} from '../../traceDrawer/traceProfilingLink'; import { isAutogroupedNode, isMissingInstrumentationNode, @@ -798,30 +801,44 @@ function NodeActions(props: { organization, }); - const profilerId: string = useMemo(() => { - if (isTransactionNode(props.node)) { - return props.node.value.profiler_id; + const transactionProfileTarget = useMemo(() => { + const profileId = isTransactionNode(props.node) + ? props.node.value.profile_id + : isSpanNode(props.node) + ? props.node.event?.contexts?.profile?.profile_id ?? '' + : ''; + if (!profileId) { + return null; } - if (isSpanNode(props.node)) { - return props.node.value.sentry_tags?.profiler_id ?? ''; + return makeTransactionProfilingLink(profileId, { + orgSlug: props.organization.slug, + projectSlug: props.node.metadata.project_slug ?? '', + }); + }, [props.node, props.organization]); + + const continuousProfileTarget = useMemo(() => { + const profilerId = isTransactionNode(props.node) + ? props.node.value.profiler_id + : isSpanNode(props.node) + ? props.node.value.sentry_tags?.profiler_id ?? null + : null; + if (!profilerId) { + return null; } - return ''; - }, [props]); - - const profileLink = makeTraceContinuousProfilingLink(props.node, profilerId, { - orgSlug: props.organization.slug, - projectSlug: props.node.metadata.project_slug ?? '', - traceId: params.traceSlug ?? '', - threadId: getThreadIdFromNode(props.node, transaction), - }); + return makeTraceContinuousProfilingLink(props.node, profilerId, { + orgSlug: props.organization.slug, + projectSlug: props.node.metadata.project_slug ?? '', + traceId: params.traceSlug ?? '', + threadId: getThreadIdFromNode(props.node, transaction), + }); + }, [params.traceSlug, props.node, props.organization, transaction]); if (!hasNewTraceUi) { return ( ); } @@ -850,11 +867,23 @@ function NodeActions(props: { /> ) : null} - {profileLink ? ( - + {continuousProfileTarget ? ( + + traceAnalytics.trackViewContinuousProfile(props.organization)} + to={continuousProfileTarget} + size="xs" + aria-label={t('Profile')} + icon={} + /> + + ) : transactionProfileTarget ? ( + traceAnalytics.trackViewTransactionProfile(props.organization)} + to={transactionProfileTarget} size="xs" - aria-label={t('Continuous Profile')} + aria-label={t('Profile')} icon={} /> @@ -888,6 +917,7 @@ const ActionWrapper = styled('div')` `; function LegacyNodeActions(props: { + continuousProfileTarget: LocationDescriptor | null; node: TraceTreeNode; onTabScrollToNode: ( node: @@ -896,20 +926,18 @@ function LegacyNodeActions(props: { | SiblingAutogroupNode | MissingInstrumentationNode ) => void; - profileLink: LocationDescriptor | null; - profilerId: string; - transaction: EventTransaction | undefined; + organization: Organization; + transactionProfileTarget: LocationDescriptor | null; eventSize?: number | undefined; }) { const navigate = useNavigate(); - const organization = useOrganization(); const items = useMemo((): MenuItemProps[] => { const showInView: MenuItemProps = { key: 'show-in-view', label: t('Show in View'), onAction: () => { - traceAnalytics.trackShowInView(organization); + traceAnalytics.trackShowInView(props.organization); props.onTabScrollToNode(props.node); }, }; @@ -925,9 +953,9 @@ function LegacyNodeActions(props: { const jsonDetails: MenuItemProps = { key: 'json-details', onAction: () => { - traceAnalytics.trackViewEventJSON(organization); + traceAnalytics.trackViewEventJSON(props.organization); window.open( - `/api/0/projects/${organization.slug}/${projectSlug}/events/${eventId}/json/`, + `/api/0/projects/${props.organization.slug}/${projectSlug}/events/${eventId}/json/`, '_blank' ); }, @@ -936,28 +964,37 @@ function LegacyNodeActions(props: { (typeof eventSize === 'number' ? ` (${formatBytesBase10(eventSize, 0)})` : ''), }; - const continuousProfileLink: MenuItemProps | null = props.profileLink + const profileLink: MenuItemProps | null = props.continuousProfileTarget ? { - key: 'continuous-profile', + key: 'profile', onAction: () => { - traceAnalytics.trackViewContinuousProfile(organization); - navigate(props.profileLink!); + traceAnalytics.trackViewContinuousProfile(props.organization); + navigate(props.continuousProfileTarget!); }, - label: t('Continuous Profile'), + label: t('View Profile'), } - : null; + : props.transactionProfileTarget + ? { + key: 'profile', + onAction: () => { + traceAnalytics.trackViewTransactionProfile(props.organization); + navigate(props.transactionProfileTarget!); + }, + label: t('View Profile'), + } + : null; if (isTransactionNode(props.node)) { - return [showInView, jsonDetails, continuousProfileLink].filter(TypeSafeBoolean); + return [showInView, jsonDetails, profileLink].filter(TypeSafeBoolean); } if (isSpanNode(props.node)) { - return [showInView, continuousProfileLink].filter(TypeSafeBoolean); + return [showInView, profileLink].filter(TypeSafeBoolean); } if (isMissingInstrumentationNode(props.node)) { - return [showInView, continuousProfileLink].filter(TypeSafeBoolean); + return [showInView, profileLink].filter(TypeSafeBoolean); } if (isTraceErrorNode(props.node)) { - return [showInView, continuousProfileLink].filter(TypeSafeBoolean); + return [showInView, profileLink].filter(TypeSafeBoolean); } if (isRootNode(props.node)) { return [showInView]; @@ -967,20 +1004,24 @@ function LegacyNodeActions(props: { } return [showInView]; - }, [props, navigate, organization]); + }, [props, navigate]); return ( - {props.profileLink ? ( - - {t('Continuous Profile')} + {props.continuousProfileTarget ? ( + + {t('View Profile')} + + ) : props.transactionProfileTarget ? ( + + {t('View Profile')} ) : null}