groupReplays.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {useEffect, useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Location} from 'history';
  4. import * as Layout from 'sentry/components/layouts/thirds';
  5. import type {Group, Organization} from 'sentry/types';
  6. import {trackAnalytics} from 'sentry/utils/analytics';
  7. import EventView from 'sentry/utils/discover/eventView';
  8. import useReplayList from 'sentry/utils/replays/hooks/useReplayList';
  9. import {useLocation} from 'sentry/utils/useLocation';
  10. import useOrganization from 'sentry/utils/useOrganization';
  11. import useReplaysFromIssue from 'sentry/views/issueDetails/groupReplays/useReplaysFromIssue';
  12. import ReplayTable from 'sentry/views/replays/replayTable';
  13. import {ReplayColumn} from 'sentry/views/replays/replayTable/types';
  14. import type {ReplayListLocationQuery} from 'sentry/views/replays/types';
  15. type Props = {
  16. group: Group;
  17. };
  18. const VISIBLE_COLUMNS = [
  19. ReplayColumn.REPLAY,
  20. ReplayColumn.OS,
  21. ReplayColumn.BROWSER,
  22. ReplayColumn.DURATION,
  23. ReplayColumn.COUNT_ERRORS,
  24. ReplayColumn.ACTIVITY,
  25. ];
  26. function GroupReplays({group}: Props) {
  27. const organization = useOrganization();
  28. const location = useLocation<ReplayListLocationQuery>();
  29. const {eventView, fetchError, pageLinks} = useReplaysFromIssue({
  30. group,
  31. location,
  32. organization,
  33. });
  34. useEffect(() => {
  35. trackAnalytics('replay.render-issues-group-list', {
  36. project_id: group.project.id,
  37. platform: group.project.platform,
  38. organization,
  39. });
  40. // we only want to fire this event once
  41. // eslint-disable-next-line react-hooks/exhaustive-deps
  42. }, []);
  43. if (!eventView) {
  44. return (
  45. <StyledLayoutPage withPadding>
  46. <ReplayTable
  47. fetchError={fetchError}
  48. isFetching
  49. replays={[]}
  50. sort={undefined}
  51. visibleColumns={VISIBLE_COLUMNS}
  52. showDropdownFilters={false}
  53. />
  54. </StyledLayoutPage>
  55. );
  56. }
  57. return (
  58. <GroupReplaysTable
  59. eventView={eventView}
  60. organization={organization}
  61. pageLinks={pageLinks}
  62. visibleColumns={VISIBLE_COLUMNS}
  63. />
  64. );
  65. }
  66. function GroupReplaysTable({
  67. eventView,
  68. organization,
  69. visibleColumns,
  70. }: {
  71. eventView: EventView;
  72. organization: Organization;
  73. pageLinks: string | null;
  74. visibleColumns: ReplayColumn[];
  75. }) {
  76. const location = useMemo(() => ({query: {}}) as Location<ReplayListLocationQuery>, []);
  77. const {replays, isFetching, fetchError} = useReplayList({
  78. eventView,
  79. location,
  80. organization,
  81. queryReferrer: 'issueReplays',
  82. });
  83. return (
  84. <StyledLayoutPage withPadding>
  85. <ReplayTable
  86. fetchError={fetchError}
  87. isFetching={isFetching}
  88. replays={replays}
  89. sort={undefined}
  90. visibleColumns={visibleColumns}
  91. showDropdownFilters={false}
  92. />
  93. </StyledLayoutPage>
  94. );
  95. }
  96. const StyledLayoutPage = styled(Layout.Page)`
  97. box-shadow: 0px 0px 1px ${p => p.theme.gray200};
  98. background-color: ${p => p.theme.background};
  99. `;
  100. export default GroupReplays;