content.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import {useCallback, useMemo} 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 {ALLOWED_EXPLORE_VISUALIZE_AGGREGATES} from 'sentry/utils/fields';
  22. import {useLocation} from 'sentry/utils/useLocation';
  23. import {useNavigate} from 'sentry/utils/useNavigate';
  24. import useOrganization from 'sentry/utils/useOrganization';
  25. import usePageFilters from 'sentry/utils/usePageFilters';
  26. import {ExploreCharts} from 'sentry/views/explore/charts';
  27. import {
  28. SpanTagsProvider,
  29. useSpanTags,
  30. } from 'sentry/views/explore/contexts/spanTagsContext';
  31. import {useDataset} from 'sentry/views/explore/hooks/useDataset';
  32. import {useResultMode} from 'sentry/views/explore/hooks/useResultsMode';
  33. import {useUserQuery} from 'sentry/views/explore/hooks/useUserQuery';
  34. import {ExploreTables} from 'sentry/views/explore/tables';
  35. import {ExploreToolbar} from 'sentry/views/explore/toolbar';
  36. interface ExploreContentProps {
  37. location: Location;
  38. }
  39. function ExploreContentImpl({}: ExploreContentProps) {
  40. const location = useLocation();
  41. const navigate = useNavigate();
  42. const organization = useOrganization();
  43. const {selection} = usePageFilters();
  44. const [dataset] = useDataset();
  45. const [resultsMode] = useResultMode();
  46. const numberTags = useSpanTags('number');
  47. const stringTags = useSpanTags('string');
  48. const supportedAggregates = useMemo(() => {
  49. return resultsMode === 'aggregate' ? ALLOWED_EXPLORE_VISUALIZE_AGGREGATES : [];
  50. }, [resultsMode]);
  51. const [userQuery, setUserQuery] = useUserQuery();
  52. const toolbarExtras = organization.features.includes('visibility-explore-dataset')
  53. ? ['dataset toggle' as const]
  54. : [];
  55. const switchToOldTraceExplorer = useCallback(() => {
  56. navigate({
  57. ...location,
  58. query: {
  59. ...location.query,
  60. view: 'trace',
  61. },
  62. });
  63. }, [location, navigate]);
  64. return (
  65. <SentryDocumentTitle title={t('Explore')} orgSlug={organization.slug}>
  66. <PageFiltersContainer>
  67. <Layout.Page>
  68. <Layout.Header>
  69. <Layout.HeaderContent>
  70. <Layout.Title>{t('Explore')}</Layout.Title>
  71. </Layout.HeaderContent>
  72. <Layout.HeaderActions>
  73. <ButtonBar gap={1}>
  74. <Button onClick={switchToOldTraceExplorer} size="sm">
  75. {t('Switch to Old Trace Explore')}
  76. </Button>
  77. <FeedbackWidgetButton />
  78. </ButtonBar>
  79. </Layout.HeaderActions>
  80. </Layout.Header>
  81. <Body>
  82. <PageFilterBar condensed>
  83. <ProjectPageFilter />
  84. <EnvironmentPageFilter />
  85. <DatePageFilter />
  86. </PageFilterBar>
  87. {dataset === DiscoverDatasets.SPANS_INDEXED ? (
  88. <StyledSpanSearchQueryBuilder
  89. supportedAggregates={supportedAggregates}
  90. projects={selection.projects}
  91. initialQuery={userQuery}
  92. onSearch={setUserQuery}
  93. searchSource="explore"
  94. />
  95. ) : (
  96. <StyledEAPSpanSearchQueryBuilder
  97. supportedAggregates={supportedAggregates}
  98. projects={selection.projects}
  99. initialQuery={userQuery}
  100. onSearch={setUserQuery}
  101. searchSource="explore"
  102. numberTags={numberTags}
  103. stringTags={stringTags}
  104. />
  105. )}
  106. <ExploreToolbar extras={toolbarExtras} />
  107. <Main fullWidth>
  108. <ExploreCharts query={userQuery} />
  109. <ExploreTables />
  110. </Main>
  111. </Body>
  112. </Layout.Page>
  113. </PageFiltersContainer>
  114. </SentryDocumentTitle>
  115. );
  116. }
  117. export function ExploreContent(props: ExploreContentProps) {
  118. const [dataset] = useDataset();
  119. return (
  120. <SpanTagsProvider dataset={dataset}>
  121. <ExploreContentImpl {...props} />
  122. </SpanTagsProvider>
  123. );
  124. }
  125. const Body = styled(Layout.Body)`
  126. display: flex;
  127. flex-direction: column;
  128. gap: ${space(2)};
  129. @media (min-width: ${p => p.theme.breakpoints.large}) {
  130. grid-template-columns: 300px minmax(100px, auto);
  131. }
  132. `;
  133. const StyledSpanSearchQueryBuilder = styled(SpanSearchQueryBuilder)`
  134. grid-column: 2/3;
  135. `;
  136. const StyledEAPSpanSearchQueryBuilder = styled(EAPSpanSearchQueryBuilder)`
  137. grid-column: 2/3;
  138. `;
  139. const Main = styled(Layout.Main)`
  140. grid-column: 2/3;
  141. `;