eventOrGroupTitle.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import React 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 {Group, 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 StacktracePreview from './stacktracePreview';
  10. type Props = Partial<DefaultProps> & {
  11. data: Event | Group | GroupTombstone;
  12. organization: Organization;
  13. style?: React.CSSProperties;
  14. hasGuideAnchor?: boolean;
  15. withStackTracePreview?: boolean;
  16. guideAnchorName?: string;
  17. };
  18. type DefaultProps = {
  19. guideAnchorName: string;
  20. };
  21. class EventOrGroupTitle extends React.Component<Props> {
  22. static defaultProps: DefaultProps = {
  23. guideAnchorName: 'issue_title',
  24. };
  25. render() {
  26. const {
  27. hasGuideAnchor,
  28. data,
  29. organization,
  30. withStackTracePreview,
  31. guideAnchorName,
  32. } = this.props;
  33. const {title, subtitle} = getTitle(data as Event, organization);
  34. const {id, eventID, groupID, projectID} = data as Event;
  35. const titleWithHoverStacktrace = (
  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. {title}
  46. </StacktracePreview>
  47. );
  48. return subtitle ? (
  49. <span style={this.props.style}>
  50. <GuideAnchor
  51. disabled={!hasGuideAnchor}
  52. target={guideAnchorName}
  53. position="bottom"
  54. >
  55. <span>{titleWithHoverStacktrace}</span>
  56. </GuideAnchor>
  57. <Spacer />
  58. <Subtitle title={subtitle}>{subtitle}</Subtitle>
  59. <br />
  60. </span>
  61. ) : (
  62. <span style={this.props.style}>
  63. <GuideAnchor
  64. disabled={!hasGuideAnchor}
  65. target={guideAnchorName}
  66. position="bottom"
  67. >
  68. {titleWithHoverStacktrace}
  69. </GuideAnchor>
  70. </span>
  71. );
  72. }
  73. }
  74. export default withOrganization(EventOrGroupTitle);
  75. /**
  76. * &nbsp; is used instead of margin/padding to split title and subtitle
  77. * into 2 separate text nodes on the HTML AST. This allows the
  78. * title to be highlighted without spilling over to the subtitle.
  79. */
  80. const Spacer = () => <span style={{display: 'inline-block', width: 10}}>&nbsp;</span>;
  81. const Subtitle = styled('em')`
  82. color: ${p => p.theme.gray300};
  83. font-style: normal;
  84. `;