eventOrGroupTitle.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import * as 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 {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 StacktracePreview from './stacktracePreview';
  10. type Props = Partial<DefaultProps> & {
  11. data: Event | BaseGroup | 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 {hasGuideAnchor, data, organization, withStackTracePreview, guideAnchorName} =
  27. this.props;
  28. const {title, subtitle} = getTitle(data as Event, organization);
  29. const {id, eventID, groupID, projectID} = data as Event;
  30. const titleWithHoverStacktrace = (
  31. <StacktracePreview
  32. organization={organization}
  33. issueId={groupID ? groupID : id}
  34. // we need eventId and projectSlug only when hovering over Event, not Group
  35. // (different API call is made to get the stack trace then)
  36. eventId={eventID}
  37. projectSlug={eventID ? ProjectsStore.getById(projectID)?.slug : undefined}
  38. disablePreview={!withStackTracePreview}
  39. >
  40. {title}
  41. </StacktracePreview>
  42. );
  43. return subtitle ? (
  44. <span style={this.props.style}>
  45. <GuideAnchor
  46. disabled={!hasGuideAnchor}
  47. target={guideAnchorName}
  48. position="bottom"
  49. >
  50. <span>{titleWithHoverStacktrace}</span>
  51. </GuideAnchor>
  52. <Spacer />
  53. <Subtitle title={subtitle}>{subtitle}</Subtitle>
  54. <br />
  55. </span>
  56. ) : (
  57. <span style={this.props.style}>
  58. <GuideAnchor
  59. disabled={!hasGuideAnchor}
  60. target={guideAnchorName}
  61. position="bottom"
  62. >
  63. {titleWithHoverStacktrace}
  64. </GuideAnchor>
  65. </span>
  66. );
  67. }
  68. }
  69. export default withOrganization(EventOrGroupTitle);
  70. /**
  71. * &nbsp; is used instead of margin/padding to split title and subtitle
  72. * into 2 separate text nodes on the HTML AST. This allows the
  73. * title to be highlighted without spilling over to the subtitle.
  74. */
  75. const Spacer = () => <span style={{display: 'inline-block', width: 10}}>&nbsp;</span>;
  76. const Subtitle = styled('em')`
  77. color: ${p => p.theme.gray300};
  78. font-style: normal;
  79. `;