viewIssueLink.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import styled from '@emotion/styled';
  2. import Button from 'sentry/components/button';
  3. import {Hovercard} from 'sentry/components/hovercard';
  4. import ProjectBadge from 'sentry/components/idBadge/projectBadge';
  5. import ShortId from 'sentry/components/shortId';
  6. import {t} from 'sentry/locale';
  7. import space from 'sentry/styles/space';
  8. import {BreadcrumbTypeDefault, Crumb} from 'sentry/types/breadcrumbs';
  9. import useOrganization from 'sentry/utils/useOrganization';
  10. type Props = {
  11. breadcrumb: Extract<Crumb, BreadcrumbTypeDefault>;
  12. };
  13. function ViewIssueLink({breadcrumb}: Props) {
  14. const organization = useOrganization();
  15. if (breadcrumb.category !== 'exception') {
  16. return null;
  17. }
  18. const {project: projectSlug, groupId, groupShortId, eventId} = breadcrumb.data || {};
  19. if (!groupId || !groupShortId || !eventId) {
  20. return null;
  21. }
  22. const to = {
  23. pathname: `/organizations/${organization.slug}/issues/${groupId}/events/${eventId}/`,
  24. };
  25. return (
  26. <StyledHovercard
  27. body={
  28. <ShortIdBreadrcumb>
  29. <ProjectBadge
  30. project={{slug: projectSlug}}
  31. avatarSize={16}
  32. hideName
  33. avatarProps={{tooltip: projectSlug}}
  34. />
  35. <StyledShortId to={to} shortId={groupShortId} />
  36. </ShortIdBreadrcumb>
  37. }
  38. >
  39. <StyledButton to={to} priority="link">
  40. {t('View Details')}
  41. </StyledButton>
  42. </StyledHovercard>
  43. );
  44. }
  45. const StyledButton = styled(Button)`
  46. height: auto;
  47. min-height: auto;
  48. `;
  49. const ShortIdBreadrcumb = styled('div')`
  50. display: flex;
  51. gap: ${space(1)};
  52. align-items: center;
  53. `;
  54. const StyledShortId = styled(ShortId)`
  55. font-family: ${p => p.theme.text.family};
  56. font-size: ${p => p.theme.fontSizeMedium};
  57. `;
  58. const StyledHovercard = styled(
  59. ({children, bodyClassName, ...props}: React.ComponentProps<typeof Hovercard>) => (
  60. <Hovercard bodyClassName={bodyClassName || '' + ' view-issue-hovercard'} {...props}>
  61. {children}
  62. </Hovercard>
  63. )
  64. )`
  65. width: auto;
  66. .view-issue-hovercard {
  67. padding: ${space(0.75)} ${space(1.5)};
  68. }
  69. `;
  70. export default ViewIssueLink;