solutionsSection.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import {useRef} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Button} from 'sentry/components/button';
  4. import useDrawer from 'sentry/components/globalDrawer';
  5. import {useGroupSummary} from 'sentry/components/group/groupSummary';
  6. import Placeholder from 'sentry/components/placeholder';
  7. import {t} from 'sentry/locale';
  8. import {space} from 'sentry/styles/space';
  9. import type {Event} from 'sentry/types/event';
  10. import type {Group} from 'sentry/types/group';
  11. import {IssueCategory} from 'sentry/types/group';
  12. import type {Project} from 'sentry/types/project';
  13. import {SidebarSectionTitle} from 'sentry/views/issueDetails/streamline/sidebar';
  14. import {SolutionsDrawer} from 'sentry/views/issueDetails/streamline/solutionsDrawer';
  15. const isSummaryEnabled = (hasGenAIConsent: boolean, groupCategory: IssueCategory) => {
  16. return hasGenAIConsent && groupCategory === IssueCategory.ERROR;
  17. };
  18. export default function SolutionsSection({
  19. group,
  20. project,
  21. event,
  22. }: {
  23. event: Event | undefined;
  24. group: Group;
  25. project: Project;
  26. }) {
  27. const {openDrawer} = useDrawer();
  28. const openButtonRef = useRef<HTMLButtonElement>(null);
  29. const openSolutionsDrawer = () => {
  30. openDrawer(() => <SolutionsDrawer group={group} project={project} event={event} />, {
  31. ariaLabel: t('Solutions drawer'),
  32. // We prevent a click on the Open/Close Autofix button from closing the drawer so that
  33. // we don't reopen it immediately, and instead let the button handle this itself.
  34. shouldCloseOnInteractOutside: element => {
  35. const viewAllButton = openButtonRef.current;
  36. if (
  37. viewAllButton?.contains(element) ||
  38. document.getElementById('sentry-feedback')?.contains(element)
  39. ) {
  40. return false;
  41. }
  42. return true;
  43. },
  44. transitionProps: {stiffness: 1000},
  45. });
  46. };
  47. const {data, isPending, hasGenAIConsent} = useGroupSummary(
  48. group.id,
  49. group.issueCategory
  50. );
  51. return (
  52. <div>
  53. <SidebarSectionTitle style={{marginTop: 0}}>
  54. {t('Solutions & Resources')}
  55. </SidebarSectionTitle>
  56. {isPending && isSummaryEnabled(hasGenAIConsent, group.issueCategory) && (
  57. <Placeholder height="19px" width="95%" style={{marginBottom: space(1)}} />
  58. )}
  59. {isSummaryEnabled(hasGenAIConsent, group.issueCategory) && data && (
  60. <Summary>{data.headline}</Summary>
  61. )}
  62. <StyledButton ref={openButtonRef} onClick={() => openSolutionsDrawer()}>
  63. {t('See More')}
  64. </StyledButton>
  65. </div>
  66. );
  67. }
  68. const Summary = styled('div')`
  69. margin-bottom: ${space(1)};
  70. `;
  71. const StyledButton = styled(Button)`
  72. width: 100%;
  73. `;