traceLevelOpsBreakdown.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import styled from '@emotion/styled';
  2. import {pickBarColor} from 'sentry/components/performance/waterfall/utils';
  3. import Placeholder from 'sentry/components/placeholder';
  4. import {IconCircleFill} from 'sentry/icons/iconCircleFill';
  5. import {space} from 'sentry/styles/space';
  6. import type {Color} from 'sentry/utils/theme';
  7. import type {TraceMetaQueryResults} from './traceApi/useTraceMeta';
  8. import {useHasTraceNewUi} from './useHasTraceNewUi';
  9. function LoadingPlaceHolder() {
  10. return (
  11. <Container>
  12. <StyledPlaceholder height={'16px'} width={'100px'} />
  13. <StyledPlaceholder height={'16px'} width={'100px'} />
  14. <StyledPlaceholder height={'16px'} width={'100px'} />
  15. </Container>
  16. );
  17. }
  18. type Props = {
  19. isTraceLoading: boolean;
  20. metaQueryResults: TraceMetaQueryResults;
  21. };
  22. export function TraceLevelOpsBreakdown({metaQueryResults, isTraceLoading}: Props) {
  23. const hasNewTraceUi = useHasTraceNewUi();
  24. if (!hasNewTraceUi || metaQueryResults.status === 'error') {
  25. return null;
  26. }
  27. if (isTraceLoading || metaQueryResults.status === 'pending') {
  28. return <LoadingPlaceHolder />;
  29. }
  30. const {span_count, span_count_map} = metaQueryResults.data!;
  31. if (span_count <= 0) {
  32. return null;
  33. }
  34. return (
  35. <Container>
  36. {Object.entries(span_count_map)
  37. .sort((a, b) => b[1] - a[1]) // Sort by count
  38. .slice(0, 4)
  39. .map(([op, count]) => {
  40. const percentage = count / span_count;
  41. const color = pickBarColor(op);
  42. const pctLabel = isFinite(percentage) ? Math.round(percentage * 100) : '∞';
  43. return (
  44. <HighlightsOpRow key={op}>
  45. <IconCircleFill size="xs" color={color as Color} />
  46. {op}
  47. <span>{pctLabel}%</span>
  48. </HighlightsOpRow>
  49. );
  50. })}
  51. </Container>
  52. );
  53. }
  54. const HighlightsOpRow = styled('div')`
  55. display: flex;
  56. align-items: center;
  57. font-size: ${p => p.theme.fontSizeSmall};
  58. gap: 5px;
  59. `;
  60. const Container = styled('div')`
  61. display: flex;
  62. align-items: center;
  63. padding-left: ${space(1)};
  64. gap: ${space(2)};
  65. `;
  66. const StyledPlaceholder = styled(Placeholder)`
  67. border-radius: ${p => p.theme.borderRadius};
  68. `;