import {useCallback} from 'react'; import styled from '@emotion/styled'; import type {Location} from 'history'; import Feature from 'sentry/components/acl/feature'; import GuideAnchor from 'sentry/components/assistant/guideAnchor'; import FeatureBadge from 'sentry/components/badge/featureBadge'; import ButtonBar from 'sentry/components/buttonBar'; import {CreateAlertFromViewButton} from 'sentry/components/createAlertButton'; import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton'; import IdBadge from 'sentry/components/idBadge'; import * as Layout from 'sentry/components/layouts/thirds'; import ReplayCountBadge from 'sentry/components/replays/replayCountBadge'; import {TabList} from 'sentry/components/tabs'; import {Tooltip} from 'sentry/components/tooltip'; import {t} from 'sentry/locale'; import type {Organization} from 'sentry/types/organization'; import type {Project} from 'sentry/types/project'; import {trackAnalytics} from 'sentry/utils/analytics'; import type EventView from 'sentry/utils/discover/eventView'; import type {MetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality'; import HasMeasurementsQuery from 'sentry/utils/performance/vitals/hasMeasurementsQuery'; import {isProfilingSupportedOrProjectHasProfiles} from 'sentry/utils/profiling/platforms'; import useReplayCountForTransactions from 'sentry/utils/replayCount/useReplayCountForTransactions'; import projectSupportsReplay from 'sentry/utils/replays/projectSupportsReplay'; import Breadcrumb from 'sentry/views/performance/breadcrumb'; import {getCurrentLandingDisplay, LandingDisplayField} from '../landing/utils'; import Tab from './tabs'; import TeamKeyTransactionButton from './teamKeyTransactionButton'; import TransactionThresholdButton from './transactionThresholdButton'; import type {TransactionThresholdMetric} from './transactionThresholdModal'; type Props = { currentTab: Tab; eventView: EventView; hasWebVitals: 'maybe' | 'yes' | 'no'; location: Location; organization: Organization; projectId: string; projects: Project[]; transactionName: string; metricsCardinality?: MetricsCardinalityContext; onChangeThreshold?: (threshold: number, metric: TransactionThresholdMetric) => void; }; function TransactionHeader({ eventView, organization, projects, projectId, metricsCardinality, location, transactionName, onChangeThreshold, currentTab, hasWebVitals, }: Props) { function handleCreateAlertSuccess() { trackAnalytics('performance_views.summary.create_alert_clicked', { organization, }); } const project = projects.find(p => p.id === projectId); const hasAnomalyDetection = organization.features?.includes( 'performance-anomaly-detection-ui' ); const hasSessionReplay = organization.features.includes('session-replay') && project && projectSupportsReplay(project); const hasProfiling = project && organization.features.includes('profiling') && isProfilingSupportedOrProjectHasProfiles(project); const hasAggregateWaterfall = organization.features.includes( 'insights-initial-modules' ); const getWebVitals = useCallback( (hasMeasurements: boolean) => { switch (hasWebVitals) { case 'maybe': // need to check if the web vitals tab should be shown // frontend projects should always show the web vitals tab if ( getCurrentLandingDisplay(location, projects, eventView).field === LandingDisplayField.FRONTEND_OTHER ) { return true; } // if it is not a frontend project, then we check to see if there // are any web vitals associated with the transaction recently return hasMeasurements; case 'yes': // always show the web vitals tab return true; case 'no': default: // never show the web vitals tab return false; } }, [hasWebVitals, location, projects, eventView] ); const {getReplayCountForTransaction} = useReplayCountForTransactions({ statsPeriod: '90d', }); const replaysCount = getReplayCountForTransaction(transactionName); return ( {project && ( )} {transactionName} {({hasFeature}) => hasFeature && !metricsCardinality?.isLoading ? ( ) : null } {({hasMeasurements}) => { const renderWebVitals = getWebVitals(!!hasMeasurements); return ( {t('Overview')} {t('Sampled Events')} {t('Tags')} {t('Spans')} ); }} ); } const TransactionName = styled('div')` ${p => p.theme.overflowEllipsis} `; export default TransactionHeader;