widgetHeader.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import styled from '@emotion/styled';
  2. import FeatureBadge from 'sentry/components/badge/featureBadge';
  3. import {HeaderTitleLegend} from 'sentry/components/charts/styles';
  4. import QuestionTooltip from 'sentry/components/questionTooltip';
  5. import TextOverflow from 'sentry/components/textOverflow';
  6. import {space} from 'sentry/styles/space';
  7. import {MEPTag} from 'sentry/utils/performance/contexts/metricsEnhancedPerformanceDataContext';
  8. import type {
  9. GenericPerformanceWidgetProps,
  10. WidgetDataConstraint,
  11. WidgetDataProps,
  12. } from '../types';
  13. import {PerformanceWidgetSetting} from '../widgetDefinitions';
  14. export function WidgetHeader<T extends WidgetDataConstraint>(
  15. props: GenericPerformanceWidgetProps<T> & WidgetDataProps<T>
  16. ) {
  17. const {title, titleTooltip, Subtitle, HeaderActions, InteractiveTitle, chartSetting} =
  18. props;
  19. const isWebVitalsWidget = [
  20. PerformanceWidgetSetting.HIGHEST_OPPORTUNITY_PAGES,
  21. PerformanceWidgetSetting.OVERALL_PERFORMANCE_SCORE,
  22. ].includes(chartSetting);
  23. const isCacheWidget =
  24. chartSetting === PerformanceWidgetSetting.HIGHEST_CACHE_MISS_RATE_TRANSACTIONS;
  25. const featureBadge =
  26. isWebVitalsWidget || isCacheWidget ? <FeatureBadge type="new" /> : null;
  27. return (
  28. <WidgetHeaderContainer>
  29. <TitleContainer>
  30. <StyledHeaderTitleLegend data-test-id="performance-widget-title">
  31. {InteractiveTitle ? (
  32. <InteractiveTitle {...props} />
  33. ) : (
  34. <TextOverflow>{title}</TextOverflow>
  35. )}
  36. {featureBadge}
  37. <MEPTag />
  38. {titleTooltip && (
  39. <QuestionTooltip position="top" size="sm" title={titleTooltip} />
  40. )}
  41. </StyledHeaderTitleLegend>
  42. {Subtitle ? <Subtitle {...props} /> : null}
  43. </TitleContainer>
  44. <HeaderActionsContainer>
  45. {HeaderActions && <HeaderActions {...props} />}
  46. </HeaderActionsContainer>
  47. </WidgetHeaderContainer>
  48. );
  49. }
  50. const StyledHeaderTitleLegend = styled(HeaderTitleLegend)`
  51. position: relative;
  52. z-index: initial;
  53. top: -${space(0.5)};
  54. ${FeatureBadge} {
  55. position: relative;
  56. top: -${space(0.25)};
  57. margin-left: ${space(0.25)};
  58. }
  59. `;
  60. const TitleContainer = styled('div')`
  61. display: flex;
  62. flex-direction: column;
  63. align-items: flex-start;
  64. `;
  65. const WidgetHeaderContainer = styled('div')`
  66. display: flex;
  67. justify-content: space-between;
  68. align-items: flex-start;
  69. gap: ${space(1)};
  70. `;
  71. const HeaderActionsContainer = styled('div')`
  72. display: flex;
  73. align-items: center;
  74. gap: ${space(1)};
  75. `;