import type {DateString} from 'sentry/types/core'; import type {Group, IssueAttachment} from 'sentry/types/group'; import { type ApiQueryKey, useApiQuery, type UseApiQueryOptions, } from 'sentry/utils/queryClient'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; import {useEventQuery} from 'sentry/views/issueDetails/streamline/eventSearch'; import {useIssueDetailsEventView} from 'sentry/views/issueDetails/streamline/hooks/useIssueDetailsDiscoverQuery'; import {useHasStreamlinedUI} from 'sentry/views/issueDetails/utils'; interface UseGroupEventAttachmentsOptions { activeAttachmentsTab: 'all' | 'onlyCrash' | 'screenshot'; group: Group; options?: { /** * If true, the query will fetch all available attachments for the group, ignoring the * current filters (for environment, date, query, etc). */ fetchAllAvailable?: boolean; placeholderData?: UseApiQueryOptions['placeholderData']; }; } interface MakeFetchGroupEventAttachmentsQueryKeyOptions extends UseGroupEventAttachmentsOptions { cursor: string | undefined; environment: string[] | string | undefined; orgSlug: string; end?: DateString; eventQuery?: string; start?: DateString; statsPeriod?: string; } type GroupEventAttachmentsTypeFilter = | 'event.minidump' | 'event.applecrashreport' | 'event.screenshot'; interface GroupEventAttachmentsQuery { cursor?: string; end?: DateString; environment?: string[] | string; per_page?: string; query?: string; screenshot?: '1'; start?: DateString; statsPeriod?: string; types?: | `${GroupEventAttachmentsTypeFilter}` | Array<`${GroupEventAttachmentsTypeFilter}`>; } export const makeFetchGroupEventAttachmentsQueryKey = ({ activeAttachmentsTab, group, orgSlug, cursor, environment, eventQuery, start, end, statsPeriod, }: MakeFetchGroupEventAttachmentsQueryKeyOptions): ApiQueryKey => { const query: GroupEventAttachmentsQuery = {}; if (environment) { query.environment = environment; } if (eventQuery) { query.query = eventQuery; } if (start) { query.start = start; } if (end) { query.end = end; } if (statsPeriod) { query.statsPeriod = statsPeriod; } if (cursor) { query.cursor = cursor; } if (activeAttachmentsTab === 'screenshot') { query.screenshot = '1'; } else if (activeAttachmentsTab === 'onlyCrash') { query.types = ['event.minidump', 'event.applecrashreport']; } return [`/organizations/${orgSlug}/issues/${group.id}/attachments/`, {query}]; }; export function useGroupEventAttachments({ group, activeAttachmentsTab, options, }: UseGroupEventAttachmentsOptions) { const hasStreamlinedUI = useHasStreamlinedUI(); const location = useLocation(); const organization = useOrganization(); const eventQuery = useEventQuery({groupId: group.id}); const eventView = useIssueDetailsEventView({group}); const fetchAllAvailable = hasStreamlinedUI ? options?.fetchAllAvailable : true; const { data: attachments = [], isPending, isError, getResponseHeader, refetch, } = useApiQuery( makeFetchGroupEventAttachmentsQueryKey({ activeAttachmentsTab, group, orgSlug: organization.slug, cursor: location.query.cursor as string | undefined, // We only want to filter by date/query/environment if we're using the Streamlined UI environment: fetchAllAvailable ? undefined : (eventView.environment as string[]), start: fetchAllAvailable ? undefined : eventView.start, end: fetchAllAvailable ? undefined : eventView.end, statsPeriod: fetchAllAvailable ? undefined : eventView.statsPeriod, eventQuery: fetchAllAvailable ? undefined : eventQuery, }), {placeholderData: options?.placeholderData, staleTime: 60_000} ); return { attachments, isPending, isError, getResponseHeader, refetch, }; }