eventOrGroupExtraDetails.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import {withRouter, WithRouterProps} from 'react-router';
  2. import styled from '@emotion/styled';
  3. import EventAnnotation from 'sentry/components/events/eventAnnotation';
  4. import GlobalSelectionLink from 'sentry/components/globalSelectionLink';
  5. import InboxReason from 'sentry/components/group/inboxBadges/inboxReason';
  6. import InboxShortId from 'sentry/components/group/inboxBadges/shortId';
  7. import TimesTag from 'sentry/components/group/inboxBadges/timesTag';
  8. import UnhandledTag from 'sentry/components/group/inboxBadges/unhandledTag';
  9. import ProjectBadge from 'sentry/components/idBadge/projectBadge';
  10. import Link from 'sentry/components/links/link';
  11. import Placeholder from 'sentry/components/placeholder';
  12. import {IconChat} from 'sentry/icons';
  13. import {tct} from 'sentry/locale';
  14. import space from 'sentry/styles/space';
  15. import {Group} from 'sentry/types';
  16. import {Event} from 'sentry/types/event';
  17. type Props = WithRouterProps<{orgId: string}> & {
  18. data: Event | Group;
  19. showAssignee?: boolean;
  20. showInboxTime?: boolean;
  21. };
  22. function EventOrGroupExtraDetails({data, showAssignee, params, showInboxTime}: Props) {
  23. const {
  24. id,
  25. lastSeen,
  26. firstSeen,
  27. subscriptionDetails,
  28. numComments,
  29. logger,
  30. assignedTo,
  31. annotations,
  32. shortId,
  33. project,
  34. lifetime,
  35. isUnhandled,
  36. inbox,
  37. } = data as Group;
  38. const issuesPath = `/organizations/${params.orgId}/issues/`;
  39. return (
  40. <GroupExtra>
  41. {inbox && <InboxReason inbox={inbox} showDateAdded={showInboxTime} />}
  42. {shortId && (
  43. <InboxShortId
  44. shortId={shortId}
  45. avatar={
  46. project && (
  47. <ShadowlessProjectBadge project={project} avatarSize={12} hideName />
  48. )
  49. }
  50. />
  51. )}
  52. {isUnhandled && <UnhandledTag />}
  53. {!lifetime && !firstSeen && !lastSeen ? (
  54. <Placeholder height="14px" width="100px" />
  55. ) : (
  56. <TimesTag
  57. lastSeen={lifetime?.lastSeen || lastSeen}
  58. firstSeen={lifetime?.firstSeen || firstSeen}
  59. />
  60. )}
  61. {/* Always display comment count on inbox */}
  62. {numComments > 0 && (
  63. <CommentsLink to={`${issuesPath}${id}/activity/`} className="comments">
  64. <IconChat
  65. size="xs"
  66. color={subscriptionDetails?.reason === 'mentioned' ? 'green300' : undefined}
  67. />
  68. <span>{numComments}</span>
  69. </CommentsLink>
  70. )}
  71. {logger && (
  72. <LoggerAnnotation>
  73. <GlobalSelectionLink
  74. to={{
  75. pathname: issuesPath,
  76. query: {
  77. query: `logger:${logger}`,
  78. },
  79. }}
  80. >
  81. {logger}
  82. </GlobalSelectionLink>
  83. </LoggerAnnotation>
  84. )}
  85. {annotations?.map((annotation, key) => (
  86. <AnnotationNoMargin
  87. dangerouslySetInnerHTML={{
  88. __html: annotation,
  89. }}
  90. key={key}
  91. />
  92. ))}
  93. {showAssignee && assignedTo && (
  94. <div>{tct('Assigned to [name]', {name: assignedTo.name})}</div>
  95. )}
  96. </GroupExtra>
  97. );
  98. }
  99. const GroupExtra = styled('div')`
  100. display: inline-grid;
  101. grid-auto-flow: column dense;
  102. gap: ${space(1.5)};
  103. justify-content: start;
  104. align-items: center;
  105. color: ${p => p.theme.textColor};
  106. font-size: ${p => p.theme.fontSizeSmall};
  107. position: relative;
  108. min-width: 500px;
  109. white-space: nowrap;
  110. line-height: 1.2;
  111. a {
  112. color: inherit;
  113. }
  114. @media (min-width: ${p => p.theme.breakpoints.xlarge}) {
  115. line-height: 1;
  116. }
  117. `;
  118. const ShadowlessProjectBadge = styled(ProjectBadge)`
  119. * > img {
  120. box-shadow: none;
  121. }
  122. `;
  123. const CommentsLink = styled(Link)`
  124. display: inline-grid;
  125. gap: ${space(0.5)};
  126. align-items: center;
  127. grid-auto-flow: column;
  128. color: ${p => p.theme.textColor};
  129. `;
  130. const AnnotationNoMargin = styled(EventAnnotation)`
  131. margin-left: 0;
  132. padding-left: 0;
  133. border-left: none;
  134. & > a {
  135. color: ${p => p.theme.textColor};
  136. }
  137. `;
  138. const LoggerAnnotation = styled(AnnotationNoMargin)`
  139. color: ${p => p.theme.textColor};
  140. `;
  141. export default withRouter(EventOrGroupExtraDetails);