content.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import {useCallback} from 'react';
  2. import styled from '@emotion/styled';
  3. import type {Location} from 'history';
  4. import {Button} from 'sentry/components/button';
  5. import ButtonBar from 'sentry/components/buttonBar';
  6. import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton';
  7. import * as Layout from 'sentry/components/layouts/thirds';
  8. import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
  9. import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
  10. import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
  11. import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
  12. import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter';
  13. import {
  14. EAPSpanSearchQueryBuilder,
  15. SpanSearchQueryBuilder,
  16. } from 'sentry/components/performance/spanSearchQueryBuilder';
  17. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  18. import {t} from 'sentry/locale';
  19. import {space} from 'sentry/styles/space';
  20. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  21. import {useLocation} from 'sentry/utils/useLocation';
  22. import {useNavigate} from 'sentry/utils/useNavigate';
  23. import useOrganization from 'sentry/utils/useOrganization';
  24. import usePageFilters from 'sentry/utils/usePageFilters';
  25. import {ExploreCharts} from 'sentry/views/explore/charts';
  26. import {
  27. SpanTagsProvider,
  28. useSpanTags,
  29. } from 'sentry/views/explore/contexts/spanTagsContext';
  30. import {useDataset} from 'sentry/views/explore/hooks/useDataset';
  31. import {useUserQuery} from 'sentry/views/explore/hooks/useUserQuery';
  32. import {ExploreTables} from 'sentry/views/explore/tables';
  33. import {ExploreToolbar} from 'sentry/views/explore/toolbar';
  34. interface ExploreContentProps {
  35. location: Location;
  36. }
  37. function ExploreContentImpl({}: ExploreContentProps) {
  38. const location = useLocation();
  39. const navigate = useNavigate();
  40. const organization = useOrganization();
  41. const {selection} = usePageFilters();
  42. const [dataset] = useDataset();
  43. const numberTags = useSpanTags('number');
  44. const stringTags = useSpanTags('string');
  45. const [userQuery, setUserQuery] = useUserQuery();
  46. const toolbarExtras = organization.features.includes('visibility-explore-dataset')
  47. ? ['dataset toggle' as const]
  48. : [];
  49. const switchToOldTraceExplorer = useCallback(() => {
  50. navigate({
  51. ...location,
  52. query: {
  53. ...location.query,
  54. view: 'trace',
  55. },
  56. });
  57. }, [location, navigate]);
  58. return (
  59. <SentryDocumentTitle title={t('Explore')} orgSlug={organization.slug}>
  60. <PageFiltersContainer>
  61. <Layout.Page>
  62. <Layout.Header>
  63. <Layout.HeaderContent>
  64. <Layout.Title>{t('Explore')}</Layout.Title>
  65. </Layout.HeaderContent>
  66. <Layout.HeaderActions>
  67. <ButtonBar gap={1}>
  68. <Button onClick={switchToOldTraceExplorer} size="sm">
  69. {t('Switch to Old Trace Explore')}
  70. </Button>
  71. <FeedbackWidgetButton />
  72. </ButtonBar>
  73. </Layout.HeaderActions>
  74. </Layout.Header>
  75. <Body>
  76. <TopSection>
  77. <StyledPageFilterBar condensed>
  78. <ProjectPageFilter />
  79. <EnvironmentPageFilter />
  80. <DatePageFilter />
  81. </StyledPageFilterBar>
  82. {dataset === DiscoverDatasets.SPANS_INDEXED ? (
  83. <SpanSearchQueryBuilder
  84. projects={selection.projects}
  85. initialQuery={userQuery}
  86. onSearch={setUserQuery}
  87. searchSource="explore"
  88. />
  89. ) : (
  90. <EAPSpanSearchQueryBuilder
  91. projects={selection.projects}
  92. initialQuery={userQuery}
  93. onSearch={setUserQuery}
  94. searchSource="explore"
  95. numberTags={numberTags}
  96. stringTags={stringTags}
  97. />
  98. )}
  99. </TopSection>
  100. <ExploreToolbar extras={toolbarExtras} />
  101. <MainSection fullWidth>
  102. <ExploreCharts query={userQuery} />
  103. <ExploreTables />
  104. </MainSection>
  105. </Body>
  106. </Layout.Page>
  107. </PageFiltersContainer>
  108. </SentryDocumentTitle>
  109. );
  110. }
  111. export function ExploreContent(props: ExploreContentProps) {
  112. const [dataset] = useDataset();
  113. return (
  114. <SpanTagsProvider dataset={dataset}>
  115. <ExploreContentImpl {...props} />
  116. </SpanTagsProvider>
  117. );
  118. }
  119. const Body = styled(Layout.Body)`
  120. gap: ${space(2)};
  121. @media (min-width: ${p => p.theme.breakpoints.medium}) {
  122. grid-template-columns: 300px minmax(100px, auto);
  123. }
  124. @media (min-width: ${p => p.theme.breakpoints.xxlarge}) {
  125. grid-template-columns: 350px minmax(100px, auto);
  126. }
  127. `;
  128. const TopSection = styled('div')`
  129. display: grid;
  130. gap: ${space(2)};
  131. grid-column: 1/3;
  132. margin-bottom: ${space(2)};
  133. @media (min-width: ${p => p.theme.breakpoints.large}) {
  134. grid-template-columns: minmax(300px, auto) 1fr;
  135. margin-bottom: 0;
  136. }
  137. @media (min-width: ${p => p.theme.breakpoints.xxlarge}) {
  138. grid-template-columns: minmax(350px, auto) 1fr;
  139. }
  140. `;
  141. const MainSection = styled(Layout.Main)`
  142. grid-column: 2/3;
  143. `;
  144. const StyledPageFilterBar = styled(PageFilterBar)`
  145. width: auto;
  146. `;