eventOrGroupTitle.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import GuideAnchor from 'app/components/assistant/guideAnchor';
  4. import ProjectsStore from 'app/stores/projectsStore';
  5. import {BaseGroup, GroupTombstone, Organization} from 'app/types';
  6. import {Event} from 'app/types/event';
  7. import {getTitle} from 'app/utils/events';
  8. import withOrganization from 'app/utils/withOrganization';
  9. import EventTitleTreeLabel from './eventTitleTreeLabel';
  10. import StacktracePreview from './stacktracePreview';
  11. type Props = Partial<DefaultProps> & {
  12. data: Event | BaseGroup | GroupTombstone;
  13. organization: Organization;
  14. style?: React.CSSProperties;
  15. hasGuideAnchor?: boolean;
  16. withStackTracePreview?: boolean;
  17. guideAnchorName?: string;
  18. };
  19. type DefaultProps = {
  20. guideAnchorName: string;
  21. };
  22. function EventOrGroupTitle({
  23. guideAnchorName = 'issue_title',
  24. organization,
  25. data,
  26. withStackTracePreview,
  27. hasGuideAnchor,
  28. style,
  29. }: Props) {
  30. const event = data as Event;
  31. const {id, eventID, groupID, projectID} = event;
  32. const {title, subtitle, treeLabel} = getTitle(event, organization?.features);
  33. return (
  34. <span style={style}>
  35. <GuideAnchor disabled={!hasGuideAnchor} target={guideAnchorName} position="bottom">
  36. <StacktracePreview
  37. organization={organization}
  38. issueId={groupID ? groupID : id}
  39. // we need eventId and projectSlug only when hovering over Event, not Group
  40. // (different API call is made to get the stack trace then)
  41. eventId={eventID}
  42. projectSlug={eventID ? ProjectsStore.getById(projectID)?.slug : undefined}
  43. disablePreview={!withStackTracePreview}
  44. >
  45. {treeLabel ? <EventTitleTreeLabel treeLabel={treeLabel} /> : title}
  46. </StacktracePreview>
  47. </GuideAnchor>
  48. {subtitle && (
  49. <Fragment>
  50. <Spacer />
  51. <Subtitle title={subtitle}>{subtitle}</Subtitle>
  52. <br />
  53. </Fragment>
  54. )}
  55. </span>
  56. );
  57. }
  58. export default withOrganization(EventOrGroupTitle);
  59. /**
  60. * &nbsp; is used instead of margin/padding to split title and subtitle
  61. * into 2 separate text nodes on the HTML AST. This allows the
  62. * title to be highlighted without spilling over to the subtitle.
  63. */
  64. const Spacer = () => <span style={{display: 'inline-block', width: 10}}>&nbsp;</span>;
  65. const Subtitle = styled('em')`
  66. color: ${p => p.theme.gray300};
  67. font-style: normal;
  68. `;