useReplaysFromIssue.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import {useCallback, useEffect, useMemo, useState} from 'react';
  2. import * as Sentry from '@sentry/react';
  3. import {Location} from 'history';
  4. import type {Group, Organization} from 'sentry/types';
  5. import {TableData} from 'sentry/utils/discover/discoverQuery';
  6. import EventView from 'sentry/utils/discover/eventView';
  7. import {doDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
  8. import {decodeScalar} from 'sentry/utils/queryString';
  9. import {DEFAULT_SORT, REPLAY_LIST_FIELDS} from 'sentry/utils/replays/fetchReplayList';
  10. import useApi from 'sentry/utils/useApi';
  11. import useCleanQueryParamsOnRouteLeave from 'sentry/utils/useCleanQueryParamsOnRouteLeave';
  12. import type {ReplayListLocationQuery} from 'sentry/views/replays/types';
  13. function useReplayFromIssue({
  14. group,
  15. location,
  16. organization,
  17. }: {
  18. group: Group;
  19. location: Location;
  20. organization: Organization;
  21. }) {
  22. const api = useApi();
  23. const [response, setResponse] = useState<{
  24. pageLinks: null | string;
  25. replayIds: undefined | string[];
  26. }>({pageLinks: null, replayIds: undefined});
  27. const [fetchError, setFetchError] = useState();
  28. const {cursor} = location.query;
  29. const fetchReplayIds = useCallback(async () => {
  30. const eventView = EventView.fromSavedQuery({
  31. id: '',
  32. name: `Errors within replay`,
  33. version: 2,
  34. fields: ['replayId', 'count()'],
  35. query: `issue.id:${group.id} !replayId:""`,
  36. projects: [Number(group.project.id)],
  37. });
  38. try {
  39. const [{data}, _textStatus, resp] = await doDiscoverQuery<TableData>(
  40. api,
  41. `/organizations/${organization.slug}/events/`,
  42. eventView.getEventsAPIPayload({
  43. query: {cursor},
  44. } as Location<ReplayListLocationQuery>)
  45. );
  46. setResponse({
  47. pageLinks: resp?.getResponseHeader('Link') ?? '',
  48. replayIds: data.map(record => String(record.replayId)),
  49. });
  50. } catch (err) {
  51. Sentry.captureException(err);
  52. setFetchError(err);
  53. }
  54. }, [api, cursor, organization.slug, group.id, group.project.id]);
  55. const eventView = useMemo(() => {
  56. if (!response.replayIds) {
  57. return null;
  58. }
  59. return EventView.fromSavedQuery({
  60. id: '',
  61. name: '',
  62. version: 2,
  63. fields: REPLAY_LIST_FIELDS,
  64. projects: [Number(group.project.id)],
  65. query: `id:[${String(response.replayIds)}]`,
  66. orderby: decodeScalar(location.query.sort, DEFAULT_SORT),
  67. });
  68. }, [location.query.sort, group.project.id, response.replayIds]);
  69. useCleanQueryParamsOnRouteLeave({fieldsToClean: ['cursor']});
  70. useEffect(() => {
  71. fetchReplayIds();
  72. }, [fetchReplayIds]);
  73. return {
  74. eventView,
  75. fetchError,
  76. pageLinks: response.pageLinks,
  77. };
  78. }
  79. export default useReplayFromIssue;