styles.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import styled from '@emotion/styled';
  2. import {LocationDescriptor} from 'history';
  3. import MenuHeader from 'sentry/components/actions/menuHeader';
  4. import ExternalLink from 'sentry/components/links/externalLink';
  5. import MenuItem from 'sentry/components/menuItem';
  6. import Tag, {Background} from 'sentry/components/tag';
  7. import Truncate from 'sentry/components/truncate';
  8. import space from 'sentry/styles/space';
  9. import {getDuration} from 'sentry/utils/formatters';
  10. import {QuickTraceEvent} from 'sentry/utils/performance/quickTrace/types';
  11. import {Theme} from 'sentry/utils/theme';
  12. export const SectionSubtext = styled('div')`
  13. color: ${p => p.theme.subText};
  14. font-size: ${p => p.theme.fontSizeMedium};
  15. `;
  16. export const QuickTraceContainer = styled('div')`
  17. display: flex;
  18. align-items: center;
  19. `;
  20. const nodeColors = (theme: Theme) => ({
  21. error: {
  22. color: theme.white,
  23. background: theme.red300,
  24. border: theme.red300,
  25. },
  26. warning: {
  27. color: theme.red300,
  28. background: theme.background,
  29. border: theme.red300,
  30. },
  31. white: {
  32. color: theme.textColor,
  33. background: theme.background,
  34. border: theme.textColor,
  35. },
  36. black: {
  37. color: theme.background,
  38. background: theme.textColor,
  39. border: theme.textColor,
  40. },
  41. });
  42. export const EventNode = styled(Tag)`
  43. span {
  44. display: flex;
  45. color: ${p => nodeColors(p.theme)[p.type || 'white'].color};
  46. }
  47. & ${Background} {
  48. background-color: ${p => nodeColors(p.theme)[p.type || 'white'].background};
  49. border: 1px solid ${p => nodeColors(p.theme)[p.type || 'white'].border};
  50. }
  51. `;
  52. export const TraceConnector = styled('div')`
  53. width: ${space(1)};
  54. border-top: 1px solid ${p => p.theme.textColor};
  55. `;
  56. /**
  57. * The DropdownLink component is styled directly with less and the way the
  58. * elements are laid out within means we can't apply any styles directly
  59. * using emotion. Instead, we wrap it all inside a span and indirectly
  60. * style it here.
  61. */
  62. export const DropdownContainer = styled('span')`
  63. .dropdown-menu {
  64. padding: 0;
  65. }
  66. `;
  67. export const DropdownMenuHeader = styled(MenuHeader)<{first?: boolean}>`
  68. background: ${p => p.theme.backgroundSecondary};
  69. ${p => p.first && 'border-radius: 2px'};
  70. padding: ${space(1)} ${space(1.5)};
  71. `;
  72. const StyledMenuItem = styled(MenuItem)<{width: 'small' | 'large'}>`
  73. width: ${p => (p.width === 'large' ? '350px' : '200px')};
  74. &:not(:last-child) {
  75. border-bottom: 1px solid ${p => p.theme.innerBorder};
  76. }
  77. `;
  78. const MenuItemContent = styled('div')`
  79. display: flex;
  80. justify-content: space-between;
  81. width: 100%;
  82. `;
  83. type DropdownItemProps = {
  84. children: React.ReactNode;
  85. allowDefaultEvent?: boolean;
  86. onSelect?: (eventKey: any) => void;
  87. to?: string | LocationDescriptor;
  88. width?: 'small' | 'large';
  89. };
  90. export function DropdownItem({
  91. children,
  92. onSelect,
  93. allowDefaultEvent,
  94. to,
  95. width = 'large',
  96. }: DropdownItemProps) {
  97. return (
  98. <StyledMenuItem
  99. data-test-id="dropdown-item"
  100. to={to}
  101. onSelect={onSelect}
  102. width={width}
  103. allowDefaultEvent={allowDefaultEvent}
  104. >
  105. <MenuItemContent>{children}</MenuItemContent>
  106. </StyledMenuItem>
  107. );
  108. }
  109. export const DropdownItemSubContainer = styled('div')`
  110. display: flex;
  111. flex-direction: row;
  112. > a {
  113. padding-left: 0 !important;
  114. }
  115. `;
  116. export const QuickTraceValue = styled(Truncate)`
  117. margin-left: ${space(1)};
  118. white-space: nowrap;
  119. `;
  120. export const ErrorNodeContent = styled('div')`
  121. display: grid;
  122. grid-template-columns: repeat(2, auto);
  123. gap: ${space(0.25)};
  124. align-items: center;
  125. `;
  126. export const ExternalDropdownLink = styled(ExternalLink)`
  127. display: inherit !important;
  128. padding: 0 !important;
  129. color: ${p => p.theme.textColor};
  130. &:hover {
  131. color: ${p => p.theme.textColor};
  132. }
  133. `;
  134. export function SingleEventHoverText({event}: {event: QuickTraceEvent}) {
  135. return (
  136. <div>
  137. <Truncate
  138. value={event.transaction}
  139. maxLength={30}
  140. leftTrim
  141. trimRegex={/\.|\//g}
  142. expandable={false}
  143. />
  144. <div>
  145. {getDuration(
  146. event['transaction.duration'] / 1000,
  147. event['transaction.duration'] < 1000 ? 0 : 2,
  148. true
  149. )}
  150. </div>
  151. </div>
  152. );
  153. }