useReplaysFromIssue.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import {useCallback, useEffect, useMemo, useState} from 'react';
  2. import * as Sentry from '@sentry/react';
  3. import type {Location} from 'history';
  4. import {ALL_ACCESS_PROJECTS} from 'sentry/constants/pageFilters';
  5. import {type Group, IssueCategory} from 'sentry/types/group';
  6. import type {Organization} from 'sentry/types/organization';
  7. import EventView from 'sentry/utils/discover/eventView';
  8. import {decodeScalar} from 'sentry/utils/queryString';
  9. import {DEFAULT_SORT} from 'sentry/utils/replays/fetchReplayList';
  10. import useApi from 'sentry/utils/useApi';
  11. import useCleanQueryParamsOnRouteLeave from 'sentry/utils/useCleanQueryParamsOnRouteLeave';
  12. import {REPLAY_LIST_FIELDS} from 'sentry/views/replays/types';
  13. export default function useReplaysFromIssue({
  14. group,
  15. location,
  16. organization,
  17. }: {
  18. group: Group;
  19. location: Location;
  20. organization: Organization;
  21. }) {
  22. const api = useApi();
  23. const [replayIds, setReplayIds] = useState<string[]>();
  24. const [fetchError, setFetchError] = useState();
  25. // use Discover for errors and Issue Platform for everything else
  26. const dataSource =
  27. group.issueCategory === IssueCategory.ERROR ? 'discover' : 'search_issues';
  28. const fetchReplayIds = useCallback(async () => {
  29. try {
  30. const response = await api.requestPromise(
  31. `/organizations/${organization.slug}/replay-count/`,
  32. {
  33. query: {
  34. returnIds: true,
  35. query: `issue.id:[${group.id}]`,
  36. data_source: dataSource,
  37. statsPeriod: '90d',
  38. environment: location.query.environment,
  39. project: ALL_ACCESS_PROJECTS,
  40. },
  41. }
  42. );
  43. setReplayIds(response[group.id] || []);
  44. } catch (error) {
  45. Sentry.captureException(error);
  46. setFetchError(error);
  47. }
  48. }, [api, organization.slug, group.id, dataSource, location.query.environment]);
  49. const eventView = useMemo(() => {
  50. if (!replayIds || !replayIds.length) {
  51. return null;
  52. }
  53. return EventView.fromSavedQuery({
  54. id: '',
  55. name: '',
  56. version: 2,
  57. fields: REPLAY_LIST_FIELDS,
  58. query: replayIds.length ? `id:[${String(replayIds)}]` : `id:1`,
  59. range: '90d',
  60. projects: [],
  61. orderby: decodeScalar(location.query.sort, DEFAULT_SORT),
  62. });
  63. }, [location.query.sort, replayIds]);
  64. useCleanQueryParamsOnRouteLeave({
  65. fieldsToClean: ['cursor'],
  66. shouldClean: newLocation => newLocation.pathname.includes(`/issues/${group.id}/`),
  67. });
  68. useEffect(() => {
  69. fetchReplayIds();
  70. }, [fetchReplayIds]);
  71. return {
  72. eventView,
  73. fetchError,
  74. isFetching: replayIds === undefined,
  75. pageLinks: null,
  76. };
  77. }