seenInfo.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import {Fragment} from 'react';
  2. import {css} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import DateTime from 'sentry/components/dateTime';
  5. import {Body, Header, Hovercard} from 'sentry/components/hovercard';
  6. import TimeSince from 'sentry/components/timeSince';
  7. import Version from 'sentry/components/version';
  8. import VersionHoverCard from 'sentry/components/versionHoverCard';
  9. import {t} from 'sentry/locale';
  10. import space from 'sentry/styles/space';
  11. import {Organization, Release} from 'sentry/types';
  12. import {defined, toTitleCase} from 'sentry/utils';
  13. type RelaxedDateType = React.ComponentProps<typeof TimeSince>['date'];
  14. type Props = {
  15. date: RelaxedDateType;
  16. dateGlobal: RelaxedDateType;
  17. hasRelease: boolean;
  18. organization: Organization;
  19. projectId: string;
  20. projectSlug: string;
  21. title: string;
  22. environment?: string;
  23. release?: Release;
  24. };
  25. function SeenInfo({
  26. date,
  27. dateGlobal,
  28. environment,
  29. release,
  30. organization,
  31. projectSlug,
  32. projectId,
  33. }: Props) {
  34. return (
  35. <HovercardWrapper>
  36. <StyledHovercard
  37. showUnderline
  38. header={
  39. <div>
  40. <TimeSinceWrapper>
  41. {t('Any Environment')}
  42. <TimeSince date={dateGlobal} disabledAbsoluteTooltip />
  43. </TimeSinceWrapper>
  44. {environment && (
  45. <TimeSinceWrapper>
  46. {toTitleCase(environment)}
  47. {date ? (
  48. <TimeSince date={date} disabledAbsoluteTooltip />
  49. ) : (
  50. <span>{t('N/A')}</span>
  51. )}
  52. </TimeSinceWrapper>
  53. )}
  54. </div>
  55. }
  56. body={
  57. date ? (
  58. <StyledDateTime date={date} />
  59. ) : (
  60. <NoEnvironment>{t('N/A for %s', environment)}</NoEnvironment>
  61. )
  62. }
  63. position="top"
  64. >
  65. <DateWrapper>
  66. {date ? (
  67. <TooltipWrapper>
  68. <StyledTimeSince date={date} disabledAbsoluteTooltip />
  69. </TooltipWrapper>
  70. ) : dateGlobal && environment === '' ? (
  71. <Fragment>
  72. <TimeSince date={dateGlobal} disabledAbsoluteTooltip />
  73. <StyledTimeSince date={dateGlobal} disabledAbsoluteTooltip />
  74. </Fragment>
  75. ) : (
  76. <NoDateTime>{t('N/A')}</NoDateTime>
  77. )}
  78. </DateWrapper>
  79. </StyledHovercard>
  80. <DateWrapper>
  81. {defined(release) && (
  82. <Fragment>
  83. {t('in release ')}
  84. <VersionHoverCard
  85. organization={organization}
  86. projectSlug={projectSlug}
  87. releaseVersion={release.version}
  88. >
  89. <span>
  90. <Version version={release.version} projectId={projectId} />
  91. </span>
  92. </VersionHoverCard>
  93. </Fragment>
  94. )}
  95. </DateWrapper>
  96. </HovercardWrapper>
  97. );
  98. }
  99. const dateTimeCss = p => css`
  100. color: ${p.theme.gray300};
  101. font-size: ${p.theme.fontSizeMedium};
  102. display: flex;
  103. justify-content: center;
  104. `;
  105. const HovercardWrapper = styled('div')`
  106. display: flex;
  107. align-items: baseline;
  108. `;
  109. const DateWrapper = styled('div')`
  110. margin-bottom: 0;
  111. ${p => p.theme.overflowEllipsis};
  112. `;
  113. const StyledDateTime = styled(DateTime)`
  114. ${dateTimeCss};
  115. `;
  116. const NoEnvironment = styled('div')`
  117. ${dateTimeCss};
  118. `;
  119. const NoDateTime = styled('span')`
  120. margin-right: ${space(0.5)};
  121. `;
  122. const TooltipWrapper = styled('span')`
  123. margin-right: ${space(0.25)};
  124. svg {
  125. margin-right: ${space(0.5)};
  126. position: relative;
  127. top: 1px;
  128. }
  129. `;
  130. const TimeSinceWrapper = styled('div')`
  131. margin-bottom: ${space(0.5)};
  132. display: flex;
  133. justify-content: space-between;
  134. `;
  135. const StyledTimeSince = styled(TimeSince)`
  136. font-size: ${p => p.theme.fontSizeMedium};
  137. line-height: 1.2;
  138. `;
  139. const StyledHovercard = styled(Hovercard)`
  140. width: 250px;
  141. ${Header} {
  142. font-weight: normal;
  143. border-bottom: 1px solid ${p => p.theme.innerBorder};
  144. }
  145. ${Body} {
  146. padding: ${space(1.5)};
  147. }
  148. `;
  149. export default SeenInfo;