deadRageClickList.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {browserHistory} from 'react-router';
  2. import styled from '@emotion/styled';
  3. import Alert from 'sentry/components/alert';
  4. import FeatureBadge from 'sentry/components/featureBadge';
  5. import * as Layout from 'sentry/components/layouts/thirds';
  6. import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
  7. import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
  8. import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
  9. import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
  10. import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter';
  11. import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionTooltip';
  12. import Pagination from 'sentry/components/pagination';
  13. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  14. import {t} from 'sentry/locale';
  15. import {space} from 'sentry/styles/space';
  16. import useDeadRageSelectors from 'sentry/utils/replays/hooks/useDeadRageSelectors';
  17. import {useLocation} from 'sentry/utils/useLocation';
  18. import useOrganization from 'sentry/utils/useOrganization';
  19. import SelectorTable from 'sentry/views/replays/deadRageClick/selectorTable';
  20. import ReplayTabs from 'sentry/views/replays/tabs';
  21. export default function DeadRageClickList() {
  22. const organization = useOrganization();
  23. const location = useLocation();
  24. const hasDeadClickFeature = organization.features.includes(
  25. 'session-replay-rage-dead-selectors'
  26. );
  27. const {isLoading, isError, data, pageLinks} = useDeadRageSelectors({
  28. per_page: 50,
  29. sort: '-count_dead_clicks',
  30. cursor: location.query.cursor,
  31. prefix: '',
  32. isWidgetData: false,
  33. });
  34. if (!hasDeadClickFeature) {
  35. return (
  36. <Layout.Page withPadding>
  37. <Alert type="warning">{t("You don't have access to this feature")}</Alert>
  38. </Layout.Page>
  39. );
  40. }
  41. return (
  42. <SentryDocumentTitle
  43. title={t('Top Selectors with Dead Clicks')}
  44. orgSlug={organization.slug}
  45. >
  46. <Layout.Header>
  47. <Layout.HeaderContent>
  48. <Layout.Title>
  49. {t('Top Selectors with Dead and Rage Clicks')}
  50. <PageHeadingQuestionTooltip
  51. title={t('See the top selectors your users have dead and rage clicked on.')}
  52. docsUrl="https://docs.sentry.io/product/session-replay/replay-page-and-filters/"
  53. />
  54. <FeatureBadge type="beta" />
  55. </Layout.Title>
  56. </Layout.HeaderContent>
  57. <div /> {/* wraps the tabs below the page title */}
  58. <ReplayTabs selected="selectors" />
  59. </Layout.Header>
  60. <PageFiltersContainer>
  61. <Layout.Body>
  62. <Layout.Main fullWidth>
  63. <PageFilterBar condensed>
  64. <ProjectPageFilter resetParamsOnChange={['cursor']} />
  65. <EnvironmentPageFilter resetParamsOnChange={['cursor']} />
  66. <DatePageFilter resetParamsOnChange={['cursor']} />
  67. </PageFilterBar>
  68. <LayoutGap>
  69. <SelectorTable
  70. data={data}
  71. isError={isError}
  72. isLoading={isLoading}
  73. location={location}
  74. clickCountColumns={[
  75. {key: 'count_dead_clicks', name: 'dead clicks'},
  76. {key: 'count_rage_clicks', name: 'rage clicks'},
  77. ]}
  78. clickCountSortable
  79. />
  80. </LayoutGap>
  81. <PaginationNoMargin
  82. pageLinks={pageLinks}
  83. onCursor={(cursor, path, searchQuery) => {
  84. browserHistory.push({
  85. pathname: path,
  86. query: {...searchQuery, cursor},
  87. });
  88. }}
  89. />
  90. </Layout.Main>
  91. </Layout.Body>
  92. </PageFiltersContainer>
  93. </SentryDocumentTitle>
  94. );
  95. }
  96. const LayoutGap = styled('div')`
  97. margin-top: ${space(2)};
  98. `;
  99. const PaginationNoMargin = styled(Pagination)`
  100. margin: 0;
  101. `;