eventOrGroupTitle.tsx 2.8 KB

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