headers.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import ToolbarHeader from 'sentry/components/toolbarHeader';
  4. import {t} from 'sentry/locale';
  5. import {space} from 'sentry/styles/space';
  6. import {PageFilters} from 'sentry/types';
  7. type Props = {
  8. isReprocessingQuery: boolean;
  9. onSelectStatsPeriod: (statsPeriod: string) => void;
  10. selection: PageFilters;
  11. statsPeriod: string;
  12. anySelected?: boolean;
  13. isSavedSearchesOpen?: boolean;
  14. };
  15. function Headers({
  16. selection,
  17. statsPeriod,
  18. onSelectStatsPeriod,
  19. isReprocessingQuery,
  20. isSavedSearchesOpen,
  21. }: Props) {
  22. return (
  23. <Fragment>
  24. {isReprocessingQuery ? (
  25. <Fragment>
  26. <StartedColumn>{t('Started')}</StartedColumn>
  27. <EventsReprocessedColumn>{t('Events Reprocessed')}</EventsReprocessedColumn>
  28. <ProgressColumn>{t('Progress')}</ProgressColumn>
  29. </Fragment>
  30. ) : (
  31. <Fragment>
  32. <GraphHeaderWrapper isSavedSearchesOpen={isSavedSearchesOpen}>
  33. <GraphHeader>
  34. <StyledToolbarHeader>{t('Graph:')}</StyledToolbarHeader>
  35. {selection.datetime.period !== '24h' && (
  36. <GraphToggle
  37. active={statsPeriod === '24h'}
  38. onClick={() => onSelectStatsPeriod('24h')}
  39. >
  40. {t('24h')}
  41. </GraphToggle>
  42. )}
  43. <GraphToggle
  44. active={statsPeriod === 'auto'}
  45. onClick={() => onSelectStatsPeriod('auto')}
  46. >
  47. {selection.datetime.period || t('Custom')}
  48. </GraphToggle>
  49. </GraphHeader>
  50. </GraphHeaderWrapper>
  51. <EventsOrUsersLabel>{t('Events')}</EventsOrUsersLabel>
  52. <EventsOrUsersLabel>{t('Users')}</EventsOrUsersLabel>
  53. <AssigneesLabel isSavedSearchesOpen={isSavedSearchesOpen}>
  54. <ToolbarHeader>{t('Assignee')}</ToolbarHeader>
  55. </AssigneesLabel>
  56. </Fragment>
  57. )}
  58. </Fragment>
  59. );
  60. }
  61. export default Headers;
  62. const GraphHeaderWrapper = styled('div')<{isSavedSearchesOpen?: boolean}>`
  63. width: 160px;
  64. margin-left: ${space(2)};
  65. margin-right: ${space(2)};
  66. animation: 0.25s FadeIn linear forwards;
  67. @media (max-width: ${p =>
  68. p.isSavedSearchesOpen ? p.theme.breakpoints.xlarge : p.theme.breakpoints.large}) {
  69. display: none;
  70. }
  71. @keyframes FadeIn {
  72. 0% {
  73. opacity: 0;
  74. }
  75. 100% {
  76. opacity: 1;
  77. }
  78. }
  79. `;
  80. const GraphHeader = styled('div')`
  81. display: flex;
  82. `;
  83. const StyledToolbarHeader = styled(ToolbarHeader)`
  84. flex: 1;
  85. `;
  86. const GraphToggle = styled('a')<{active: boolean}>`
  87. font-size: 13px;
  88. padding-left: ${space(1)};
  89. &,
  90. &:hover,
  91. &:focus,
  92. &:active {
  93. color: ${p => (p.active ? p.theme.textColor : p.theme.disabled)};
  94. }
  95. `;
  96. const EventsOrUsersLabel = styled(ToolbarHeader)`
  97. display: inline-grid;
  98. align-items: center;
  99. justify-content: flex-end;
  100. text-align: right;
  101. width: 60px;
  102. margin: 0 ${space(2)};
  103. @media (min-width: ${p => p.theme.breakpoints.xlarge}) {
  104. width: 80px;
  105. }
  106. `;
  107. const AssigneesLabel = styled('div')<{isSavedSearchesOpen?: boolean}>`
  108. justify-content: flex-end;
  109. text-align: right;
  110. width: 80px;
  111. margin-left: ${space(2)};
  112. margin-right: ${space(2)};
  113. @media (max-width: ${p =>
  114. p.isSavedSearchesOpen ? p.theme.breakpoints.large : p.theme.breakpoints.medium}) {
  115. display: none;
  116. }
  117. `;
  118. // Reprocessing
  119. const StartedColumn = styled(ToolbarHeader)`
  120. margin: 0 ${space(2)};
  121. ${p => p.theme.overflowEllipsis};
  122. width: 85px;
  123. @media (min-width: ${p => p.theme.breakpoints.small}) {
  124. width: 140px;
  125. }
  126. `;
  127. const EventsReprocessedColumn = styled(ToolbarHeader)`
  128. margin: 0 ${space(2)};
  129. ${p => p.theme.overflowEllipsis};
  130. width: 75px;
  131. @media (min-width: ${p => p.theme.breakpoints.small}) {
  132. width: 140px;
  133. }
  134. `;
  135. const ProgressColumn = styled(ToolbarHeader)`
  136. margin: 0 ${space(2)};
  137. display: none;
  138. @media (min-width: ${p => p.theme.breakpoints.small}) {
  139. display: block;
  140. width: 160px;
  141. }
  142. `;