diff --git a/static/app/components/events/groupingInfo/groupingInfo.tsx b/static/app/components/events/groupingInfo/groupingInfo.tsx index ddf07bd67752d0..cc47a1d51b872d 100644 --- a/static/app/components/events/groupingInfo/groupingInfo.tsx +++ b/static/app/components/events/groupingInfo/groupingInfo.tsx @@ -39,8 +39,8 @@ export default function GroupingInfo({ projectSlug, }); - const variants = groupInfo - ? Object.values(groupInfo).sort((a, b) => { + const variants = groupInfo?.variants + ? Object.values(groupInfo.variants).sort((a, b) => { // Sort contributing variants before non-contributing ones if (a.contributes && !b.contributes) { return -1; diff --git a/static/app/components/events/groupingInfo/groupingInfoSection.spec.tsx b/static/app/components/events/groupingInfo/groupingInfoSection.spec.tsx index 0c5a5c5ed90bd1..7f24fd75c6d2b8 100644 --- a/static/app/components/events/groupingInfo/groupingInfoSection.spec.tsx +++ b/static/app/components/events/groupingInfo/groupingInfoSection.spec.tsx @@ -67,4 +67,59 @@ describe('EventGroupingInfo', () => { // Should not make grouping-info request expect(groupingInfoRequest).not.toHaveBeenCalled(); }); + + it('works with new groupingInfo format', async () => { + groupingInfoRequest = MockApiClient.addMockResponse({ + url: `/projects/org-slug/project-slug/events/${event.id}/grouping-info/`, + body: { + grouping_config: 'default:XXXX', + variants: { + app: { + contributes: true, + description: 'variant description', + hash: '123', + hashMismatch: false, + key: 'key', + type: EventGroupVariantType.CHECKSUM, + }, + }, + }, + }); + render(); + + expect(await screen.findByText('variant description')).toBeInTheDocument(); + expect(screen.getByText('123')).toBeInTheDocument(); + }); + it('gets performance new grouping info from group/event data', async () => { + groupingInfoRequest = MockApiClient.addMockResponse({ + url: `/projects/org-slug/project-slug/events/${event.id}/grouping-info/`, + body: { + grouping_config: null, + variants: { + app: { + contributes: true, + description: 'variant description', + hash: '123', + hashMismatch: false, + key: 'key', + type: EventGroupVariantType.CHECKSUM, + }, + }, + }, + }); + const perfEvent = EventFixture({ + type: 'transaction', + occurrence: {fingerprint: ['123'], evidenceData: {op: 'bad-op'}}, + }); + const perfGroup = GroupFixture({issueCategory: IssueCategory.PERFORMANCE}); + + render( + + ); + + expect(await screen.findByText('performance problem')).toBeInTheDocument(); + expect(screen.getByText('123')).toBeInTheDocument(); + // Should not make grouping-info request + expect(groupingInfoRequest).not.toHaveBeenCalled(); + }); }); diff --git a/static/app/components/events/groupingInfo/groupingSummary.tsx b/static/app/components/events/groupingInfo/groupingSummary.tsx index a139f192f5767a..3e63cf01c400ba 100644 --- a/static/app/components/events/groupingInfo/groupingSummary.tsx +++ b/static/app/components/events/groupingInfo/groupingSummary.tsx @@ -22,22 +22,15 @@ export function GroupInfoSummary({ group, projectSlug, }); - const groupedBy = groupInfo - ? Object.values(groupInfo) + const groupedBy = groupInfo?.variants + ? Object.values(groupInfo.variants) .filter(variant => variant.contributes && variant.description !== null) .map(variant => variant.description!) .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())) .join(', ') : t('nothing'); - const groupingConfig = - showGroupingConfig && groupInfo - ? ( - Object.values(groupInfo).find( - variant => 'config' in variant && variant.config?.id - ) as any - )?.config?.id - : null; + const groupingConfig = showGroupingConfig && groupInfo?.grouping_config; if (isPending && !hasPerformanceGrouping) { return ( diff --git a/static/app/components/events/groupingInfo/useEventGroupingInfo.tsx b/static/app/components/events/groupingInfo/useEventGroupingInfo.tsx index bfa8aca59befdd..c7daffa6360cf4 100644 --- a/static/app/components/events/groupingInfo/useEventGroupingInfo.tsx +++ b/static/app/components/events/groupingInfo/useEventGroupingInfo.tsx @@ -8,7 +8,37 @@ import type {Group} from 'sentry/types/group'; import {useApiQuery} from 'sentry/utils/queryClient'; import useOrganization from 'sentry/utils/useOrganization'; -type EventGroupingInfoResponse = Record; +type EventGroupingInfoResponseOld = Record; +type EventGroupingInfoResponse = { + grouping_config: string | null; + variants: Record; +}; + +// temporary function to convert the old response structure to the new one +function eventGroupingInfoResponseOldToNew( + old: EventGroupingInfoResponseOld | null +): EventGroupingInfoResponse | null { + const grouping_config = old + ? ( + Object.values(old).find( + variant => 'config' in variant && variant.config?.id + ) as any + )?.config?.id + : null; + return old + ? { + grouping_config, + variants: old, + } + : null; +} + +// temporary function to check if the respinse is old type +function isOld( + data: EventGroupingInfoResponseOld | EventGroupingInfoResponse | null +): data is EventGroupingInfoResponseOld { + return data ? !('grouping_config' in data) : false; +} function generatePerformanceGroupInfo({ event, @@ -27,21 +57,24 @@ function generatePerformanceGroupInfo({ return group ? { - [group.issueType]: { - contributes: true, - description: t('performance problem'), - hash: event.occurrence?.fingerprint[0] || '', - hashMismatch: false, - hint: null, - key: group.issueType, - type: EventGroupVariantType.PERFORMANCE_PROBLEM, - evidence: { - op: evidenceData?.op, - parent_span_ids: evidenceData?.parentSpanIds, - cause_span_ids: evidenceData?.causeSpanIds, - offender_span_ids: evidenceData?.offenderSpanIds, - desc: t('performance problem'), - fingerprint: hash, + grouping_config: null, + variants: { + [group.issueType]: { + contributes: true, + description: t('performance problem'), + hash: event.occurrence?.fingerprint[0] || '', + hashMismatch: false, + hint: null, + key: group.issueType, + type: EventGroupVariantType.PERFORMANCE_PROBLEM, + evidence: { + op: evidenceData?.op, + parent_span_ids: evidenceData?.parentSpanIds, + cause_span_ids: evidenceData?.causeSpanIds, + offender_span_ids: evidenceData?.offenderSpanIds, + desc: t('performance problem'), + fingerprint: hash, + }, }, }, } @@ -61,14 +94,26 @@ export function useEventGroupingInfo({ const hasPerformanceGrouping = event.occurrence && event.type === 'transaction'; - const {data, isPending, isError, isSuccess} = useApiQuery( - [`/projects/${organization.slug}/${projectSlug}/events/${event.id}/grouping-info/`], - {enabled: !hasPerformanceGrouping, staleTime: Infinity} - ); + const {data, isPending, isError, isSuccess} = useApiQuery< + EventGroupingInfoResponseOld | EventGroupingInfoResponse + >([`/projects/${organization.slug}/${projectSlug}/events/${event.id}/grouping-info/`], { + enabled: !hasPerformanceGrouping, + staleTime: Infinity, + }); - const groupInfo = hasPerformanceGrouping + const groupInfoRaw = hasPerformanceGrouping ? generatePerformanceGroupInfo({group, event}) : (data ?? null); - return {groupInfo, isPending, isError, isSuccess, hasPerformanceGrouping}; + const groupInfo = isOld(groupInfoRaw) + ? eventGroupingInfoResponseOldToNew(groupInfoRaw) + : groupInfoRaw; + + return { + groupInfo, + isPending, + isError, + isSuccess, + hasPerformanceGrouping, + }; }