Browse Source

feat(eap): Switch to eap for explore autocompletion (#79156)

This switches the autocompletion for the explore search bar to use the
RPC layer.
Tony Xiao 4 months ago
parent
commit
faab8aad59

+ 6 - 0
static/app/actionCreators/tags.tsx

@@ -171,10 +171,12 @@ export function fetchSpanFieldValues({
   endpointParams,
   projectIds,
   search,
+  dataset,
 }: {
   api: Client;
   fieldKey: string;
   orgSlug: string;
+  dataset?: 'spans' | 'spansIndexed';
   endpointParams?: Query;
   projectIds?: string[];
   search?: string;
@@ -199,6 +201,10 @@ export function fetchSpanFieldValues({
       query.statsPeriod = endpointParams.statsPeriod;
     }
   }
+  if (dataset === 'spans') {
+    query.dataset = 'spans';
+    query.type = 'string';
+  }
 
   return api.requestPromise(url, {
     method: 'GET',

+ 80 - 0
static/app/components/performance/spanSearchQueryBuilder.tsx

@@ -146,3 +146,83 @@ export function SpanSearchQueryBuilder({
     />
   );
 }
+
+interface EAPSpanSearchQueryBuilderProps extends SpanSearchQueryBuilderProps {
+  numberTags: TagCollection;
+  stringTags: TagCollection;
+}
+
+export function EAPSpanSearchQueryBuilder({
+  initialQuery,
+  placeholder,
+  onSearch,
+  searchSource,
+  numberTags,
+  stringTags,
+}: EAPSpanSearchQueryBuilderProps) {
+  const api = useApi();
+  const organization = useOrganization();
+  const {selection} = usePageFilters();
+
+  const placeholderText = placeholder ?? t('Search for spans, users, tags, and more');
+
+  const tags = useMemo(() => {
+    return {...numberTags, ...stringTags};
+  }, [numberTags, stringTags]);
+
+  const filterKeySections = useMemo(() => {
+    const predefined = new Set(
+      SPANS_FILTER_KEY_SECTIONS.flatMap(section => section.children)
+    );
+    return [
+      ...SPANS_FILTER_KEY_SECTIONS,
+      {
+        value: 'custom_fields',
+        label: 'Custom Tags',
+        children: Object.keys(stringTags).filter(key => !predefined.has(key)),
+      },
+    ];
+  }, [stringTags]);
+
+  const getSpanFilterTagValues = useCallback(
+    async (tag: Tag, queryString: string) => {
+      if (isAggregateField(tag.key) || numberTags.hasOwnProperty(tag.key)) {
+        // We can't really auto suggest values for aggregate fields
+        // or measurements, so we simply don't
+        return Promise.resolve([]);
+      }
+
+      try {
+        const results = await fetchSpanFieldValues({
+          api,
+          orgSlug: organization.slug,
+          fieldKey: tag.key,
+          search: queryString,
+          projectIds: selection.projects.map(String),
+          endpointParams: normalizeDateTimeParams(selection.datetime),
+          dataset: 'spans',
+        });
+        return results.filter(({name}) => defined(name)).map(({name}) => name);
+      } catch (e) {
+        throw new Error(`Unable to fetch event field values: ${e}`);
+      }
+    },
+    [api, organization.slug, selection.projects, selection.datetime, numberTags]
+  );
+
+  return (
+    <SearchQueryBuilder
+      placeholder={placeholderText}
+      filterKeys={tags}
+      initialQuery={initialQuery}
+      fieldDefinitionGetter={getSpanFieldDefinition}
+      onSearch={onSearch}
+      searchSource={searchSource}
+      filterKeySections={filterKeySections}
+      getTagValues={getSpanFilterTagValues}
+      disallowUnsupportedFilters
+      recentSearches={SavedSearchType.SPAN}
+      showUnsubmittedIndicator
+    />
+  );
+}

+ 36 - 9
static/app/views/explore/content.tsx

@@ -11,17 +11,24 @@ import {EnvironmentPageFilter} from 'sentry/components/organizations/environment
 import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
 import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
 import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter';
-import {SpanSearchQueryBuilder} from 'sentry/components/performance/spanSearchQueryBuilder';
+import {
+  EAPSpanSearchQueryBuilder,
+  SpanSearchQueryBuilder,
+} from 'sentry/components/performance/spanSearchQueryBuilder';
 import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
+import {DiscoverDatasets} from 'sentry/utils/discover/types';
 import {ALLOWED_EXPLORE_VISUALIZE_AGGREGATES} from 'sentry/utils/fields';
 import {useLocation} from 'sentry/utils/useLocation';
 import {useNavigate} from 'sentry/utils/useNavigate';
 import useOrganization from 'sentry/utils/useOrganization';
 import usePageFilters from 'sentry/utils/usePageFilters';
 import {ExploreCharts} from 'sentry/views/explore/charts';
-import {SpanTagsProvider} from 'sentry/views/explore/contexts/spanTagsContext';
+import {
+  SpanTagsProvider,
+  useSpanTags,
+} from 'sentry/views/explore/contexts/spanTagsContext';
 import {useDataset} from 'sentry/views/explore/hooks/useDataset';
 import {useResultMode} from 'sentry/views/explore/hooks/useResultsMode';
 import {useUserQuery} from 'sentry/views/explore/hooks/useUserQuery';
@@ -37,8 +44,12 @@ function ExploreContentImpl({}: ExploreContentProps) {
   const navigate = useNavigate();
   const organization = useOrganization();
   const {selection} = usePageFilters();
+  const [dataset] = useDataset();
   const [resultsMode] = useResultMode();
 
+  const numberTags = useSpanTags('number');
+  const stringTags = useSpanTags('string');
+
   const supportedAggregates = useMemo(() => {
     return resultsMode === 'aggregate' ? ALLOWED_EXPLORE_VISUALIZE_AGGREGATES : [];
   }, [resultsMode]);
@@ -82,13 +93,25 @@ function ExploreContentImpl({}: ExploreContentProps) {
               <EnvironmentPageFilter />
               <DatePageFilter />
             </PageFilterBar>
-            <StyledSpanSearchQueryBuilder
-              supportedAggregates={supportedAggregates}
-              projects={selection.projects}
-              initialQuery={userQuery}
-              onSearch={setUserQuery}
-              searchSource="explore"
-            />
+            {dataset === DiscoverDatasets.SPANS_INDEXED ? (
+              <StyledSpanSearchQueryBuilder
+                supportedAggregates={supportedAggregates}
+                projects={selection.projects}
+                initialQuery={userQuery}
+                onSearch={setUserQuery}
+                searchSource="explore"
+              />
+            ) : (
+              <StyledEAPSpanSearchQueryBuilder
+                supportedAggregates={supportedAggregates}
+                projects={selection.projects}
+                initialQuery={userQuery}
+                onSearch={setUserQuery}
+                searchSource="explore"
+                numberTags={numberTags}
+                stringTags={stringTags}
+              />
+            )}
             <ExploreToolbar extras={toolbarExtras} />
             <Main fullWidth>
               <ExploreCharts query={userQuery} />
@@ -125,6 +148,10 @@ const StyledSpanSearchQueryBuilder = styled(SpanSearchQueryBuilder)`
   grid-column: 2/3;
 `;
 
+const StyledEAPSpanSearchQueryBuilder = styled(EAPSpanSearchQueryBuilder)`
+  grid-column: 2/3;
+`;
+
 const Main = styled(Layout.Main)`
   grid-column: 2/3;
 `;