import styled from '@emotion/styled'; import {SectionHeading} from 'sentry/components/charts/styles'; import Count from 'sentry/components/count'; import PerformanceDuration from 'sentry/components/performanceDuration'; import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {defined} from 'sentry/utils'; import {formatPercentage} from 'sentry/utils/number/formatPercentage'; import type {SpanSlug, SuspectSpan} from 'sentry/utils/performance/suspectSpans/types'; interface HeaderProps { spanSlug: SpanSlug; totalCount: number | null; suspectSpan?: SuspectSpan; } export default function SpanDetailsHeader(props: HeaderProps) { const {spanSlug, suspectSpan, totalCount} = props; const { description, frequency, avgOccurrences, p50ExclusiveTime, p75ExclusiveTime, p95ExclusiveTime, p99ExclusiveTime, sumExclusiveTime, } = suspectSpan ?? {}; return ( {t('Span Operation')} {description ?? emptyValue} {spanSlug.op} {t('Self Time Percentiles')}
{defined(p50ExclusiveTime) ? ( ) : ( '\u2014' )} {t('p50')}
{defined(p75ExclusiveTime) ? ( ) : ( '\u2014' )} {t('p75')}
{defined(p95ExclusiveTime) ? ( ) : ( '\u2014' )} {t('p95')}
{defined(p99ExclusiveTime) ? ( ) : ( '\u2014' )} {t('p99')}
{t('Frequency')} {defined(frequency) && defined(totalCount) ? formatPercentage(Math.min(frequency, totalCount) / totalCount) : '\u2014'} {defined(avgOccurrences) ? tct('[times] times per event', {times: avgOccurrences.toFixed(2)}) : '\u2014'} {t('Total Self Time')} {defined(sumExclusiveTime) ? ( ) : ( '\u2014' )} {defined(frequency) ? tct('[events] events', {events: }) : '\u2014'}
); } const ContentHeader = styled('div')` display: grid; grid-template-columns: 1fr; gap: ${space(4)}; margin-bottom: ${space(2)}; @media (min-width: ${p => p.theme.breakpoints.medium}) { grid-template-columns: 1fr repeat(3, max-content); } `; const HeaderInfo = styled('div')` ${p => p.theme.overflowEllipsis}; height: 78px; `; const StyledSectionHeading = styled(SectionHeading)` margin: 0; `; const SectionBody = styled('div')<{overflowEllipsis?: boolean}>` font-size: ${p => p.theme.fontSizeExtraLarge}; padding: ${space(0.5)} 0; max-height: 32px; `; const SectionSubtext = styled('div')` color: ${p => p.theme.subText}; font-size: ${p => p.theme.fontSizeMedium}; `; const PercentileHeaderBodyWrapper = styled('div')` display: grid; grid-template-columns: repeat(4, max-content); gap: ${space(3)}; `; export const SpanLabelContainer = styled('div')` ${p => p.theme.overflowEllipsis}; `; const EmptyValueContainer = styled('span')` color: ${p => p.theme.gray300}; `; const emptyValue = {t('(unnamed span)')};