vitalPercents.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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: any) {
  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. : // @ts-expect-error TS(2551): Property 'measurements.ttfb' does not exist on typ... Remove this comment to see the full error message
  25. tct('(>[threshold][unit])', {threshold: webVitalPoor[vital], unit});
  26. case VitalState.MEH:
  27. return Array.isArray(vital)
  28. ? t('Meh')
  29. : // @ts-expect-error TS(2551): Property 'measurements.ttfb' does not exist on typ... Remove this comment to see the full error message
  30. tct('(>[threshold][unit])', {threshold: webVitalMeh[vital], unit});
  31. case VitalState.GOOD:
  32. return Array.isArray(vital)
  33. ? t('Good')
  34. : // @ts-expect-error TS(2551): Property 'measurements.ttfb' does not exist on typ... Remove this comment to see the full error message
  35. tct('(<=[threshold][unit])', {threshold: webVitalMeh[vital], unit});
  36. default:
  37. return null;
  38. }
  39. }
  40. export default function VitalPercents(props: Props) {
  41. return (
  42. <VitalSet>
  43. {props.percents.map(pct => (
  44. <VitalStatus data-test-id="vital-status" key={pct.vitalState}>
  45. {vitalStateIcons[pct.vitalState]}
  46. {props.showVitalPercentNames && pct.vitalState}{' '}
  47. {formatPercentage(pct.percent, 0)}
  48. {props.showVitalThresholds && getVitalStateText(props.vital, pct.vitalState)}
  49. </VitalStatus>
  50. ))}
  51. </VitalSet>
  52. );
  53. }
  54. const VitalSet = styled('div')`
  55. display: inline-grid;
  56. grid-auto-flow: column;
  57. gap: ${space(2)};
  58. `;
  59. const VitalStatus = styled('div')`
  60. display: flex;
  61. align-items: center;
  62. gap: ${space(0.5)};
  63. font-size: ${p => p.theme.fontSizeMedium};
  64. `;