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)')};