listContent.tsx 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import {Fragment, useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Button} from 'sentry/components/button';
  4. import ReplayRageClickSdkVersionBanner from 'sentry/components/replays/replayRageClickSdkVersionBanner';
  5. import {t} from 'sentry/locale';
  6. import {space} from 'sentry/styles/space';
  7. import {useHaveSelectedProjectsSentAnyReplayEvents} from 'sentry/utils/replays/hooks/useReplayOnboarding';
  8. import {MIN_DEAD_RAGE_CLICK_SDK} from 'sentry/utils/replays/sdkVersions';
  9. import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams';
  10. import useOrganization from 'sentry/utils/useOrganization';
  11. import usePageFilters from 'sentry/utils/usePageFilters';
  12. import useProjectSdkNeedsUpdate from 'sentry/utils/useProjectSdkNeedsUpdate';
  13. import DeadRageSelectorCards from 'sentry/views/replays/deadRageClick/deadRageSelectorCards';
  14. import ReplaysFilters from 'sentry/views/replays/list/filters';
  15. import ReplayOnboardingPanel from 'sentry/views/replays/list/replayOnboardingPanel';
  16. import ReplaysList from 'sentry/views/replays/list/replaysList';
  17. import ReplaysSearch from 'sentry/views/replays/list/search';
  18. export default function ListContent() {
  19. const organization = useOrganization();
  20. const hasSessionReplay = organization.features.includes('session-replay');
  21. const hasSentReplays = useHaveSelectedProjectsSentAnyReplayEvents();
  22. const {
  23. selection: {projects},
  24. } = usePageFilters();
  25. const rageClicksSdkVersion = useProjectSdkNeedsUpdate({
  26. minVersion: MIN_DEAD_RAGE_CLICK_SDK.minVersion,
  27. organization,
  28. projectId: projects.map(String),
  29. });
  30. const [widgetIsOpen, setWidgetIsOpen] = useState(true);
  31. useRouteAnalyticsParams({
  32. hasSessionReplay,
  33. hasSentReplays: hasSentReplays.hasSentOneReplay,
  34. hasRageClickMinSDK: !rageClicksSdkVersion.needsUpdate,
  35. });
  36. if (hasSentReplays.fetching || rageClicksSdkVersion.isFetching) {
  37. return null;
  38. }
  39. if (!hasSessionReplay || !hasSentReplays.hasSentOneReplay) {
  40. return (
  41. <Fragment>
  42. <FiltersContainer>
  43. <ReplaysFilters />
  44. <ReplaysSearch />
  45. </FiltersContainer>
  46. <ReplayOnboardingPanel />
  47. </Fragment>
  48. );
  49. }
  50. if (rageClicksSdkVersion.needsUpdate) {
  51. return (
  52. <Fragment>
  53. <FiltersContainer>
  54. <ReplaysFilters />
  55. <ReplaysSearch />
  56. </FiltersContainer>
  57. <ReplayRageClickSdkVersionBanner />
  58. <ReplaysList />
  59. </Fragment>
  60. );
  61. }
  62. return (
  63. <Fragment>
  64. <FiltersContainer>
  65. <ReplaysFilters />
  66. <SearchWrapper>
  67. <ReplaysSearch />
  68. <Button onClick={() => setWidgetIsOpen(!widgetIsOpen)}>
  69. {widgetIsOpen ? t('Hide Widgets') : t('Show Widgets')}
  70. </Button>
  71. </SearchWrapper>
  72. </FiltersContainer>
  73. {widgetIsOpen ? <DeadRageSelectorCards /> : null}
  74. <ReplaysList />
  75. </Fragment>
  76. );
  77. }
  78. const FiltersContainer = styled('div')`
  79. display: flex;
  80. flex-direction: row;
  81. gap: ${space(2)};
  82. flex-wrap: wrap;
  83. `;
  84. const SearchWrapper = styled(FiltersContainer)`
  85. flex-grow: 1;
  86. flex-wrap: nowrap;
  87. `;