useGroupEventAttachments.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import type {DateString} from 'sentry/types/core';
  2. import type {Group, IssueAttachment} from 'sentry/types/group';
  3. import {
  4. type ApiQueryKey,
  5. useApiQuery,
  6. type UseApiQueryOptions,
  7. } from 'sentry/utils/queryClient';
  8. import {useLocation} from 'sentry/utils/useLocation';
  9. import useOrganization from 'sentry/utils/useOrganization';
  10. import {useEventQuery} from 'sentry/views/issueDetails/streamline/eventSearch';
  11. import {useIssueDetailsEventView} from 'sentry/views/issueDetails/streamline/hooks/useIssueDetailsDiscoverQuery';
  12. import {useHasStreamlinedUI} from 'sentry/views/issueDetails/utils';
  13. interface UseGroupEventAttachmentsOptions {
  14. activeAttachmentsTab: 'all' | 'onlyCrash' | 'screenshot';
  15. group: Group;
  16. options?: {
  17. /**
  18. * If true, the query will fetch all available attachments for the group, ignoring the
  19. * current filters (for environment, date, query, etc).
  20. */
  21. fetchAllAvailable?: boolean;
  22. placeholderData?: UseApiQueryOptions<IssueAttachment[]>['placeholderData'];
  23. };
  24. }
  25. interface MakeFetchGroupEventAttachmentsQueryKeyOptions
  26. extends UseGroupEventAttachmentsOptions {
  27. cursor: string | undefined;
  28. environment: string[] | string | undefined;
  29. orgSlug: string;
  30. end?: DateString;
  31. eventQuery?: string;
  32. start?: DateString;
  33. statsPeriod?: string;
  34. }
  35. type GroupEventAttachmentsTypeFilter =
  36. | 'event.minidump'
  37. | 'event.applecrashreport'
  38. | 'event.screenshot';
  39. interface GroupEventAttachmentsQuery {
  40. cursor?: string;
  41. end?: DateString;
  42. environment?: string[] | string;
  43. per_page?: string;
  44. query?: string;
  45. screenshot?: '1';
  46. start?: DateString;
  47. statsPeriod?: string;
  48. types?: `${GroupEventAttachmentsTypeFilter}` | `${GroupEventAttachmentsTypeFilter}`[];
  49. }
  50. export const makeFetchGroupEventAttachmentsQueryKey = ({
  51. activeAttachmentsTab,
  52. group,
  53. orgSlug,
  54. cursor,
  55. environment,
  56. eventQuery,
  57. start,
  58. end,
  59. statsPeriod,
  60. }: MakeFetchGroupEventAttachmentsQueryKeyOptions): ApiQueryKey => {
  61. const query: GroupEventAttachmentsQuery = {};
  62. if (environment) {
  63. query.environment = environment;
  64. }
  65. if (eventQuery) {
  66. query.query = eventQuery;
  67. }
  68. if (start) {
  69. query.start = start;
  70. }
  71. if (end) {
  72. query.end = end;
  73. }
  74. if (statsPeriod) {
  75. query.statsPeriod = statsPeriod;
  76. }
  77. if (cursor) {
  78. query.cursor = cursor;
  79. }
  80. if (activeAttachmentsTab === 'screenshot') {
  81. query.screenshot = '1';
  82. } else if (activeAttachmentsTab === 'onlyCrash') {
  83. query.types = ['event.minidump', 'event.applecrashreport'];
  84. }
  85. return [`/organizations/${orgSlug}/issues/${group.id}/attachments/`, {query}];
  86. };
  87. export function useGroupEventAttachments({
  88. group,
  89. activeAttachmentsTab,
  90. options,
  91. }: UseGroupEventAttachmentsOptions) {
  92. const hasStreamlinedUI = useHasStreamlinedUI();
  93. const location = useLocation();
  94. const organization = useOrganization();
  95. const eventQuery = useEventQuery({groupId: group.id});
  96. const eventView = useIssueDetailsEventView({group});
  97. const fetchAllAvailable = hasStreamlinedUI ? options?.fetchAllAvailable : true;
  98. const {
  99. data: attachments = [],
  100. isPending,
  101. isError,
  102. getResponseHeader,
  103. refetch,
  104. } = useApiQuery<IssueAttachment[]>(
  105. makeFetchGroupEventAttachmentsQueryKey({
  106. activeAttachmentsTab,
  107. group,
  108. orgSlug: organization.slug,
  109. cursor: location.query.cursor as string | undefined,
  110. // We only want to filter by date/query/environment if we're using the Streamlined UI
  111. environment: fetchAllAvailable ? undefined : (eventView.environment as string[]),
  112. start: fetchAllAvailable ? undefined : eventView.start,
  113. end: fetchAllAvailable ? undefined : eventView.end,
  114. statsPeriod: fetchAllAvailable ? undefined : eventView.statsPeriod,
  115. eventQuery: fetchAllAvailable ? undefined : eventQuery,
  116. }),
  117. {placeholderData: options?.placeholderData, staleTime: 60_000}
  118. );
  119. return {
  120. attachments,
  121. isPending,
  122. isError,
  123. getResponseHeader,
  124. refetch,
  125. };
  126. }