Browse Source

feat(dashboards): Events `SearchQueryBuilder` (#76958)

Follow-up to #76944

I'm using `ResultsSearchQueryBuilder` here because it does everything
I'd need to do and more. I had to tweak it a little (accept an
`onChange`, allow an optional `onSearch`, remove a bottom margin) but
otherwise I'm using it straight as-is.

IMO it probably deserves a more generic name, but to be honest once the
dataset splits in the UI are complete this might look pretty different.

Here as in the other PR, the flag that controls the query builder is
`'search-query-builder-discover'` so it's in sync with what Discover is
doing.
George Gritsouk 6 months ago
parent
commit
6dd27d40fa

+ 15 - 1
static/app/views/dashboards/widgetBuilder/buildSteps/filterResultsStep/eventsSearchBar.tsx

@@ -15,6 +15,7 @@ import {
   MAX_MENU_HEIGHT,
   MAX_SEARCH_ITEMS,
 } from 'sentry/views/dashboards/widgetBuilder/utils';
+import ResultsSearchQueryBuilder from 'sentry/views/discover/resultsSearchQueryBuilder';
 
 interface Props {
   getFilterWarning: SearchBarProps['getFilterWarning'];
@@ -42,7 +43,20 @@ export function EventsSearchBar({
     ? generateAggregateFields(organization, eventView.fields)
     : eventView.fields;
 
-  return (
+  return organization.features.includes('search-query-builder-discover') ? (
+    <ResultsSearchQueryBuilder
+      projectIds={eventView.project}
+      query={widgetQuery.conditions}
+      fields={fields}
+      onChange={(query, state) => {
+        onClose?.(query, {validSearch: state.queryIsValid});
+      }}
+      customMeasurements={customMeasurements}
+      dataset={dataset}
+      includeTransactions={hasDatasetSelector(organization) ? false : true}
+      searchSource="widget_builder"
+    />
+  ) : (
     <Search
       searchSource="widget_builder"
       organization={organization}

+ 5 - 1
static/app/views/discover/results.tsx

@@ -685,7 +685,7 @@ export class Results extends Component<Props, State> {
 
     if (organization.features.includes('search-query-builder-discover')) {
       return (
-        <ResultsSearchQueryBuilder
+        <StyledResultsSearchQueryBuilder
           projectIds={eventView.project}
           query={eventView.query}
           fields={fields}
@@ -872,6 +872,10 @@ const Wrapper = styled('div')`
   }
 `;
 
+const StyledResultsSearchQueryBuilder = styled(ResultsSearchQueryBuilder)`
+  margin-bottom: ${space(2)};
+`;
+
 const StyledSearchBar = styled(SearchBar)`
   margin-bottom: ${space(2)};
 `;

+ 10 - 10
static/app/views/discover/resultsSearchQueryBuilder.tsx

@@ -1,5 +1,4 @@
 import {useCallback, useMemo} from 'react';
-import styled from '@emotion/styled';
 import omit from 'lodash/omit';
 
 import {fetchSpanFieldValues, fetchTagValues} from 'sentry/actionCreators/tags';
@@ -14,9 +13,11 @@ import {
 } from 'sentry/components/events/searchBarFieldConstants';
 import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse';
 import {SearchQueryBuilder} from 'sentry/components/searchQueryBuilder';
-import type {FilterKeySection} from 'sentry/components/searchQueryBuilder/types';
+import type {
+  CallbackSearchState,
+  FilterKeySection,
+} from 'sentry/components/searchQueryBuilder/types';
 import {t} from 'sentry/locale';
-import {space} from 'sentry/styles/space';
 import {SavedSearchType, type TagCollection} from 'sentry/types/group';
 import {defined} from 'sentry/utils';
 import type {CustomMeasurementCollection} from 'sentry/utils/customMeasurements/customMeasurements';
@@ -112,16 +113,18 @@ export const getHasTag = (tags: TagCollection) => ({
 });
 
 type Props = {
-  onSearch: (query: string) => void;
   customMeasurements?: CustomMeasurementCollection;
   dataset?: DiscoverDatasets;
   fields?: Readonly<Field[]>;
   includeSessionTagsValues?: boolean;
   includeTransactions?: boolean;
   omitTags?: string[];
+  onChange?: (query: string, state: CallbackSearchState) => void;
+  onSearch?: (query: string) => void;
   placeholder?: string;
   projectIds?: number[] | Readonly<number[]>;
   query?: string;
+  searchSource?: string;
   supportedTags?: TagCollection | undefined;
 };
 
@@ -277,12 +280,13 @@ function ResultsSearchQueryBuilder(props: Props) {
   }, [filteredTags, dataset]);
 
   return (
-    <StyledResultsSearchQueryBuilder
+    <SearchQueryBuilder
       placeholder={placeholderText}
       filterKeys={getTagList}
       initialQuery={props.query ?? ''}
       onSearch={props.onSearch}
-      searchSource={'eventsv2'}
+      onChange={props.onChange}
+      searchSource={props.searchSource || 'eventsv2'}
       filterKeySections={filterKeySections}
       getTagValues={getEventFieldValues}
       recentSearches={SavedSearchType.EVENT}
@@ -290,8 +294,4 @@ function ResultsSearchQueryBuilder(props: Props) {
   );
 }
 
-const StyledResultsSearchQueryBuilder = styled(SearchQueryBuilder)`
-  margin-bottom: ${space(2)};
-`;
-
 export default ResultsSearchQueryBuilder;