eventOrGroupTitle.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {BaseGroup, GroupTombstoneHelper, Organization} from 'sentry/types';
  4. import {Event} from 'sentry/types/event';
  5. import {getTitle, isTombstone} from 'sentry/utils/events';
  6. import withOrganization from 'sentry/utils/withOrganization';
  7. import EventTitleTreeLabel from './eventTitleTreeLabel';
  8. import GroupPreviewTooltip from './groupPreviewTooltip';
  9. interface EventOrGroupTitleProps {
  10. data: Event | BaseGroup | GroupTombstoneHelper;
  11. organization: Organization;
  12. className?: string;
  13. /* is issue breakdown? */
  14. grouping?: boolean;
  15. withStackTracePreview?: boolean;
  16. }
  17. function EventOrGroupTitle({
  18. organization,
  19. data,
  20. withStackTracePreview,
  21. grouping = false,
  22. className,
  23. }: EventOrGroupTitleProps) {
  24. const {id, eventID, groupID, projectID} = data as Event;
  25. const {title, subtitle, treeLabel} = getTitle(data, organization?.features, grouping);
  26. const titleLabel = treeLabel ? (
  27. <EventTitleTreeLabel treeLabel={treeLabel} />
  28. ) : (
  29. title ?? ''
  30. );
  31. return (
  32. <Wrapper className={className}>
  33. {!isTombstone(data) && withStackTracePreview ? (
  34. <GroupPreviewTooltip
  35. groupId={groupID ? groupID : id}
  36. issueCategory={data.issueCategory}
  37. groupingCurrentLevel={data.metadata?.current_level}
  38. eventId={eventID}
  39. projectId={projectID}
  40. >
  41. {titleLabel}
  42. </GroupPreviewTooltip>
  43. ) : (
  44. titleLabel
  45. )}
  46. {subtitle && (
  47. <Fragment>
  48. <Spacer />
  49. <Subtitle title={subtitle}>{subtitle}</Subtitle>
  50. <br />
  51. </Fragment>
  52. )}
  53. </Wrapper>
  54. );
  55. }
  56. export default withOrganization(EventOrGroupTitle);
  57. /**
  58. * &nbsp; is used instead of margin/padding to split title and subtitle
  59. * into 2 separate text nodes on the HTML AST. This allows the
  60. * title to be highlighted without spilling over to the subtitle.
  61. */
  62. function Spacer() {
  63. return <span style={{display: 'inline-block', width: 10}}>&nbsp;</span>;
  64. }
  65. const Subtitle = styled('em')`
  66. ${p => p.theme.overflowEllipsis};
  67. display: inline-block;
  68. color: ${p => p.theme.gray300};
  69. font-style: normal;
  70. height: 100%;
  71. `;
  72. const Wrapper = styled('span')`
  73. font-size: ${p => p.theme.fontSizeLarge};
  74. display: inline-grid;
  75. grid-template-columns: auto max-content 1fr max-content;
  76. align-items: baseline;
  77. `;