headers.tsx 4.5 KB

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