diff --git a/static/app/views/issueDetails/streamline/sidebar/sidebar.tsx b/static/app/views/issueDetails/streamline/sidebar/sidebar.tsx index 9da52c748257fb..c35151a3bdc092 100644 --- a/static/app/views/issueDetails/streamline/sidebar/sidebar.tsx +++ b/static/app/views/issueDetails/streamline/sidebar/sidebar.tsx @@ -30,6 +30,7 @@ import {MergedIssuesSidebarSection} from 'sentry/views/issueDetails/streamline/s import {PeopleSection} from 'sentry/views/issueDetails/streamline/sidebar/peopleSection'; import {SeerSection} from 'sentry/views/issueDetails/streamline/sidebar/seerSection'; import {SimilarIssuesSidebarSection} from 'sentry/views/issueDetails/streamline/sidebar/similarIssuesSidebarSection'; +import {SupergroupSection} from 'sentry/views/issueDetails/streamline/sidebar/supergroupSection'; type Props = {group: Group; project: Project; event?: Event}; @@ -130,6 +131,9 @@ export function StreamlinedSidebar({group, event, project}: Props) { {issueTypeConfig.detector.enabled && ( )} + + + )} diff --git a/static/app/views/issueDetails/streamline/sidebar/supergroupSection.spec.tsx b/static/app/views/issueDetails/streamline/sidebar/supergroupSection.spec.tsx new file mode 100644 index 00000000000000..a5a2838f9e11a2 --- /dev/null +++ b/static/app/views/issueDetails/streamline/sidebar/supergroupSection.spec.tsx @@ -0,0 +1,36 @@ +import {GroupFixture} from 'sentry-fixture/group'; +import {OrganizationFixture} from 'sentry-fixture/organization'; + +import {render, screen} from 'sentry-test/reactTestingLibrary'; + +import {SupergroupSection} from 'sentry/views/issueDetails/streamline/sidebar/supergroupSection'; + +describe('SupergroupSection', () => { + it('renders supergroup info when issue belongs to one', async () => { + const organization = OrganizationFixture({features: ['top-issues-ui']}); + const group = GroupFixture({id: '1'}); + MockApiClient.addMockResponse({ + url: `/organizations/${organization.slug}/seer/supergroups/by-group/`, + body: { + data: [ + { + id: 10, + title: 'Null pointer in auth flow', + error_type: 'TypeError', + code_area: 'auth/login', + summary: '', + group_ids: [1, 2, 3], + created_at: '2024-01-01T00:00:00Z', + updated_at: '2024-01-01T00:00:00Z', + }, + ], + }, + }); + + render(, {organization}); + + expect(await screen.findByText('TypeError')).toBeInTheDocument(); + expect(screen.getByText('Null pointer in auth flow')).toBeInTheDocument(); + expect(screen.getByText('3 issues')).toBeInTheDocument(); + }); +}); diff --git a/static/app/views/issueDetails/streamline/sidebar/supergroupSection.tsx b/static/app/views/issueDetails/streamline/sidebar/supergroupSection.tsx new file mode 100644 index 00000000000000..1701ae8fb67348 --- /dev/null +++ b/static/app/views/issueDetails/streamline/sidebar/supergroupSection.tsx @@ -0,0 +1,110 @@ +import {Fragment} from 'react'; +import styled from '@emotion/styled'; + +import InteractionStateLayer from '@sentry/scraps/interactionStateLayer'; +import {Flex, Stack} from '@sentry/scraps/layout'; +import {Text} from '@sentry/scraps/text'; + +import {useDrawer} from 'sentry/components/globalDrawer'; +import {IconStack} from 'sentry/icons'; +import {t, tn} from 'sentry/locale'; +import type {Group} from 'sentry/types/group'; +import {useOrganization} from 'sentry/utils/useOrganization'; +import {SidebarSectionTitle} from 'sentry/views/issueDetails/streamline/sidebar/sidebar'; +import {SupergroupDetailDrawer} from 'sentry/views/issueList/supergroups/supergroupDrawer'; +import {useSuperGroups} from 'sentry/views/issueList/supergroups/useSuperGroups'; + +interface SupergroupSectionProps { + group: Group; +} + +export function SupergroupSection({group}: SupergroupSectionProps) { + const organization = useOrganization(); + const {openDrawer} = useDrawer(); + const {data: lookup, isLoading} = useSuperGroups([group.id]); + const supergroup = lookup[group.id]; + + if (!organization.features.includes('top-issues-ui')) { + return null; + } + + if (isLoading || !supergroup) { + return null; + } + + const issueCount = supergroup.group_ids.length; + + const handleClick = () => { + openDrawer( + () => ( + + ), + { + ariaLabel: t('Supergroup details'), + drawerKey: 'supergroup-drawer', + } + ); + }; + + return ( +
+ {t('Supergroup')} + + + + + + {supergroup.error_type ? ( + + {supergroup.error_type} + + ) : null} + + {supergroup.title} + + + {supergroup.code_area ? ( + + + {supergroup.code_area} + + + + ) : null} + + {tn('%s issue', '%s issues', issueCount)} + + + + + +
+ ); +} + +const SupergroupCard = styled('button')` + position: relative; + width: 100%; + padding: ${p => p.theme.space.md}; + border: 1px solid ${p => p.theme.tokens.border.primary}; + border-radius: ${p => p.theme.radius.md}; + cursor: pointer; + background: transparent; + text-align: left; + font: inherit; + color: inherit; +`; + +const AccentIcon = styled(IconStack)` + color: ${p => p.theme.tokens.graphics.accent.vibrant}; + flex-shrink: 0; + margin-top: 2px; +`; + +const Dot = styled('div')` + width: 3px; + height: 3px; + border-radius: 50%; + background: currentcolor; + flex-shrink: 0; +`;