useReplaysFromIssue.tsx 2.5 KB

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