vitalPercents.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import styled from '@emotion/styled';
  2. import {t, tct} from 'sentry/locale';
  3. import {space} from 'sentry/styles/space';
  4. import {WebVital} from 'sentry/utils/fields';
  5. import {formatPercentage} from 'sentry/utils/number/formatPercentage';
  6. import {VitalState, vitalStateIcons, webVitalMeh, webVitalPoor} from './utils';
  7. type Percent = {
  8. percent: number;
  9. vitalState: VitalState;
  10. };
  11. type Props = {
  12. percents: Percent[];
  13. vital: WebVital | WebVital[];
  14. hideTooltips?: boolean;
  15. showVitalPercentNames?: boolean;
  16. showVitalThresholds?: boolean;
  17. };
  18. function getVitalStateText(vital: WebVital | WebVital[], vitalState) {
  19. const unit = !Array.isArray(vital) && vital !== WebVital.CLS ? 'ms' : '';
  20. switch (vitalState) {
  21. case VitalState.POOR:
  22. return Array.isArray(vital)
  23. ? t('Poor')
  24. : tct('(>[threshold][unit])', {threshold: webVitalPoor[vital], unit});
  25. case VitalState.MEH:
  26. return Array.isArray(vital)
  27. ? t('Meh')
  28. : tct('(>[threshold][unit])', {threshold: webVitalMeh[vital], unit});
  29. case VitalState.GOOD:
  30. return Array.isArray(vital)
  31. ? t('Good')
  32. : tct('(<=[threshold][unit])', {threshold: webVitalMeh[vital], unit});
  33. default:
  34. return null;
  35. }
  36. }
  37. export default function VitalPercents(props: Props) {
  38. return (
  39. <VitalSet>
  40. {props.percents.map(pct => (
  41. <VitalStatus data-test-id="vital-status" key={pct.vitalState}>
  42. {vitalStateIcons[pct.vitalState]}
  43. {props.showVitalPercentNames && pct.vitalState}{' '}
  44. {formatPercentage(pct.percent, 0)}
  45. {props.showVitalThresholds && getVitalStateText(props.vital, pct.vitalState)}
  46. </VitalStatus>
  47. ))}
  48. </VitalSet>
  49. );
  50. }
  51. const VitalSet = styled('div')`
  52. display: inline-grid;
  53. grid-auto-flow: column;
  54. gap: ${space(2)};
  55. `;
  56. const VitalStatus = styled('div')`
  57. display: flex;
  58. align-items: center;
  59. gap: ${space(0.5)};
  60. font-size: ${p => p.theme.fontSizeMedium};
  61. `;