import type {ReactText} from 'react';
import {Fragment} from 'react';
import styled from '@emotion/styled';
import Duration from 'sentry/components/duration';
import FileSize from 'sentry/components/fileSize';
import LoadingIndicator from 'sentry/components/loadingIndicator';
import {PercentChange, type Polarity} from 'sentry/components/percentChange';
import {Tooltip} from 'sentry/components/tooltip';
import {defined} from 'sentry/utils';
import {
type CountUnit,
CurrencyUnit,
DurationUnit,
type PercentageUnit,
type PercentChangeUnit,
RateUnit,
SizeUnit,
} from 'sentry/utils/discover/fields';
import {formatAbbreviatedNumber, formatRate} from 'sentry/utils/formatters';
import {formatPercentage} from 'sentry/utils/number/formatPercentage';
import {Block} from 'sentry/views/insights/common/views/spanSummaryPage/block';
type Unit =
| DurationUnit.MILLISECOND
| SizeUnit.BYTE
| RateUnit
| CountUnit
| PercentageUnit
| PercentChangeUnit
| CurrencyUnit;
interface Props {
title: string;
unit: Unit;
value: ReactText | undefined;
align?: 'left' | 'right';
isLoading?: boolean;
preferredPolarity?: Polarity;
tooltip?: React.ReactNode;
}
export function MetricReadout(props: Props) {
return (
);
}
function ReadoutContent({
unit,
value,
tooltip,
align = 'right',
isLoading,
preferredPolarity,
}: Props) {
if (isLoading) {
return (
);
}
if (!defined(value)) {
return --;
}
let renderedValue: React.ReactNode;
if (isARateUnit(unit)) {
renderedValue = (
{formatRate(typeof value === 'string' ? parseFloat(value) : value, unit, {
minimumValue: MINIMUM_RATE_VALUE,
})}
);
}
if (unit === DurationUnit.MILLISECOND) {
// TODO: Implement other durations
renderedValue = (
);
}
if (unit === SizeUnit.BYTE) {
// TODO: Implement other sizes
renderedValue = (
);
}
if (unit === 'count') {
renderedValue = (
{formatAbbreviatedNumber(typeof value === 'string' ? parseInt(value, 10) : value)}
);
}
if (unit === CurrencyUnit.USD) {
const numericValue = typeof value === 'string' ? parseFloat(value) : value;
if (numericValue <= 1) {
renderedValue = (
US ${numericValue.toFixed(3)}
);
} else {
renderedValue = (
US ${formatAbbreviatedNumber(numericValue)}
);
}
}
if (unit === 'percentage') {
renderedValue = (
{formatPercentage(
typeof value === 'string' ? parseFloat(value) : value,
undefined,
{minimumValue: MINIMUM_PERCENTAGE_VALUE}
)}
);
}
if (unit === 'percent_change') {
renderedValue = (
);
}
if (tooltip) {
return (
{renderedValue}
);
}
return {renderedValue};
}
const MINIMUM_RATE_VALUE = 0.01;
const MINIMUM_PERCENTAGE_VALUE = 0.0001; // 0.01%
const NumberContainer = styled('div')<{align: 'left' | 'right'}>`
text-align: ${p => p.align};
font-variant-numeric: tabular-nums;
`;
const LoadingContainer = styled('div')<{align: 'left' | 'right'}>`
display: flex;
justify-content: ${p => (p.align === 'right' ? 'flex-end' : 'flex-start')};
align-items: center;
`;
function isARateUnit(unit: string): unit is RateUnit {
return (Object.values(RateUnit) as string[]).includes(unit);
}